Makes init doc debug response optional
[mkjsf-moved-to-github.git] / src / main / java / com / indexdata / mkjsf / pazpar2 / sp / ServiceProxyClient.java
1 package com.indexdata.mkjsf.pazpar2.sp;\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.ByteArrayOutputStream;\r
7 import java.io.File;\r
8 import java.io.FileReader;\r
9 import java.io.IOException;\r
10 import java.util.ArrayList;\r
11 import java.util.HashMap;\r
12 import java.util.List;\r
13 import java.util.Map;\r
14 import java.util.StringTokenizer;\r
15 \r
16 import org.apache.http.HttpEntity;\r
17 import org.apache.http.HttpResponse;\r
18 import org.apache.http.StatusLine;\r
19 import org.apache.http.client.ClientProtocolException;\r
20 import org.apache.http.client.HttpClient;\r
21 import org.apache.http.client.ResponseHandler;\r
22 import org.apache.http.client.methods.HttpGet;\r
23 import org.apache.http.client.methods.HttpPost;\r
24 import org.apache.http.conn.ClientConnectionManager;\r
25 import org.apache.http.conn.scheme.PlainSocketFactory;\r
26 import org.apache.http.conn.scheme.Scheme;\r
27 import org.apache.http.conn.scheme.SchemeRegistry;\r
28 import org.apache.http.entity.ByteArrayEntity;\r
29 import org.apache.http.entity.FileEntity;\r
30 import org.apache.http.impl.client.DefaultHttpClient;\r
31 import org.apache.http.impl.conn.PoolingClientConnectionManager;\r
32 import org.apache.http.util.EntityUtils;\r
33 import org.apache.log4j.Logger;\r
34 \r
35 import com.indexdata.masterkey.pazpar2.client.exceptions.Pazpar2ErrorException;\r
36 import com.indexdata.mkjsf.config.Configuration;\r
37 import com.indexdata.mkjsf.config.ConfigurationReader;\r
38 import com.indexdata.mkjsf.errors.ConfigurationException;\r
39 import com.indexdata.mkjsf.pazpar2.CommandResponse;\r
40 import com.indexdata.mkjsf.pazpar2.SearchClient;\r
41 import com.indexdata.mkjsf.pazpar2.commands.CommandParameter;\r
42 import com.indexdata.mkjsf.pazpar2.commands.Pazpar2Command;\r
43 import com.indexdata.mkjsf.pazpar2.commands.sp.AuthCommand;\r
44 import com.indexdata.mkjsf.pazpar2.sp.auth.ServiceProxyUser;\r
45 import com.indexdata.mkjsf.utils.Utils;\r
46 \r
47 public class ServiceProxyClient implements SearchClient {\r
48     \r
49   private static final long serialVersionUID = -4031644009579840277L;\r
50   private static Logger logger = Logger.getLogger(ServiceProxyClient.class);\r
51   public static final String MODULENAME = "proxyclient";\r
52   public static final String SERVICE_PROXY_URL = "SERVICE_PROXY_URL";\r
53   public static final String SP_INIT_DOC_PATHS = "SP_INIT_DOC_PATHS";\r
54   private String selectedServiceUrl = "";\r
55   private List<String> serviceUrls = new ArrayList<String>();\r
56   private List<String> initDocPaths = null;\r
57   private Configuration config = null;\r
58   \r
59   ProxyPz2ResponseHandler handler = new ProxyPz2ResponseHandler();\r
60   private transient HttpClient client;  \r
61   private Pazpar2Command checkAuth = null;\r
62   private Pazpar2Command ipAuth = null;\r
63 \r
64   public ServiceProxyClient () {\r
65     SchemeRegistry schemeRegistry = new SchemeRegistry();\r
66     schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));\r
67     ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);\r
68     client = new DefaultHttpClient(cm);\r
69   }\r
70     \r
71   @Override\r
72   public void configure (ConfigurationReader configReader) {\r
73     logger.info(Utils.objectId(this) + " is configuring using the provided " + Utils.objectId(configReader));\r
74     try {\r
75       config = configReader.getConfiguration(this);      \r
76       serviceUrls = getMultiProperty(config.get(SERVICE_PROXY_URL));\r
77       if (serviceUrls.size()==1) {\r
78         selectedServiceUrl = serviceUrls.get(0);\r
79       }\r
80       this.initDocPaths = getMultiProperty(config.get(SP_INIT_DOC_PATHS));\r
81       checkAuth = new AuthCommand(null);\r
82       checkAuth.setParameterInState(new CommandParameter("action","=","check"));\r
83       ipAuth = new AuthCommand(null);\r
84       ipAuth.setParameterInState(new CommandParameter("action","=","ipauth"));\r
85     } catch (ConfigurationException c) {\r
86       c.printStackTrace();\r
87     }    \r
88   }\r
89   \r
90   private List<String> getMultiProperty(String prop) {\r
91     List<String> props = new ArrayList<String>();\r
92     if (prop != null) {      \r
93       StringTokenizer tokenizer = new StringTokenizer(prop,",");\r
94       while (tokenizer.hasMoreElements()) {\r
95         props.add(tokenizer.nextToken());\r
96       }     \r
97     }\r
98     return props;\r
99   }\r
100   \r
101   public boolean authenticate (ServiceProxyUser user) {\r
102     try {      \r
103       logger.info("Authenticating [" + user.getProperty("name") + "]");            \r
104       Pazpar2Command auth = new AuthCommand(null);\r
105       auth.setParametersInState(new CommandParameter("action","=","login"), \r
106                                 new CommandParameter("username","=",user.getProperty("name")), \r
107                                 new CommandParameter("password","=",user.getProperty("password")));                                \r
108       byte[] response = send(auth);\r
109       String responseStr = new String(response,"UTF-8");\r
110       logger.info(responseStr);      \r
111       if (responseStr.contains("FAIL")) {\r
112         user.isAuthenticated(false);\r
113         return false;\r
114       } else {\r
115         user.isAuthenticated(true);\r
116         return true;\r
117       }      \r
118     } catch (ClientProtocolException e) {\r
119       // TODO Auto-generated catch block\r
120       e.printStackTrace();\r
121       return false;\r
122     } catch (IOException e) {\r
123       // TODO Auto-generated catch block\r
124       e.printStackTrace();\r
125       return false;\r
126     }        \r
127   }\r
128   \r
129   public boolean checkAuthentication (ServiceProxyUser user) {    \r
130     try {\r
131       byte[] response = send(checkAuth);\r
132       logger.info(new String(response,"UTF-8"));\r
133       String responseStr = new String(response,"UTF-8");    \r
134       if (responseStr.contains("FAIL")) {  \r
135         user.isAuthenticated(false);\r
136         return false;\r
137       } else {        \r
138         user.isAuthenticated(true);\r
139         return true;\r
140       }      \r
141     } catch (ClientProtocolException e) {\r
142       // TODO Auto-generated catch block\r
143       e.printStackTrace();\r
144       return false;\r
145     } catch (IOException e) {\r
146       // TODO Auto-generated catch block\r
147       e.printStackTrace();\r
148       return false;\r
149     }        \r
150   }\r
151   \r
152   public boolean ipAuthenticate (ServiceProxyUser user) {\r
153     try {\r
154       byte[] response = send(ipAuth);\r
155       logger.info(new String(response,"UTF-8"));\r
156       String responseStr = new String(response,"UTF-8");    \r
157       if (responseStr.contains("FAIL")) {\r
158         user.isAuthenticated(false);\r
159         return false;\r
160       } else {\r
161         user.isAuthenticated(true);\r
162         return true;\r
163       }      \r
164     } catch (ClientProtocolException e) {\r
165       // TODO Auto-generated catch block\r
166       e.printStackTrace();\r
167       return false;\r
168     } catch (IOException e) {\r
169       // TODO Auto-generated catch block\r
170       e.printStackTrace();\r
171       return false;\r
172     }        \r
173     \r
174   }\r
175   \r
176   public boolean isAuthenticatingClient () {\r
177     return true;\r
178   }\r
179   \r
180   public boolean isAuthenticated (ServiceProxyUser user) {\r
181     if (user.getProperty("name") != null && user.getProperty("password") != null) {\r
182       return checkAuthentication(user);\r
183     } else {\r
184       return false;\r
185     }\r
186   }\r
187   \r
188   /**\r
189    * Makes the request\r
190    * @param request\r
191    * @return HTTP response as a String\r
192    * @throws ClientProtocolException\r
193    * @throws IOException\r
194    */\r
195   private byte[] send(Pazpar2Command command) throws ClientProtocolException, IOException {\r
196     String url = selectedServiceUrl + "?" + command.getEncodedQueryString(); \r
197     logger.info("Sending request "+url);    \r
198     HttpGet httpget = new HttpGet(url);     \r
199     byte[] response = client.execute(httpget, handler);    \r
200     return response;\r
201   }\r
202   \r
203   public class ProxyPz2ResponseHandler implements ResponseHandler<byte[]> {\r
204     private StatusLine statusLine = null;\r
205     public byte[] handleResponse(HttpResponse response) throws ClientProtocolException, IOException {\r
206       byte[] resp = null;\r
207       HttpEntity entity = response.getEntity();      \r
208       statusLine = response.getStatusLine();\r
209       if (entity != null) {        \r
210         resp = EntityUtils.toByteArray(entity);        \r
211       } \r
212       EntityUtils.consume(entity);\r
213       return resp;\r
214     }\r
215     public int getStatusCode() {\r
216       return statusLine.getStatusCode();\r
217     }    \r
218     public String getReasonPhrase() {\r
219       return statusLine.getReasonPhrase();\r
220     }\r
221   }\r
222 \r
223   public int getStatusCode () {\r
224     return handler.getStatusCode();\r
225   }\r
226   \r
227   public String getReasonPhrase() {\r
228     return handler.getReasonPhrase();\r
229   }\r
230 \r
231   @Override\r
232   public void setSearchCommand(Pazpar2Command command) {\r
233     // Do nothing, Service Proxy is handling this    \r
234   }\r
235 \r
236   @Override\r
237   public CommandResponse executeCommand(Pazpar2Command command,\r
238       ByteArrayOutputStream baos) throws Pazpar2ErrorException, IOException {\r
239     byte[] response = send(command);\r
240     baos.write(response);\r
241     return new ServiceProxyClientCommandResponse(getStatusCode(), new String(response,"UTF-8"));    \r
242   }\r
243 \r
244   public ServiceProxyClient cloneMe() {\r
245     logger.debug("Cloning Pz2Client");\r
246     ServiceProxyClient clone = new ServiceProxyClient();\r
247     clone.client = this.client;\r
248     clone.serviceUrls = this.serviceUrls;\r
249     clone.selectedServiceUrl = this.selectedServiceUrl;\r
250     clone.initDocPaths = this.initDocPaths;\r
251     return clone;\r
252   }\r
253 \r
254   @Override\r
255   public Map<String, String> getDefaults() {    \r
256     return new HashMap<String,String>();\r
257   }\r
258 \r
259   @Override\r
260   public String getModuleName() {\r
261     return MODULENAME;\r
262   }\r
263   \r
264   @Override\r
265   public List<String> documentConfiguration () {\r
266     List<String> doc = new ArrayList<String>();\r
267     doc.add(nl+ MODULENAME + " was configured to access the Pazpar2 service proxy at: " + (selectedServiceUrl.length()>0 ? selectedServiceUrl : "[not defined yet]"));\r
268     return null;\r
269   }\r
270   \r
271   public byte[] postInitDoc (String filePath) throws IOException {\r
272     logger.info("Looking to post the file in : [" + filePath +"]");\r
273     HttpPost post = new HttpPost(selectedServiceUrl+"?command=init&includeDebug=yes");\r
274     File initDoc = new File(filePath);\r
275     logger.info("Posting to SP: ");\r
276     if (logger.isDebugEnabled()) {\r
277       BufferedReader reader = new BufferedReader(new FileReader(initDoc));\r
278       String line;\r
279       while ( (line = reader.readLine()) != null) {\r
280         System.out.println(line);\r
281       }\r
282       reader.close();\r
283     }\r
284     post.setEntity(new FileEntity(initDoc));\r
285     byte[] response = client.execute(post, handler);\r
286     logger.debug("Response on POST was: " + new String(response,"UTF-8"));    \r
287     return response;\r
288   }\r
289   \r
290   public List<String> getInitDocPaths () {\r
291     logger.debug("Get init doc paths ");\r
292     logger.debug("length: " + initDocPaths.size());\r
293     return initDocPaths;\r
294   }\r
295   \r
296   public byte[] postInitDoc(byte[] initDoc, boolean includeDebug) throws IOException {\r
297     HttpPost post = new HttpPost(selectedServiceUrl+"?command=init" + (includeDebug? "&includeDebug=yes" : ""));\r
298     post.setEntity(new ByteArrayEntity(initDoc));\r
299     byte[] response = client.execute(post, handler);\r
300     logger.debug("Response on POST was: " + new String(response,"UTF-8"));    \r
301     return response;\r
302   }\r
303   \r
304   public void setServiceProxyUrl (String url) {\r
305     selectedServiceUrl = url;\r
306   }\r
307   \r
308   public String getServiceProxyUrl () {\r
309     return selectedServiceUrl;\r
310   }\r
311   \r
312   public List<String> getServiceProxyUrls () {\r
313     return serviceUrls;\r
314   }\r
315     \r
316   public Configuration getConfiguration () {\r
317     return config;\r
318   }\r
319   \r
320 }\r