1 /* 2 * Copyright 2014 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.internal; 18 19 import com.google.common.base.Objects; 20 import com.google.common.base.Preconditions; 21 import io.grpc.Attributes; 22 import io.grpc.CallCredentials; 23 import io.grpc.ChannelCredentials; 24 import io.grpc.ChannelLogger; 25 import io.grpc.HttpConnectProxiedSocketAddress; 26 import java.io.Closeable; 27 import java.net.SocketAddress; 28 import java.util.concurrent.ScheduledExecutorService; 29 import javax.annotation.CheckReturnValue; 30 import javax.annotation.Nullable; 31 32 /** Pre-configured factory for creating {@link ConnectionClientTransport} instances. */ 33 public interface ClientTransportFactory extends Closeable { 34 /** 35 * Creates an unstarted transport for exclusive use. Ownership of {@code options} is passed to the 36 * callee; the caller should not reuse or read from the options after this method is called. 37 * 38 * @param serverAddress the address that the transport is connected to 39 * @param options additional configuration 40 * @param channelLogger logger for the transport. 41 */ newClientTransport( SocketAddress serverAddress, ClientTransportOptions options, ChannelLogger channelLogger)42 ConnectionClientTransport newClientTransport( 43 SocketAddress serverAddress, 44 ClientTransportOptions options, 45 ChannelLogger channelLogger); 46 47 /** 48 * Returns an executor for scheduling provided by the transport. The service should be configured 49 * to allow cancelled scheduled runnables to be GCed. 50 * 51 * <p>The executor should not be used after the factory has been closed. The caller should ensure 52 * any outstanding tasks are cancelled before the factory is closed. However, it is a 53 * <a href="https://github.com/grpc/grpc-java/issues/1981">known issue</a> that ClientCallImpl may 54 * use this executor after close, so implementations should not go out of their way to prevent 55 * usage. 56 */ getScheduledExecutorService()57 ScheduledExecutorService getScheduledExecutorService(); 58 59 /** 60 * Swaps to a new ChannelCredentials with all other settings unchanged. Returns null if the 61 * ChannelCredentials is not supported by the current ClientTransportFactory settings. 62 */ 63 @CheckReturnValue 64 @Nullable swapChannelCredentials(ChannelCredentials channelCreds)65 SwapChannelCredentialsResult swapChannelCredentials(ChannelCredentials channelCreds); 66 67 /** 68 * Releases any resources. 69 * 70 * <p>After this method has been called, it's no longer valid to call 71 * {@link #newClientTransport}. No guarantees about thread-safety are made. 72 */ 73 @Override close()74 void close(); 75 76 /** 77 * Options passed to {@link #newClientTransport}. Although it is safe to save this object if 78 * received, it is generally expected that the useful fields are copied and then the options 79 * object is discarded. This allows using {@code final} for those fields as well as avoids 80 * retaining unused objects contained in the options. 81 */ 82 final class ClientTransportOptions { 83 private ChannelLogger channelLogger; 84 private String authority = "unknown-authority"; 85 private Attributes eagAttributes = Attributes.EMPTY; 86 @Nullable private String userAgent; 87 @Nullable private HttpConnectProxiedSocketAddress connectProxiedSocketAddr; 88 getChannelLogger()89 public ChannelLogger getChannelLogger() { 90 return channelLogger; 91 } 92 setChannelLogger(ChannelLogger channelLogger)93 public ClientTransportOptions setChannelLogger(ChannelLogger channelLogger) { 94 this.channelLogger = channelLogger; 95 return this; 96 } 97 getAuthority()98 public String getAuthority() { 99 return authority; 100 } 101 102 /** Sets the non-null authority. */ setAuthority(String authority)103 public ClientTransportOptions setAuthority(String authority) { 104 this.authority = Preconditions.checkNotNull(authority, "authority"); 105 return this; 106 } 107 getEagAttributes()108 public Attributes getEagAttributes() { 109 return eagAttributes; 110 } 111 112 /** Sets the non-null EquivalentAddressGroup's attributes. */ setEagAttributes(Attributes eagAttributes)113 public ClientTransportOptions setEagAttributes(Attributes eagAttributes) { 114 Preconditions.checkNotNull(eagAttributes, "eagAttributes"); 115 this.eagAttributes = eagAttributes; 116 return this; 117 } 118 119 @Nullable getUserAgent()120 public String getUserAgent() { 121 return userAgent; 122 } 123 setUserAgent(@ullable String userAgent)124 public ClientTransportOptions setUserAgent(@Nullable String userAgent) { 125 this.userAgent = userAgent; 126 return this; 127 } 128 129 @Nullable getHttpConnectProxiedSocketAddress()130 public HttpConnectProxiedSocketAddress getHttpConnectProxiedSocketAddress() { 131 return connectProxiedSocketAddr; 132 } 133 setHttpConnectProxiedSocketAddress( @ullable HttpConnectProxiedSocketAddress connectProxiedSocketAddr)134 public ClientTransportOptions setHttpConnectProxiedSocketAddress( 135 @Nullable HttpConnectProxiedSocketAddress connectProxiedSocketAddr) { 136 this.connectProxiedSocketAddr = connectProxiedSocketAddr; 137 return this; 138 } 139 140 @Override hashCode()141 public int hashCode() { 142 return Objects.hashCode(authority, eagAttributes, userAgent, connectProxiedSocketAddr); 143 } 144 145 @Override equals(Object o)146 public boolean equals(Object o) { 147 if (!(o instanceof ClientTransportOptions)) { 148 return false; 149 } 150 ClientTransportOptions that = (ClientTransportOptions) o; 151 return this.authority.equals(that.authority) 152 && this.eagAttributes.equals(that.eagAttributes) 153 && Objects.equal(this.userAgent, that.userAgent) 154 && Objects.equal(this.connectProxiedSocketAddr, that.connectProxiedSocketAddr); 155 } 156 } 157 158 final class SwapChannelCredentialsResult { 159 final ClientTransportFactory transportFactory; 160 @Nullable final CallCredentials callCredentials; 161 SwapChannelCredentialsResult( ClientTransportFactory transportFactory, @Nullable CallCredentials callCredentials)162 public SwapChannelCredentialsResult( 163 ClientTransportFactory transportFactory, @Nullable CallCredentials callCredentials) { 164 this.transportFactory = Preconditions.checkNotNull(transportFactory, "transportFactory"); 165 this.callCredentials = callCredentials; 166 } 167 } 168 } 169