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 @SuppressWarnings(value
= { "unchecked" })
39 public <T
> T
callService(String path
, Map
<String
, String
> parameters
) {
40 return (T
)callService(path
, parameters
, null);
43 @SuppressWarnings(value
= { "unchecked" })
44 public <T
> T
callService(String path
, Map
<String
, String
> parameters
,
47 return (T
) callServiceLowLevel(path
, parameters
, body
);
48 } catch (Exception e
) {
49 throw new SlcException("Cannot call service " + path
+ " on "
54 @SuppressWarnings(value
= { "unchecked" })
55 public <T
> T
callServiceSafe(String path
, Map
<String
, String
> parameters
,
56 Condition
<T
> condition
, Long timeout
) {
58 long begin
= System
.currentTimeMillis();
61 while (System
.currentTimeMillis() - begin
< timeout(timeout
)) {
63 obj
= callServiceLowLevel(path
, parameters
, null);
64 } catch (IOException e
) {
65 if (log
.isTraceEnabled())
66 log
.trace("Exception when calling service " + path
67 + " on " + baseUrl
, e
);
71 if (condition
== null)
74 if (condition
.check((T
) obj
))
80 Thread
.sleep(retryPeriod
);
81 } catch (InterruptedException e
) {
87 throw new SlcException(
92 + " did not return an answer after calling it safely for "
93 + timeout(timeout
) + " ms.");
95 } catch (Exception e
) {
96 throw new SlcException(
97 "Unexpected exception when safely calling service " + path
98 + " on " + baseUrl
, e
);
102 protected Object
callServiceLowLevel(String path
,
103 Map
<String
, String
> parameters
, Object body
) throws IOException
{
104 Assert
.notNull(baseUrl
, "base url");
105 HttpURLConnection connection
= null;
106 Writer writer
= null;
107 Reader reader
= null;
109 URL url
= createUrl(path
, parameters
);
110 connection
= (HttpURLConnection
) url
.openConnection();
113 connection
.setRequestMethod("POST");
114 connection
.setDoOutput(true);
115 connection
.setDoInput(true);
116 connection
.setUseCaches(false);
117 connection
.setAllowUserInteraction(false);
118 connection
.setRequestProperty("Content-type",
119 "text/xml; charset=" + encoding
);
122 // Establish the connection
123 connection
.connect();
126 writer
= new OutputStreamWriter(connection
.getOutputStream(),
128 StreamResult result
= new StreamResult(writer
);
129 marshaller
.marshal(body
, result
);
131 IOUtils
.closeQuietly(writer
);
135 reader
= new InputStreamReader(connection
.getInputStream(),
137 Source source
= new StreamSource(reader
);
138 Object obj
= unmarshaller
.unmarshal(source
);
141 IOUtils
.closeQuietly(reader
);
142 IOUtils
.closeQuietly(writer
);
143 if (connection
!= null) {
144 connection
.disconnect();
149 protected URL
createUrl(String service
, Map
<String
, String
> parameters
) {
150 // URL encoded with UTF-8, as recommended by W3C
151 final String urlEncoding
= "UTF-8";
153 StringBuffer buf
= new StringBuffer(baseUrl
+ service
);
155 if (parameters
!= null && parameters
.size() != 0) {
157 boolean first
= true;
158 for (String key
: parameters
.keySet()) {
159 String value
= parameters
.get(key
);
165 String keyEncoded
= URLEncoder
.encode(key
, urlEncoding
);
166 String valueEncoded
= URLEncoder
.encode(value
,
168 buf
.append(keyEncoded
).append('=').append(valueEncoded
);
173 return new URL(buf
.toString());
174 } catch (Exception e
) {
175 throw new SlcException("Cannot create URL: " + buf
, e
);
179 public Long
timeout(Long timeout
) {
181 timeout
= getDefaultTimeout();
185 public void setUnmarshaller(Unmarshaller unmarshaller
) {
186 this.unmarshaller
= unmarshaller
;
189 public void setBaseUrl(String baseUrl
) {
190 this.baseUrl
= baseUrl
;
193 public Long
getRetryPeriod() {
197 /** Retry period in ms when accessing service safely. Default is 1000 ms. */
198 public void setRetryPeriod(Long retryPeriod
) {
199 this.retryPeriod
= retryPeriod
;
202 public void setMarshaller(Marshaller marshaller
) {
203 this.marshaller
= marshaller
;
206 /** Default is UTF-8. */
207 public void setEncoding(String encoding
) {
208 this.encoding
= encoding
;
211 /** Default is 30s */
212 public void setDefaultTimeout(Long defaultTimeout
) {
213 this.defaultTimeout
= defaultTimeout
;
216 public Long
getDefaultTimeout() {
217 return defaultTimeout
;