Skip to content

Commit cb048f4

Browse files
iHiroakiKawaiU-kawai-x230\kawai
authored andcommitted
Some rework stratosphere ssp plugin
* add missing command entry in commands.properties * migrate httpclient 3.x to 4.x * fix the broken SspClient * add webapp session checking in mock ssp server
1 parent b32b49e commit cb048f4

5 files changed

Lines changed: 194 additions & 211 deletions

File tree

client/tomcatconf/commands.properties.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,11 @@ addBigSwitchVnsDevice=1
593593
deleteBigSwitchVnsDevice=1
594594
listBigSwitchVnsDevices=1
595595

596+
#### stratosphere ssp commands
597+
598+
addStratosphereSsp=1
599+
deleteStratoshereSsp=1
600+
596601
#### host simulator commands
597602

598603
configureSimulator=1

plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java

Lines changed: 115 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -17,142 +17,107 @@
1717
package org.apache.cloudstack.network.element;
1818

1919
import java.io.IOException;
20+
import java.io.InputStreamReader;
2021
import java.io.UnsupportedEncodingException;
21-
22-
import org.apache.commons.httpclient.HttpClient;
23-
import org.apache.commons.httpclient.HttpConnectionManager;
24-
import org.apache.commons.httpclient.HttpException;
25-
import org.apache.commons.httpclient.HttpMethod;
26-
import org.apache.commons.httpclient.HttpStatus;
27-
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
28-
import org.apache.commons.httpclient.URIException;
29-
import org.apache.commons.httpclient.cookie.CookiePolicy;
30-
import org.apache.commons.httpclient.methods.DeleteMethod;
31-
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
32-
import org.apache.commons.httpclient.methods.PostMethod;
33-
import org.apache.commons.httpclient.methods.PutMethod;
34-
import org.apache.commons.httpclient.methods.RequestEntity;
35-
import org.apache.commons.httpclient.methods.StringRequestEntity;
36-
import org.apache.commons.httpclient.params.HttpClientParams;
22+
import java.net.URI;
23+
import java.net.URISyntaxException;
24+
import java.util.Arrays;
25+
26+
import org.apache.http.HttpResponse;
27+
import org.apache.http.HttpStatus;
28+
import org.apache.http.client.HttpClient;
29+
import org.apache.http.client.entity.UrlEncodedFormEntity;
30+
import org.apache.http.client.methods.HttpDelete;
31+
import org.apache.http.client.methods.HttpPost;
32+
import org.apache.http.client.methods.HttpPut;
33+
import org.apache.http.client.methods.HttpRequestBase;
34+
import org.apache.http.client.params.ClientPNames;
35+
import org.apache.http.client.params.CookiePolicy;
36+
import org.apache.http.entity.ContentType;
37+
import org.apache.http.entity.StringEntity;
38+
import org.apache.http.impl.client.DefaultHttpClient;
39+
import org.apache.http.impl.conn.PoolingClientConnectionManager;
40+
import org.apache.http.message.BasicNameValuePair;
41+
import org.apache.http.params.CoreConnectionPNames;
3742
import org.apache.log4j.Logger;
3843

3944
import com.google.gson.Gson;
45+
import com.google.gson.JsonIOException;
46+
import com.google.gson.JsonSyntaxException;
4047
import com.google.gson.annotations.SerializedName;
4148

4249
/**
4350
* Stratosphere sdn platform api client
4451
*/
4552
public class SspClient {
4653
private static final Logger s_logger = Logger.getLogger(SspClient.class);
47-
private static final HttpConnectionManager s_httpclient_manager = new MultiThreadedHttpConnectionManager();
48-
private static final HttpClientParams s_httpclient_params = new HttpClientParams();
54+
private static final HttpClient s_client = new DefaultHttpClient(
55+
new PoolingClientConnectionManager());
4956
static {
50-
s_httpclient_params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
57+
s_client.getParams()
58+
.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY)
59+
.setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);
5160
}
5261

5362
private final String apiUrl;
5463
private final String username;
5564
private final String password;
5665

