Skip to content

Commit

Permalink
KYLIN-1654: Upgrade http client library to 4.5
Browse files Browse the repository at this point in the history
Signed-off-by: Li Yang <liyang@apache.org>
  • Loading branch information
yiming187 authored and liyang-kylin committed Jul 5, 2016
1 parent ff1aec3 commit 1397bbb
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 341 deletions.
4 changes: 2 additions & 2 deletions core-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@
<artifactId>commons-email</artifactId>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.kylin.common.util.Bytes;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.kylin.common.util.JsonUtil;

/**
Expand All @@ -44,7 +45,7 @@ public class RestClient {
protected String baseUrl;
protected String userName;
protected String password;
protected HttpClient client;
protected CloseableHttpClient client;

protected static Pattern fullRestPattern = Pattern.compile("(?:([^:]+)[:]([^@]+)[@])?([^:]+)(?:[:](\\d+))?");

Expand Down Expand Up @@ -78,27 +79,28 @@ private void init(String host, int port, String userName, String password) {
this.password = password;
this.baseUrl = "http://" + host + ":" + port + "/kylin/api";

client = new HttpClient();
client = HttpClients.createDefault();

if (userName != null && password != null) {
client.getParams().setAuthenticationPreemptive(true);
Credentials creds = new UsernamePasswordCredentials(userName, password);
client.getState().setCredentials(new AuthScope(host, port, AuthScope.ANY_REALM), creds);
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(userName, password);
provider.setCredentials(AuthScope.ANY, credentials);
client = HttpClients.custom().setDefaultCredentialsProvider(provider).build();
}
}

public void wipeCache(String type, String action, String name) throws IOException {
String url = baseUrl + "/cache/" + type + "/" + name + "/" + action;
HttpMethod request = new PutMethod(url);
HttpPut request = new HttpPut(url);

try {
int code = client.executeMethod(request);
String msg = Bytes.toString(request.getResponseBody());
CloseableHttpResponse response = client.execute(request);
String msg = EntityUtils.toString(response.getEntity());

if (code != 200)
throw new IOException("Invalid response " + code + " with cache wipe url " + url + "\n" + msg);

} catch (HttpException ex) {
if (response.getStatusLine().getStatusCode() != 200)
throw new IOException("Invalid response " + response.getStatusLine().getStatusCode() + " with cache wipe url " + url + "\n" + msg);
response.close();
} catch (Exception ex) {
throw new IOException(ex);
} finally {
request.releaseConnection();
Expand All @@ -107,18 +109,17 @@ public void wipeCache(String type, String action, String name) throws IOExceptio

public String getKylinProperties() throws IOException {
String url = baseUrl + "/admin/config";
HttpMethod request = new GetMethod(url);
HttpGet request = new HttpGet(url);
try {
int code = client.executeMethod(request);
String msg = Bytes.toString(request.getResponseBody());
CloseableHttpResponse response = client.execute(request);
String msg = EntityUtils.toString(response.getEntity());
Map<String, String> map = JsonUtil.readValueAsMap(msg);
msg = map.get("config");

if (code != 200)
throw new IOException("Invalid response " + code + " with cache wipe url " + url + "\n" + msg);

if (response.getStatusLine().getStatusCode() != 200)
throw new IOException("Invalid response " + response.getStatusLine().getStatusCode() + " with cache wipe url " + url + "\n" + msg);
response.close();
return msg;

} finally {
request.releaseConnection();
}
Expand Down
4 changes: 2 additions & 2 deletions jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
Expand Down
94 changes: 59 additions & 35 deletions jdbc/src/main/java/org/apache/kylin/jdbc/KylinClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.io.IOException;
import java.math.BigDecimal;
import java.security.cert.X509Certificate;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
Expand All @@ -30,19 +31,26 @@
import java.util.Map;
import java.util.Properties;

import javax.net.ssl.SSLContext;
import javax.xml.bind.DatatypeConverter;

import org.apache.calcite.avatica.AvaticaParameter;
import org.apache.calcite.avatica.ColumnMetaData;
import org.apache.calcite.avatica.ColumnMetaData.Rep;
import org.apache.calcite.avatica.ColumnMetaData.ScalarType;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.apache.kylin.jdbc.KylinMeta.KMetaCatalog;
import org.apache.kylin.jdbc.KylinMeta.KMetaColumn;
import org.apache.kylin.jdbc.KylinMeta.KMetaProject;
Expand All @@ -54,7 +62,6 @@
import org.apache.kylin.jdbc.json.StatementParameter;
import org.apache.kylin.jdbc.json.TableMetaStub;
import org.apache.kylin.jdbc.json.TableMetaStub.ColumnMetaStub;
import org.apache.kylin.jdbc.util.DefaultSslProtocolSocketFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -67,18 +74,28 @@ public class KylinClient implements IRemoteClient {

private final KylinConnection conn;
private final Properties connProps;
private final HttpClient httpClient;
private CloseableHttpClient httpClient;
private final ObjectMapper jsonMapper;

public KylinClient(KylinConnection conn) {
this.conn = conn;
this.connProps = conn.getConnectionProperties();
this.httpClient = new HttpClient();
this.httpClient = HttpClients.createDefault();
this.jsonMapper = new ObjectMapper();

// trust all certificates
if (isSSL()) {
Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) new DefaultSslProtocolSocketFactory(), 443));
try {
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
public boolean isTrusted(X509Certificate[] certificate, String type) {
return true;
}
};
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
httpClient = HttpClients.custom().setSSLHostnameVerifier(new DefaultHostnameVerifier()).setSSLContext(sslContext).build();
} catch (Exception e) {
throw new RuntimeException("Initialize HTTPS client failed", e);
}
}
}

Expand Down Expand Up @@ -193,50 +210,52 @@ private String baseUrl() {
return (isSSL() ? "https://" : "http://") + conn.getBaseUrl();
}

private void addHttpHeaders(HttpMethodBase method) {
method.addRequestHeader("Accept", "application/json, text/plain, */*");
method.addRequestHeader("Content-Type", "application/json");
private void addHttpHeaders(HttpRequestBase method) {
method.addHeader("Accept", "application/json, text/plain, */*");
method.addHeader("Content-Type", "application/json");

String username = connProps.getProperty("user");
String password = connProps.getProperty("password");
String basicAuth = DatatypeConverter.printBase64Binary((username + ":" + password).getBytes());
method.addRequestHeader("Authorization", "Basic " + basicAuth);
method.addHeader("Authorization", "Basic " + basicAuth);
}

@Override
public void connect() throws IOException {
PostMethod post = new PostMethod(baseUrl() + "/kylin/api/user/authentication");
HttpPost post = new HttpPost(baseUrl() + "/kylin/api/user/authentication");
addHttpHeaders(post);
StringRequestEntity requestEntity = new StringRequestEntity("{}", "application/json", "UTF-8");
post.setRequestEntity(requestEntity);
StringEntity requestEntity = new StringEntity("{}", ContentType.create("application/json", "UTF-8"));
post.setEntity(requestEntity);

httpClient.executeMethod(post);
CloseableHttpResponse response = httpClient.execute(post);

if (post.getStatusCode() != 200 && post.getStatusCode() != 201) {
throw asIOException(post);
if (response.getStatusLine().getStatusCode() != 200 && response.getStatusLine().getStatusCode() != 201) {
throw asIOException(post, response);
}
response.close();
}

@Override
public KMetaProject retrieveMetaData(String project) throws IOException {
assert conn.getProject().equals(project);

String url = baseUrl() + "/kylin/api/tables_and_columns?project=" + project;
GetMethod get = new GetMethod(url);
HttpGet get = new HttpGet(url);
addHttpHeaders(get);

httpClient.executeMethod(get);
CloseableHttpResponse response = httpClient.execute(get);

if (get.getStatusCode() != 200 && get.getStatusCode() != 201) {
throw asIOException(get);
if (response.getStatusLine().getStatusCode() != 200 && response.getStatusLine().getStatusCode() != 201) {
throw asIOException(get, response);
}

List<TableMetaStub> tableMetaStubs = jsonMapper.readValue(get.getResponseBodyAsStream(), new TypeReference<List<TableMetaStub>>() {
List<TableMetaStub> tableMetaStubs = jsonMapper.readValue(response.getEntity().getContent(), new TypeReference<List<TableMetaStub>>() {
});

List<KMetaTable> tables = convertMetaTables(tableMetaStubs);
List<KMetaSchema> schemas = convertMetaSchemas(tables);
List<KMetaCatalog> catalogs = convertMetaCatalogs(schemas);
response.close();
return new KMetaProject(project, catalogs);
}

Expand Down Expand Up @@ -341,21 +360,23 @@ private SQLResponseStub executeKylinQuery(String sql, List<StatementParameter> p
request.setSql(sql);
request.setProject(project);

PostMethod post = new PostMethod(url);
HttpPost post = new HttpPost(url);
addHttpHeaders(post);

String postBody = jsonMapper.writeValueAsString(request);
logger.debug("Post body:\n " + postBody);
StringRequestEntity requestEntity = new StringRequestEntity(postBody, "application/json", "UTF-8");
post.setRequestEntity(requestEntity);
StringEntity requestEntity = new StringEntity(postBody, ContentType.create("application/json", "UTF-8"));
post.setEntity(requestEntity);

httpClient.executeMethod(post);
CloseableHttpResponse response = httpClient.execute(post);

if (post.getStatusCode() != 200 && post.getStatusCode() != 201) {
throw asIOException(post);
if (response.getStatusLine().getStatusCode() != 200 && response.getStatusLine().getStatusCode() != 201) {
throw asIOException(post, response);
}

return jsonMapper.readValue(post.getResponseBodyAsStream(), SQLResponseStub.class);
SQLResponseStub stub = jsonMapper.readValue(response.getEntity().getContent(), SQLResponseStub.class);
response.close();
return stub;
}

private List<ColumnMetaData> convertColumnMeta(SQLResponseStub queryResp) {
Expand Down Expand Up @@ -388,11 +409,14 @@ private List<Object> convertResultData(SQLResponseStub queryResp, List<ColumnMet
return (List<Object>) data;
}

private IOException asIOException(HttpMethodBase method) throws IOException {
return new IOException(method + " failed, error code " + method.getStatusCode() + " and response: " + method.getResponseBodyAsString());
private IOException asIOException(HttpRequestBase request, HttpResponse response) throws IOException {
return new IOException(request.getMethod() + " failed, error code " + response.getStatusLine().getStatusCode() + " and response: " + EntityUtils.toString(response.getEntity()));
}

@Override
public void close() throws IOException {
if (httpClient != null) {
httpClient.close();
}
}
}
Loading

0 comments on commit 1397bbb

Please sign in to comment.