Skip to content

Commit

Permalink
Minor gRPC changes: The helidon-microprofile-grpc-metrics module depe…
Browse files Browse the repository at this point in the history
…ndency on helidon-microprofile-metrics should have a scope of provided. Allow a gRPC service descriptors to be created without needing a BeanManager. Support creating gRPC Channels configured for a target URI in addition to a host and port.
  • Loading branch information
thegridman committed Jan 14, 2020
1 parent 7416128 commit dfe62fe
Show file tree
Hide file tree
Showing 10 changed files with 420 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,23 +16,33 @@

package io.helidon.grpc.client;

import java.util.Optional;

import io.helidon.config.objectmapping.Value;
import io.helidon.grpc.core.GrpcTlsDescriptor;

import io.grpc.NameResolver;

/**
* GrpcChannelDescriptor contains the configuration for a {@link io.grpc.Channel}.
*/
public class GrpcChannelDescriptor {
private boolean inProcessChannel;
private String host;
private int port;
private String target;
private GrpcTlsDescriptor tlsDescriptor;
private String loadBalancerPolicy;
private NameResolver.Factory nameResolver;

private GrpcChannelDescriptor(boolean inProcessChannel, String host, int port, GrpcTlsDescriptor tlsDescriptor) {
this.inProcessChannel = inProcessChannel;
this.host = host;
this.port = port;
this.tlsDescriptor = tlsDescriptor;
private GrpcChannelDescriptor(Builder builder) {
this.inProcessChannel = builder.inProcessChannel();
this.target = builder.target();
this.host = builder.host();
this.port = builder.port();
this.tlsDescriptor = builder.tlsDescriptor();
this.loadBalancerPolicy = builder.loadBalancerPolicy();
this.nameResolver = builder.nameResolverFactory();
}

/**
Expand Down Expand Up @@ -70,15 +80,48 @@ public int port() {
return port;
}

/**
* Get the optional target string to use to resolve channel addresses.
*
* @return the optional target string to use to resolve channel addresses
*/
public Optional<String> target() {
return Optional.ofNullable(target);
}

/**
* Get the default load balancer policy to use.
*
* @return the optional default load balancer policy to use
*/
public Optional<String> loadBalancerPolicy() {
return Optional.ofNullable(loadBalancerPolicy);
}

/**
* Get the {@link NameResolver.Factory} to use.
*
* @return the optional {@link NameResolver.Factory} to use
*/
public Optional<NameResolver.Factory> nameResolverFactory() {
return Optional.ofNullable(nameResolver);
}

/**
* Get the {@link io.helidon.grpc.core.GrpcTlsDescriptor}. If this method returns null or
* if {@code tlsDescriptor.isEnabled()} is false, then no TLS will be used (and none of the other configuration
* values from {@code tlsDescriptor} will be used).
* <p>
* If the {@link GrpcTlsDescriptor} has been set but the value of {@link io.helidon.grpc.core.GrpcTlsDescriptor#isEnabled()}
* returns {@code false} then an empty {@link Optional} will be returned.
*
* @return the {@link io.helidon.grpc.core.GrpcTlsDescriptor} instance (or {@code null} if no configuration was specified)
* @return the optional {@link io.helidon.grpc.core.GrpcTlsDescriptor}
*/
public GrpcTlsDescriptor tlsDescriptor() {
return tlsDescriptor;
public Optional<GrpcTlsDescriptor> tlsDescriptor() {
if (tlsDescriptor != null && tlsDescriptor.isEnabled()) {
return Optional.of(tlsDescriptor);
}
return Optional.empty();
}

/**
Expand All @@ -89,6 +132,9 @@ public static class Builder implements io.helidon.common.Builder<GrpcChannelDesc
private String host = GrpcChannelsProvider.DEFAULT_HOST;
private int port = GrpcChannelsProvider.DEFAULT_PORT;
private GrpcTlsDescriptor tlsDescriptor;
private String target;
private String loadBalancerPolicy;
private NameResolver.Factory nameResolver;

/**
* Set the host name to connect.
Expand All @@ -101,6 +147,22 @@ public Builder inProcess() {
return this;
}

/**
* Set the target string, which can be either a valid {@link io.grpc.NameResolver}
* compliant URI, or an authority string.
*
* @param target the target string
*
* @return this instance for fluent API
*
* @see io.grpc.ManagedChannelBuilder#forTarget(String)
*/
@Value
public Builder target(String target) {
this.target = target;
return this;
}

/**
* Set the host name to connect.
* @param host set the host name
Expand Down Expand Up @@ -138,12 +200,66 @@ public Builder sslDescriptor(GrpcTlsDescriptor tlsDescriptor) {
return this;
}

/**
* Set the default load balancer policy name.
* @param policy the load balancer policy name
*
* @return this instance for fluent API
*
* @see io.grpc.ManagedChannelBuilder#defaultLoadBalancingPolicy(String)
*/
public Builder loadBalancerPolicy(String policy) {
loadBalancerPolicy = policy;
return this;
}

/**
* Set the {@link io.grpc.NameResolver.Factory} to use.
* @param factory the {@link io.grpc.NameResolver.Factory} to use
*
* @return this instance for fluent API
*
* @see io.grpc.ManagedChannelBuilder#nameResolverFactory(io.grpc.NameResolver.Factory)
*/
public Builder nameResolverFactory(NameResolver.Factory factory) {
this.nameResolver = factory;
return this;
}

boolean inProcessChannel() {
return inProcessChannel;
}

String host() {
return host;
}

int port() {
return port;
}

GrpcTlsDescriptor tlsDescriptor() {
return tlsDescriptor;
}

String target() {
return target;
}

String loadBalancerPolicy() {
return loadBalancerPolicy;
}

NameResolver.Factory nameResolverFactory() {
return nameResolver;
}

/**
* Build and return a new GrpcChannelDescriptor.
* @return a new GrpcChannelDescriptor
*/
public GrpcChannelDescriptor build() {
return new GrpcChannelDescriptor(this.inProcessChannel, this.host, this.port, this.tlsDescriptor);
return new GrpcChannelDescriptor(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,7 +25,6 @@
import io.helidon.config.Config;
import io.helidon.grpc.core.GrpcTlsDescriptor;

import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.netty.GrpcSslContexts;
Expand Down Expand Up @@ -126,14 +125,14 @@ private static SslContext createClientSslContext(Resource trustCert,
// --------------- private methods of GrpcChannelsProvider ---------------

/**
* Returns a {@link io.grpc.Channel} for the specified channel configuration name.
* Returns a {@link io.grpc.ManagedChannel} for the specified channel configuration name.
*
* @param name the name of the channel configuration as specified in the configuration file
* @return a new instance of {@link io.grpc.Channel}
* @return a new instance of {@link io.grpc.ManagedChannel}
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if name is empty
*/
public Channel channel(String name) {
public ManagedChannel channel(String name) {
if (name == null) {
throw new NullPointerException("name cannot be null.");
}
Expand All @@ -152,25 +151,47 @@ Map<String, GrpcChannelDescriptor> channels() {
return channelConfigs;
}

private Channel createChannel(GrpcChannelDescriptor descriptor) {
private ManagedChannel createChannel(GrpcChannelDescriptor descriptor) {
ManagedChannelBuilder<?> builder = descriptor.tlsDescriptor()
.map(tlsDescriptor -> createNettyChannelBuilder(descriptor, tlsDescriptor))
.orElse(createManagedChannelBuilder(descriptor));

ManagedChannel channel;
GrpcTlsDescriptor tlsDescriptor = descriptor.tlsDescriptor();
descriptor.loadBalancerPolicy().ifPresent(builder::defaultLoadBalancingPolicy);
descriptor.nameResolverFactory().ifPresent(builder::nameResolverFactory);

if (tlsDescriptor == null || !tlsDescriptor.isEnabled()) {
ManagedChannelBuilder builder = ManagedChannelBuilder.forAddress(descriptor.host(), descriptor.port());
channel = builder.usePlaintext().build();
} else {
SslContext sslContext = createClientSslContext(tlsDescriptor.tlsCaCert(),
tlsDescriptor.tlsCert(),
tlsDescriptor.tlsKey());
return builder.build();
}

channel = NettyChannelBuilder.forAddress(descriptor.host(), descriptor.port())
.negotiationType(NegotiationType.TLS)
.sslContext(sslContext)
.build();
}
return channel;
/**
* Create a TLS enabled {@link ManagedChannelBuilder}.
*
* @param descriptor the {@link GrpcChannelDescriptor} to use to configure the builder
* @return a plain (non-TLS) ManagedChannelBuilder
*/
@SuppressWarnings("rawtypes")
private ManagedChannelBuilder createNettyChannelBuilder(GrpcChannelDescriptor descriptor,
GrpcTlsDescriptor tlsDescriptor) {
return descriptor.target()
.map(NettyChannelBuilder::forTarget)
.orElse(NettyChannelBuilder.forAddress(descriptor.host(), descriptor.port()))
.negotiationType(NegotiationType.TLS)
.sslContext(createClientSslContext(tlsDescriptor.tlsCaCert(),
tlsDescriptor.tlsCert(),
tlsDescriptor.tlsKey()));
}

/**
* Create a plain (non-TLS) {@link ManagedChannelBuilder}.
*
* @param descriptor the {@link GrpcChannelDescriptor} to use to configure the builder
* @return a plain (non-TLS) ManagedChannelBuilder
*/
@SuppressWarnings("rawtypes")
private ManagedChannelBuilder createManagedChannelBuilder(GrpcChannelDescriptor descriptor) {
return descriptor.target()
.map(ManagedChannelBuilder::forTarget)
.orElse(ManagedChannelBuilder.forAddress(descriptor.host(), descriptor.port()))
.usePlaintext();
}

/**
Expand Down
Loading

0 comments on commit dfe62fe

Please sign in to comment.