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