/**
* Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Description: Data system object cache client management.
*/
#ifndef DATASYSTEM_OBJECT_CLIENT_H
#define DATASYSTEM_OBJECT_CLIENT_H
#include <memory>
#include <unordered_set>
#include <vector>
#include "datasystem/context/context.h"
#include "datasystem/object/buffer.h"
#include "datasystem/object/object_enum.h"
#include "datasystem/utils/connection.h"
#include "datasystem/utils/optional.h"
#include "datasystem/utils/status.h"
#include "datasystem/utils/string_view.h"
namespace datasystem {
namespace object_cache {
class ObjectClientImpl;
} // namespace object_cache
} // namespace datasystem
namespace datasystem {
struct CreateParam {
ConsistencyType consistencyType = ConsistencyType::PRAM;
CacheType cacheType = CacheType::MEMORY;
};
struct ObjMetaInfo {
uint64_t objSize{ 0 }; // the size of object data, 0 if object not found.
std::vector<std::string> locations; // the workerIds of the locations
};
class __attribute((visibility("default"))) ObjectClient : public std::enable_shared_from_this<ObjectClient> {
public:
/// \brief Construct ObjectClient.
///
/// \param[in] connectOptions the connect options.
explicit ObjectClient(const ConnectOptions &connectOptions = {});
~ObjectClient();
/// \brief Shutdown the object client.
///
/// \return K_OK on success; the error code otherwise.
Status ShutDown();
/// \brief Init the object client.
///
/// \return K_OK on success; the error code otherwise.
Status Init();
/// \brief Increase the global reference count to objects in the data system.
///
/// \param[in] objectKeys The object keys to increase, it cannot be empty. ID should not be empty and should only
/// contains english alphabetics (a-zA-Z), numbers and ~!@#$%^&*.-_ only. ID length should less than 256.
/// \param[out] failedObjectKeys Increase failed object keys.
/// \param[in] remoteClientId The remote client id of the client that outside the cloud. Resolve scenarios that ELB
/// forwards requests to different gateways, resulting in incorrect increase or decrease in reference counts, and
/// system availability after gateway crash.
///
/// \return K_OK on any object success, the failedObjectKeys indicate the failed list.
/// K_RPC_UNAVAILABLE: Disconnect from worker or master.
/// K_INVALID: The parameter is invalid.
Status GIncreaseRef(const std::vector<std::string> &objectKeys, std::vector<std::string> &failedObjectKeys,
const std::string &remoteClientId = "");
/// \brief Decrease the global reference count to objects in the data system.
///
/// \param[in] objectKeys The object keys to decrease, it cannot be empty. ID should not be empty and should only
/// contains english alphabetics (a-zA-Z), numbers and ~!@#$%^&*.-_ only. ID length should less than 256.
/// \param[out] failedObjectKeys Decrease failed object keys.
/// \param[in] remoteClientId The remote client id of the client that outside the cloud. Resolve scenarios that ELB
/// forwards requests to different gateways, resulting in incorrect increase or decrease in reference counts, and
/// system availability after gateway crash.
///
/// \return K_OK on any object success, the failedObjectKeys indicate the failed list.
/// K_RPC_UNAVAILABLE: Disconnect from worker or master.
/// K_INVALID: The parameter is invalid.
Status GDecreaseRef(const std::vector<std::string> &objectKeys, std::vector<std::string> &failedObjectKey,
const std::string &remoteClientId = "");
/// \brief Release obj Ref of remote client id when remote client that outside the cloud crash.
///
/// \param[in] remoteClientId The remote client id of the client that outside the cloud.
///
/// \return K_OK on any object success, the failedObjectKeys indicate the failed list.
/// K_RPC_UNAVAILABLE: Disconnect from worker or master.
/// K_INVALID: The parameter is invalid.
Status ReleaseGRefs(const std::string &remoteClientId);
/// \brief Query all objects global references in the cluster (out-cloud reference not included).
///
/// \param[in] objectKey The specific object key that to query. ID should not be empty and should only contains
/// letters, numbers and ~!@#$%^&*.-_ only. ID length should less than 256.
///
/// \return The objects' global reference num; -1 in case of failure.
int QueryGlobalRefNum(const std::string &objectKey);
/// \brief Invoke worker client to create an object.
///
/// \param[in] objectKey The ID of the object to create. ID should not be empty and should only contains english
/// alphabetics (a-zA-Z), numbers and ~!@#$%^&*.-_ only. ID length should less than 256.
/// \param[in] size The size in bytes of object.
/// \param[in] param The create parameters.
/// \param[out] buffer The buffer for the object.
///
/// \return K_OK on success; the error code otherwise.
/// K_INVALID: the key or val is empty.
/// K_RUNTIME_ERROR: client fd mmap failed
Status Create(const std::string &objectKey, uint64_t size, const CreateParam ¶m,
std::shared_ptr<Buffer> &buffer);
/// \brief Invoke worker client to put an object (publish semantics).
///
/// \param[in] objectKey The ID of the object to create. ID should not be empty and should only contains english
/// alphabetics (a-zA-Z), numbers and ~!@#$%^&*.-_ only. ID length should less than 256.
/// \param[in] data The data pointer of the user.
/// \param[in] size The size in bytes of object.
/// \param[in] param The create parameters.
/// \param[in] nestedObjectKeys Objects that depend on objectKey.
///
/// \return K_OK on success; the error code otherwise.
Status Put(const std::string &objectKey, const uint8_t *data, uint64_t size, const CreateParam ¶m,
const std::unordered_set<std::string> &nestedObjectKeys = {});
/// \brief Invoke worker client to get all buffers of all the given object keys.
///
/// \param[in] objectKeys The vector of the object key. ID should not be empty and should only contains english
/// alphabetics (a-zA-Z), numbers and ~!@#$%^&*.-_ only. ID length should less than 256.
/// \param[in] subTimeoutMs Timeout(ms) of waiting for the result return if object not ready. A positive integer
/// number required. 0 means no waiting time allowed. And the range is [0, INT32_MAX].
/// \param[out] buffers The return vector of the objects.
///
/// \return K_OK on any object success; the error code otherwise.
/// K_INVALID: the vector of keys is empty or include empty key.
/// K_NOT_FOUND: The objects not exists.
/// K_RUNTIME_ERROR: Cannot get objects from worker.
Status Get(const std::vector<std::string> &objectKeys, int32_t subTimeoutMs,
std::vector<Optional<Buffer>> &buffers);
/// \brief Update token for yr iam
///
/// \param[in] token message for auth certification
///
/// \return K_OK on success; the error code otherwise.
Status UpdateToken(SensitiveValue token);
/// \brief Update aksk for yr iam
///
/// \param[in] accessKey message for auth certification
/// \param[in] secretKey message for auth certification
///
/// \return K_OK on success; the error code otherwise.
Status UpdateAkSk(const std::string accessKey, SensitiveValue secretKey);
/// \brief Get meta info of the given objects.
///
/// \param[in] tenantId The tenant that the objs belong to.
/// \param[in] objectKeys The vector of the object key.
/// \param[out] objMetas The vector of the return metas.
///
/// \return K_OK on any object success.
/// K_INVALID: the vector of keys is empty or include invalid key.
/// K_RPC_UNAVAILABLE: Disconnect from worker or master.
/// K_NOT_AUTHORIZED: The client is not authorized for the tenantId.
Status GetObjMetaInfo(const std::string &tenantId, const std::vector<std::string> &objectKeys,
std::vector<ObjMetaInfo> &objMetas);
/// \brief Generate an object key.
///
/// \param[in] prefix The objectKey generated by user.
/// \param[out] key If prefix is empty, returns a random unique key; otherwise returns prefix.
///
/// \return K_OK on any object success; the error code otherwise.
Status GenerateKey(const std::string &prefix, std::string &key);
/// \brief Generate an object key.
///
/// \param[in] prefix The objectId generated by user.
/// \param[out] objectId If prefix is empty, returns a random unique key; otherwise returns prefix.
///
/// \return K_OK on any object success; the error code otherwise.
Status GenerateObjectKey(const std::string &prefix, std::string &objectId);
/// \brief Worker health check.
///
/// \return K_OK on any object success; the error code otherwise.
Status HealthCheck();
private:
std::shared_ptr<object_cache::ObjectClientImpl> impl_;
};
} // namespace datasystem
#endif // DATASYSTEM_OBJECT_CACHE_OBJECT_CLIENT_H