57-
protected HttpClient client;
58-
protected PostMethod postMethod;
59-
protected DeleteMethod deleteMethod;
60-
protected PutMethod putMethod;
61-
6266
public SspClient(String apiUrl, String username, String password) {
6367
super();
6468
this.apiUrl = apiUrl;
6569
this.username = username;
6670
this.password = password;
67-
client = new HttpClient(s_httpclient_params, s_httpclient_manager);
68-
postMethod = new PostMethod(apiUrl);
69-
deleteMethod = new DeleteMethod(apiUrl);
70-
putMethod = new PutMethod(apiUrl);
7171
}
7272

73-
public boolean login() {
74-
PostMethod method = postMethod;
75-
method.setPath("/ws.v1/login"); // NOTE: /ws.v1/login is correct
76-
method.addParameter("username", username);
77-
method.addParameter("password", password);
73+
protected HttpClient getHttpClient() { // for mock test
74+
return s_client;
75+
}
7876

77+
private HttpResponse innerExecuteMethod(HttpRequestBase req, String path) {
7978
try {
80-
client.executeMethod(method);
81-
} catch (HttpException e) {
82-
s_logger.info("Login " + username + " to " + apiUrl + " failed", e);
83-
return false;
84-
} catch (IOException e) {
85-
s_logger.info("Login " + username + " to " + apiUrl + " failed", e);
86-
return false;
87-
} finally {
88-
method.releaseConnection();
79+
URI base = new URI(apiUrl);
80+
req.setURI(new URI(base.getScheme(), base.getUserInfo(), base.getHost(),
81+
base.getPort(), path, null, null));
82+
} catch (URISyntaxException e) {
83+
s_logger.error("invalid API URL " + apiUrl + " path " + path, e);
84+
return null;
8985
}
90-
String apiCallPath = null;
86+
HttpResponse res = null;
9187
try {
92-
apiCallPath = method.getName() + " " + method.getURI().toString();
93-
} catch (URIException e) {
94-
s_logger.error("method getURI failed", e);
95-
}
96-
s_logger.info("ssp api call:" + apiCallPath + " user=" + username + " status=" + method.getStatusLine());
97-
if (method.getStatusCode() == HttpStatus.SC_OK) {
98-
return true;
88+
res = getHttpClient().execute(req);
89+
s_logger.info("ssp api call:" + req + " status=" + res.getStatusLine());
90+
} catch (IOException e) {
91+
s_logger.error("ssp api call failed: " + req, e);
9992
}
100-
return false;
93+
return res;
10194
}
10295

103-
private String executeMethod(HttpMethod method) {
104-
String apiCallPath = null;
105-
try {
106-
apiCallPath = method.getName() + " " + method.getURI().toString();
107-
} catch (URIException e) {
108-
s_logger.error("method getURI failed", e);
96+
private HttpResponse executeMethod(HttpRequestBase req, String path) {
97+
HttpResponse res = innerExecuteMethod(req, path);
98+
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED && login()) {
99+
req.reset();
100+
res = innerExecuteMethod(req, path);
109101
}
102+
return res;
103+
}
110104

111-
String response = null;
105+
public boolean login() {
106+
HttpPost method = new HttpPost();
112107
try {
113-
client.executeMethod(method);
114-
response = method.getResponseBodyAsString();
115-
} catch (HttpException e) {
116-
s_logger.error("ssp api call failed " + apiCallPath, e);
117-
return null;
118-
} catch (IOException e) {
119-
s_logger.error("ssp api call failed " + apiCallPath, e);
120-
return null;
121-
} finally {
122-
method.releaseConnection();
108+
method.setEntity(new UrlEncodedFormEntity(Arrays.asList(
109+
new BasicNameValuePair("username", username),
110+
new BasicNameValuePair("password", password))));
111+
} catch (UnsupportedEncodingException e) {
112+
s_logger.error("invalid username or password", e);
113+
return false;
123114
}
124115

125-
if (method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
126-
if (!login()) {
127-
return null;
128-
}
129-
130-
try {
131-
client.executeMethod(method);
132-
response = method.getResponseBodyAsString();
133-
} catch (HttpException e) {
134-
s_logger.error("ssp api call failed " + apiCallPath, e);
135-
return null;
136-
} catch (IOException e) {
137-
s_logger.error("ssp api call failed " + apiCallPath, e);
138-
return null;
139-
} finally {
140-
method.releaseConnection();
141-
}
142-
}
143-
s_logger.info("ssp api call:" + apiCallPath + " user=" + username + " status=" + method.getStatusLine());
144-
if (method instanceof EntityEnclosingMethod) {
145-
EntityEnclosingMethod emethod = (EntityEnclosingMethod)method;
146-
RequestEntity reqEntity = emethod.getRequestEntity();
147-
if (reqEntity instanceof StringRequestEntity) {
148-
StringRequestEntity strReqEntity = (StringRequestEntity)reqEntity;
149-
s_logger.debug("ssp api request body:" + strReqEntity.getContent());
150-
} else {
151-
s_logger.debug("ssp api request body:" + emethod.getRequestEntity());
152-
}
116+
HttpResponse res = this.innerExecuteMethod(method, "/ws.v1/login");
117+
if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
118+
return true;
153119
}
154-
s_logger.debug("ssp api response body:" + response);
155-
return response;
120+
return false;
156121
}
157122

158123
public class TenantNetwork {
@@ -167,30 +132,31 @@ public TenantNetwork createTenantNetwork(String tenantUuid, String networkName)
167132
req.name = networkName;
168133
req.tenantUuid = tenantUuid;
169134

170-
PostMethod method = postMethod;
171-
method.setPath("/ssp.v1/tenant-networks");
172-
StringRequestEntity entity = null;
173-
try {
174-
entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8");
175-
} catch (UnsupportedEncodingException e) {
176-
s_logger.error("failed creating http request body", e);
135+
HttpPost method = new HttpPost();
136+
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
137+
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks");
138+
if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
177139
return null;
178140
}
179-
method.setRequestEntity(entity);
180-
181-
String response = executeMethod(method);
182-
if (response != null && method.getStatusCode() == HttpStatus.SC_CREATED) {
183-
return new Gson().fromJson(response, TenantNetwork.class);
141+
try {
142+
return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()),
143+
TenantNetwork.class);
144+
} catch (JsonSyntaxException e) {
145+
s_logger.error("reading response body failed", e);
146+
} catch (JsonIOException e) {
147+
s_logger.error("reading response body failed", e);
148+
} catch (IllegalStateException e) {
149+
s_logger.error("reading response body failed", e);
150+
} catch (IOException e) {
151+
s_logger.error("reading response body failed", e);
184152
}
185153
return null;
186154
}
187155

188156
public boolean deleteTenantNetwork(String tenantNetworkUuid) {
189-
DeleteMethod method = deleteMethod;
190-
method.setPath("/ssp.v1/tenant-networks/" + tenantNetworkUuid);
191-
192-
executeMethod(method);
193-
if (method.getStatusCode() == HttpStatus.SC_NO_CONTENT) {
157+
HttpDelete method = new HttpDelete();
158+
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks/" + tenantNetworkUuid);
159+
if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
194160
return true;
195161
}
196162
return false;
@@ -214,30 +180,33 @@ public TenantPort createTenantPort(String tenantNetworkUuid) {
214180
req.networkUuid = tenantNetworkUuid;
215181
req.attachmentType = "NoAttachment";
216182

217-
PostMethod method = postMethod;
218-
method.setPath("/ssp.v1/tenant-ports");
219-
StringRequestEntity entity = null;
220-
try {
221-
entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8");
222-
} catch (UnsupportedEncodingException e) {
223-
s_logger.error("failed creating http request body", e);
183+
HttpPost method = new HttpPost();
184+
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
185+
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports");
186+
187+
if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
224188
return null;
225189
}
226-
method.setRequestEntity(entity);
227-
228-
String response = executeMethod(method);
229-
if (response != null && method.getStatusCode() == HttpStatus.SC_CREATED) {
230-
return new Gson().fromJson(response, TenantPort.class);
190+
try {
191+
return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()),
192+
TenantPort.class);
193+
} catch (JsonSyntaxException e) {
194+
s_logger.error("reading response body failed", e);
195+
} catch (JsonIOException e) {
196+
s_logger.error("reading response body failed", e);
197+
} catch (IllegalStateException e) {
198+
s_logger.error("reading response body failed", e);
199+
} catch (IOException e) {
200+
s_logger.error("reading response body failed", e);
231201
}
232202
return null;
233203
}
234204

235205
public boolean deleteTenantPort(String tenantPortUuid) {
236-
DeleteMethod method = deleteMethod;
237-
method.setPath("/ssp.v1/tenant-ports/" + tenantPortUuid);
206+
HttpDelete method = new HttpDelete();
207+
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + tenantPortUuid);
238208

239-
executeMethod(method);
240-
if (method.getStatusCode() == HttpStatus.SC_NO_CONTENT) {
209+
if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
241210
return true;
242211
}
243212
return false;
@@ -252,20 +221,23 @@ public TenantPort updateTenantVifBinding(String portUuid, String hypervisorIpAdd
252221
req.attachmentType = "NoAttachment";
253222
}
254223

255-
PutMethod method = putMethod;
256-
method.setPath("/ssp.v1/tenant-ports/" + portUuid);
257-
StringRequestEntity entity = null;
258-
try {
259-
entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8");
260-
} catch (UnsupportedEncodingException e) {
261-
s_logger.error("failed creating http request body", e);
224+
HttpPut method = new HttpPut();
225+
method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON));
226+
HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + portUuid);
227+
if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
262228
return null;
263229
}
264-
method.setRequestEntity(entity);
265-
266-
String response = executeMethod(method);
267-
if (response != null && method.getStatusCode() == HttpStatus.SC_OK) {
268-
return new Gson().fromJson(response, TenantPort.class);
230+
try {
231+
return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()),
232+
TenantPort.class);
233+
} catch (JsonSyntaxException e) {
234+
s_logger.error("reading response body failed", e);
235+
} catch (JsonIOException e) {
236+
s_logger.error("reading response body failed", e);
237+
} catch (IllegalStateException e) {
238+
s_logger.error("reading response body failed", e);
239+
} catch (IOException e) {
240+
s_logger.error("reading response body failed", e);
269241
}
270242
return null;
271243
}

plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
public class SspElement extends AdapterBase implements ConnectivityProvider, SspManager, SspService, NetworkMigrationResponder {
9393
private static final Logger s_logger = Logger.getLogger(SspElement.class);
9494
public static final String s_SSP_NAME = "StratosphereSsp";
95+
private static final Provider s_ssp_provider = new Provider(s_SSP_NAME, false);
9596

9697
@Inject
9798
NetworkServiceMapDao _ntwkSrvcDao;
@@ -134,15 +135,7 @@ public Map<Service, Map<Capability, String>> getCapabilities() {
134135

135136
@Override
136137
public Provider getProvider() {
137-
Provider provider = null;
138-
synchronized (s_SSP_NAME) {
139-
provider = Provider.getProvider(s_SSP_NAME);
140-
if (provider == null) {
141-
provider = new Provider(s_SSP_NAME, true);
142-
s_logger.debug("registering Network.Provider " + s_SSP_NAME);
143-
}
144-
}
145-
return provider;
138+
return s_ssp_provider;
146139
}
147140

148141
private List<SspClient> fetchSspClients(Long physicalNetworkId, Long dataCenterId, boolean enabledOnly) {
@@ -187,14 +180,10 @@ private List<SspClient> fetchSspClients(Long physicalNetworkId, Long dataCenterI
187180
public boolean isReady(PhysicalNetworkServiceProvider provider) {
188181
PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(provider.getPhysicalNetworkId());
189182
assert (physicalNetwork != null);
190-
if (physicalNetwork != null) {
191-
if (fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), false).size() > 0) {
192-
return true;
193-
}
194-
s_logger.warn("Ssp api endpoint not found. " + physicalNetwork.toString());
195-
} else {
196-
s_logger.warn("PhysicalNetwork is NULL.");
183+
if (fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), false).size() > 0) {
184+
return true;
197185
}
186+
s_logger.warn("Ssp api endpoint not found. " + physicalNetwork.toString());
198187
return false;
199188
}
200189

0 commit comments

Comments
 (0)