Implement C++ Admin Interface API (#25753)
* Implement C++ Admin Interface API * Address reviewer's requests * Remove static asserts for raw pointers * Make sanity tests happy * Windows: pacify conflict between ifndef and macros * Disable admin services test on iOS * Make iOS happy by: * Letting grpcpp_admin conditionally depend on grpcpp_csds * Fix an unexpected side-effect of dependency updatepull/25793/head
parent
55e32434ec
commit
b457f43227
9 changed files with 329 additions and 1 deletions
@ -0,0 +1,33 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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 GRPCPP_EXT_ADMIN_SERVICES_H |
||||
#define GRPCPP_EXT_ADMIN_SERVICES_H |
||||
|
||||
#include <grpcpp/server_builder.h> |
||||
|
||||
namespace grpc { |
||||
|
||||
// Registers admin services to the given ServerBuilder. This function will add
|
||||
// admin services based on build time dependencies, for example, it only adds
|
||||
// CSDS service if xDS is enabled in this binary.
|
||||
void AddAdminServices(grpc::ServerBuilder* builder); |
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCPP_EXT_ADMIN_SERVICES_H
|
@ -0,0 +1,52 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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 <grpc/support/port_platform.h> |
||||
|
||||
#include "absl/memory/memory.h" |
||||
|
||||
#include <grpcpp/ext/admin_services.h> |
||||
#include <grpcpp/impl/server_builder_plugin.h> |
||||
|
||||
#include <grpcpp/server_builder.h> |
||||
|
||||
// TODO(lidiz) build a real registration system that can pull in services
|
||||
// automatically with minimum amount of code.
|
||||
#include "src/cpp/server/channelz/channelz_service.h" |
||||
#ifndef GRPC_NO_XDS |
||||
#include "src/cpp/server/csds/csds.h" |
||||
#endif // GRPC_NO_XDS
|
||||
namespace grpc { |
||||
|
||||
namespace { |
||||
|
||||
static auto* g_channelz_service = new ChannelzService(); |
||||
#ifndef GRPC_NO_XDS |
||||
static auto* g_csds = new xds::experimental::ClientStatusDiscoveryService(); |
||||
#endif // GRPC_NO_XDS
|
||||
|
||||
} // namespace
|
||||
|
||||
void AddAdminServices(ServerBuilder* builder) { |
||||
builder->RegisterService(g_channelz_service); |
||||
#ifndef GRPC_NO_XDS |
||||
builder->RegisterService(g_csds); |
||||
#endif // GRPC_NO_XDS
|
||||
} |
||||
|
||||
} // namespace grpc
|
@ -0,0 +1,103 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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 <gmock/gmock.h> |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "absl/strings/str_cat.h" |
||||
|
||||
#include <grpcpp/ext/admin_services.h> |
||||
#include <grpcpp/ext/proto_server_reflection_plugin.h> |
||||
#include <grpcpp/grpcpp.h> |
||||
|
||||
#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" |
||||
#include "test/core/util/port.h" |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
namespace grpc { |
||||
namespace testing { |
||||
|
||||
class AdminServicesTest : public ::testing::Test { |
||||
public: |
||||
void SetUp() override { |
||||
std::string address = |
||||
absl::StrCat("localhost:", grpc_pick_unused_port_or_die()); |
||||
// Create admin server
|
||||
grpc::reflection::InitProtoReflectionServerBuilderPlugin(); |
||||
ServerBuilder builder; |
||||
builder.AddListeningPort(address, InsecureServerCredentials()); |
||||
::grpc::AddAdminServices(&builder); |
||||
server_ = builder.BuildAndStart(); |
||||
// Create channel
|
||||
auto reflection_stub = reflection::v1alpha::ServerReflection::NewStub( |
||||
CreateChannel(address, InsecureChannelCredentials())); |
||||
stream_ = reflection_stub->ServerReflectionInfo(&reflection_ctx_); |
||||
} |
||||
|
||||
std::vector<std::string> GetServiceList() { |
||||
std::vector<std::string> services; |
||||
reflection::v1alpha::ServerReflectionRequest request; |
||||
reflection::v1alpha::ServerReflectionResponse response; |
||||
request.set_list_services(""); |
||||
stream_->Write(request); |
||||
stream_->Read(&response); |
||||
for (auto& service : response.list_services_response().service()) { |
||||
services.push_back(service.name()); |
||||
} |
||||
return services; |
||||
} |
||||
|
||||
private: |
||||
std::unique_ptr<Server> server_; |
||||
ClientContext reflection_ctx_; |
||||
std::shared_ptr< |
||||
ClientReaderWriter<reflection::v1alpha::ServerReflectionRequest, |
||||
reflection::v1alpha::ServerReflectionResponse>> |
||||
stream_; |
||||
}; |
||||
|
||||
#ifndef GRPC_NO_XDS |
||||
// The ifndef conflicts with TEST_F and EXPECT_THAT macros, so we better isolate
|
||||
// the condition at test case level.
|
||||
TEST_F(AdminServicesTest, XdsEnabled) { |
||||
EXPECT_THAT(GetServiceList(), |
||||
::testing::UnorderedElementsAre( |
||||
"envoy.service.status.v3.ClientStatusDiscoveryService", |
||||
"grpc.channelz.v1.Channelz", |
||||
"grpc.reflection.v1alpha.ServerReflection")); |
||||
} |
||||
#endif // GRPC_NO_XDS
|
||||
|
||||
#ifdef GRPC_NO_XDS |
||||
TEST_F(AdminServicesTest, XdsDisabled) { |
||||
EXPECT_THAT(GetServiceList(), |
||||
::testing::UnorderedElementsAre( |
||||
"grpc.channelz.v1.Channelz", |
||||
"grpc.reflection.v1alpha.ServerReflection")); |
||||
} |
||||
#endif // GRPC_NO_XDS
|
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc::testing::TestEnvironment env(argc, argv); |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
int ret = RUN_ALL_TESTS(); |
||||
return ret; |
||||
} |
Loading…
Reference in new issue