blob: 3dc52ce470dfb12e563353bb678258e3a5bb1216 [file] [log] [blame]
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed 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 com.googlesource.gerrit.plugins.its.rtc.network;
import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultRedirectHandler;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.eclipse.jgit.lib.Config;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.its.rtc.api.RtcEntity;
import com.googlesource.gerrit.plugins.its.rtc.api.RtcEntityDeserializer;
import com.googlesource.gerrit.plugins.its.rtc.session.SessionApi;
import com.googlesource.gerrit.plugins.its.rtc.session.SessionApiImpl;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcComment;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcCommentDeserializer;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcRelatedLink;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcRelatedLinkDeserializer;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcWorkItem;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcWorkItemDeserializer;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcWorkflowAction;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcWorkflowActionDeserializer;
import com.googlesource.gerrit.plugins.its.rtc.workitems.WorkItemsApi;
import com.googlesource.gerrit.plugins.its.rtc.workitems.WorkItemsApiImpl;
public class RTCClient {
private static Log LOG = LogFactory.getLog(RTCClient.class);
private String baseUrl;
private DefaultHttpClient httpclient;
private BasicCookieStore cookieStore;
private Gson gson;
private Transport transport;
private CachableResourcesFactory factory;
private SessionApi sessionApi;
private WorkItemsApi workItemsApi;
private boolean loggedIn;
private String rtcUser;
private String rtcPassword;
@Inject
public RTCClient(@PluginName String pluginName,
@GerritServerConfig Config config, RTCHttpParams httpParams)
throws IOException {
this(config.getString(pluginName, null, "url"), config
.getBoolean(pluginName, null, "sslVerify", true),
httpParams);
}
public RTCClient(String url, boolean sslVerify, HttpParams httpParams)
throws IOException {
super();
this.baseUrl = (url.endsWith("/") ? url.substring(url.length() - 1) : url);
if (httpParams == null) {
httpParams = new BasicHttpParams();
}
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
this.httpclient =
new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams,
schemeRegistry), httpParams);
this.transport = new Transport(this, baseUrl, httpclient, httpParams);
this.factory = new CachableResourcesFactory(transport);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(RtcWorkItem.class, new RtcWorkItemDeserializer(
factory));
builder.registerTypeAdapter(RtcComment.class, new RtcCommentDeserializer());
builder.registerTypeAdapter(RtcEntity.class, new RtcEntityDeserializer());
builder.registerTypeAdapter(RtcRelatedLink.class,
new RtcRelatedLinkDeserializer());
builder.registerTypeAdapter(RtcWorkflowAction.class,
new RtcWorkflowActionDeserializer());
gson = builder.create();
transport.setGson(gson);
setCookieStore();
setRedirectStategy();
setSSLTrustStrategy(sslVerify);
sessionApi = new SessionApiImpl(this, transport);
workItemsApi = new WorkItemsApiImpl(this, transport);
}
public boolean isLoggedIn() {
return loggedIn;
}
public SessionApi sessionApi() throws IOException {
collectSessionCookie();
return sessionApi;
}
public WorkItemsApi workItemsApi() throws IOException {
collectSessionCookie();
return workItemsApi;
}
private void collectSessionCookie() throws IOException {
if (cookieStore.getCookies().size() <= 0) {
LOG.debug("Initial collecting of session cookie...");
transport.get(baseUrl);
LOG.debug("Succesfully collected cookies: " + cookieStore.getCookies());
}
}
private void setCookieStore() {
cookieStore = new BasicCookieStore();
httpclient.setCookieStore(cookieStore);
}
private void setSSLTrustStrategy(boolean sslVerify) throws IOException {
try {
TrustManager[] trustAllCerts =
new TrustManager[] {new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
}
}};
SSLContext sc;
if (sslVerify) {
sc = SSLContext.getDefault();
} else {
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
}
SSLSocketFactory sf = new SSLSocketFactory(sc);
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
SchemeRegistry schemeRegistry =
httpclient.getConnectionManager().getSchemeRegistry();
schemeRegistry.register(new Scheme("https", sf, 443));
} catch (Exception any) {
throw new IOException(any);
}
}
private void setRedirectStategy() {
httpclient.setRedirectHandler(new DefaultRedirectHandler() {
@Override
public boolean isRedirectRequested(HttpResponse response,
HttpContext context) {
boolean isRedirect = super.isRedirectRequested(response, context);
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return isRedirect;
}
});
}
public Transport getTransportForTest() {
return transport;
}
public void setLoginCredentials(String rtcUser, String rtcPassword) {
this.rtcUser = rtcUser;
this.rtcPassword = rtcPassword;
}
public void login() throws IOException {
sessionApi().login(rtcUser, rtcPassword);
loggedIn = true;
}
public void ping() throws IOException {
if (loggedIn) {
sessionApi().ping();
}
}
public void setLoggedIn(boolean b) {
loggedIn = b;
}
}