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