44
55import io .grpc .ChannelCredentials ;
66import io .grpc .Grpc ;
7- import io .grpc .InsecureChannelCredentials ;
87import io .grpc .ManagedChannel ;
98import org .slf4j .Logger ;
109import org .slf4j .LoggerFactory ;
@@ -34,6 +33,10 @@ public abstract class ChannelManager implements AutoCloseable {
3433 public static final String MAX_INBOUND_MESSAGE_BYTE_SIZE = GRPC_CHANNEL_PREFIX + "MAX_INBOUND_MESSAGE_BYTE_SIZE" ;
3534 public static final String MAX_INBOUND_METADATA_BYTE_SIZE = GRPC_CHANNEL_PREFIX + "MAX_INBOUND_METADATA_BYTE_SIZE" ;
3635
36+ protected static final String LOCALHOST = "localhost" ;
37+ protected static final String DNS_PREFIX = "dns:///" ;
38+ protected static final int MAX_PORT_NUMBER = 0xFFFF ;
39+
3740 protected final Logger logger ;
3841
3942 protected final String host ;
@@ -54,16 +57,17 @@ public abstract class ChannelManager implements AutoCloseable {
5457 * @param host gRPC service hostname or DNS target
5558 * @param port gRPC service port
5659 * @param configG configuration provider for channel parameters
60+ * @param credentials transport-level credentials for the gRPC server
5761 * @see ChannelManager
5862 * @see <a href="https://docs.microsoft.com/en-us/aspnet/core/grpc/performance?view=aspnetcore-5.0">Source</a> for
5963 * default gRPC configurations.
6064 */
61- protected ChannelManager (String host , int port , Configurator configG ) {
65+ protected ChannelManager (String host , int port , Configurator configG , ChannelCredentials credentials ) {
6266 this .logger = LoggerFactory .getLogger (this .getClass ().getName ());
6367
64- this .host = host ;
65- this .port = port ;
66- this .target = host + ":" + port ; // target may be a host or dns service
68+ this .host = validateHostName ( host ) ;
69+ this .port = validatePortNumber ( port ) ;
70+ this .target = createTarget ( host , port );
6771
6872 // How often (in milliseconds) to send pings when the connection is idle
6973 this .keepAliveMillis = configG .findLongEntry (KEEP_ALIVE_MILLIS , 60000L );
@@ -84,32 +88,42 @@ protected ChannelManager(String host, int port, Configurator configG) {
8488 this .maxInboundMessageByteSize = configG .findIntEntry (MAX_INBOUND_MESSAGE_BYTE_SIZE , 4 << 20 ); // 4 MiB
8589 this .maxInboundMetadataByteSize = configG .findIntEntry (MAX_INBOUND_METADATA_BYTE_SIZE , 8 << 10 ); // 8 KiB
8690
87- this .channelCredentials = createChannelCredentials ( configG ) ;
91+ this .channelCredentials = credentials ;
8892 }
8993
90- /**
91- * Creates a new {@link ChannelCredentials} object with all security and encryption configurations necessary for
92- * establishing a gRPC connection. Base class returns {@link InsecureChannelCredentials}, which asserts that no client
93- * identity, authentication, or encryption is to be used. Subclasses should override this method as necessary.
94- *
95- * @param configG any necessary configurations for creating the credentials object
96- * @return gRPC channel credentials
97- */
98- protected ChannelCredentials createChannelCredentials (Configurator configG ) {
99- return InsecureChannelCredentials .create ();
94+ protected String validateHostName (String host ) {
95+ if (host .equals (LOCALHOST ) || host .startsWith (DNS_PREFIX )) {
96+ return host ;
97+ }
98+ throw new IllegalArgumentException (String .format ("Expected DNS URI prefix \" dns:///\" but got \" %s\" " , host ));
99+ }
100+
101+ protected int validatePortNumber (int port ) {
102+ if (port > 0 && port <= MAX_PORT_NUMBER ) {
103+ return port ;
104+ }
105+ throw new IllegalArgumentException (String .format ("Port \" %d\" is outside valid range [1, %d]" , port , MAX_PORT_NUMBER ));
106+ }
107+
108+ protected String createTarget (String host , int port ) {
109+ return host + ":" + port ;
100110 }
101111
102- public static ChannelManager ofSubClass (String className , String host , int port , Configurator configG ) {
112+ public static ChannelManager ofSubClass (
113+ String className , String host , int port , Configurator configG , ChannelCredentials credentials ) {
103114 try {
104- return ofSubClass (Class .forName (className ).asSubclass (ChannelManager .class ), host , port , configG );
115+ return ofSubClass (Class .forName (className ).asSubclass (ChannelManager .class ), host , port , configG , credentials );
105116 } catch (ClassNotFoundException e ) {
106117 throw new IllegalArgumentException ("Cannot find class: " + className , e );
107118 }
108119 }
109120
110- public static ChannelManager ofSubClass (Class <? extends ChannelManager > clz , String host , int port , Configurator configG ) {
121+ public static ChannelManager ofSubClass (
122+ Class <? extends ChannelManager > clz , String host , int port , Configurator configG , ChannelCredentials credentials ) {
111123 try {
112- return clz .getDeclaredConstructor (String .class , int .class , Configurator .class ).newInstance (host , port , configG );
124+ return clz
125+ .getDeclaredConstructor (String .class , int .class , Configurator .class , ChannelCredentials .class )
126+ .newInstance (host , port , configG , credentials );
113127 } catch (ReflectiveOperationException e ) {
114128 throw new IllegalStateException ("Unable to instantiate new ChannelManager: " + e .getMessage (), e );
115129 }
0 commit comments