yyweii commented on code in PR #1922: URL: https://github.com/apache/incubator-brpc/pull/1922#discussion_r967996947
########## src/brpc/policy/nacos_naming_service.cpp: ########## @@ -0,0 +1,287 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 "nacos_naming_service.h" + +#include <gflags/gflags.h> + +#include <set> + +#include "brpc/http_status_code.h" +#include "brpc/log.h" +#include "butil/iobuf.h" +#include "butil/logging.h" +#include "butil/third_party/rapidjson/document.h" + +namespace brpc { +namespace policy { + +DEFINE_string(nacos_address, "http://127.0.0.1:8848", + "The query string of request nacos for discovering service."); +DEFINE_string(nacos_service_discovery_path, "/nacos/v1/ns/instance/list", + "The url path for discovering service."); +DEFINE_string(nacos_service_auth_path, "/nacos/v1/auth/login", + "The url path for authentiction."); +DEFINE_int32(nacos_connect_timeout_ms, 200, + "Timeout for creating connections to nacos in milliseconds"); +DEFINE_string(nacos_username, "", "nacos username"); +DEFINE_string(nacos_password, "", "nacos password"); + +int NacosNamingService::Connect() { + ChannelOptions opt; + opt.protocol = PROTOCOL_HTTP; + opt.connect_timeout_ms = FLAGS_nacos_connect_timeout_ms; + const int ret = _channel.Init(FLAGS_nacos_address.c_str(), "rr", &opt); + if (ret != 0) { + LOG(ERROR) << "Fail to init channel to nacos at " + << FLAGS_nacos_address; + } + return ret; +} + +int NacosNamingService::RefreshAccessToken(const char *service_name) { + Controller cntl; + cntl.http_request().uri() = FLAGS_nacos_service_auth_path; + cntl.http_request().set_method(brpc::HttpMethod::HTTP_METHOD_POST); + cntl.http_request().set_content_type("application/x-www-form-urlencoded"); + + auto &buf = cntl.request_attachment(); + buf.append("username="); + buf.append(FLAGS_nacos_username); + buf.append("&password="); + buf.append(FLAGS_nacos_password); + + _channel.CallMethod(nullptr, &cntl, nullptr, nullptr, nullptr); + if (cntl.Failed()) { + LOG(ERROR) << "Fail to access " << FLAGS_nacos_service_auth_path << ": " + << cntl.ErrorText(); + return -1; + } + + BUTIL_RAPIDJSON_NAMESPACE::Document doc; + if (doc.Parse(cntl.response_attachment().to_string().c_str()) + .HasParseError()) { + LOG(ERROR) << "Failed to parse nacos auth response"; + return -1; + } + if (!doc.IsObject()) { + LOG(ERROR) << "The nacos's auth response for " << service_name + << " is not a json object"; + return -1; + } + + auto iter = doc.FindMember("accessToken"); + if (iter != doc.MemberEnd() && iter->value.IsString()) { + _access_token = iter->value.GetString(); + } else { + LOG(ERROR) << "The nacos's auth response for " << service_name + << " has no accessToken field"; + return -1; + } + + auto iter_ttl = doc.FindMember("tokenTtl"); + if (iter_ttl != doc.MemberEnd() && iter_ttl->value.IsInt()) { + _token_expire_time = time(NULL) + iter_ttl->value.GetInt() - 10; + } else { + _token_expire_time = 0; + } + + return 0; +} + +int NacosNamingService::GetServerNodes(const char *service_name, + bool token_changed, + std::vector<ServerNode> *nodes) { + if (_nacos_url.empty() || token_changed) { + _nacos_url = FLAGS_nacos_service_discovery_path; + _nacos_url += "?"; + if (!_access_token.empty()) { + _nacos_url += "accessToken=" + _access_token; + _nacos_url += "&"; + } + _nacos_url += service_name; + } + + Controller cntl; + cntl.http_request().uri() = _nacos_url; + _channel.CallMethod(nullptr, &cntl, nullptr, nullptr, nullptr); + if (cntl.Failed()) { + LOG(ERROR) << "Fail to access " << _nacos_url << ": " + << cntl.ErrorText(); + return -1; + } + if (cntl.http_response().status_code() != HTTP_STATUS_OK) { + LOG(ERROR) << "Failed to request nacos, http status code: " + << cntl.http_response().status_code(); + return -1; + } + + BUTIL_RAPIDJSON_NAMESPACE::Document doc; + if (doc.Parse(cntl.response_attachment().to_string().c_str()) + .HasParseError()) { + LOG(ERROR) << "Failed to parse nacos response"; + return -1; + } + if (!doc.IsObject()) { + LOG(ERROR) << "The nacos's response for " << service_name + << " is not a json object"; + return -1; + } + + auto it_hosts = doc.FindMember("hosts"); + if (it_hosts == doc.MemberEnd()) { + LOG(ERROR) << "The nacos's response for " << service_name + << " has no hosts member"; + return -1; + } + auto &hosts = it_hosts->value; + if (!hosts.IsArray()) { + LOG(ERROR) << "hosts member in nacos response is not an array"; + return -1; + } + + std::set<ServerNode> presence; + for (auto it = hosts.Begin(); it != hosts.End(); ++it) { + auto &host = *it; + if (!host.IsObject()) { + LOG(ERROR) << "host member in nacos response is not an object"; + continue; + } + + auto it_ip = host.FindMember("ip"); + auto it_port = host.FindMember("port"); + auto it_weight = host.FindMember("weight"); + if (it_ip == host.MemberEnd() || it_port == host.MemberEnd()) { Review Comment: 已改 ########## src/brpc/policy/nacos_naming_service.h: ########## @@ -0,0 +1,69 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 BRPC_POLICY_NACOS_NAMING_SERVICE_H +#define BRPC_POLICY_NACOS_NAMING_SERVICE_H + +#include <time.h> + +#include <string> +#include <vector> + +#include "brpc/channel.h" +#include "brpc/periodic_naming_service.h" +#include "brpc/server_node.h" + +namespace brpc { +namespace policy { + +// Acquire server list from nacos +class NacosNamingService : public PeriodicNamingService { +public: + NacosNamingService(); + + virtual int GetServers(const char* service_name, Review Comment: 已改 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
