Created
July 24, 2015 16:16
-
-
Save cbweixin/a095055617b5f1f0208d to your computer and use it in GitHub Desktop.
how to use jax-rs rest client to accept all certifications. the way is different from the way which used by org.apache.httpclient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.intuit.sb.dispatcher; | |
import com.intuit.qbn.util.ids.CompanyId; | |
import com.intuit.sb.dispatcher.common.domain.CompanyShardVHost; | |
import com.intuit.sb.dispatcher.common.error.ServiceErrorBean; | |
import com.intuit.sb.dispatcher.error.ServiceException; | |
import org.apache.http.conn.ssl.NoopHostnameVerifier; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import javax.net.ssl.HostnameVerifier; | |
import javax.net.ssl.SSLSession; | |
import javax.ws.rs.client.Client; | |
import javax.ws.rs.client.ClientBuilder; | |
import javax.ws.rs.client.WebTarget; | |
import javax.ws.rs.core.Response; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.security.KeyStore; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class DispatcherLib { | |
// TODO use moco or wiremock to emulate server | |
// TODO See if https certificates an issue | |
public static String dispatcherServiceUrl; | |
private static final Logger logger = LoggerFactory.getLogger(DispatcherLib.class); | |
public DispatcherLib() { | |
setEnv(); | |
} | |
public static void main(String[] args) { | |
DispatcherLib lib = new DispatcherLib(); | |
lib.makeHttpCall("realm/11111111/qbo", "GET"); | |
} | |
// TODO this should probably be called in the constructor, and this object needs to be singleton | |
// What do you mean by singleton? | |
public static void setEnv() { // env = prod, qa, etc.... | |
String env; | |
if ((env = System.getProperty("env")) == null) { | |
env = "app"; // default to localhost | |
} | |
try { | |
ClassLoader classLoader = DispatcherLib.class.getClassLoader(); | |
System.getProperties() | |
.load(classLoader.getResourceAsStream("dispatcher." + env + ".properties")); | |
} catch (FileNotFoundException error) { | |
logger | |
.error("Cannot locate configuration file {0}", "dispatcher." + env + ".properties"); | |
error.printStackTrace(); | |
} catch (IOException error) { | |
logger.error("Error opening file {0}", "dispatcher." + env + ".properties"); | |
error.printStackTrace(); | |
} | |
dispatcherServiceUrl = System.getProperty("url"); | |
} | |
/** | |
* Default appId is "qbo". | |
* QBNResiliencyResolver / Edge router request for shard/host and data center info. | |
* Endpoint: v1/dispatcher/realm/{realmId}/{appId} | |
* | |
* @param companyId | |
* @return CompanyShardVHost | |
* @throws CompanyShardVHost | |
*/ | |
public static CompanyShardVHost getCompanyShardVHost(CompanyId companyId) | |
throws ServiceException { | |
return getCompanyShardVHost("qbo", companyId); | |
} | |
/** | |
* QBNResiliencyResolver / Edge router request for shard/host and data center info. | |
* Endpoint: v1/dispatcher/realm/{realmId}/{appId} | |
* | |
* @param appId | |
* @param companyId | |
* @return CompanyShardVHost | |
* @throws ServiceException | |
*/ | |
public static CompanyShardVHost getCompanyShardVHost(String appId, CompanyId companyId) | |
throws ServiceException { | |
try { | |
Response response = makeHttpCall("realm/" + companyId.getId() + "/" + appId, "GET"); | |
int status = response.getStatus(); | |
if (status == Response.Status.OK.getStatusCode()) { | |
return response.readEntity(CompanyShardVHost.class); | |
} else { | |
logError(appId, companyId, status); | |
} | |
throw new ServiceException(response.readEntity(ServiceErrorBean.class), status); | |
} catch (ServiceException error) { // TODO Do we need this? Yes, | |
// in order to throw ServiceException error instead of an Exception | |
logger.error(error.getServiceErrorBean().getMessage()); | |
throw error; | |
} catch (Exception error) { | |
logger.error( | |
"Exception at endpoint: " + dispatcherServiceUrl + "realm/" + companyId.getId() | |
+ "/" + appId); | |
throw error; | |
} | |
} | |
private static void logError(String appId, CompanyId companyId, int responseStatus) { | |
if (responseStatus == Response.Status.NO_CONTENT.getStatusCode()) // 204 No Content | |
{ | |
logger.error( | |
"204 No Content. Endpoint: " + dispatcherServiceUrl + companyId.getId() + "/" | |
+ appId); | |
} else if (responseStatus == Response.Status.NOT_FOUND.getStatusCode()) { | |
logger.error( | |
"404 Not Found. Endpoint: " + dispatcherServiceUrl + companyId.getId() + "/" | |
+ appId); | |
} else if (responseStatus == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) { | |
logger.error( | |
"500 Internal Server Error. Endpoint: " + dispatcherServiceUrl + companyId.getId() | |
+ "/" + appId); | |
} | |
} | |
/** | |
* Default appId is "qbo" | |
* Retrieve mapping of companyIds to shards | |
* Endpoint: v1/dispatcher/shard/{appId}/{shardId} | |
* | |
* @param companyIds | |
* @return List<CompanyShardVHost> | |
* @throws ServiceException | |
*/ | |
public List<CompanyShardVHost> getCompanyShardVHostsFromCompanyIds(List<CompanyId> companyIds) | |
throws ServiceException { | |
return getCompanyShardVHostsFromCompanyIds("qbp", companyIds); | |
} | |
/** | |
* Retrieve mapping of companyIds to shards | |
* Endpoint: v1/dispatcher/shard/{appId}/{shardId} | |
* | |
* @param appId | |
* @param companyIds | |
* @return List<CompanyShardVHost> | |
* @throws ServiceException | |
*/ | |
public List<CompanyShardVHost> getCompanyShardVHostsFromCompanyIds( | |
String appId, List<CompanyId> companyIds) throws ServiceException { | |
try { | |
//TODO Define own class as a Map<CompanyId, CompanyShardVHost> to avoid redundancy | |
// (don't need realm id in value) | |
List<CompanyShardVHost> list = new ArrayList<CompanyShardVHost>(); | |
for (CompanyId companyId : companyIds) { | |
list.add(getCompanyShardVHost(appId, companyId)); | |
} | |
return list; | |
} catch (ServiceException error) { | |
throw error; | |
} catch (Exception error) { | |
throw error; | |
} | |
} | |
/** | |
* Default appId is "qbo". | |
* QBNResiliencyResolver / Edge router request for shard/host and data center info. | |
* Endpoint: v1/dispatcher/realm/{realmId}/{appId} | |
* | |
* @param companyId | |
* @return | |
* @throws ServiceException | |
*/ | |
public static String getHostFromCompanyId(CompanyId companyId) throws ServiceException { | |
return getHostFromCompanyId("qbo", companyId); | |
} | |
/** | |
* QBNResiliencyResolver / Edge router request for shard/host and data center info. | |
* Endpoint: v1/dispatcher/realm/{realmId}/{appId} | |
* | |
* @param appId | |
* @param companyId | |
* @return String | |
* @throws ServiceException | |
*/ | |
public static String getHostFromCompanyId(String appId, CompanyId companyId) | |
throws ServiceException { | |
try { | |
Response response = makeHttpCall("realm/" + companyId.getId() + "/" + appId, "GET"); | |
int status = response.getStatus(); | |
if (status == Response.Status.OK.getStatusCode()) { | |
return response.readEntity(CompanyShardVHost.class).getHost(); | |
} else { | |
logError(appId, companyId, status); | |
} | |
throw new ServiceException(response.readEntity(ServiceErrorBean.class), status); | |
} | |
/* Not sure we need this | |
catch (ServiceException error) { | |
logger.error(error.getServiceErrorBean().getMessage()); | |
throw error; | |
} */ catch (Exception error) { | |
logger.error( | |
"Exception at endpoint: " + dispatcherServiceUrl + companyId.getId() + "/" + appId); | |
throw error; | |
} | |
} | |
/** | |
* Default appId is "qbo" | |
* Retrieve mapping of companyIds to host name | |
* Endpoint: v1/dispatcher/shard/{appId}/{shardId} | |
* | |
* @param companyIds | |
* @return List<String> | |
* @throws ServiceException | |
*/ | |
public static List<String> getHostsFromCompanyIds(List<CompanyId> companyIds) | |
throws ServiceException { | |
return getHostsFromCompanyIds("qbo", companyIds); | |
} | |
/** | |
* Retrieve mapping of companyIds to host name | |
* Endpoint: v1/dispatcher/shard/{appId}/{shardId} | |
* | |
* @param appId | |
* @param companyIds | |
* @return List<String> | |
* @throws ServiceException | |
*/ | |
public static List<String> getHostsFromCompanyIds(String appId, List<CompanyId> companyIds) | |
throws ServiceException { | |
try { | |
List<String> list = new ArrayList<String>(); | |
for (CompanyId companyId : companyIds) { | |
list.add( | |
getHostFromCompanyId( | |
appId, companyId)); // TODO make the batch call /realm/batch/{appId}, | |
} | |
// and pass in list of realm Ids in the body of the request. You might | |
// have to add checks around batch size, etc... | |
return list; | |
} catch (ServiceException error) { | |
throw error; | |
} | |
} | |
/** | |
* Default appId is "qbo" | |
* Create or move/update company. | |
* Endpoint: v1/dispatcher/realm/{appId}/{shardId}/{hostUrl}/{realmId} | |
* | |
* @param shardId | |
* @param companyId | |
* @return Returns true for successful company creation or update. Returns false if error is | |
* thrown. | |
*/ | |
public static boolean createOrUpdateCompany(CompanyId companyId, int shardId, String vHost) | |
throws Exception { | |
return createOrUpdateCompany("qbo", companyId, shardId, vHost); | |
} | |
/** | |
* Create or move/update company. | |
* Endpoint: v1/dispatcher/realm/{appId}/{shardId}/{hostUrl}/{realmId} | |
* | |
* @param appId | |
* @param companyId | |
* @param shardId | |
* @param vHost | |
* @return Returns true for successful company creation or update. Returns false if error is | |
* thrown. | |
* @throws ServiceException | |
*/ | |
public static boolean createOrUpdateCompany( | |
String appId, CompanyId companyId, int shardId, String vHost) throws ServiceException { | |
try { | |
Response response = makeHttpCall( | |
"realm/" + appId + "/" + shardId + "/" + vHost + "/" + companyId.getId(), "POST"); | |
int status = response.getStatus(); | |
if (status == Response.Status.OK.getStatusCode()) { | |
logger.info("Shard updated for company {0}", companyId.getId()); | |
} else if (status == Response.Status.CREATED.getStatusCode()) { | |
logger.info( | |
"Entry created for company {} app {} shard {}", companyId.getId(), appId, | |
shardId); | |
} else { | |
logError(appId, companyId, status); | |
return false; | |
} | |
return true; | |
// Do we need this ? throw new ServiceException(ErrorEnum.UNKNOWN_COMPANY_AND_APP_ID, | |
// status); | |
} | |
/* TODO Who's going to throw Service Exception | |
catch (ServiceException error) { | |
logger.error(error.getServiceErrorBean().getMessage()); | |
throw error; | |
} | |
*/ catch (Exception exception) { | |
//TODO Convert exception to ServiceException and throw it | |
logger.error( | |
"Exception at endpoint: " + dispatcherServiceUrl + companyId.getId() + "/" + appId); | |
throw exception; | |
} | |
} | |
/** | |
* Helper method that sends the jersey rest call and retrieves the response | |
* | |
* @param endpoint | |
* @param methodType | |
* @return Response | |
*/ | |
private static Response makeHttpCall(String endpoint, String methodType) { | |
dispatcherServiceUrl = | |
"https://ci-develop-dispatcher-service.sbfs-acct-sbg-dispatcher-dev.a.intuit" + | |
".com/webapp/v1/dispatcher/"; | |
logger.debug("endpoint: " + dispatcherServiceUrl + endpoint); | |
MySecureProtocolSocketFactory contextFactory = new MySecureProtocolSocketFactory(); | |
Client client = null; | |
ClientBuilder builder = ClientBuilder.newBuilder(); | |
try { | |
// builder.keyStore( | |
// loadStore("/Users/xwei/Documents/mykey/dispatcherkey", "123456"), | |
// "123456"); | |
builder.hostnameVerifier(new NoopHostnameVerifier()).sslContext( | |
contextFactory.getSslContext()); | |
client = builder.build(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
WebTarget target = client.target(dispatcherServiceUrl).path(endpoint); | |
Response response = null; | |
switch (methodType) { | |
case "GET": | |
response = target.request().get(); | |
break; | |
case "POST": | |
response = target.request().post(null); | |
break; | |
default: | |
response = null; | |
} | |
System.out.println(response.getStatus()); | |
CompanyShardVHost companyShardVHost = response.readEntity(CompanyShardVHost.class); | |
System.out.println(companyShardVHost.getRealmId()); | |
System.out.println(companyShardVHost.getShard()); | |
System.out.println(companyShardVHost.getHost()); | |
System.out.println(companyShardVHost.getAppId()); | |
return response; | |
} | |
// if we got any CA authorized cert, then we need to load it as 'keystore', also | |
// we need to load 'truststore'. but for accepting all cert purpose, it is no use | |
// TODO : Fix Me. use me later | |
private static KeyStore loadStore(String trustStoreFile, String password) throws Exception { | |
KeyStore store = KeyStore.getInstance("JKS"); | |
store.load(new FileInputStream(trustStoreFile), password.toCharArray()); | |
return store; | |
} | |
} | |
// since we already used 'NoopHostnameVerifier', we don't need to implement our own verfier anymore | |
class VerifyEverythingHostnameVerifier implements HostnameVerifier { | |
@Override | |
public boolean verify(String string, SSLSession sslSession) { | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.intuit.sb.dispatcher; | |
import javax.net.ssl.SSLContext; | |
import javax.net.ssl.TrustManager; | |
import javax.net.ssl.X509TrustManager; | |
import java.security.KeyManagementException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.SecureRandom; | |
import java.security.cert.CertificateException; | |
import java.security.cert.X509Certificate; | |
/** | |
* Created by xwei on 7/22/15. | |
*/ | |
public class MySecureProtocolSocketFactory { | |
private SSLContext sslContext = null; | |
private SSLContext createSSLContext() { | |
SSLContext sslContext1 = null; | |
try { | |
sslContext1 = SSLContext.getInstance("TLS"); | |
sslContext1.init( | |
null, new TrustManager[] {new TrustAnyTrustManager()}, new SecureRandom()); | |
} catch (NoSuchAlgorithmException e) { | |
e.printStackTrace(); | |
} catch (KeyManagementException e) { | |
e.printStackTrace(); | |
} | |
return sslContext1; | |
} | |
public SSLContext getSslContext() { | |
if (this.sslContext == null) { | |
this.sslContext = createSSLContext(); | |
} | |
return this.sslContext; | |
} | |
private static class TrustAnyTrustManager implements X509TrustManager { | |
@Override | |
public void checkClientTrusted( | |
X509Certificate[] x509Certificates, String s) throws CertificateException { | |
} | |
@Override | |
public void checkServerTrusted( | |
X509Certificate[] x509Certificates, String s) throws CertificateException { | |
} | |
@Override | |
public X509Certificate[] getAcceptedIssuers() { | |
return new X509Certificate[0]; | |
// return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment