9493e4993a708941c52a8afd8c1b00a18726e204
[mkjsf-moved-to-github.git] / src / main / java / com / indexdata / mkjsf / pazpar2 / ServiceProxyClient.java
1 package com.indexdata.mkjsf.pazpar2;\r
2 \r
3 import static com.indexdata.mkjsf.utils.Utils.nl;\r
4 \r
5 import java.io.BufferedReader;\r
6 import java.io.File;\r
7 import java.io.FileReader;\r
8 import java.io.IOException;\r
9 import java.util.ArrayList;\r
10 import java.util.HashMap;\r
11 import java.util.List;\r
12 import java.util.Map;\r
13 \r
14 import org.apache.http.Header;\r
15 import org.apache.http.HttpEntity;\r
16 import org.apache.http.HttpResponse;\r
17 import org.apache.http.StatusLine;\r
18 import org.apache.http.client.ClientProtocolException;\r
19 import org.apache.http.client.HttpClient;\r
20 import org.apache.http.client.ResponseHandler;\r
21 import org.apache.http.client.methods.HttpGet;\r
22 import org.apache.http.client.methods.HttpPost;\r
23 import org.apache.http.conn.ClientConnectionManager;\r
24 import org.apache.http.conn.scheme.PlainSocketFactory;\r
25 import org.apache.http.conn.scheme.Scheme;\r
26 import org.apache.http.conn.scheme.SchemeRegistry;\r
27 import org.apache.http.entity.ByteArrayEntity;\r
28 import org.apache.http.entity.FileEntity;\r
29 import org.apache.http.impl.client.DefaultHttpClient;\r
30 import org.apache.http.impl.conn.PoolingClientConnectionManager;\r
31 import org.apache.http.util.EntityUtils;\r
32 import org.apache.log4j.Logger;\r
33 \r
34 import com.indexdata.mkjsf.config.Configuration;\r
35 import com.indexdata.mkjsf.config.ConfigurationReader;\r
36 import com.indexdata.mkjsf.errors.ConfigurationException;\r
37 import com.indexdata.mkjsf.pazpar2.commands.CommandParameter;\r
38 import com.indexdata.mkjsf.pazpar2.commands.Pazpar2Command;\r
39 import com.indexdata.mkjsf.pazpar2.commands.sp.AuthCommand;\r
40 import com.indexdata.mkjsf.pazpar2.data.CommandError;\r
41 import com.indexdata.mkjsf.utils.Utils;\r
42 \r
43 public class ServiceProxyClient implements SearchClient {\r
44     \r
45   private static final long serialVersionUID = -4031644009579840277L;\r
46   private static Logger logger = Logger.getLogger(ServiceProxyClient.class);\r
47   public static final String MODULENAME = "proxyclient";\r
48   \r
49   public static final String SP_INIT_DOC_PATHS = "SP_INIT_DOC_PATHS";\r
50   private String serviceUrl = "";\r
51   \r
52   private List<String> initDocPaths = null;\r
53   private Configuration config = null;\r
54   \r
55   ProxyPz2ResponseHandler handler = new ProxyPz2ResponseHandler();\r
56   private transient HttpClient client;  \r
57   private Pazpar2Command checkAuth = null;\r
58   private Pazpar2Command ipAuth = null;\r
59 \r
60   public ServiceProxyClient () {\r
61     SchemeRegistry schemeRegistry = new SchemeRegistry();\r
62     schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));\r
63     ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);\r
64     client = new DefaultHttpClient(cm);\r
65   }\r
66     \r
67   @Override\r
68   public void configure (ConfigurationReader configReader) {\r
69     logger.info(Utils.objectId(this) + " is configuring using the provided " + Utils.objectId(configReader));\r
70     try {\r
71       config = configReader.getConfiguration(this);      \r
72       serviceUrl = config.get("SERVICE_PROXY_URL");\r
73       this.initDocPaths = config.getMultiProperty(SP_INIT_DOC_PATHS,",");\r
74       checkAuth = new AuthCommand(null);\r
75       checkAuth.setParameterInState(new CommandParameter("action","=","check"));\r
76       ipAuth = new AuthCommand(null);\r
77       ipAuth.setParameterInState(new CommandParameter("action","=","ipauth"));\r
78     } catch (ConfigurationException c) {\r
79       // TODO: \r
80       c.printStackTrace();\r
81     }    \r
82   }\r
83     \r
84   public boolean isAuthenticatingClient () {\r
85     return true;\r
86   }\r
87     \r
88   /**\r
89    * Makes the request\r
90    * @param request\r
91    * @return HTTP response as a String\r
92    * @throws ClientProtocolException\r
93    * @throws IOException\r
94    */\r
95   public ClientCommandResponse send(Pazpar2Command command) {\r
96     ClientCommandResponse commandResponse = null;\r
97     String url = serviceUrl + "?" + command.getEncodedQueryString(); \r
98     logger.info("Sending request "+url);    \r
99     HttpGet httpget = new HttpGet(url);     \r
100     byte[] response = null;\r
101     try {\r
102       response = client.execute(httpget, handler);\r
103       if (handler.getStatusCode()==200) {\r
104         commandResponse = new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType());\r
105       } else {\r
106         logger.error("Service Proxy status code: " + handler.getStatusCode());\r
107         commandResponse = new ClientCommandResponse(handler.getStatusCode(),CommandError.insertPazpar2ErrorXml(command.getCommandName(), "Service Proxy error occurred", new String(response,"UTF-8")),"text/xml");                       \r
108       }       \r
109     } catch (Exception e) {\r
110       e.printStackTrace();\r
111       commandResponse = new ClientCommandResponse(-1,CommandError.createErrorXml(command.getCommandName(), e.getClass().getSimpleName(), (e.getMessage()!= null ? e.getMessage() : "") + (e.getCause()!=null ? e.getCause().getMessage() : "")),"text/xml");\r
112     }\r
113     return commandResponse; \r
114   }\r
115   \r
116   public class ProxyPz2ResponseHandler implements ResponseHandler<byte[]> {\r
117     private StatusLine statusLine = null;\r
118     private Header contentType = null;\r
119     public byte[] handleResponse(HttpResponse response) throws ClientProtocolException, IOException {\r
120       byte[] resp = null;\r
121       HttpEntity entity = response.getEntity();      \r
122       statusLine = response.getStatusLine();\r
123       if (entity != null) {        \r
124         resp = EntityUtils.toByteArray(entity);        \r
125         contentType = response.getEntity().getContentType();        \r
126       }       \r
127       EntityUtils.consume(entity);      \r
128       return resp;\r
129     }\r
130     public int getStatusCode() {\r
131       return statusLine.getStatusCode();\r
132     }    \r
133     public String getReasonPhrase() {\r
134       return statusLine.getReasonPhrase();\r
135     }\r
136     public String getContentType () {\r
137       return (contentType != null ? contentType.getValue() : "Content-Type not known"); \r
138     }\r
139   }\r
140 \r
141   public int getStatusCode () {\r
142     return handler.getStatusCode();\r
143   }\r
144   \r
145   public String getReasonPhrase() {\r
146     return handler.getReasonPhrase();\r
147   }\r
148 \r
149   @Override\r
150   public void setSearchCommand(Pazpar2Command command) {\r
151     // Do nothing, Service Proxy is handling this    \r
152   }\r
153 \r
154   @Override\r
155   public HttpResponseWrapper executeCommand(Pazpar2Command command) {\r
156     return send(command);\r
157   }\r
158 \r
159   public ServiceProxyClient cloneMe() {\r
160     logger.debug("Cloning Pz2Client");\r
161     ServiceProxyClient clone = new ServiceProxyClient();\r
162     clone.client = this.client;\r
163     clone.serviceUrl = this.serviceUrl;\r
164     clone.initDocPaths = this.initDocPaths;\r
165     return clone;\r
166   }\r
167 \r
168   @Override\r
169   public Map<String, String> getDefaults() {    \r
170     return new HashMap<String,String>();\r
171   }\r
172 \r
173   @Override\r
174   public String getModuleName() {\r
175     return MODULENAME;\r
176   }\r
177   \r
178   @Override\r
179   public List<String> documentConfiguration () {\r
180     List<String> doc = new ArrayList<String>();\r
181     doc.add(nl+ MODULENAME + " was configured to access the Pazpar2 service proxy at: " + (serviceUrl.length()>0 ? serviceUrl : "[not defined yet]"));\r
182     return null;\r
183   }\r
184   \r
185   public ClientCommandResponse postInitDoc (String filePath) throws IOException {\r
186     logger.info("Looking to post the file in : [" + filePath +"]");\r
187     HttpPost post = new HttpPost(serviceUrl+"?command=init&includeDebug=yes");\r
188     File initDoc = new File(filePath);\r
189     logger.info("Posting to SP: ");\r
190     if (logger.isDebugEnabled()) {\r
191       BufferedReader reader = new BufferedReader(new FileReader(initDoc));\r
192       String line;\r
193       while ( (line = reader.readLine()) != null) {\r
194         System.out.println(line);\r
195       }\r
196       reader.close();\r
197     }\r
198     post.setEntity(new FileEntity(initDoc));\r
199     byte[] response = client.execute(post, handler);\r
200     logger.debug("Response on POST was: " + new String(response,"UTF-8"));    \r
201     return new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType());    \r
202   }\r
203   \r
204   public List<String> getInitDocPaths () {\r
205     logger.debug("Get init doc paths ");\r
206     logger.debug("length: " + initDocPaths.size());\r
207     return initDocPaths;\r
208   }\r
209   \r
210   public HttpResponseWrapper postInitDoc(byte[] initDoc, boolean includeDebug) {\r
211     HttpPost post = new HttpPost(serviceUrl+"?command=init" + (includeDebug? "&includeDebug=yes" : ""));\r
212     post.setEntity(new ByteArrayEntity(initDoc));\r
213     ClientCommandResponse commandResponse = null;\r
214     byte[] response;\r
215     try {\r
216       response = client.execute(post, handler);\r
217       if (handler.getStatusCode()==200) {\r
218         commandResponse = new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType());\r
219       } else {\r
220         logger.error("Service Proxy status code: " + handler.getStatusCode());\r
221         commandResponse = new ClientCommandResponse(handler.getStatusCode(),CommandError.insertPazpar2ErrorXml("init", "Service Proxy error occurred", new String(response,"UTF-8")),"text/xml");                               \r
222       }\r
223     } catch (ClientProtocolException e) {\r
224       logger.error(e.getMessage());\r
225       e.printStackTrace();\r
226       commandResponse = new ClientCommandResponse(-1,CommandError.createErrorXml("init", "client protocol exception", e.getMessage()),"text/xml");      \r
227     } catch (IOException e) {\r
228       logger.error(e.getMessage());\r
229       e.printStackTrace();\r
230       commandResponse = new ClientCommandResponse(-1,CommandError.createErrorXml("init", "IO", e.getMessage()),"text/xml");      \r
231     }\r
232     return commandResponse;    \r
233   }\r
234   \r
235   public void setServiceUrl (String url) {    \r
236     serviceUrl = url;\r
237   }\r
238           \r
239   public Configuration getConfiguration () {\r
240     return config;\r
241   }\r
242 \r
243   @Override\r
244   public String getServiceUrl() {    \r
245     return serviceUrl;\r
246   }\r
247 \r
248   @Override\r
249   public boolean hasServiceUrl() {\r
250     return serviceUrl != null && serviceUrl.length()>0;\r
251   }\r
252   \r
253 }\r