1a4ba4cf76e42b107c1fc8fb90bafc0b7a40e325
[frank.git] / prod / net / jaekl / qd / http / RequestBroker.java
1 // Copyright (C) 2004, 2014 Christian Jaekl
2
3 package net.jaekl.qd.http;
4
5 import java.io.BufferedReader;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9 import java.io.UnsupportedEncodingException;
10 import java.lang.reflect.InvocationTargetException;
11 import java.util.ArrayList;
12
13 import net.jaekl.qd.QDException;
14 import net.jaekl.qd.util.ExceptionUtils;
15 import net.jaekl.qd.xml.ParseHandler;
16 import net.jaekl.qd.xml.ParseResult;
17
18 import org.apache.http.HttpEntity;
19 import org.apache.http.HttpResponse;
20 import org.apache.http.NameValuePair;
21 import org.apache.http.client.HttpClient;
22 import org.apache.http.client.config.RequestConfig;
23 import org.apache.http.client.entity.UrlEncodedFormEntity;
24 import org.apache.http.client.methods.HttpPost;
25 import org.apache.http.impl.client.HttpClientBuilder;
26 import org.xml.sax.InputSource;
27 import org.xml.sax.SAXException;
28 import org.xml.sax.XMLReader;
29 import org.xml.sax.helpers.XMLReaderFactory;
30
31 public class RequestBroker
32 {
33         final String UTF_8 = "UTF-8";
34         final int TIMEOUT_MSEC = 5000;  // Allow at most 5 seconds before we declare the server to be unresponsive
35         
36         String m_gatewayUrl;
37         ArrayList<NameValuePair> m_baseParams;
38
39         public RequestBroker(String gatewayUrl, ArrayList<NameValuePair> baseParams)
40         {
41                 m_gatewayUrl = gatewayUrl;
42                 m_baseParams = new ArrayList<NameValuePair>(baseParams);
43         }
44         
45         // NB:  Caller is responsible for close()ing the returned InputStream
46         //
47         InputStream doSubmit(String method, ArrayList<NameValuePair> passedParams) throws QDException
48         {
49                 ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(m_baseParams);
50                 params.addAll(passedParams);
51                 
52                 try {
53                         RequestConfig.Builder requestBuilder = RequestConfig.custom();
54                         requestBuilder = requestBuilder.setConnectTimeout(TIMEOUT_MSEC);
55                         requestBuilder = requestBuilder.setSocketTimeout(TIMEOUT_MSEC);
56                         HttpClientBuilder builder = HttpClientBuilder.create();
57                         builder.setDefaultRequestConfig(requestBuilder.build());
58                         HttpClient httpClient = builder.build(); 
59                         HttpPost httpPost = new HttpPost(m_gatewayUrl + "/" + method + "/");
60                         httpPost.setEntity(new UrlEncodedFormEntity(params, UTF_8));
61                         HttpResponse response = httpClient.execute(httpPost);
62                         HttpEntity entity = response.getEntity();
63
64                         if (null != entity) {
65                                 InputStream is = entity.getContent();
66                                 return is;
67                         }
68                 }
69                 catch (UnsupportedEncodingException uee) {
70                         // We should actually be guaranteed that this never happens, 
71                         // because all JVMs are required to support UTF-8
72                         assert(false);
73                         throw new Error(uee);
74                 }
75                 catch (IOException ioe) {
76                         throw new QDException(ioe);
77                 }
78                 
79                 return null;
80         }
81
82         public String submit(String method, ArrayList<NameValuePair> passedParams) throws QDException
83         {
84                 StringBuilder sb = new StringBuilder();
85                 InputStream is = null;
86
87                 try {
88                         is = doSubmit(method, passedParams);
89                         BufferedReader br = new BufferedReader(new InputStreamReader(is));
90                         String line = br.readLine();
91                         while (null != line) {
92                                 sb.append(line).append("\n");
93                                 line = br.readLine();
94                         }
95                 }
96                 catch (IOException ioe) {
97                         throw new QDException(ioe);
98                 }
99                 finally {
100                         ExceptionUtils.tryClose(is);
101                 }
102
103                 return sb.toString();
104         }
105         
106         public ParseResult submitAndParse(String method, 
107                           ArrayList<NameValuePair> passedParams, 
108                           Class<? extends ParseResult> rootParserClass)
109         throws QDException
110         {
111                 return submitAndParse(method, passedParams, rootParserClass, null);
112         }
113         
114         public ParseResult submitAndParse(String method, 
115                                                                           ArrayList<NameValuePair> passedParams, 
116                                                                           Class<? extends ParseResult> rootParserClass,
117                                                                           String rootTagName)
118         throws QDException
119         {
120                 ParseResult result = null;
121                 InputStream is = null;
122                 
123                 try {
124                         if (null == rootTagName) {
125                                 result = (ParseResult) rootParserClass.newInstance();
126                         } 
127                         else {
128                                 result = (ParseResult) rootParserClass.getDeclaredConstructor(String.class).newInstance(rootTagName);
129                         }
130                         is = doSubmit(method, passedParams);
131                         XMLReader reader = XMLReaderFactory.createXMLReader();
132                         ParseHandler ph = new ParseHandler(result);
133                         reader.setContentHandler(ph);
134                         reader.parse(new InputSource(is));
135                 } 
136                 catch ( InstantiationException
137                                 | InvocationTargetException
138                                 | IllegalAccessException
139                                 | IOException 
140                                 | NoSuchMethodException
141                                 | SAXException 
142                                 e )
143                 {
144                         throw new QDException(e);
145                 } 
146                 finally {
147                         ExceptionUtils.tryClose(is);
148                 }
149                 
150                 return result;
151         }
152 }