Renames variable
[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.pazpar2.sp.auth.ServiceProxyUser;\r
42 import com.indexdata.mkjsf.utils.Utils;\r
43 \r
44 public class ServiceProxyClient implements SearchClient {\r
45     \r
46   private static final long serialVersionUID = -4031644009579840277L;\r
47   private static Logger logger = Logger.getLogger(ServiceProxyClient.class);\r
48   public static final String MODULENAME = "proxyclient";\r
49   \r
50   public static final String SP_INIT_DOC_PATHS = "SP_INIT_DOC_PATHS";\r
51   private String serviceUrl = "";\r
52   \r
53   private List<String> initDocPaths = null;\r
54   private Configuration config = null;\r
55   \r
56   ProxyPz2ResponseHandler handler = new ProxyPz2ResponseHandler();\r
57   private transient HttpClient client;  \r
58   private Pazpar2Command checkAuth = null;\r
59   private Pazpar2Command ipAuth = null;\r
60 \r
61   public ServiceProxyClient () {\r
62     SchemeRegistry schemeRegistry = new SchemeRegistry();\r
63     schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));\r
64     ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);\r
65     client = new DefaultHttpClient(cm);\r
66   }\r
67     \r
68   @Override\r
69   public void configure (ConfigurationReader configReader) {\r
70     logger.info(Utils.objectId(this) + " is configuring using the provided " + Utils.objectId(configReader));\r
71     try {\r
72       config = configReader.getConfiguration(this);      \r
73       serviceUrl = config.get("SERVICE_PROXY_URL");\r
74       this.initDocPaths = config.getMultiProperty(SP_INIT_DOC_PATHS,",");\r
75       checkAuth = new AuthCommand(null);\r
76       checkAuth.setParameterInState(new CommandParameter("action","=","check"));\r
77       ipAuth = new AuthCommand(null);\r
78       ipAuth.setParameterInState(new CommandParameter("action","=","ipauth"));\r
79     } catch (ConfigurationException c) {\r
80       // TODO: \r
81       c.printStackTrace();\r
82     }    \r
83   }\r
84   \r
85   \r
86   public boolean authenticate (ServiceProxyUser user) {\r
87     logger.info("Authenticating [" + user.getProperty("name") + "]");            \r
88     Pazpar2Command auth = new AuthCommand(null);\r
89     auth.setParametersInState(new CommandParameter("action","=","login"), \r
90                               new CommandParameter("username","=",user.getProperty("name")), \r
91                               new CommandParameter("password","=",user.getProperty("password")));                                \r
92     ClientCommandResponse commandResponse = send(auth);\r
93     String responseStr = commandResponse.getResponseString();\r
94     logger.info(responseStr);      \r
95     if (responseStr.contains("FAIL")) {\r
96       user.credentialsAuthenticationSucceeded(false);\r
97       return false;\r
98     } else {\r
99       user.credentialsAuthenticationSucceeded(true);\r
100       return true;\r
101     }      \r
102   }\r
103   \r
104   public boolean checkAuthentication (ServiceProxyUser user) {    \r
105     ClientCommandResponse commandResponse = send(checkAuth);      \r
106     String responseStr = commandResponse.getResponseString();    \r
107     logger.info(responseStr);\r
108     if (responseStr.contains("FAIL")) {  \r
109       user.authenticationCheckFailed();\r
110       return false;\r
111     } else {                \r
112       return true;\r
113     }      \r
114   }\r
115   \r
116   public boolean ipAuthenticate (ServiceProxyUser user) {\r
117     ClientCommandResponse commandResponse = send(ipAuth);      \r
118     String responseStr = commandResponse.getResponseString();\r
119     logger.info(responseStr);\r
120     if (responseStr.contains("FAIL")) {\r
121       user.ipAuthenticationSucceeded(false);        \r
122       return false;\r
123     } else {\r
124       user.ipAuthenticationSucceeded(true);\r
125       return true;\r
126     }          \r
127   }\r
128   \r
129   public boolean isAuthenticatingClient () {\r
130     return true;\r
131   }\r
132   \r
133   public boolean isAuthenticated (ServiceProxyUser user) {\r
134     if (user.getProperty("name") != null && user.getProperty("password") != null) {\r
135       return checkAuthentication(user);\r
136     } else {\r
137       return false;\r
138     }\r
139   }\r
140   \r
141   /**\r
142    * Makes the request\r
143    * @param request\r
144    * @return HTTP response as a String\r
145    * @throws ClientProtocolException\r
146    * @throws IOException\r
147    */\r
148   private ClientCommandResponse send(Pazpar2Command command) {\r
149     ClientCommandResponse commandResponse = null;\r
150     String url = serviceUrl + "?" + command.getEncodedQueryString(); \r
151     logger.info("Sending request "+url);    \r
152     HttpGet httpget = new HttpGet(url);     \r
153     byte[] response = null;\r
154     try {\r
155       response = client.execute(httpget, handler);\r
156       if (handler.getStatusCode()==200) {\r
157         commandResponse = new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType());\r
158       } else {\r
159         logger.error("Service Proxy status code: " + handler.getStatusCode());\r
160         commandResponse = new ClientCommandResponse(handler.getStatusCode(),CommandError.insertPazpar2ErrorXml(command.getCommandName(), "Service Proxy error occurred", new String(response,"UTF-8")),"text/xml");                       \r
161       }       \r
162     } catch (Exception e) {\r
163       e.printStackTrace();\r
164       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
165     }\r
166     return commandResponse; \r
167   }\r
168   \r
169   public class ProxyPz2ResponseHandler implements ResponseHandler<byte[]> {\r
170     private StatusLine statusLine = null;\r
171     private Header contentType = null;\r
172     public byte[] handleResponse(HttpResponse response) throws ClientProtocolException, IOException {\r
173       byte[] resp = null;\r
174       HttpEntity entity = response.getEntity();      \r
175       statusLine = response.getStatusLine();\r
176       if (entity != null) {        \r
177         resp = EntityUtils.toByteArray(entity);        \r
178         contentType = response.getEntity().getContentType();        \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     public String getContentType () {\r
190       return (contentType != null ? contentType.getValue() : "Content-Type not known"); \r
191     }\r
192   }\r
193 \r
194   public int getStatusCode () {\r
195     return handler.getStatusCode();\r
196   }\r
197   \r
198   public String getReasonPhrase() {\r
199     return handler.getReasonPhrase();\r
200   }\r
201 \r
202   @Override\r
203   public void setSearchCommand(Pazpar2Command command) {\r
204     // Do nothing, Service Proxy is handling this    \r
205   }\r
206 \r
207   @Override\r
208   public HttpResponseWrapper executeCommand(Pazpar2Command command) {\r
209     return send(command);\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.length()>0 ? serviceUrl : "[not defined yet]"));\r
235     return null;\r
236   }\r
237   \r
238   public ClientCommandResponse 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     if (logger.isDebugEnabled()) {\r
244       BufferedReader reader = new BufferedReader(new FileReader(initDoc));\r
245       String line;\r
246       while ( (line = reader.readLine()) != null) {\r
247         System.out.println(line);\r
248       }\r
249       reader.close();\r
250     }\r
251     post.setEntity(new FileEntity(initDoc));\r
252     byte[] response = client.execute(post, handler);\r
253     logger.debug("Response on POST was: " + new String(response,"UTF-8"));    \r
254     return new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType());    \r
255   }\r
256   \r
257   public List<String> getInitDocPaths () {\r
258     logger.debug("Get init doc paths ");\r
259     logger.debug("length: " + initDocPaths.size());\r
260     return initDocPaths;\r
261   }\r
262   \r
263   public ClientCommandResponse postInitDoc(byte[] initDoc, boolean includeDebug) throws IOException {\r
264     HttpPost post = new HttpPost(serviceUrl+"?command=init" + (includeDebug? "&includeDebug=yes" : ""));\r
265     post.setEntity(new ByteArrayEntity(initDoc));\r
266     byte[] response = client.execute(post, handler);\r
267     logger.debug("Response on POST was: " + new String(response,"UTF-8"));    \r
268     return new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType());    \r
269   }\r
270   \r
271   public void setServiceUrl (String url) {    \r
272     serviceUrl = url;\r
273   }\r
274           \r
275   public Configuration getConfiguration () {\r
276     return config;\r
277   }\r
278 \r
279   @Override\r
280   public String getServiceUrl() {    \r
281     return serviceUrl;\r
282   }\r
283 \r
284   @Override\r
285   public boolean hasServiceUrl() {\r
286     return serviceUrl != null && serviceUrl.length()>0;\r
287   }\r
288   \r
289 }\r