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