• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #20349

07 Jul 2026 10:24AM UTC coverage: 89.111% (-0.01%) from 89.122%
#20349

push

github

web-flow
enable child channel plugins (#12578)

Implements https://github.com/grpc/proposal/pull/529

38030 of 42677 relevant lines covered (89.11%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/../xds/src/main/java/io/grpc/xds/GrpcXdsTransportFactory.java
1
/*
2
 * Copyright 2024 The gRPC Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package io.grpc.xds;
18

19
import static com.google.common.base.Preconditions.checkNotNull;
20

21
import com.google.common.annotations.VisibleForTesting;
22
import io.grpc.CallCredentials;
23
import io.grpc.CallOptions;
24
import io.grpc.ChannelConfigurator;
25
import io.grpc.ChannelCredentials;
26
import io.grpc.ClientCall;
27
import io.grpc.Context;
28
import io.grpc.Grpc;
29
import io.grpc.ManagedChannel;
30
import io.grpc.ManagedChannelBuilder;
31
import io.grpc.Metadata;
32
import io.grpc.MethodDescriptor;
33
import io.grpc.Status;
34
import io.grpc.xds.client.Bootstrapper;
35
import io.grpc.xds.client.XdsTransportFactory;
36
import java.util.concurrent.TimeUnit;
37

38
final class GrpcXdsTransportFactory implements XdsTransportFactory {
39

40
  private final CallCredentials callCredentials;
41
  private final ChannelConfigurator channelConfigurator;
42

43
  GrpcXdsTransportFactory(CallCredentials callCredentials,
44
                          ChannelConfigurator channelConfigurator) {
1✔
45
    this.callCredentials = callCredentials;
1✔
46
    this.channelConfigurator = channelConfigurator;
1✔
47
  }
1✔
48

49
  @Override
50
  public XdsTransport create(Bootstrapper.ServerInfo serverInfo) {
51
    return new GrpcXdsTransport(serverInfo, callCredentials, channelConfigurator);
1✔
52
  }
53

54
  @VisibleForTesting
55
  public XdsTransport createForTest(ManagedChannel channel) {
56
    return new GrpcXdsTransport(channel, callCredentials);
1✔
57
  }
58

59
  @VisibleForTesting
60
  static class GrpcXdsTransport implements XdsTransport {
61

62
    private final ManagedChannel channel;
63
    private final CallCredentials callCredentials;
64

65
    public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo) {
66
      this(serverInfo, null, null);
×
67
    }
×
68

69
    @VisibleForTesting
70
    public GrpcXdsTransport(ManagedChannel channel) {
71
      this(channel, null);
1✔
72
    }
1✔
73

74
    public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo, CallCredentials callCredentials) {
75
      this(serverInfo, callCredentials, null);
×
76
    }
×
77

78
    public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo,
79
                            CallCredentials callCredentials,
80
                            ChannelConfigurator channelConfigurator) {
1✔
81
      String target = serverInfo.target();
1✔
82
      ChannelCredentials channelCredentials = (ChannelCredentials) serverInfo.implSpecificConfig();
1✔
83
      ManagedChannelBuilder<?> channelBuilder = Grpc.newChannelBuilder(target, channelCredentials)
1✔
84
          .keepAliveTime(5, TimeUnit.MINUTES);
1✔
85
      if (channelConfigurator != null) {
1✔
86
        channelConfigurator.configureChannelBuilder(channelBuilder);
1✔
87
        channelBuilder.childChannelConfigurator(channelConfigurator);
1✔
88
      }
89
      this.channel = channelBuilder.build();
1✔
90
      this.callCredentials = callCredentials;
1✔
91
    }
1✔
92

93
    @VisibleForTesting
94
    public GrpcXdsTransport(ManagedChannel channel, CallCredentials callCredentials) {
1✔
95
      this.channel = checkNotNull(channel, "channel");
1✔
96
      this.callCredentials = callCredentials;
1✔
97
    }
1✔
98

99
    @Override
100
    public <ReqT, RespT> StreamingCall<ReqT, RespT> createStreamingCall(
101
        String fullMethodName,
102
        MethodDescriptor.Marshaller<ReqT> reqMarshaller,
103
        MethodDescriptor.Marshaller<RespT> respMarshaller) {
104
      Context prevContext = Context.ROOT.attach();
1✔
105
      try {
106
        return new XdsStreamingCall<>(
1✔
107
            fullMethodName, reqMarshaller, respMarshaller, callCredentials);
108
      } finally {
109
        Context.ROOT.detach(prevContext);
1✔
110
      }
111

112
    }
113

114
    @Override
115
    public void shutdown() {
116
      channel.shutdown();
1✔
117
    }
1✔
118

119
    private class XdsStreamingCall<ReqT, RespT> implements
120
        XdsTransportFactory.StreamingCall<ReqT, RespT> {
121

122
      private final ClientCall<ReqT, RespT> call;
123

124
      public XdsStreamingCall(
125
          String methodName,
126
          MethodDescriptor.Marshaller<ReqT> reqMarshaller,
127
          MethodDescriptor.Marshaller<RespT> respMarshaller,
128
          CallCredentials callCredentials) {
1✔
129
        this.call =
1✔
130
            channel.newCall(
1✔
131
                MethodDescriptor.<ReqT, RespT>newBuilder()
1✔
132
                    .setFullMethodName(methodName)
1✔
133
                    .setType(MethodDescriptor.MethodType.BIDI_STREAMING)
1✔
134
                    .setRequestMarshaller(reqMarshaller)
1✔
135
                    .setResponseMarshaller(respMarshaller)
1✔
136
                    .setSampledToLocalTracing(true)
1✔
137
                    .build(),
1✔
138
                CallOptions.DEFAULT.withCallCredentials(
1✔
139
                    callCredentials)); // TODO(zivy): support waitForReady
140
      }
1✔
141

142
      @Override
143
      public void start(EventHandler<RespT> eventHandler) {
144
        call.start(new EventHandlerToCallListenerAdapter<>(eventHandler), new Metadata());
1✔
145
        call.request(1);
1✔
146
      }
1✔
147

148
      @Override
149
      public void sendMessage(ReqT message) {
150
        call.sendMessage(message);
1✔
151
      }
1✔
152

153
      @Override
154
      public void startRecvMessage() {
155
        call.request(1);
1✔
156
      }
1✔
157

158
      @Override
159
      public void sendError(Exception e) {
160
        call.cancel("Cancelled by XdsClientImpl", e);
1✔
161
      }
1✔
162

163
      @Override
164
      public boolean isReady() {
165
        return call.isReady();
1✔
166
      }
167
    }
168
  }
169

170
  private static class EventHandlerToCallListenerAdapter<T> extends ClientCall.Listener<T> {
171
    private final EventHandler<T> handler;
172

173
    EventHandlerToCallListenerAdapter(EventHandler<T> eventHandler) {
1✔
174
      this.handler = checkNotNull(eventHandler, "eventHandler");
1✔
175
    }
1✔
176

177
    @Override
178
    public void onHeaders(Metadata headers) {}
1✔
179

180
    @Override
181
    public void onMessage(T message) {
182
      handler.onRecvMessage(message);
1✔
183
    }
1✔
184

185
    @Override
186
    public void onClose(Status status, Metadata trailers) {
187
      handler.onStatusReceived(status);
1✔
188
    }
1✔
189

190
    @Override
191
    public void onReady() {
192
      handler.onReady();
1✔
193
    }
1✔
194
  }
195
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc