mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
stratosphere-ssp plugin: Fix HttpClient4 connection leak
Replaced HttpClient#execute(HttpUriRequest) with HttpClient#execute(HttpUriRequest,ResponseHandler<T>). The former requires extra EntityUtils#consume(HttpEntity).
This commit is contained in:
parent
54f32a8e46
commit
0d222b14a1
@ -17,15 +17,15 @@
|
|||||||
package org.apache.cloudstack.network.element;
|
package org.apache.cloudstack.network.element;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.http.client.ClientProtocolException;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.HttpResponseException;
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
import org.apache.http.client.methods.HttpDelete;
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
@ -35,6 +35,7 @@ import org.apache.http.client.params.ClientPNames;
|
|||||||
import org.apache.http.client.params.CookiePolicy;
|
import org.apache.http.client.params.CookiePolicy;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.BasicResponseHandler;
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
import org.apache.http.impl.conn.PoolingClientConnectionManager;
|
import org.apache.http.impl.conn.PoolingClientConnectionManager;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
@ -42,8 +43,6 @@ import org.apache.http.params.CoreConnectionPNames;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonIOException;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +73,7 @@ public class SspClient {
|
|||||||
return s_client;
|
return s_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpResponse innerExecuteMethod(HttpRequestBase req, String path) {
|
private String executeMethod(HttpRequestBase req, String path) {
|
||||||
try {
|
try {
|
||||||
URI base = new URI(apiUrl);
|
URI base = new URI(apiUrl);
|
||||||
req.setURI(new URI(base.getScheme(), base.getUserInfo(), base.getHost(),
|
req.setURI(new URI(base.getScheme(), base.getUserInfo(), base.getHost(),
|
||||||
@ -83,23 +82,26 @@ public class SspClient {
|
|||||||
s_logger.error("invalid API URL " + apiUrl + " path " + path, e);
|
s_logger.error("invalid API URL " + apiUrl + " path " + path, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
HttpResponse res = null;
|
|
||||||
try {
|
try {
|
||||||
res = getHttpClient().execute(req);
|
String content = null;
|
||||||
s_logger.info("ssp api call:" + req + " status=" + res.getStatusLine());
|
try {
|
||||||
|
content = getHttpClient().execute(req, new BasicResponseHandler());
|
||||||
|
s_logger.info("ssp api call: " + req);
|
||||||
|
} catch (HttpResponseException e) {
|
||||||
|
s_logger.info("ssp api call failed: " + req, e);
|
||||||
|
if (e.getStatusCode() == HttpStatus.SC_UNAUTHORIZED && login()) {
|
||||||
|
req.reset();
|
||||||
|
content = getHttpClient().execute(req, new BasicResponseHandler());
|
||||||
|
s_logger.info("ssp api retry call: " + req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
} catch (ClientProtocolException e) { // includes HttpResponseException
|
||||||
|
s_logger.error("ssp api call failed: " + req, e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
s_logger.error("ssp api call failed: " + req, e);
|
s_logger.error("ssp api call failed: " + req, e);
|
||||||
}
|
}
|
||||||
return res;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
private HttpResponse executeMethod(HttpRequestBase req, String path) {
|
|
||||||
HttpResponse res = innerExecuteMethod(req, path);
|
|
||||||
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED && login()) {
|
|
||||||
req.reset();
|
|
||||||
res = innerExecuteMethod(req, path);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean login() {
|
public boolean login() {
|
||||||
@ -112,9 +114,7 @@ public class SspClient {
|
|||||||
s_logger.error("invalid username or password", e);
|
s_logger.error("invalid username or password", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (executeMethod(method, "/ws.v1/login") != null) {
|
||||||
HttpResponse res = this.innerExecuteMethod(method, "/ws.v1/login");
|
|
||||||
if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -134,29 +134,14 @@ public class SspClient {
|
|||||||
|
|
||||||
HttpPost method = new HttpPost();
|
HttpPost method = new HttpPost();
|
||||||
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
|
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
|
||||||
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks");
|
return new Gson().fromJson(
|
||||||
if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
|
executeMethod(method, "/ssp.v1/tenant-networks"),
|
||||||
return null;
|
TenantNetwork.class);
|
||||||
}
|
|
||||||
try {
|
|
||||||
return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"),
|
|
||||||
TenantNetwork.class);
|
|
||||||
} catch (JsonSyntaxException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (JsonIOException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean deleteTenantNetwork(String tenantNetworkUuid) {
|
public boolean deleteTenantNetwork(String tenantNetworkUuid) {
|
||||||
HttpDelete method = new HttpDelete();
|
HttpDelete method = new HttpDelete();
|
||||||
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks/" + tenantNetworkUuid);
|
if (executeMethod(method, "/ssp.v1/tenant-networks/" + tenantNetworkUuid) != null) {
|
||||||
if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -182,31 +167,14 @@ public class SspClient {
|
|||||||
|
|
||||||
HttpPost method = new HttpPost();
|
HttpPost method = new HttpPost();
|
||||||
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
|
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
|
||||||
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports");
|
return new Gson().fromJson(
|
||||||
|
executeMethod(method, "/ssp.v1/tenant-ports"),
|
||||||
if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
|
TenantPort.class);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"),
|
|
||||||
TenantPort.class);
|
|
||||||
} catch (JsonSyntaxException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (JsonIOException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean deleteTenantPort(String tenantPortUuid) {
|
public boolean deleteTenantPort(String tenantPortUuid) {
|
||||||
HttpDelete method = new HttpDelete();
|
HttpDelete method = new HttpDelete();
|
||||||
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + tenantPortUuid);
|
if (executeMethod(method, "/ssp.v1/tenant-ports/" + tenantPortUuid) != null) {
|
||||||
|
|
||||||
if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -223,22 +191,8 @@ public class SspClient {
|
|||||||
|
|
||||||
HttpPut method = new HttpPut();
|
HttpPut method = new HttpPut();
|
||||||
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
|
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
|
||||||
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + portUuid);
|
return new Gson().fromJson(
|
||||||
if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
executeMethod(method, "/ssp.v1/tenant-ports/" + portUuid),
|
||||||
return null;
|
TenantPort.class);
|
||||||
}
|
|
||||||
try {
|
|
||||||
return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"),
|
|
||||||
TenantPort.class);
|
|
||||||
} catch (JsonSyntaxException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (JsonIOException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
s_logger.error("reading response body failed", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,15 +23,11 @@ import static org.mockito.Mockito.when;
|
|||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpUriRequest;
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
|
import org.apache.http.impl.client.BasicResponseHandler;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class SspClientTest {
|
public class SspClientTest {
|
||||||
@ -46,10 +42,8 @@ public class SspClientTest {
|
|||||||
SspClient sspClient = spy(new SspClient(apiUrl, username, password));
|
SspClient sspClient = spy(new SspClient(apiUrl, username, password));
|
||||||
|
|
||||||
HttpClient client = mock(HttpClient.class);
|
HttpClient client = mock(HttpClient.class);
|
||||||
HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS);
|
|
||||||
doReturn(client).when(sspClient).getHttpClient();
|
doReturn(client).when(sspClient).getHttpClient();
|
||||||
when(client.execute(any(HttpUriRequest.class))).thenReturn(res);
|
when(client.execute(any(HttpUriRequest.class), any(BasicResponseHandler.class))).thenReturn("");
|
||||||
when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_OK);
|
|
||||||
|
|
||||||
assertTrue(sspClient.login());
|
assertTrue(sspClient.login());
|
||||||
assertTrue(sspClient.login());
|
assertTrue(sspClient.login());
|
||||||
@ -63,14 +57,10 @@ public class SspClientTest {
|
|||||||
SspClient sspClient = spy(new SspClient(apiUrl, username, password));
|
SspClient sspClient = spy(new SspClient(apiUrl, username, password));
|
||||||
|
|
||||||
HttpClient client = mock(HttpClient.class);
|
HttpClient client = mock(HttpClient.class);
|
||||||
HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS);
|
|
||||||
doReturn(client).when(sspClient).getHttpClient();
|
doReturn(client).when(sspClient).getHttpClient();
|
||||||
when(client.execute(any(HttpUriRequest.class))).thenReturn(res);
|
|
||||||
when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_CREATED);
|
|
||||||
String body = "{\"uuid\":\"" + tenant_net_uuid + "\",\"name\":\"" + networkName
|
String body = "{\"uuid\":\"" + tenant_net_uuid + "\",\"name\":\"" + networkName
|
||||||
+ "\",\"tenant_uuid\":\"" + uuid + "\"}";
|
+ "\",\"tenant_uuid\":\"" + uuid + "\"}";
|
||||||
when(res.getEntity().getContent()).thenReturn(
|
when(client.execute(any(HttpUriRequest.class), any(BasicResponseHandler.class))).thenReturn(body);
|
||||||
new ByteArrayInputStream(body.getBytes("UTF-8")));
|
|
||||||
|
|
||||||
SspClient.TenantNetwork tnet = sspClient.createTenantNetwork(uuid, networkName);
|
SspClient.TenantNetwork tnet = sspClient.createTenantNetwork(uuid, networkName);
|
||||||
assertEquals(tnet.name, networkName);
|
assertEquals(tnet.name, networkName);
|
||||||
@ -84,10 +74,8 @@ public class SspClientTest {
|
|||||||
SspClient sspClient = spy(new SspClient(apiUrl, username, password));
|
SspClient sspClient = spy(new SspClient(apiUrl, username, password));
|
||||||
|
|
||||||
HttpClient client = mock(HttpClient.class);
|
HttpClient client = mock(HttpClient.class);
|
||||||
HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS);
|
|
||||||
doReturn(client).when(sspClient).getHttpClient();
|
doReturn(client).when(sspClient).getHttpClient();
|
||||||
when(client.execute(any(HttpUriRequest.class))).thenReturn(res);
|
when(client.execute(any(HttpUriRequest.class), any(BasicResponseHandler.class))).thenReturn("");
|
||||||
when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT);
|
|
||||||
|
|
||||||
sspClient.deleteTenantNetwork(tenant_net_uuid);
|
sspClient.deleteTenantNetwork(tenant_net_uuid);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user