All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glowroot.agent.shaded.grpc.netty.NettyChannelBuilder Maven / Gradle / Ivy

There is a newer version: 0.9.28
Show newest version
/*
 * Copyright 2014, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *
 *    * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.glowroot.agent.shaded.grpc.netty;

import static org.glowroot.agent.shaded.google.common.base.Preconditions.checkArgument;
import static org.glowroot.agent.shaded.grpc.internal.GrpcUtil.DEFAULT_MAX_MESSAGE_SIZE;

import org.glowroot.agent.shaded.google.common.base.Preconditions;

import org.glowroot.agent.shaded.grpc.ExperimentalApi;
import org.glowroot.agent.shaded.grpc.internal.AbstractManagedChannelImplBuilder;
import org.glowroot.agent.shaded.grpc.internal.AbstractReferenceCounted;
import org.glowroot.agent.shaded.grpc.internal.ClientTransport;
import org.glowroot.agent.shaded.grpc.internal.ClientTransportFactory;
import org.glowroot.agent.shaded.grpc.internal.GrpcUtil;
import org.glowroot.agent.shaded.grpc.internal.SharedResourceHolder;
import org.glowroot.agent.shaded.netty.channel.Channel;
import org.glowroot.agent.shaded.netty.channel.EventLoopGroup;
import org.glowroot.agent.shaded.netty.channel.socket.nio.NioSocketChannel;
import org.glowroot.agent.shaded.netty.handler.ssl.SslContext;

import java.net.InetSocketAddress;
import java.net.SocketAddress;

import javax.annotation.Nullable;
import javax.net.ssl.SSLException;

/**
 * A builder to help simplify construction of channels using the Netty transport.
 */
