* Copyright (c) Huawei Technologies Co., Ltd. 2025. 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.
*/
#ifndef FUNCTION_AGENT_COMMON_UTILS_H
#define FUNCTION_AGENT_COMMON_UTILS_H
#include <string>
#include <async/option.hpp>
#include "common/proto/pb/message_pb.h"
#include "common/metadata/metadata.h"
namespace functionsystem::function_agent {
std::shared_ptr<messages::DeployRequest> SetDeployRequestConfig(
const std::shared_ptr<messages::DeployInstanceRequest> &req, const std::shared_ptr<messages::Layer> &layer);
std::shared_ptr <messages::DeployRequest> BuildDeployRequestConfigByLayerInfo(
const Layer &info, const std::shared_ptr <messages::DeployRequest> &config);
void AddDefaultEnv(const std::shared_ptr<messages::DeployInstanceRequest> &req, messages::RuntimeConfig &runtimeConf);
messages::RuntimeConfig SetRuntimeConfig(const std::shared_ptr<messages::DeployInstanceRequest> &req);
void SetDeploymentConfig(messages::DeploymentConfig *deploymentConf,
const std::shared_ptr<messages::DeployInstanceRequest> &req);
void SetTenantCredConfig(const std::shared_ptr<messages::DeployInstanceRequest> &req,
messages::RuntimeConfig &runtimeConf);
messages::RuntimeInstanceInfo SetRuntimeInstanceInfo(const std::shared_ptr<messages::DeployInstanceRequest> &req);
messages::DeploymentConfig SetDeploymentConfigOfLayer(const std::shared_ptr<messages::DeployInstanceRequest> &req,
const std::shared_ptr<messages::Layer> &layer);
void SetUserEnv(const std::shared_ptr<messages::DeployInstanceRequest> &req, messages::RuntimeConfig &runtimeConf);
void ParseDelegateEnv(const std::string &value, messages::RuntimeConfig &runtimeConf);
void SetCreateOptions(const std::shared_ptr<messages::DeployInstanceRequest> &req, messages::RuntimeConfig &runtimeConf,
const std::vector<std::string> &keyList);
void SetTLSConfig(const std::shared_ptr<messages::DeployInstanceRequest> &req, messages::RuntimeConfig &runtimeConf);
void SetStartRuntimeInstanceRequestConfig(const std::unique_ptr<messages::StartInstanceRequest> &startInstanceRequest,
const std::shared_ptr<messages::DeployInstanceRequest> &req);
void SetStopRuntimeInstanceRequest(messages::StopInstanceRequest &stopInstanceRequest,
const std::shared_ptr<messages::KillInstanceRequest> &req);
void SetDelegateDecryptInfo(const std::shared_ptr<messages::DeployInstanceRequest> &req,
messages::RuntimeConfig &runtimeConf);
void SetSubDirConfig(const std::shared_ptr<messages::DeployInstanceRequest> &req, messages::RuntimeConfig &runtimeConf);
std::unordered_map<std::string, std::shared_ptr<messages::Layer>> SetDeployingRequestLayers(
const messages::FuncDeploySpec &spec);
std::string JoinEntryFile(const std::shared_ptr<messages::DeployInstanceRequest> &req,
const std::string &entryFileName);
bool HasSuffix(const std::string &source, const std::string &suffix);
bool IsDir(const std::string &path);
std::vector<std::string> Field(const std::string &str, const char &ch);
void AddLayer(const std::shared_ptr<messages::DeployInstanceRequest> &req);
litebus::Option<std::string> DecryptDelegateData(const std::string &str, const std::string &defKey);
void ParseEnvInfoJson(const std::string &parsedJson, messages::RuntimeConfig &runtimeConf);
void ParseMountConfig(messages::RuntimeConfig &runtimeConfig, const std::string &str);
template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
std::optional<T> GetBoundedJsonValue(const nlohmann::json &j, const std::string &key, T min, T max)
{
if (!j.contains(key)) {
YRLOG_DEBUG("json field {} not exist.", key);
return std::nullopt;
}
T value;
try {
const auto &item = j.at(key);
if (item.is_number()) {
value = item.get<T>();
} else if (item.is_string()) {
auto valueStr = item.get<std::string>();
value = static_cast<T>(std::stoll(valueStr));
} else {
YRLOG_DEBUG("json field {} invalid type.", key);
return std::nullopt;
}
} catch (const std::exception &e) {
YRLOG_DEBUG("json field {} parse error: {}", key, e.what());
return std::nullopt;
}
if (value < min || value > max) {
YRLOG_DEBUG("json field {} value {} out of range: [{}, {}]", key, value, min, max);
return std::nullopt;
}
return value;
}
}
#endif