* 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.
*/
#include "remote_plugin_client.h"
#include <grpcpp/grpcpp.h>
#include "function_agent/plugin/plugin_config.h"
namespace functionsystem::function_agent {
inline bool IsLocalAddress(const std::string &address)
{
return address.find("localhost") != std::string::npos ||
address.find("127.0.0.1") != std::string::npos ||
address.find("[::1]") != std::string::npos;
}
inline bool IsUnixSocket(const std::string &address)
{
return address.find("unix://") == 0;
}
RemotePluginClient::RemotePluginClient(const std::string &address, const long timeout)
{
bool useInsecureChannel = IsLocalAddress(address) || IsUnixSocket(address);
if (useInsecureChannel) {
channel_ = grpc::CreateChannel(address, grpc::InsecureChannelCredentials());
} else {
channel_ = grpc::CreateChannel(address, grpc::SslCredentials(grpc::SslCredentialsOptions()));
}
stub_ = agent_plugin::PluginService::NewStub(channel_);
this->callTimeout_ = timeout;
YRLOG_INFO("init remote plugin client, address: {}, useInsecureChannel {}", address, useInsecureChannel);
}
Status RemotePluginClient::Call(const agent_plugin::PluginRequest &request, agent_plugin::PluginResponse &response)
{
grpc::ClientContext context;
auto deadline = std::chrono::system_clock::now() + std::chrono::milliseconds(callTimeout_);
if (request.method() == METHOD_HEALTHCHECK) {
deadline = std::chrono::system_clock::now() + std::chrono::milliseconds(healthCheckTimeout_);
}
context.set_deadline(deadline);
auto grpcStatus = stub_->Call(&context, request, &response);
if (!grpcStatus.ok()) {
YRLOG_ERROR("{}|{}|failed to call remote plugin client, error code: {}, error message: {}, error details: {}",
request.traceid(), request.requestid(), static_cast<int>(grpcStatus.error_code()),
grpcStatus.error_message(), grpcStatus.error_details());
if (grpcStatus.error_code() == grpc::StatusCode::DEADLINE_EXCEEDED) {
return Status(StatusCode::REQUEST_TIME_OUT,
"call remote plugin client time out after " + std::to_string(callTimeout_));
}
return Status(StatusCode::FAILED, "failed to call remote plugin client");
}
if (response.code() != 0) {
YRLOG_ERROR("{}|{}|remote plugin client response is not ok, error code: {}, error message: {}",
request.traceid(), request.requestid(), response.code(), response.message());
return Status(StatusCode::FAILED, "remote plugin client response is not ok, " + response.message());
}
return Status::OK();
}
void RemotePluginClient::Close()
{
if (stub_) {
stub_.reset();
YRLOG_INFO("stub_ is reset");
} else {
YRLOG_WARN("stub_ is null");
}
if (channel_) {
channel_.reset();
YRLOG_INFO("channel_ is reset");
} else {
YRLOG_WARN("channel_ is null");
}
}
}