1 package org
.argeo
.slc
.server
.client
.impl
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStreamReader
;
5 import java
.io
.OutputStreamWriter
;
8 import java
.net
.HttpURLConnection
;
10 import java
.net
.URLEncoder
;
13 import javax
.xml
.transform
.Source
;
14 import javax
.xml
.transform
.stream
.StreamResult
;
15 import javax
.xml
.transform
.stream
.StreamSource
;
17 import org
.apache
.commons
.io
.IOUtils
;
18 import org
.apache
.commons
.logging
.Log
;
19 import org
.apache
.commons
.logging
.LogFactory
;
20 import org
.argeo
.slc
.Condition
;
21 import org
.argeo
.slc
.SlcException
;
22 import org
.argeo
.slc
.server
.client
.HttpServicesClient
;
23 import org
.springframework
.oxm
.Marshaller
;
24 import org
.springframework
.oxm
.Unmarshaller
;
25 import org
.springframework
.util
.Assert
;
27 public abstract class AbstractHttpServicesClient
implements HttpServicesClient
{
28 private final static Log log
= LogFactory
29 .getLog(AbstractHttpServicesClient
.class);
30 private Unmarshaller unmarshaller
;
31 private Marshaller marshaller
;
32 private String baseUrl
;
33 private String encoding
= "UTF-8";
35 private Long retryPeriod
= 1000l;
36 private Long defaultTimeout
= 30 * 1000l;
38 public <T
> T
callService(String path
, Map
<String
, String
> parameters
) {
39 return callService(path
, parameters
, null);
42 @SuppressWarnings(value
= { "unchecked" })
43 public <T
> T
callService(String path
, Map
<String
, String
> parameters
,
46 return (T
) callServiceLowLevel(path
, parameters
, body
);
47 } catch (Exception e
) {
48 throw new SlcException("Cannot call service " + path
+ " on "
53 @SuppressWarnings(value
= { "unchecked" })
54 public <T
> T
callServiceSafe(String path
, Map
<String
, String
> parameters
,
55 Condition
<T
> condition
, Long timeout
) {
57 long begin
= System
.currentTimeMillis();
60 while (System
.currentTimeMillis() - begin
< timeout(timeout
)) {
62 obj
= callServiceLowLevel(path
, parameters
, null);
63 } catch (IOException e
) {
64 if (log
.isTraceEnabled())
65 log
.trace("Exception when calling service " + path
66 + " on " + baseUrl
, e
);
70 if (condition
== null)
73 if (condition
.check((T
) obj
))
79 Thread
.sleep(retryPeriod
);
80 } catch (InterruptedException e
) {
86 throw new SlcException(
91 + " did not return an answer after calling it safely for "
92 + timeout(timeout
) + " ms.");
94 } catch (Exception e
) {
95 throw new SlcException(
96 "Unexpected exception when safely calling service " + path
97 + " on " + baseUrl
, e
);
101 protected Object
callServiceLowLevel(String path
,
102 Map
<String
, String
> parameters
, Object body
) throws IOException
{
103 Assert
.notNull(baseUrl
, "base url");
104 HttpURLConnection connection
= null;
105 Writer writer
= null;
106 Reader reader
= null;
108 URL url
= createUrl(path
, parameters
);
109 connection
= (HttpURLConnection
) url
.openConnection();
112 connection
.setRequestMethod("POST");
113 connection
.setDoOutput(true);
114 connection
.setDoInput(true);
115 connection
.setUseCaches(false);
116 connection
.setAllowUserInteraction(false);
117 connection
.setRequestProperty("Content-type",
118 "text/xml; charset=" + encoding
);
121 // Establish the connection
122 connection
.connect();
125 writer
= new OutputStreamWriter(connection
.getOutputStream(),
127 StreamResult result
= new StreamResult(writer
);
128 marshaller
.marshal(body
, result
);
130 IOUtils
.closeQuietly(writer
);
134 reader
= new InputStreamReader(connection
.getInputStream(),
136 Source source
= new StreamSource(reader
);
137 Object obj
= unmarshaller
.unmarshal(source
);
140 IOUtils
.closeQuietly(reader
);
141 IOUtils
.closeQuietly(writer
);
142 if (connection
!= null) {
143 connection
.disconnect();
148 protected URL
createUrl(String service
, Map
<String
, String
> parameters
) {
149 // URL encoded with UTF-8, as recommended by W3C
150 final String urlEncoding
= "UTF-8";
152 StringBuffer buf
= new StringBuffer(baseUrl
+ service
);
154 if (parameters
!= null && parameters
.size() != 0) {
156 boolean first
= true;
157 for (String key
: parameters
.keySet()) {
158 String value
= parameters
.get(key
);
164 String keyEncoded
= URLEncoder
.encode(key
, urlEncoding
);
165 String valueEncoded
= URLEncoder
.encode(value
,
167 buf
.append(keyEncoded
).append('=').append(valueEncoded
);
172 return new URL(buf
.toString());
173 } catch (Exception e
) {
174 throw new SlcException("Cannot create URL: " + buf
, e
);
178 public Long
timeout(Long timeout
) {
180 timeout
= getDefaultTimeout();
184 public void setUnmarshaller(Unmarshaller unmarshaller
) {
185 this.unmarshaller
= unmarshaller
;
188 public void setBaseUrl(String baseUrl
) {
189 this.baseUrl
= baseUrl
;
192 public Long
getRetryPeriod() {
196 /** Retry period in ms when accessing service safely. Default is 1000 ms. */
197 public void setRetryPeriod(Long retryPeriod
) {
198 this.retryPeriod
= retryPeriod
;
201 public void setMarshaller(Marshaller marshaller
) {
202 this.marshaller
= marshaller
;
205 /** Default is UTF-8. */
206 public void setEncoding(String encoding
) {
207 this.encoding
= encoding
;
210 /** Default is 30s */
211 public void setDefaultTimeout(Long defaultTimeout
) {
212 this.defaultTimeout
= defaultTimeout
;
215 public Long
getDefaultTimeout() {
216 return defaultTimeout
;