1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <grpc/support/port_platform.h>
20 
21 #include "src/core/ext/filters/client_channel/client_channel.h"
22 #include "src/core/ext/filters/client_channel/client_channel_channelz.h"
23 #include "src/core/lib/channel/channelz_registry.h"
24 #include "src/core/lib/gpr/useful.h"
25 #include "src/core/lib/surface/channel.h"
26 #include "src/core/lib/transport/connectivity_state.h"
27 
28 #include <grpc/support/string_util.h>
29 
30 namespace grpc_core {
31 namespace channelz {
32 
SubchannelNode(std::string target_address,size_t channel_tracer_max_nodes)33 SubchannelNode::SubchannelNode(std::string target_address,
34                                size_t channel_tracer_max_nodes)
35     : BaseNode(EntityType::kSubchannel, target_address),
36       target_(std::move(target_address)),
37       trace_(channel_tracer_max_nodes) {}
38 
~SubchannelNode()39 SubchannelNode::~SubchannelNode() {}
40 
UpdateConnectivityState(grpc_connectivity_state state)41 void SubchannelNode::UpdateConnectivityState(grpc_connectivity_state state) {
42   connectivity_state_.Store(state, MemoryOrder::RELAXED);
43 }
44 
SetChildSocket(RefCountedPtr<SocketNode> socket)45 void SubchannelNode::SetChildSocket(RefCountedPtr<SocketNode> socket) {
46   MutexLock lock(&socket_mu_);
47   child_socket_ = std::move(socket);
48 }
49 
RenderJson()50 Json SubchannelNode::RenderJson() {
51   // Create and fill the data child.
52   grpc_connectivity_state state =
53       connectivity_state_.Load(MemoryOrder::RELAXED);
54   Json::Object data = {
55       {"state",
56        Json::Object{
57            {"state", ConnectivityStateName(state)},
58        }},
59       {"target", target_},
60   };
61 
62   // Fill in the channel trace if applicable
63   Json trace_json = trace_.RenderJson();
64   if (trace_json.type() != Json::Type::JSON_NULL) {
65     data["trace"] = std::move(trace_json);
66   }
67   // Ask CallCountingHelper to populate call count data.
68   call_counter_.PopulateCallCounts(&data);
69   // Construct top-level object.
70   Json::Object object{
71       {"ref",
72        Json::Object{
73            {"subchannelId", std::to_string(uuid())},
74        }},
75       {"data", std::move(data)},
76   };
77   // Populate the child socket.
78   RefCountedPtr<SocketNode> child_socket;
79   {
80     MutexLock lock(&socket_mu_);
81     child_socket = child_socket_;
82   }
83   if (child_socket != nullptr && child_socket->uuid() != 0) {
84     object["socketRef"] = Json::Array{
85         Json::Object{
86             {"socketId", std::to_string(child_socket->uuid())},
87             {"name", child_socket->name()},
88         },
89     };
90   }
91   return object;
92 }
93 
94 }  // namespace channelz
95 }  // namespace grpc_core
96