Skip to content

Commit

Permalink
Merge pull request #31 from robmoffat/master
Browse files Browse the repository at this point in the history
Fixing Enums and Proxies
  • Loading branch information
VladimirPar committed Feb 27, 2020
2 parents b0a40ba + 8694cb9 commit ab27dc8
Show file tree
Hide file tree
Showing 14 changed files with 328 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.symphony.api.bindings;

import java.util.EnumSet;

import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
import javax.ws.rs.core.Response.Status.Family;

public abstract class AbstractApiBuilder implements ConfigurableApiBuilder {

Expand All @@ -26,6 +29,7 @@ public AbstractApiBuilder(String url, KeyManager[] keyManagers) {
protected String password;
protected int port;
protected ApiWrapper[] wrappers = new ApiWrapper[0];
protected Long connectTimeout = null;

@Override
public void setProxyDetails(String proxyHost, String user, String password, int port) {
Expand Down Expand Up @@ -69,5 +73,19 @@ public ApiWrapper[] getWrappers() {
return this.wrappers;
}

@Override
public void setConnectTimeout(long ct) {
this.connectTimeout = ct;
}

/**
* Should be overridden by specific implementations
*/
@Override
public boolean testConnection(String url) {
return true;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ public interface ConfigurableApiBuilder extends ApiBuilder {
ApiWrapper[] getWrappers();
TrustManager[] getTrustManagers();
KeyManager[] getKeyManagers();

boolean testConnection(String url);

void setConnectTimeout(long ct);

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.List;

import javax.net.ssl.KeyManager;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status.Family;

import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.jaxrs.client.ClientConfiguration;
Expand All @@ -18,15 +20,16 @@
import com.symphony.api.bindings.AbstractApiBuilder;

/**
* You should write your own version of this, or modify the returned webclient if you want to make use of proxies,
* or set different characteristics on the webclient.
* You should write your own version of this, or modify the returned webclient
* if you want to make use of proxies, or set different characteristics on the
* webclient.
*
* The URL should be:
*
* <ul>
<li>https://&lt;your-pod&gt;.symphony.com:443/sessionauth
<li>https://&lt;your agent&gt;:8444/agent
<li>https://&lt;your key manager&gt;:8444/keyauth
* <ul>
* <li>https://&lt;your-pod&gt;.symphony.com:443/sessionauth
* <li>https://&lt;your agent&gt;:8444/agent
* <li>https://&lt;your key manager&gt;:8444/keyauth
* </ul>
*
*
Expand All @@ -35,28 +38,29 @@
*/
public class CXFApiBuilder extends AbstractApiBuilder {


public CXFApiBuilder() {
}

/**
* Call this class to create a basic xcf webclient.
* Call this class to create a basic xcf webclient.
*
*/
public CXFApiBuilder(String url) {
super(url);
}

/**
* Call this class to create a basic xcf webclient for authenticating using certificates.
* Call this class to create a basic xcf webclient for authenticating using
* certificates.
*/
public CXFApiBuilder(String url, KeyManager[] keyManagers) {
super(url, keyManagers);
}

/**
* Call this with an api, e.g. {@link MessagesApi}.class if you have constructed with the /agent endpoint,
* or {@link AuthenticationApi} if you have constructed with keyauth or sessionauth endpoints.
* Call this with an api, e.g. {@link MessagesApi}.class if you have constructed
* with the /agent endpoint, or {@link AuthenticationApi} if you have
* constructed with keyauth or sessionauth endpoints.
*/
@Override
public <X> X getApi(Class<X> c) {
Expand All @@ -65,7 +69,9 @@ public <X> X getApi(Class<X> c) {
}

/**
* Sets the list of providers, by default will be {@link JacksonJsonProvider} and {@link ContentDispositionMultipartProvider}.
* Sets the list of providers, by default will be {@link JacksonJsonProvider}
* and {@link ContentDispositionMultipartProvider}.
*
* @return
*/
protected List<Object> getProviders() {
Expand All @@ -75,18 +81,18 @@ protected List<Object> getProviders() {
providers.add(new SymphonyExceptionMapper());
return providers;
}

protected <X> X buildProxy(Class<X> c, WebClient wc) {
X out = JAXRSClientFactory.fromClient(wc, c);

for (int i = 0; i < wrappers.length; i++) {
out = wrappers[i].wrap(c, out);
}

return out;
}
protected WebClient createWebClient() {

protected WebClient createWebClient(String url) {
List<Object> providers = getProviders();
WebClient wc = WebClient.create(url, providers);
setProxy(wc);
Expand All @@ -95,36 +101,52 @@ protected WebClient createWebClient() {
return wc;
}

protected WebClient createWebClient() {
return createWebClient(this.url);
}

protected void setupClientConfiguration(ClientConfiguration config) {
HTTPConduit conduit = config.getHttpConduit();

TLSClientParameters params = conduit.getTlsClientParameters();

if (params == null) {
params = new TLSClientParameters();
conduit.setTlsClientParameters(params);
}

if (connectTimeout != null) {
conduit.getClient().setConnectionTimeout(connectTimeout);
}

setupTLSParameters(params);
}

protected void setupTLSParameters(TLSClientParameters params) {
params.setKeyManagers(keyManagers);

if (trustManagers != null) {
params.setTrustManagers(trustManagers);
}
}

public void setProxy(WebClient wc) {
HTTPConduit conduit = WebClient.getConfig(wc).getHttpConduit();
HTTPClientPolicy policy = conduit.getClient();
if ((this.proxyHost!= null) && (this.proxyHost.length() > 0)) {
if ((this.proxyHost != null) && (this.proxyHost.length() > 0)) {
policy.setProxyServer(proxyHost);
policy.setProxyServerPort(port);
}
}


@Override
public boolean testConnection(String url) {
try {
Response response = createWebClient(url).get();
return response != null;
} catch (Exception e) {
return false;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import javax.net.ssl.SSLContext;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status.Family;

import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
Expand Down Expand Up @@ -52,19 +54,23 @@ public <X> X getApi(Class<X> c) {
return buildProxy(c, wt);
}

public WebTarget newWebTarget() {
protected WebTarget newWebTarget(String url) {
try {
JerseyClientBuilder jcb = new JerseyClientBuilder();
jcb.sslContext(createSSLContext());
jcb = jcb.withConfig(createConfig());
registerFeatures(jcb);
Client client = jcb.build();
WebTarget webTarget = client.target(this.url);
WebTarget webTarget = client.target(url);
return webTarget;
} catch (Exception e) {
throw new UnsupportedOperationException("Couldn't create jersey client", e);
}
}

protected WebTarget newWebTarget() {
return newWebTarget(this.url);
}

protected void registerFeatures(JerseyClientBuilder jcb) {
jcb.register(MultiPartFeature.class);
Expand All @@ -86,6 +92,11 @@ protected ClientConfig createConfig() {
config.property(ClientProperties.PROXY_USERNAME,user);
config.property(ClientProperties.PROXY_PASSWORD,password);
}

if (connectTimeout != null) {
config.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout.intValue());
}

return config;
}

Expand All @@ -99,5 +110,13 @@ protected <X> X buildProxy(Class<X> c, WebTarget wt) {
return out;
}


@Override
public boolean testConnection(String url) {
try {
Response response = newWebTarget(url).request().get();
return response != null; // any response from the server means we at least connected.
} catch (Exception e) {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ public interface TestClientStrategy {
public com.symphony.api.login.AuthenticationApi getRSASessionAuthApi();

public com.symphony.api.login.AuthenticationApi getRSAKeyAuthApi();

public ConfigurableApiBuilder getApiBuilder();
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ public com.symphony.api.login.AuthenticationApi getRSAKeyAuthApi() {
b.setProxyDetails(CI_PROXY, null, null, 8080);
return b.getApi(com.symphony.api.login.AuthenticationApi.class);
}

@Override
public ConfigurableApiBuilder getApiBuilder() {
return pab.call();
}


}

public static final class CertTestClientStrategy extends AbstractTestClientStrategy {
Expand Down Expand Up @@ -172,12 +179,12 @@ public AuthenticationApi getKeyAuthApi() {
private static final SymphonyIdentity BOT1_ID = TestIdentityProvider.getIdentity("symphony-develop-bot1-identity");

private static final String CI_PROXY = System.getProperty("proxy");
private static final String SESSION_AUTH_URL = "https://develop-api.symphony.com/sessionauth";
private static final String KEY_AUTH_URL = "https://develop-api.symphony.com/keyauth";
private static final String AGENT_URL = "https://develop.symphony.com/agent";
private static final String POD_URL = "https://develop.symphony.com/pod";
private static final String LOGIN_URL = "https://develop.symphony.com/login";
private static final String RELAY_URL = "https://develop.symphony.com/relay";
public static final String SESSION_AUTH_URL = "https://develop-api.symphony.com/sessionauth";
public static final String KEY_AUTH_URL = "https://develop-api.symphony.com/keyauth";
public static final String AGENT_URL = "https://develop.symphony.com/agent";
public static final String POD_URL = "https://develop.symphony.com/pod";
public static final String LOGIN_URL = "https://develop.symphony.com/login";
public static final String RELAY_URL = "https://develop.symphony.com/relay";

public static final TestClientStrategy JERSEY_RSA = new RSATestClientStrategy(BOT1_ID, () -> new JerseyApiBuilder());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.symphony.api.bindings;

import org.junit.Assert;
import org.junit.experimental.theories.Theory;

public class TestProxyConnection extends AbstractTest {

@Theory
public void testConnectionToRandomUrl(TestClientStrategy tcs) {
ConfigurableApiBuilder b = tcs.getApiBuilder();
b.setProxyDetails(null, null, null, 8080);
Assert.assertTrue(b.testConnection("https://google.com"));
}

@Theory
public void testConnectionToSymphonyPod(TestClientStrategy tcs) {
ConfigurableApiBuilder b = tcs.getApiBuilder();
b.setProxyDetails(null, null, null, 8080);
Assert.assertTrue(b.testConnection(TestPodConfig.POD_URL));
}

@Theory
public void testConnectionToSymphonyRelay(TestClientStrategy tcs) {
ConfigurableApiBuilder b = tcs.getApiBuilder();
b.setConnectTimeout(6000);
b.setProxyDetails(null, null, null, 8080);
Assert.assertTrue(b.testConnection(TestPodConfig.RELAY_URL));
}

@Theory
public void testConnectionToSomethingBroken(TestClientStrategy tcs) {
ConfigurableApiBuilder b = tcs.getApiBuilder();
b.setProxyDetails(null, null, null, 8080);
Assert.assertFalse(b.testConnection("https://idontexist.co.uk"));
}

@Theory
public void testWithBrokenProxy(TestClientStrategy tcs) {
ConfigurableApiBuilder b = tcs.getApiBuilder();
b.setProxyDetails("idontexist.co.uk", null, null, 8080);
Assert.assertFalse(b.testConnection(TestPodConfig.POD_URL));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p,
public boolean useForType(JavaType t) {
boolean out = super.useForType(t);

if (t.isEnumType()) {
return false;
}

if (!out) {
String className = t.getRawClass().getCanonicalName();
for (VersionSpace versionSpace : allowed) {
Expand Down
Loading

0 comments on commit ab27dc8

Please sign in to comment.