1717package org .apache .cloudstack .network .element ;
1818
1919import java .io .IOException ;
20+ import java .io .InputStreamReader ;
2021import 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 ;
3742import org .apache .log4j .Logger ;
3843
3944import com .google .gson .Gson ;
45+ import com .google .gson .JsonIOException ;
46+ import com .google .gson .JsonSyntaxException ;
4047import com .google .gson .annotations .SerializedName ;
4148
4249/**
4350 * Stratosphere sdn platform api client
4451 */
4552public 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 }
0 commit comments