From: Niels Erik G. Nielsen Date: Thu, 9 May 2013 01:24:17 +0000 (-0400) Subject: Tweaks configuration, command responses, pz2/sp switching X-Git-Tag: v0.0.7~124 X-Git-Url: http://lists.indexdata.dk/?a=commitdiff_plain;h=038cea23aa13e84430b55dda29fdea9fdf64828d;p=mkjsf-moved-to-github.git Tweaks configuration, command responses, pz2/sp switching Generalizes method for retrieving char separated config properties Consolidates command responses in one common class for sp an pz2 clients Fixes switches of service urls for pz2 url to sp url and vice versa --- diff --git a/src/main/java/com/indexdata/mkjsf/config/Configuration.java b/src/main/java/com/indexdata/mkjsf/config/Configuration.java index f375318..f7935fd 100644 --- a/src/main/java/com/indexdata/mkjsf/config/Configuration.java +++ b/src/main/java/com/indexdata/mkjsf/config/Configuration.java @@ -1,8 +1,11 @@ package com.indexdata.mkjsf.config; import java.io.Serializable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.StringTokenizer; import org.apache.log4j.Logger; @@ -66,6 +69,19 @@ public class Configuration implements Serializable { } throw new MissingMandatoryParameterException("Missing mandatory parameter: " + key); } + + public List getMultiProperty(String key, String separator) { + List props = new ArrayList(); + String prop = get(key); + if (prop != null) { + StringTokenizer tokenizer = new StringTokenizer(prop,separator); + while (tokenizer.hasMoreElements()) { + props.add(tokenizer.nextToken()); + } + } + return props; + } + public String getConfigFilePath() { return get("configpath","nopathgiven"); @@ -75,5 +91,7 @@ public class Configuration implements Serializable { return properties; } + + } diff --git a/src/main/java/com/indexdata/mkjsf/config/Mk2ConfigReader.java b/src/main/java/com/indexdata/mkjsf/config/Mk2ConfigReader.java index bc57467..5cd0566 100644 --- a/src/main/java/com/indexdata/mkjsf/config/Mk2ConfigReader.java +++ b/src/main/java/com/indexdata/mkjsf/config/Mk2ConfigReader.java @@ -59,7 +59,7 @@ public class Mk2ConfigReader implements ConfigurationReader { MasterkeyConfiguration mkConfigContext; try { mkConfigContext = MasterkeyConfiguration.getInstance(servletContext, - "pazpar-application-jsf", ((HttpServletRequest) externalContext.getRequest()).getServerName()); + "mkjsf", ((HttpServletRequest) externalContext.getRequest()).getServerName()); } catch (IOException e) { throw new ConfigurationException(Mk2ConfigReader.class + " could not read configuration for '" + configurable.getModuleName() + "' using MasterKey configuration scheme: "+e.getMessage(),e); } diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/ClientCommandResponse.java b/src/main/java/com/indexdata/mkjsf/pazpar2/ClientCommandResponse.java new file mode 100644 index 0000000..0375ca1 --- /dev/null +++ b/src/main/java/com/indexdata/mkjsf/pazpar2/ClientCommandResponse.java @@ -0,0 +1,67 @@ +package com.indexdata.mkjsf.pazpar2; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; + +import com.indexdata.masterkey.pazpar2.client.Pazpar2HttpResponse; + +public class ClientCommandResponse implements CommandResponse { + + private int statusCode; + private String contentType; + private byte[] content = null; + private String contentString = null; + + public ClientCommandResponse(Pazpar2HttpResponse pz2response, ByteArrayOutputStream content) { + this.content = content.toByteArray(); + this.statusCode = pz2response.getStatusCode(); + this.contentType = pz2response.getContentType(); + } + + public ClientCommandResponse(int statusCode, String content, String contentType) { + this.statusCode = statusCode; + this.contentString = content; + this.contentType = contentType; + } + + public ClientCommandResponse(int statusCode, byte[] content, String contentType) { + this.statusCode = statusCode; + this.content = content; + this.contentType = contentType; + } + + @Override + public int getStatusCode() { + return statusCode; + } + + @Override + public String getContentType() { + return contentType; + } + + @Override + public String getResponseString() { + if (content == null) { + return contentString; + } else { + try { + return new String(content,"UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return "unsupported encoding"; + } + } + } + + @Override + public byte[] getBytes() { + return content; + } + + @Override + public boolean isBinary() { + return !contentType.contains("xml"); + } + +} diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/Pz2Bean.java b/src/main/java/com/indexdata/mkjsf/pazpar2/Pz2Bean.java index 490cee6..03bd096 100644 --- a/src/main/java/com/indexdata/mkjsf/pazpar2/Pz2Bean.java +++ b/src/main/java/com/indexdata/mkjsf/pazpar2/Pz2Bean.java @@ -295,20 +295,30 @@ public class Pz2Bean implements Pz2Interface, StateListener, Configurable, Seria public void setServiceProxyUrl(String url) { searchClient = spClient; + setServiceType(SERVICE_TYPE_SP); setServiceUrl(url); } public String getServiceProxyUrl () { - return spClient.getServiceUrl(); + if (isServiceProxyService()) { + return spClient.getServiceUrl(); + } else { + return ""; + } } public void setPazpar2Url(String url) { searchClient = pz2Client; + setServiceType(SERVICE_TYPE_PZ2); setServiceUrl(url); } public String getPazpar2Url() { - return pz2Client.getServiceUrl(); + if (isPazpar2Service()) { + return pz2Client.getServiceUrl(); + } else { + return ""; + } } diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/Pz2CommandResponse.java b/src/main/java/com/indexdata/mkjsf/pazpar2/Pz2CommandResponse.java deleted file mode 100644 index 27cf441..0000000 --- a/src/main/java/com/indexdata/mkjsf/pazpar2/Pz2CommandResponse.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.indexdata.mkjsf.pazpar2; - -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; - -import com.indexdata.masterkey.pazpar2.client.Pazpar2HttpResponse; - -public class Pz2CommandResponse implements CommandResponse { - - private Pazpar2HttpResponse pz2httpResponse = null; - private int statusCode; - private String contentType; - private byte[] content = null; - private String contentString = null; - - public Pz2CommandResponse(Pazpar2HttpResponse pz2response, ByteArrayOutputStream content) { - pz2httpResponse = pz2response; - this.content = content.toByteArray(); - this.statusCode = pz2httpResponse.getStatusCode(); - this.contentType = pz2httpResponse.getContentType(); - } - - public Pz2CommandResponse(Pazpar2HttpResponse pz2response, String content) { - pz2httpResponse = pz2response; - this.contentString = content; - } - - public Pz2CommandResponse(int statusCode, String content, String contentType) { - this.statusCode = statusCode; - this.contentString = content; - this.contentType = contentType; - } - - @Override - public int getStatusCode() { - return statusCode; - } - - @Override - public String getContentType() { - return contentType; - } - - @Override - public String getResponseString() { - if (content == null) { - return contentString; - } else { - try { - return new String(content,"UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - return "unsupported encoding"; - } - } - } - - @Override - public byte[] getBytes() { - return content; - } - - @Override - public boolean isBinary() { - return !contentType.contains("xml"); - } - -} diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/ServiceProxyClient.java b/src/main/java/com/indexdata/mkjsf/pazpar2/ServiceProxyClient.java new file mode 100644 index 0000000..a43432e --- /dev/null +++ b/src/main/java/com/indexdata/mkjsf/pazpar2/ServiceProxyClient.java @@ -0,0 +1,289 @@ +package com.indexdata.mkjsf.pazpar2; + +import static com.indexdata.mkjsf.utils.Utils.nl; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.FileEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.util.EntityUtils; +import org.apache.log4j.Logger; + +import com.indexdata.mkjsf.config.Configuration; +import com.indexdata.mkjsf.config.ConfigurationReader; +import com.indexdata.mkjsf.errors.ConfigurationException; +import com.indexdata.mkjsf.pazpar2.commands.CommandParameter; +import com.indexdata.mkjsf.pazpar2.commands.Pazpar2Command; +import com.indexdata.mkjsf.pazpar2.commands.sp.AuthCommand; +import com.indexdata.mkjsf.pazpar2.data.CommandError; +import com.indexdata.mkjsf.pazpar2.sp.auth.ServiceProxyUser; +import com.indexdata.mkjsf.utils.Utils; + +public class ServiceProxyClient implements SearchClient { + + private static final long serialVersionUID = -4031644009579840277L; + private static Logger logger = Logger.getLogger(ServiceProxyClient.class); + public static final String MODULENAME = "proxyclient"; + + public static final String SP_INIT_DOC_PATHS = "SP_INIT_DOC_PATHS"; + private String selectedServiceUrl = ""; + + private List initDocPaths = null; + private Configuration config = null; + + ProxyPz2ResponseHandler handler = new ProxyPz2ResponseHandler(); + private transient HttpClient client; + private Pazpar2Command checkAuth = null; + private Pazpar2Command ipAuth = null; + + public ServiceProxyClient () { + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry); + client = new DefaultHttpClient(cm); + } + + @Override + public void configure (ConfigurationReader configReader) { + logger.info(Utils.objectId(this) + " is configuring using the provided " + Utils.objectId(configReader)); + try { + config = configReader.getConfiguration(this); + selectedServiceUrl = config.get("SERVICE_PROXY_URL"); + this.initDocPaths = config.getMultiProperty(SP_INIT_DOC_PATHS,","); + checkAuth = new AuthCommand(null); + checkAuth.setParameterInState(new CommandParameter("action","=","check")); + ipAuth = new AuthCommand(null); + ipAuth.setParameterInState(new CommandParameter("action","=","ipauth")); + } catch (ConfigurationException c) { + // TODO: + c.printStackTrace(); + } + } + + + public boolean authenticate (ServiceProxyUser user) { + logger.info("Authenticating [" + user.getProperty("name") + "]"); + Pazpar2Command auth = new AuthCommand(null); + auth.setParametersInState(new CommandParameter("action","=","login"), + new CommandParameter("username","=",user.getProperty("name")), + new CommandParameter("password","=",user.getProperty("password"))); + ClientCommandResponse commandResponse = send(auth); + String responseStr = commandResponse.getResponseString(); + logger.info(responseStr); + if (responseStr.contains("FAIL")) { + user.credentialsAuthenticationSucceeded(false); + return false; + } else { + user.credentialsAuthenticationSucceeded(true); + return true; + } + } + + public boolean checkAuthentication (ServiceProxyUser user) { + ClientCommandResponse commandResponse = send(checkAuth); + String responseStr = commandResponse.getResponseString(); + logger.info(responseStr); + if (responseStr.contains("FAIL")) { + user.authenticationCheckFailed(); + return false; + } else { + return true; + } + } + + public boolean ipAuthenticate (ServiceProxyUser user) { + ClientCommandResponse commandResponse = send(ipAuth); + String responseStr = commandResponse.getResponseString(); + logger.info(responseStr); + if (responseStr.contains("FAIL")) { + user.ipAuthenticationSucceeded(false); + return false; + } else { + user.ipAuthenticationSucceeded(true); + return true; + } + } + + public boolean isAuthenticatingClient () { + return true; + } + + public boolean isAuthenticated (ServiceProxyUser user) { + if (user.getProperty("name") != null && user.getProperty("password") != null) { + return checkAuthentication(user); + } else { + return false; + } + } + + /** + * Makes the request + * @param request + * @return HTTP response as a String + * @throws ClientProtocolException + * @throws IOException + */ + private ClientCommandResponse send(Pazpar2Command command) { + ClientCommandResponse commandResponse = null; + String url = selectedServiceUrl + "?" + command.getEncodedQueryString(); + logger.info("Sending request "+url); + HttpGet httpget = new HttpGet(url); + byte[] response = null; + try { + response = client.execute(httpget, handler); + if (handler.getStatusCode()==200) { + commandResponse = new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType()); + } else { + logger.error("Service Proxy status code: " + handler.getStatusCode()); + commandResponse = new ClientCommandResponse(handler.getStatusCode(),CommandError.insertPazpar2ErrorXml(command.getCommandName(), "Service Proxy error occurred", new String(response,"UTF-8")),"text/xml"); + } + } catch (Exception e) { + e.printStackTrace(); + commandResponse = new ClientCommandResponse(-1,CommandError.createErrorXml(command.getCommandName(), e.getClass().getSimpleName(), (e.getMessage()!= null ? e.getMessage() : "") + (e.getCause()!=null ? e.getCause().getMessage() : "")),"text/xml"); + } + return commandResponse; + } + + public class ProxyPz2ResponseHandler implements ResponseHandler { + private StatusLine statusLine = null; + private Header contentType = null; + public byte[] handleResponse(HttpResponse response) throws ClientProtocolException, IOException { + byte[] resp = null; + HttpEntity entity = response.getEntity(); + statusLine = response.getStatusLine(); + if (entity != null) { + resp = EntityUtils.toByteArray(entity); + contentType = response.getEntity().getContentType(); + } + EntityUtils.consume(entity); + return resp; + } + public int getStatusCode() { + return statusLine.getStatusCode(); + } + public String getReasonPhrase() { + return statusLine.getReasonPhrase(); + } + public String getContentType () { + return (contentType != null ? contentType.getValue() : "Content-Type not known"); + } + } + + public int getStatusCode () { + return handler.getStatusCode(); + } + + public String getReasonPhrase() { + return handler.getReasonPhrase(); + } + + @Override + public void setSearchCommand(Pazpar2Command command) { + // Do nothing, Service Proxy is handling this + } + + @Override + public CommandResponse executeCommand(Pazpar2Command command) { + return send(command); + } + + public ServiceProxyClient cloneMe() { + logger.debug("Cloning Pz2Client"); + ServiceProxyClient clone = new ServiceProxyClient(); + clone.client = this.client; + clone.selectedServiceUrl = this.selectedServiceUrl; + clone.initDocPaths = this.initDocPaths; + return clone; + } + + @Override + public Map getDefaults() { + return new HashMap(); + } + + @Override + public String getModuleName() { + return MODULENAME; + } + + @Override + public List documentConfiguration () { + List doc = new ArrayList(); + doc.add(nl+ MODULENAME + " was configured to access the Pazpar2 service proxy at: " + (selectedServiceUrl.length()>0 ? selectedServiceUrl : "[not defined yet]")); + return null; + } + + public ClientCommandResponse postInitDoc (String filePath) throws IOException { + logger.info("Looking to post the file in : [" + filePath +"]"); + HttpPost post = new HttpPost(selectedServiceUrl+"?command=init&includeDebug=yes"); + File initDoc = new File(filePath); + logger.info("Posting to SP: "); + if (logger.isDebugEnabled()) { + BufferedReader reader = new BufferedReader(new FileReader(initDoc)); + String line; + while ( (line = reader.readLine()) != null) { + System.out.println(line); + } + reader.close(); + } + post.setEntity(new FileEntity(initDoc)); + byte[] response = client.execute(post, handler); + logger.debug("Response on POST was: " + new String(response,"UTF-8")); + return new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType()); + } + + public List getInitDocPaths () { + logger.debug("Get init doc paths "); + logger.debug("length: " + initDocPaths.size()); + return initDocPaths; + } + + public ClientCommandResponse postInitDoc(byte[] initDoc, boolean includeDebug) throws IOException { + HttpPost post = new HttpPost(selectedServiceUrl+"?command=init" + (includeDebug? "&includeDebug=yes" : "")); + post.setEntity(new ByteArrayEntity(initDoc)); + byte[] response = client.execute(post, handler); + logger.debug("Response on POST was: " + new String(response,"UTF-8")); + return new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType()); + } + + public void setServiceUrl (String url) { + selectedServiceUrl = url; + } + + public Configuration getConfiguration () { + return config; + } + + @Override + public String getServiceUrl() { + return selectedServiceUrl; + } + + @Override + public boolean hasServiceUrl() { + return selectedServiceUrl != null && selectedServiceUrl.length()>0; + } + +} diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/ServiceProxyInterface.java b/src/main/java/com/indexdata/mkjsf/pazpar2/ServiceProxyInterface.java new file mode 100644 index 0000000..8c31abe --- /dev/null +++ b/src/main/java/com/indexdata/mkjsf/pazpar2/ServiceProxyInterface.java @@ -0,0 +1,14 @@ +package com.indexdata.mkjsf.pazpar2; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + + +public interface ServiceProxyInterface { + public String login(String navigateTo); + public void setInitFileName (String fileName); + public String getInitFileName(); + public ClientCommandResponse postInit() throws UnsupportedEncodingException, IOException; + public ClientCommandResponse postInit(byte[] initDoc, boolean includeDebug) throws UnsupportedEncodingException, IOException; + public String getInitResponse(); +} diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/sp/ServiceProxyCommandResponse.java b/src/main/java/com/indexdata/mkjsf/pazpar2/sp/ServiceProxyCommandResponse.java deleted file mode 100644 index 90d4f2e..0000000 --- a/src/main/java/com/indexdata/mkjsf/pazpar2/sp/ServiceProxyCommandResponse.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.indexdata.mkjsf.pazpar2.sp; - -import java.io.UnsupportedEncodingException; - -import com.indexdata.mkjsf.pazpar2.CommandResponse; - -public class ServiceProxyCommandResponse implements CommandResponse { - - private int statusCode = 0; - private byte[] content = null; - private String responseString = null; - private String contentType = ""; - - public ServiceProxyCommandResponse(int statusCode, byte[] content, String contentType) { - this.statusCode = statusCode; - this.content = content; - this.contentType = contentType; - } - - public ServiceProxyCommandResponse(int statusCode, String contentString, String contentType) { - this.statusCode = statusCode; - this.contentType = contentType; - this.responseString = contentString; - } - - @Override - public int getStatusCode() { - return statusCode; - } - - @Override - public String getContentType() { - return contentType; - } - - @Override - public String getResponseString() { - if (content == null) { - return responseString; - } else { - try { - return new String(content,"UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - return "unsupported encoding"; - } - } - } - - @Override - public byte[] getBytes() { - return content; - } - - @Override - public boolean isBinary() { - // TODO Auto-generated method stub - return false; - } - -}