mirror of https://github.com/apache/jclouds.git
Merge pull request #1050 from jclouds/consolidated-proxy
consolidate proxy config so it can work w/non-http + add socks support
This commit is contained in:
commit
823f20f7aa
|
@ -46,7 +46,7 @@ import org.jclouds.cloudsigma.util.Servers;
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
@ -92,7 +92,8 @@ public class CloudSigmaClientLiveTest extends BaseComputeServiceContextLiveTest
|
||||||
|
|
||||||
client = cloudSigmaContext.getApi();
|
client = cloudSigmaContext.getApi();
|
||||||
driveNotClaimed = retry(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, 1, SECONDS);
|
driveNotClaimed = retry(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, 1, SECONDS);
|
||||||
socketTester = retry(new InetSocketAddressConnect(), maxDriveImageTime, 1, SECONDS);
|
SocketOpen socketOpten = context.utils().injector().getInstance(SocketOpen.class);
|
||||||
|
socketTester = retry(socketOpten, maxDriveImageTime, 1, SECONDS);
|
||||||
|
|
||||||
if (template == null || template.getImageId() == null) {
|
if (template == null || template.getImageId() == null) {
|
||||||
imageId = view.getComputeService().templateBuilder().build().getImage().getId();
|
imageId = view.getComputeService().templateBuilder().build().getImage().getId();
|
||||||
|
|
|
@ -54,7 +54,7 @@ import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
|
||||||
import org.jclouds.compute.ComputeService;
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.internal.BaseGenericComputeServiceContextLiveTest;
|
import org.jclouds.compute.internal.BaseGenericComputeServiceContextLiveTest;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
@ -224,7 +224,8 @@ public class BaseCloudStackClientLiveTest extends BaseGenericComputeServiceConte
|
||||||
|
|
||||||
injector = cloudStackContext.utils().injector();
|
injector = cloudStackContext.utils().injector();
|
||||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||||
socketTester = retry(new InetSocketAddressConnect(), 180, 1, 1, SECONDS);
|
SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class);
|
||||||
|
socketTester = retry(socketOpen, 180, 1, 1, SECONDS);
|
||||||
injector.injectMembers(socketTester);
|
injector.injectMembers(socketTester);
|
||||||
|
|
||||||
jobComplete = retry(new JobComplete(client), 1200, 1, 5, SECONDS);
|
jobComplete = retry(new JobComplete(client), 1200, 1, 5, SECONDS);
|
||||||
|
|
|
@ -43,7 +43,7 @@ import org.jclouds.elasticstack.domain.ServerStatus;
|
||||||
import org.jclouds.elasticstack.predicates.DriveClaimed;
|
import org.jclouds.elasticstack.predicates.DriveClaimed;
|
||||||
import org.jclouds.elasticstack.util.Servers;
|
import org.jclouds.elasticstack.util.Servers;
|
||||||
import org.jclouds.io.Payloads;
|
import org.jclouds.io.Payloads;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
@ -89,7 +89,8 @@ public class ElasticStackClientLiveTest extends BaseComputeServiceContextLiveTes
|
||||||
|
|
||||||
client = view.unwrap(ElasticStackApiMetadata.CONTEXT_TOKEN).getApi();
|
client = view.unwrap(ElasticStackApiMetadata.CONTEXT_TOKEN).getApi();
|
||||||
driveNotClaimed = retry(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, 1, SECONDS);
|
driveNotClaimed = retry(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, 1, SECONDS);
|
||||||
socketTester = retry(new InetSocketAddressConnect(), maxDriveImageTime, 1, SECONDS);
|
SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class);
|
||||||
|
socketTester = retry(socketOpen, maxDriveImageTime, 1, SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static org.jclouds.util.Predicates2.retry;
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeService;
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.ssh.SshClient.Factory;
|
import org.jclouds.ssh.SshClient.Factory;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
@ -62,7 +62,8 @@ public abstract class BaseTerremarkClientLiveTest<S extends TerremarkVCloudClien
|
||||||
public void setupContext() {
|
public void setupContext() {
|
||||||
super.setupContext();
|
super.setupContext();
|
||||||
Injector injector = view.utils().injector();
|
Injector injector = view.utils().injector();
|
||||||
socketTester = retry(new InetSocketAddressConnect(), 300, 1, SECONDS);
|
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||||
|
socketTester = retry(socketOpen, 300, 1, SECONDS);
|
||||||
sshFactory = injector.getInstance(Factory.class);
|
sshFactory = injector.getInstance(Factory.class);
|
||||||
connection = (S) RestContext.class.cast(view.unwrap()).getApi();
|
connection = (S) RestContext.class.cast(view.unwrap()).getApi();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds;
|
package org.jclouds;
|
||||||
|
|
||||||
|
import java.net.Proxy;
|
||||||
|
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.reference.LocationConstants;
|
import org.jclouds.location.reference.LocationConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,24 +106,38 @@ public interface Constants {
|
||||||
* Whether or not to use the proxy setup from the underlying operating system.
|
* Whether or not to use the proxy setup from the underlying operating system.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_PROXY_SYSTEM = "jclouds.use-system-proxy";
|
public static final String PROPERTY_PROXY_SYSTEM = "jclouds.use-system-proxy";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String property.
|
* String property.
|
||||||
* <p/>
|
* <p/>
|
||||||
*Explicitly sets the host name of a HTTP proxy server.
|
*Explicitly sets the host name of a proxy server.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_PROXY_HOST = "jclouds.proxy-host";
|
public static final String PROPERTY_PROXY_HOST = "jclouds.proxy-host";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integer property.
|
* Integer property. default is 80 when {@link #PROPERTY_PROXY_TYPE} is
|
||||||
|
* {@code HTTP}, and 1080 when {@link #PROPERTY_PROXY_TYPE} is {@code SOCKS}.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Explicitly sets the port number of a HTTP proxy server.
|
* Explicitly sets the port number of a proxy server.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_PROXY_PORT = "jclouds.proxy-port";
|
public static final String PROPERTY_PROXY_PORT = "jclouds.proxy-port";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String property. default {@code HTTP}, valid options: {@code HTTP}, {@code SOCKS}.
|
||||||
|
* <p/>
|
||||||
|
* Explicitly sets the type of a proxy server.
|
||||||
|
*
|
||||||
|
* @see Proxy.Type
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_PROXY_TYPE = "jclouds.proxy-type";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String property.
|
* String property.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Explicitly sets the user name credential for proxy authentication.
|
* Explicitly sets the user name credential for proxy authentication.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_PROXY_USER = "jclouds.proxy-user";
|
public static final String PROPERTY_PROXY_USER = "jclouds.proxy-user";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String property.
|
* String property.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|
|
@ -79,27 +79,11 @@ public class HttpUtils {
|
||||||
@Named(Constants.PROPERTY_RELAX_HOSTNAME)
|
@Named(Constants.PROPERTY_RELAX_HOSTNAME)
|
||||||
private boolean relaxHostname = false;
|
private boolean relaxHostname = false;
|
||||||
|
|
||||||
@Inject(optional = true)
|
|
||||||
@Named(Constants.PROPERTY_PROXY_SYSTEM)
|
|
||||||
private boolean systemProxies = System.getProperty("java.net.useSystemProxies") != null ? Boolean
|
|
||||||
.parseBoolean(System.getProperty("java.net.useSystemProxies")) : false;
|
|
||||||
|
|
||||||
private final int globalMaxConnections;
|
private final int globalMaxConnections;
|
||||||
private final int globalMaxConnectionsPerHost;
|
private final int globalMaxConnectionsPerHost;
|
||||||
private final int connectionTimeout;
|
private final int connectionTimeout;
|
||||||
private final int soTimeout;
|
private final int soTimeout;
|
||||||
@Inject(optional = true)
|
|
||||||
@Named(Constants.PROPERTY_PROXY_HOST)
|
|
||||||
private String proxyHost;
|
|
||||||
@Inject(optional = true)
|
|
||||||
@Named(Constants.PROPERTY_PROXY_PORT)
|
|
||||||
private Integer proxyPort;
|
|
||||||
@Inject(optional = true)
|
|
||||||
@Named(Constants.PROPERTY_PROXY_USER)
|
|
||||||
private String proxyUser;
|
|
||||||
@Inject(optional = true)
|
|
||||||
@Named(Constants.PROPERTY_PROXY_PASSWORD)
|
|
||||||
private String proxyPassword;
|
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
@Named(Constants.PROPERTY_TRUST_ALL_CERTS)
|
@Named(Constants.PROPERTY_TRUST_ALL_CERTS)
|
||||||
private boolean trustAllCerts;
|
private boolean trustAllCerts;
|
||||||
|
@ -115,34 +99,6 @@ public class HttpUtils {
|
||||||
this.globalMaxConnectionsPerHost = globalMaxConnectionsPerHost;
|
this.globalMaxConnectionsPerHost = globalMaxConnectionsPerHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.jclouds.Constants.PROPERTY_PROXY_HOST
|
|
||||||
*/
|
|
||||||
public String getProxyHost() {
|
|
||||||
return proxyHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.jclouds.Constants.PROPERTY_PROXY_PORT
|
|
||||||
*/
|
|
||||||
public Integer getProxyPort() {
|
|
||||||
return proxyPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.jclouds.Constants.PROPERTY_PROXY_USER
|
|
||||||
*/
|
|
||||||
public String getProxyUser() {
|
|
||||||
return proxyUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.jclouds.Constants.PROPERTY_PROXY_PASSWORD
|
|
||||||
*/
|
|
||||||
public String getProxyPassword() {
|
|
||||||
return proxyPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSocketOpenTimeout() {
|
public int getSocketOpenTimeout() {
|
||||||
return soTimeout;
|
return soTimeout;
|
||||||
}
|
}
|
||||||
|
@ -159,10 +115,6 @@ public class HttpUtils {
|
||||||
return trustAllCerts;
|
return trustAllCerts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean useSystemProxies() {
|
|
||||||
return systemProxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxConnections() {
|
public int getMaxConnections() {
|
||||||
return globalMaxConnections;
|
return globalMaxConnections;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.jclouds.http.internal;
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Throwables.propagate;
|
import static com.google.common.base.Throwables.propagate;
|
||||||
import static com.google.common.collect.Iterables.getLast;
|
|
||||||
import static com.google.common.io.ByteStreams.toByteArray;
|
import static com.google.common.io.ByteStreams.toByteArray;
|
||||||
import static com.google.common.io.Closeables.closeQuietly;
|
import static com.google.common.io.Closeables.closeQuietly;
|
||||||
import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
|
import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
|
||||||
|
@ -33,14 +32,10 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.Authenticator;
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.PasswordAuthentication;
|
|
||||||
import java.net.ProtocolException;
|
import java.net.ProtocolException;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.ProxySelector;
|
import java.net.URI;
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -64,6 +59,7 @@ import org.jclouds.io.ContentMetadataCodec;
|
||||||
import org.jclouds.io.MutableContentMetadata;
|
import org.jclouds.io.MutableContentMetadata;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.ImmutableMultimap.Builder;
|
import com.google.common.collect.ImmutableMultimap.Builder;
|
||||||
|
@ -83,23 +79,26 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
||||||
.getProperty("java.version"));
|
.getProperty("java.version"));
|
||||||
|
|
||||||
private final Supplier<SSLContext> untrustedSSLContextProvider;
|
private final Supplier<SSLContext> untrustedSSLContextProvider;
|
||||||
|
private final Function<URI, Proxy> proxyForURI;
|
||||||
private final HostnameVerifier verifier;
|
private final HostnameVerifier verifier;
|
||||||
private final Field methodField;
|
private final Field methodField;
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
Supplier<SSLContext> sslContextSupplier;
|
Supplier<SSLContext> sslContextSupplier;
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public JavaUrlHttpCommandExecutorService(HttpUtils utils, ContentMetadataCodec contentMetadataCodec,
|
public JavaUrlHttpCommandExecutorService(HttpUtils utils, ContentMetadataCodec contentMetadataCodec,
|
||||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
|
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
|
||||||
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
|
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
|
||||||
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
|
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
|
||||||
@Named("untrusted") Supplier<SSLContext> untrustedSSLContextProvider) throws SecurityException,
|
@Named("untrusted") Supplier<SSLContext> untrustedSSLContextProvider, Function<URI, Proxy> proxyForURI)
|
||||||
NoSuchFieldException {
|
throws SecurityException, NoSuchFieldException {
|
||||||
super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
|
super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
|
||||||
if (utils.getMaxConnections() > 0)
|
if (utils.getMaxConnections() > 0)
|
||||||
System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections()));
|
System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections()));
|
||||||
this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider");
|
this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider");
|
||||||
this.verifier = checkNotNull(verifier, "verifier");
|
this.verifier = checkNotNull(verifier, "verifier");
|
||||||
|
this.proxyForURI = checkNotNull(proxyForURI, "proxyForURI");
|
||||||
this.methodField = HttpURLConnection.class.getDeclaredField("method");
|
this.methodField = HttpURLConnection.class.getDeclaredField("method");
|
||||||
methodField.setAccessible(true);
|
methodField.setAccessible(true);
|
||||||
}
|
}
|
||||||
|
@ -159,26 +158,7 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
||||||
boolean chunked = "chunked".equals(request.getFirstHeaderOrNull("Transfer-Encoding"));
|
boolean chunked = "chunked".equals(request.getFirstHeaderOrNull("Transfer-Encoding"));
|
||||||
URL url = request.getEndpoint().toURL();
|
URL url = request.getEndpoint().toURL();
|
||||||
|
|
||||||
HttpURLConnection connection;
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxyForURI.apply(request.getEndpoint()));
|
||||||
|
|
||||||
if (utils.useSystemProxies()) {
|
|
||||||
System.setProperty("java.net.useSystemProxies", "true");
|
|
||||||
Iterable<Proxy> proxies = ProxySelector.getDefault().select(request.getEndpoint());
|
|
||||||
Proxy proxy = getLast(proxies);
|
|
||||||
connection = (HttpURLConnection) url.openConnection(proxy);
|
|
||||||
} else if (utils.getProxyHost() != null) {
|
|
||||||
SocketAddress addr = new InetSocketAddress(utils.getProxyHost(), utils.getProxyPort());
|
|
||||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
|
|
||||||
Authenticator authenticator = new Authenticator() {
|
|
||||||
public PasswordAuthentication getPasswordAuthentication() {
|
|
||||||
return new PasswordAuthentication(utils.getProxyUser(), utils.getProxyPassword().toCharArray());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Authenticator.setDefault(authenticator);
|
|
||||||
connection = (HttpURLConnection) url.openConnection(proxy);
|
|
||||||
} else {
|
|
||||||
connection = (HttpURLConnection) url.openConnection();
|
|
||||||
}
|
|
||||||
if (connection instanceof HttpsURLConnection) {
|
if (connection instanceof HttpsURLConnection) {
|
||||||
HttpsURLConnection sslCon = (HttpsURLConnection) connection;
|
HttpsURLConnection sslCon = (HttpsURLConnection) connection;
|
||||||
if (utils.relaxHostname())
|
if (utils.relaxHostname())
|
||||||
|
|
|
@ -18,9 +18,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.predicates;
|
package org.jclouds.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -28,6 +32,8 @@ import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.net.HostAndPort;
|
import com.google.common.net.HostAndPort;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
@ -47,6 +53,14 @@ public class InetSocketAddressConnect implements SocketOpen {
|
||||||
@Named("org.jclouds.socket_timeout")
|
@Named("org.jclouds.socket_timeout")
|
||||||
private int timeout = 2000;
|
private int timeout = 2000;
|
||||||
|
|
||||||
|
private final Function<URI, Proxy> proxyForURI;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
@Inject
|
||||||
|
InetSocketAddressConnect(Function<URI, Proxy> proxyForURI) {
|
||||||
|
this.proxyForURI = checkNotNull(proxyForURI, "proxyForURI");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(HostAndPort socketA) {
|
public boolean apply(HostAndPort socketA) {
|
||||||
InetSocketAddress socketAddress = new InetSocketAddress(socketA.getHostText(), socketA
|
InetSocketAddress socketAddress = new InetSocketAddress(socketA.getHostText(), socketA
|
||||||
|
@ -54,7 +68,8 @@ public class InetSocketAddressConnect implements SocketOpen {
|
||||||
Socket socket = null;
|
Socket socket = null;
|
||||||
try {
|
try {
|
||||||
logger.trace("testing socket %s", socketAddress);
|
logger.trace("testing socket %s", socketAddress);
|
||||||
socket = new Socket();
|
socket = new Socket(
|
||||||
|
proxyForURI.apply(URI.create("socket://" + socketA.getHostText() + ":" + socketA.getPort())));
|
||||||
socket.setReuseAddress(false);
|
socket.setReuseAddress(false);
|
||||||
socket.setSoLinger(false, 1);
|
socket.setSoLinger(false, 1);
|
||||||
socket.setSoTimeout(timeout);
|
socket.setSoTimeout(timeout);
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.proxy;
|
||||||
|
|
||||||
|
import java.net.Proxy.Type;
|
||||||
|
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.proxy.internal.GuiceProxyConfig;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.net.HostAndPort;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parameters needed to configure {@link java.net.Proxy}. Check presence of
|
||||||
|
* {@link #getProxyHost()} to decide if proxy support should even be attempted.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ImplementedBy(GuiceProxyConfig.class)
|
||||||
|
public interface ProxyConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.Constants#PROPERTY_PROXY_SYSTEM
|
||||||
|
*/
|
||||||
|
boolean useSystem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.Constants#PROPERTY_PROXY_TYPE
|
||||||
|
*/
|
||||||
|
Type getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.Constants#PROPERTY_PROXY_HOST
|
||||||
|
* @see org.jclouds.Constants#PROPERTY_PROXY_PORT
|
||||||
|
*/
|
||||||
|
Optional<HostAndPort> getProxy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.Constants#PROPERTY_PROXY_USER
|
||||||
|
* @see org.jclouds.Constants#PROPERTY_PROXY_PASSWORD
|
||||||
|
*/
|
||||||
|
Optional<Credentials> getCredentials();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.proxy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Iterables.getLast;
|
||||||
|
|
||||||
|
import java.net.Authenticator;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.PasswordAuthentication;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.ProxySelector;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ProxyForURI implements Function<URI, Proxy> {
|
||||||
|
private final ProxyConfig config;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
@Inject
|
||||||
|
ProxyForURI(ProxyConfig config) {
|
||||||
|
this.config = checkNotNull(config, "config");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param endpoint
|
||||||
|
* <ul>
|
||||||
|
* <li>http URI for http connections</li>
|
||||||
|
* <li>https URI for https connections</li>
|
||||||
|
* <li>ftp URI for ftp connections</li>
|
||||||
|
* <li>socket://host:port for tcp client sockets connections</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Proxy apply(URI endpoint) {
|
||||||
|
if (config.useSystem()) {
|
||||||
|
System.setProperty("java.net.useSystemProxies", "true");
|
||||||
|
Iterable<Proxy> proxies = ProxySelector.getDefault().select(endpoint);
|
||||||
|
return getLast(proxies);
|
||||||
|
} else if (config.getProxy().isPresent()) {
|
||||||
|
SocketAddress addr = new InetSocketAddress(config.getProxy().get().getHostText(), config.getProxy().get()
|
||||||
|
.getPort());
|
||||||
|
Proxy proxy = new Proxy(config.getType(), addr);
|
||||||
|
|
||||||
|
final Optional<Credentials> creds = config.getCredentials();
|
||||||
|
if (creds.isPresent()) {
|
||||||
|
Authenticator authenticator = new Authenticator() {
|
||||||
|
public PasswordAuthentication getPasswordAuthentication() {
|
||||||
|
return new PasswordAuthentication(creds.get().identity, creds.get().credential.toCharArray());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Authenticator.setDefault(authenticator);
|
||||||
|
}
|
||||||
|
return proxy;
|
||||||
|
} else {
|
||||||
|
return Proxy.NO_PROXY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.proxy.internal;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_PROXY_HOST;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_PROXY_PASSWORD;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_PROXY_PORT;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_PROXY_SYSTEM;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_PROXY_TYPE;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_PROXY_USER;
|
||||||
|
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.Proxy.Type;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.proxy.ProxyConfig;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.net.HostAndPort;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration derived from Guice properties.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class GuiceProxyConfig implements ProxyConfig {
|
||||||
|
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_PROXY_SYSTEM)
|
||||||
|
private boolean systemProxies = Boolean.parseBoolean(System.getProperty("java.net.useSystemProxies", "false"));
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_PROXY_HOST)
|
||||||
|
private String host;
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_PROXY_PORT)
|
||||||
|
private Integer port;
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_PROXY_USER)
|
||||||
|
private String user;
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_PROXY_PASSWORD)
|
||||||
|
private String password;
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_PROXY_TYPE)
|
||||||
|
private Proxy.Type type = Proxy.Type.HTTP;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<HostAndPort> getProxy() {
|
||||||
|
if (host == null)
|
||||||
|
return Optional.absent();
|
||||||
|
Integer port = this.port;
|
||||||
|
if (port == null) {
|
||||||
|
switch (type) {
|
||||||
|
case HTTP:
|
||||||
|
port = 80;
|
||||||
|
break;
|
||||||
|
case SOCKS:
|
||||||
|
port = 1080;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(type + " not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.of(HostAndPort.fromParts(host, port));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Credentials> getCredentials() {
|
||||||
|
if (user == null)
|
||||||
|
return Optional.absent();
|
||||||
|
return Optional.of(new Credentials(user, checkNotEmpty(password, "set property %s for user %s",
|
||||||
|
PROPERTY_PROXY_PASSWORD, user)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String checkNotEmpty(String nullableString, String message, Object... args) {
|
||||||
|
checkArgument(Strings.emptyToNull(nullableString) != null, message, args);
|
||||||
|
return nullableString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useSystem() {
|
||||||
|
return systemProxies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Objects.toStringHelper(this).omitNullValues().add("systemProxies", systemProxies ? "true" : null)
|
||||||
|
.add("proxy", getProxy().orNull()).add("user", user).add("type", host != null ? type : null).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ import static org.jclouds.util.Maps2.transformKeys;
|
||||||
import static org.jclouds.util.Predicates2.startsWith;
|
import static org.jclouds.util.Predicates2.startsWith;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -46,6 +47,8 @@ import org.jclouds.http.functions.config.SaxParserModule;
|
||||||
import org.jclouds.internal.FilterStringsBoundToInjectorByName;
|
import org.jclouds.internal.FilterStringsBoundToInjectorByName;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.location.config.LocationModule;
|
import org.jclouds.location.config.LocationModule;
|
||||||
|
import com.google.common.reflect.Invokable;
|
||||||
|
import org.jclouds.proxy.ProxyForURI;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.HttpAsyncClient;
|
import org.jclouds.rest.HttpAsyncClient;
|
||||||
import org.jclouds.rest.HttpClient;
|
import org.jclouds.rest.HttpClient;
|
||||||
|
@ -59,7 +62,6 @@ import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.reflect.Invokable;
|
|
||||||
import com.google.common.reflect.Parameter;
|
import com.google.common.reflect.Parameter;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
@ -147,8 +149,8 @@ public class RestModule extends AbstractModule {
|
||||||
}).toInstance(authException);
|
}).toInstance(authException);
|
||||||
bind(new TypeLiteral<Function<Predicate<String>, Map<String, String>>>() {
|
bind(new TypeLiteral<Function<Predicate<String>, Map<String, String>>>() {
|
||||||
}).to(FilterStringsBoundToInjectorByName.class);
|
}).to(FilterStringsBoundToInjectorByName.class);
|
||||||
bind(new TypeLiteral<Function<Predicate<String>, Map<String, String>>>() {
|
bind(new TypeLiteral<Function<URI, Proxy>>() {
|
||||||
}).to(FilterStringsBoundToInjectorByName.class);
|
}).to(ProxyForURI.class);
|
||||||
installLocations();
|
installLocations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.http.internal;
|
package org.jclouds.http.internal;
|
||||||
|
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -37,6 +39,7 @@ import org.jclouds.http.handlers.DelegatingRetryHandler;
|
||||||
import org.jclouds.io.ContentMetadataCodec;
|
import org.jclouds.io.ContentMetadataCodec;
|
||||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.reflect.Invokable;
|
import com.google.common.reflect.Invokable;
|
||||||
|
@ -91,10 +94,10 @@ public class TrackingJavaUrlHttpCommandExecutorService extends JavaUrlHttpComman
|
||||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
|
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
|
||||||
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
|
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
|
||||||
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
|
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
|
||||||
@Named("untrusted") Supplier<SSLContext> untrustedSSLContextProvider, List<HttpCommand> commandsInvoked)
|
@Named("untrusted") Supplier<SSLContext> untrustedSSLContextProvider, Function<URI, Proxy> proxyForURI,
|
||||||
throws SecurityException, NoSuchFieldException {
|
List<HttpCommand> commandsInvoked) throws SecurityException, NoSuchFieldException {
|
||||||
super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire, verifier,
|
super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire, verifier,
|
||||||
untrustedSSLContextProvider);
|
untrustedSSLContextProvider, proxyForURI);
|
||||||
this.commandsInvoked = commandsInvoked;
|
this.commandsInvoked = commandsInvoked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ import org.jclouds.http.apachehc.ApacheHCHttpCommandExecutorService;
|
||||||
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||||
import org.jclouds.http.config.SSLModule;
|
import org.jclouds.http.config.SSLModule;
|
||||||
import org.jclouds.lifecycle.Closer;
|
import org.jclouds.lifecycle.Closer;
|
||||||
|
import org.jclouds.proxy.ProxyConfig;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
|
@ -155,9 +156,9 @@ public class ApacheHCHttpCommandExecutorServiceModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
HttpClient newDefaultHttpClient(HttpUtils utils, BasicHttpParams params, ClientConnectionManager cm) {
|
HttpClient newDefaultHttpClient(ProxyConfig config, BasicHttpParams params, ClientConnectionManager cm) {
|
||||||
DefaultHttpClient client = new DefaultHttpClient(cm, params);
|
DefaultHttpClient client = new DefaultHttpClient(cm, params);
|
||||||
if (utils.useSystemProxies()) {
|
if (config.useSystem()) {
|
||||||
ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(client.getConnectionManager()
|
ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(client.getConnectionManager()
|
||||||
.getSchemeRegistry(), ProxySelector.getDefault());
|
.getSchemeRegistry(), ProxySelector.getDefault());
|
||||||
client.setRoutePlanner(routePlanner);
|
client.setRoutePlanner(routePlanner);
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
import org.jclouds.io.Payloads;
|
import org.jclouds.io.Payloads;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.proxy.ProxyConfig;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.ssh.SshException;
|
import org.jclouds.ssh.SshException;
|
||||||
|
@ -123,7 +124,8 @@ public class JschSshClient implements SshClient {
|
||||||
final String user;
|
final String user;
|
||||||
final String host;
|
final String host;
|
||||||
|
|
||||||
public JschSshClient(BackoffLimitedRetryHandler backoffLimitedRetryHandler, HostAndPort socket,
|
|
||||||
|
public JschSshClient(ProxyConfig proxyConfig, BackoffLimitedRetryHandler backoffLimitedRetryHandler, HostAndPort socket,
|
||||||
LoginCredentials loginCredentials, int timeout) {
|
LoginCredentials loginCredentials, int timeout) {
|
||||||
this.user = checkNotNull(loginCredentials, "loginCredentials").getUser();
|
this.user = checkNotNull(loginCredentials, "loginCredentials").getUser();
|
||||||
this.host = checkNotNull(socket, "socket").getHostText();
|
this.host = checkNotNull(socket, "socket").getHostText();
|
||||||
|
@ -142,7 +144,7 @@ public class JschSshClient implements SshClient {
|
||||||
fingerPrint, sha1, host, socket.getPort());
|
fingerPrint, sha1, host, socket.getPort());
|
||||||
}
|
}
|
||||||
sessionConnection = SessionConnection.builder().hostAndPort(HostAndPort.fromParts(host, socket.getPort())).loginCredentials(
|
sessionConnection = SessionConnection.builder().hostAndPort(HostAndPort.fromParts(host, socket.getPort())).loginCredentials(
|
||||||
loginCredentials).connectTimeout(timeout).sessionTimeout(timeout).build();
|
loginCredentials).proxy(checkNotNull(proxyConfig, "proxyConfig")).connectTimeout(timeout).sessionTimeout(timeout).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -467,8 +469,8 @@ public class JschSshClient implements SshClient {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecChannel create() throws Exception {
|
public ExecChannel create() throws Exception {
|
||||||
this.sessionConnection = acquire(SessionConnection.builder().fromSessionConnection(
|
this.sessionConnection = acquire(SessionConnection.builder().from(JschSshClient.this.sessionConnection)
|
||||||
JschSshClient.this.sessionConnection).sessionTimeout(0).build());
|
.sessionTimeout(0).build());
|
||||||
String channel = "exec";
|
String channel = "exec";
|
||||||
executor = (ChannelExec) sessionConnection.openChannel(channel);
|
executor = (ChannelExec) sessionConnection.openChannel(channel);
|
||||||
executor.setCommand(command);
|
executor.setCommand(command);
|
||||||
|
|
|
@ -20,26 +20,35 @@ package org.jclouds.ssh.jsch;
|
||||||
|
|
||||||
import static com.google.common.base.Objects.equal;
|
import static com.google.common.base.Objects.equal;
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.proxy.ProxyConfig;
|
||||||
import org.jclouds.ssh.jsch.JschSshClient.Connection;
|
import org.jclouds.ssh.jsch.JschSshClient.Connection;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.net.HostAndPort;
|
import com.google.common.net.HostAndPort;
|
||||||
import com.jcraft.jsch.JSch;
|
import com.jcraft.jsch.JSch;
|
||||||
|
import com.jcraft.jsch.Proxy;
|
||||||
|
import com.jcraft.jsch.ProxyHTTP;
|
||||||
|
import com.jcraft.jsch.ProxySOCKS5;
|
||||||
import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
|
|
||||||
public class SessionConnection implements Connection<Session> {
|
public final class SessionConnection implements Connection<Session> {
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public final static class Builder {
|
||||||
|
|
||||||
protected HostAndPort hostAndPort;
|
private HostAndPort hostAndPort;
|
||||||
protected LoginCredentials loginCredentials;
|
private LoginCredentials loginCredentials;
|
||||||
protected int connectTimeout;
|
private Optional<Proxy> proxy = Optional.absent();
|
||||||
protected int sessionTimeout;
|
private int connectTimeout;
|
||||||
|
private int sessionTimeout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SessionConnection#getHostAndPort()
|
* @see SessionConnection#getHostAndPort()
|
||||||
|
@ -57,6 +66,39 @@ public class SessionConnection implements Connection<Session> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SessionConnection#getProxy()
|
||||||
|
*/
|
||||||
|
public Builder proxy(Proxy proxy) {
|
||||||
|
this.proxy = Optional.fromNullable(proxy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #proxy(Proxy)
|
||||||
|
*/
|
||||||
|
public Builder proxy(ProxyConfig proxyConfig) {
|
||||||
|
Optional<HostAndPort> proxyEndpoint = proxyConfig.getProxy();
|
||||||
|
if (!proxyEndpoint.isPresent())
|
||||||
|
return proxy((Proxy) null);
|
||||||
|
|
||||||
|
Optional<Credentials> creds = proxyConfig.getCredentials();
|
||||||
|
switch (proxyConfig.getType()) {
|
||||||
|
case HTTP:
|
||||||
|
ProxyHTTP httpProxy = new ProxyHTTP(proxyEndpoint.get().getHostText(), proxyEndpoint.get().getPort());
|
||||||
|
if (creds.isPresent())
|
||||||
|
httpProxy.setUserPasswd(creds.get().identity, creds.get().credential);
|
||||||
|
return proxy(httpProxy);
|
||||||
|
case SOCKS:
|
||||||
|
ProxySOCKS5 socksProxy = new ProxySOCKS5(proxyEndpoint.get().getHostText(), proxyEndpoint.get().getPort());
|
||||||
|
if (creds.isPresent())
|
||||||
|
socksProxy.setUserPasswd(creds.get().identity, creds.get().credential);
|
||||||
|
return proxy(socksProxy);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(proxyConfig.getType() + " not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SessionConnection#getConnectTimeout()
|
* @see SessionConnection#getConnectTimeout()
|
||||||
*/
|
*/
|
||||||
|
@ -74,27 +116,30 @@ public class SessionConnection implements Connection<Session> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionConnection build() {
|
public SessionConnection build() {
|
||||||
return new SessionConnection(hostAndPort, loginCredentials, connectTimeout, sessionTimeout);
|
return new SessionConnection(hostAndPort, loginCredentials, proxy, connectTimeout, sessionTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Builder fromSessionConnection(SessionConnection in) {
|
public Builder from(SessionConnection in) {
|
||||||
return hostAndPort(in.getHostAndPort()).connectTimeout(in.getConnectTimeout()).loginCredentials(
|
return hostAndPort(in.hostAndPort).loginCredentials(in.loginCredentials).proxy(in.proxy.orNull())
|
||||||
in.getLoginCredentials());
|
.connectTimeout(in.connectTimeout).sessionTimeout(in.sessionTimeout);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SessionConnection(HostAndPort hostAndPort, LoginCredentials loginCredentials, int connectTimeout,
|
}
|
||||||
int sessionTimeout) {
|
|
||||||
this.hostAndPort = hostAndPort;
|
private SessionConnection(HostAndPort hostAndPort, LoginCredentials loginCredentials, Optional<Proxy> proxy,
|
||||||
this.loginCredentials = loginCredentials;
|
int connectTimeout, int sessionTimeout) {
|
||||||
|
this.hostAndPort = checkNotNull(hostAndPort, "hostAndPort");
|
||||||
|
this.loginCredentials = checkNotNull(loginCredentials, "loginCredentials for %", hostAndPort);
|
||||||
this.connectTimeout = connectTimeout;
|
this.connectTimeout = connectTimeout;
|
||||||
this.sessionTimeout = sessionTimeout;
|
this.sessionTimeout = sessionTimeout;
|
||||||
|
this.proxy = checkNotNull(proxy, "proxy for %", hostAndPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final byte[] emptyPassPhrase = new byte[0];
|
private static final byte[] emptyPassPhrase = new byte[0];
|
||||||
|
|
||||||
private final HostAndPort hostAndPort;
|
private final HostAndPort hostAndPort;
|
||||||
private final LoginCredentials loginCredentials;
|
private final LoginCredentials loginCredentials;
|
||||||
|
private final Optional<Proxy> proxy;
|
||||||
private final int connectTimeout;
|
private final int connectTimeout;
|
||||||
private final int sessionTimeout;
|
private final int sessionTimeout;
|
||||||
|
|
||||||
|
@ -126,6 +171,8 @@ public class SessionConnection implements Connection<Session> {
|
||||||
java.util.Properties config = new java.util.Properties();
|
java.util.Properties config = new java.util.Properties();
|
||||||
config.put("StrictHostKeyChecking", "no");
|
config.put("StrictHostKeyChecking", "no");
|
||||||
session.setConfig(config);
|
session.setConfig(config);
|
||||||
|
if (proxy.isPresent())
|
||||||
|
session.setProxy(proxy.get());
|
||||||
session.connect(connectTimeout);
|
session.connect(connectTimeout);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +192,14 @@ public class SessionConnection implements Connection<Session> {
|
||||||
return loginCredentials;
|
return loginCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return proxy used for this connection
|
||||||
|
*/
|
||||||
|
public Optional<Proxy> getProxy() {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return how long to wait for the initial connection to be made
|
* @return how long to wait for the initial connection to be made
|
||||||
|
@ -165,6 +220,7 @@ public class SessionConnection implements Connection<Session> {
|
||||||
*
|
*
|
||||||
* @return the current session or {@code null} if not connected
|
* @return the current session or {@code null} if not connected
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public Session getSession() {
|
public Session getSession() {
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
@ -187,10 +243,12 @@ public class SessionConnection implements Connection<Session> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Objects.toStringHelper("").add("hostAndPort", hostAndPort).add("loginUser", loginCredentials.getUser())
|
return Objects.toStringHelper("").omitNullValues()
|
||||||
.add("session", session != null ? session.hashCode() : null).add("connectTimeout", connectTimeout).add(
|
.add("hostAndPort", hostAndPort).add("loginUser", loginCredentials.getUser())
|
||||||
"sessionTimeout", sessionTimeout).toString();
|
.add("session", session != null ? session.hashCode() : null)
|
||||||
|
.add("connectTimeout", connectTimeout)
|
||||||
|
.add("proxy", proxy.orNull())
|
||||||
|
.add("sessionTimeout", sessionTimeout).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.ssh.jsch.config;
|
package org.jclouds.ssh.jsch.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||||
|
import org.jclouds.proxy.ProxyConfig;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.ssh.config.ConfiguresSshClient;
|
import org.jclouds.ssh.config.ConfiguresSshClient;
|
||||||
import org.jclouds.ssh.jsch.JschSshClient;
|
import org.jclouds.ssh.jsch.JschSshClient;
|
||||||
|
@ -49,18 +52,20 @@ public class JschSshClientModule extends AbstractModule {
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
int timeout = 60000;
|
int timeout = 60000;
|
||||||
|
|
||||||
|
private final ProxyConfig proxyConfig;
|
||||||
private final BackoffLimitedRetryHandler backoffLimitedRetryHandler;
|
private final BackoffLimitedRetryHandler backoffLimitedRetryHandler;
|
||||||
private final Injector injector;
|
private final Injector injector;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Factory(BackoffLimitedRetryHandler backoffLimitedRetryHandler, Injector injector) {
|
public Factory(ProxyConfig proxyConfig, BackoffLimitedRetryHandler backoffLimitedRetryHandler, Injector injector) {
|
||||||
this.backoffLimitedRetryHandler = backoffLimitedRetryHandler;
|
this.proxyConfig = checkNotNull(proxyConfig, "proxyConfig");
|
||||||
this.injector = injector;
|
this.backoffLimitedRetryHandler = checkNotNull(backoffLimitedRetryHandler, "backoffLimitedRetryHandler");
|
||||||
|
this.injector = checkNotNull(injector, "injector");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SshClient create(HostAndPort socket, LoginCredentials credentials) {
|
public SshClient create(HostAndPort socket, LoginCredentials credentials) {
|
||||||
SshClient client = new JschSshClient(backoffLimitedRetryHandler, socket, credentials, timeout);
|
SshClient client = new JschSshClient(proxyConfig, backoffLimitedRetryHandler, socket, credentials, timeout);
|
||||||
injector.injectMembers(client);// add logger
|
injector.injectMembers(client);// add logger
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.jclouds.joyent.cloudapi.v6_5.domain.Machine;
|
||||||
import org.jclouds.joyent.cloudapi.v6_5.internal.BaseJoyentCloudApiLiveTest;
|
import org.jclouds.joyent.cloudapi.v6_5.internal.BaseJoyentCloudApiLiveTest;
|
||||||
import org.jclouds.joyent.cloudapi.v6_5.options.CreateMachineOptions;
|
import org.jclouds.joyent.cloudapi.v6_5.options.CreateMachineOptions;
|
||||||
import org.jclouds.joyent.cloudapi.v6_5.reference.Metadata;
|
import org.jclouds.joyent.cloudapi.v6_5.reference.Metadata;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.ssh.SshKeys;
|
import org.jclouds.ssh.SshKeys;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
@ -96,7 +96,8 @@ public class MachineApiLiveTest extends BaseJoyentCloudApiLiveTest {
|
||||||
cloudApiContext.getApi().getKeyApi().create(Key.builder().name(fingerprint).key(key.get("public")).build());
|
cloudApiContext.getApi().getKeyApi().create(Key.builder().name(fingerprint).key(key.get("public")).build());
|
||||||
api = cloudApiContext.getApi().getMachineApiForDatacenter(
|
api = cloudApiContext.getApi().getMachineApiForDatacenter(
|
||||||
Iterables.get(cloudApiContext.getApi().getConfiguredDatacenters(), 0));
|
Iterables.get(cloudApiContext.getApi().getConfiguredDatacenters(), 0));
|
||||||
socketTester = retry(new InetSocketAddressConnect(), 180, 1, 1, SECONDS);
|
SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class);
|
||||||
|
socketTester = retry(socketOpen, 180, 1, 1, SECONDS);
|
||||||
machineRunning = retry(new Predicate<Machine>() {
|
machineRunning = retry(new Predicate<Machine>() {
|
||||||
public boolean apply(Machine input) {
|
public boolean apply(Machine input) {
|
||||||
return api.get(input.getId()).getState() == Machine.State.RUNNING;
|
return api.get(input.getId()).getState() == Machine.State.RUNNING;
|
||||||
|
|
|
@ -29,7 +29,7 @@ import static org.testng.Assert.assertTrue;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jclouds.collect.IterableWithMarker;
|
import org.jclouds.collect.IterableWithMarker;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rds.domain.Authorization;
|
import org.jclouds.rds.domain.Authorization;
|
||||||
import org.jclouds.rds.domain.Authorization.Status;
|
import org.jclouds.rds.domain.Authorization.Status;
|
||||||
import org.jclouds.rds.domain.Instance;
|
import org.jclouds.rds.domain.Instance;
|
||||||
|
@ -64,7 +64,8 @@ public class InstanceApiLiveTest extends BaseRDSApiLiveTest {
|
||||||
public void setupContext() {
|
public void setupContext() {
|
||||||
super.setupContext();
|
super.setupContext();
|
||||||
securityGroup = createSecurityGroupAndAuthorizeIngressToAll(INSTANCE);
|
securityGroup = createSecurityGroupAndAuthorizeIngressToAll(INSTANCE);
|
||||||
socketTester = retry(new InetSocketAddressConnect(), 180, 1, 1, SECONDS);
|
SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class);
|
||||||
|
socketTester = retry(socketOpen, 180, 1, 1, SECONDS);
|
||||||
instanceAvailable = retry(new Predicate<Instance>() {
|
instanceAvailable = retry(new Predicate<Instance>() {
|
||||||
public boolean apply(Instance input) {
|
public boolean apply(Instance input) {
|
||||||
return api().get(input.getId()).getStatus() == Instance.Status.AVAILABLE;
|
return api().get(input.getId()).getStatus() == Instance.Status.AVAILABLE;
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.jclouds.cim.OSType;
|
||||||
import org.jclouds.compute.domain.CIMOperatingSystem;
|
import org.jclouds.compute.domain.CIMOperatingSystem;
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.savvis.vpdc.domain.Network;
|
import org.jclouds.savvis.vpdc.domain.Network;
|
||||||
import org.jclouds.savvis.vpdc.domain.Resource;
|
import org.jclouds.savvis.vpdc.domain.Resource;
|
||||||
import org.jclouds.savvis.vpdc.domain.Task;
|
import org.jclouds.savvis.vpdc.domain.Task;
|
||||||
|
@ -66,7 +66,8 @@ public class VMApiLiveTest extends BaseVPDCApiLiveTest {
|
||||||
public void setupContext() {
|
public void setupContext() {
|
||||||
super.setupContext();
|
super.setupContext();
|
||||||
api = restContext.getApi().getVMApi();
|
api = restContext.getApi().getVMApi();
|
||||||
socketTester = retry(new InetSocketAddressConnect(), 130, 10, SECONDS);// make
|
SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class);
|
||||||
|
socketTester = retry(socketOpen, 130, 10, SECONDS);// make
|
||||||
}
|
}
|
||||||
|
|
||||||
private String billingSiteId;
|
private String billingSiteId;
|
||||||
|
|
|
@ -53,7 +53,7 @@ import org.jclouds.gogrid.options.GetImageListOptions;
|
||||||
import org.jclouds.gogrid.predicates.LoadBalancerLatestJobCompleted;
|
import org.jclouds.gogrid.predicates.LoadBalancerLatestJobCompleted;
|
||||||
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
|
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.testng.SkipException;
|
import org.testng.SkipException;
|
||||||
|
@ -342,10 +342,9 @@ public class GoGridLiveTestDisabled extends BaseComputeServiceContextLiveTest {
|
||||||
assertNotNull(instanceCredentials);
|
assertNotNull(instanceCredentials);
|
||||||
|
|
||||||
HostAndPort socket = HostAndPort.fromParts(createdServer.getIp().getIp(), 22);
|
HostAndPort socket = HostAndPort.fromParts(createdServer.getIp().getIp(), 22);
|
||||||
|
SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class);
|
||||||
Predicate<HostAndPort> socketOpen = retry(new InetSocketAddressConnect(), 180, 5, SECONDS);
|
Predicate<HostAndPort> socketTester = retry(socketOpen, 180, 5, SECONDS);
|
||||||
|
socketTester.apply(socket);
|
||||||
socketOpen.apply(socket);
|
|
||||||
|
|
||||||
SshClient sshClient = gocontext.utils().injector().getInstance(SshClient.Factory.class).create(socket, instanceCredentials);
|
SshClient sshClient = gocontext.utils().injector().getInstance(SshClient.Factory.class).create(socket, instanceCredentials);
|
||||||
sshClient.connect();
|
sshClient.connect();
|
||||||
|
|
Loading…
Reference in New Issue