@ExperimentalApi("There is no plan to make this API stable, given transport API instability")
public final class NettyChannelBuilder
        extends AbstractManagedChannelImplBuilder {
  public static final int DEFAULT_FLOW_CONTROL_WINDOW = 1048576; // 1MiB

  private final SocketAddress serverAddress;
  private String authority;
  private NegotiationType negotiationType = NegotiationType.TLS;
  private Class channelType = NioSocketChannel.class;
  @Nullable
  private EventLoopGroup eventLoopGroup;
  private SslContext sslContext;
  private int flowControlWindow = DEFAULT_FLOW_CONTROL_WINDOW;
  private int maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE;

  /**
   * Creates a new builder with the given server address. This factory method is primarily intended
   * for using Netty Channel types other than SocketChannel. {@link #forAddress(String, int)} should
   * generally be preferred over this method, since that API permits delaying DNS lookups and
   * noticing changes to DNS.
   */
  public static NettyChannelBuilder forAddress(SocketAddress serverAddress) {
    String authority;
    if (serverAddress instanceof InetSocketAddress) {
      InetSocketAddress address = (InetSocketAddress) serverAddress;
      authority = GrpcUtil.authorityFromHostAndPort(address.getHostString(), address.getPort());
    } else {
      // Specialized address types are allowed to support custom Channel types so just assume their
      // toString() values are valid :authority values. We defer checking validity of authority
      // until buildTransportFactory() to provide the user an opportunity to override the value.
      authority = serverAddress.toString();
    }
    return new NettyChannelBuilder(serverAddress, authority);
  }

  /**
   * Creates a new builder with the given host and port.
   */
  public static NettyChannelBuilder forAddress(String host, int port) {
    return new NettyChannelBuilder(
        new InetSocketAddress(host, port), GrpcUtil.authorityFromHostAndPort(host, port));
  }

  private NettyChannelBuilder(SocketAddress serverAddress, String authority) {
    this.serverAddress = serverAddress;
    this.authority = authority;
  }

  /**
   * Specify the channel type to use, by default we use {@link NioSocketChannel}.
   */
  public NettyChannelBuilder channelType(Class channelType) {
    this.channelType = Preconditions.checkNotNull(channelType);
    return this;
  }

  /**
   * Sets the negotiation type for the HTTP/2 connection.
   *
   * 

Default: TLS */ public NettyChannelBuilder negotiationType(NegotiationType type) { negotiationType = type; return this; } /** * Provides an EventGroupLoop to be used by the netty transport. * *

It's an optional parameter. If the user has not provided an EventGroupLoop when the channel * is built, the builder will use the default one which is static. * *

The channel won't take ownership of the given EventLoopGroup. It's caller's responsibility * to shut it down when it's desired. */ public NettyChannelBuilder eventLoopGroup(@Nullable EventLoopGroup eventLoopGroup) { this.eventLoopGroup = eventLoopGroup; return this; } /** * SSL/TLS context to use instead of the system default. It must have been configured with {@link * GrpcSslContexts}, but options could have been overridden. */ public NettyChannelBuilder sslContext(SslContext sslContext) { this.sslContext = sslContext; return this; } /** * Sets the flow control window in bytes. If not called, the default value * is {@link #DEFAULT_FLOW_CONTROL_WINDOW}). */ public NettyChannelBuilder flowControlWindow(int flowControlWindow) { Preconditions.checkArgument(flowControlWindow > 0, "flowControlWindow must be positive"); this.flowControlWindow = flowControlWindow; return this; } /** * Sets the maximum message size allowed to be received on the channel. If not called, * defaults to {@link org.glowroot.agent.shaded.grpc.internal.GrpcUtil#DEFAULT_MAX_MESSAGE_SIZE}. */ public NettyChannelBuilder maxMessageSize(int maxMessageSize) { checkArgument(maxMessageSize >= 0, "maxMessageSize must be >= 0"); this.maxMessageSize = maxMessageSize; return this; } /** * Equivalent to using {@link #negotiationType(NegotiationType)} with {@code PLAINTEXT} or * {@code PLAINTEXT_UPGRADE}. */ @Override public NettyChannelBuilder usePlaintext(boolean skipNegotiation) { if (skipNegotiation) { negotiationType(NegotiationType.PLAINTEXT); } else { negotiationType(NegotiationType.PLAINTEXT_UPGRADE); } return this; } @Override public NettyChannelBuilder overrideAuthority(String authority) { this.authority = GrpcUtil.checkAuthority(authority); return this; } @Override protected ClientTransportFactory buildTransportFactory() { // Check authority, since non-inet ServerAddresses delay the authority check. GrpcUtil.checkAuthority(authority); return new NettyTransportFactory(serverAddress, authority, channelType, eventLoopGroup, flowControlWindow, createProtocolNegotiator(), maxMessageSize); } private ProtocolNegotiator createProtocolNegotiator() { switch (negotiationType) { case PLAINTEXT: return ProtocolNegotiators.plaintext(); case PLAINTEXT_UPGRADE: return ProtocolNegotiators.plaintextUpgrade(); case TLS: if (sslContext == null) { try { sslContext = GrpcSslContexts.forClient().build(); } catch (SSLException ex) { throw new RuntimeException(ex); } } return ProtocolNegotiators.tls(sslContext, authority); default: throw new IllegalArgumentException("Unsupported negotiationType: " + negotiationType); } } private static class NettyTransportFactory extends AbstractReferenceCounted implements ClientTransportFactory { private final SocketAddress serverAddress; private final Class channelType; private final EventLoopGroup group; private final boolean usingSharedGroup; private final int flowControlWindow; private final ProtocolNegotiator negotiator; private final int maxMessageSize; private final String authority; private NettyTransportFactory(SocketAddress serverAddress, String authority, Class channelType, EventLoopGroup group, int flowControlWindow, ProtocolNegotiator negotiator, int maxMessageSize) { this.serverAddress = serverAddress; this.channelType = channelType; this.flowControlWindow = flowControlWindow; this.negotiator = negotiator; this.maxMessageSize = maxMessageSize; this.authority = authority; usingSharedGroup = group == null; if (usingSharedGroup) { // The group was unspecified, using the shared group. this.group = SharedResourceHolder.get(Utils.DEFAULT_WORKER_EVENT_LOOP_GROUP); } else { this.group = group; } } @Override public ClientTransport newClientTransport() { return new NettyClientTransport(serverAddress, channelType, group, negotiator, flowControlWindow, maxMessageSize, authority); } @Override public String authority() { return authority; } @Override protected void deallocate() { if (usingSharedGroup) { SharedResourceHolder.release(Utils.DEFAULT_WORKER_EVENT_LOOP_GROUP, group); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy