Java tutorial
/* * Copyright 2012 University of Denver * Author Chet Rebman * * This file is part of FedoraProxy. * * FedoraProxy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FedoraProxy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FedoraProxy. If not, see <http://www.gnu.org/licenses/>. */ package edu.du.penrose.systems.fedoraProxy.web.bus; import java.io.BufferedInputStream; import java.io.File; import java.io.InputStream; import javax.servlet.http.HttpServletResponse; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.du.penrose.systems.fedora.ResourceIndexUtils; // import edu.du.penrose.systems.fedoraApp.FedoraAppConstants; import edu.du.penrose.systems.fedoraApp.ProgramFileProperties; import edu.du.penrose.systems.fedoraApp.ProgramProperties; import edu.du.penrose.systems.fedoraProxy.FedoraProxyConstants; import edu.du.penrose.systems.fedoraProxy.util.FedoraProxyServletContextListener; /** * The top level proxy controller. Implements most of the code needed to perform a proxy call.<br><br> * REQUIRES that FEDORA_HOST, * FEDORA_PORT, FEDORA_USER, FEDORA_PWD, SOLR_HOST and SOLR_PORT are defined * in the batchIngest.properties file!!<br> * @author chet * */ abstract public class ProxyController { /** * Logger for this class and subclasses. */ protected final static Log logger = LogFactory .getLog("edu.du.penrose.systems.fedoraProxy.web.bus.ProxyController"); private static ProgramProperties websiteCollectionPropertiesFile = null; protected static String FEDORA_HOST = null; protected static int FEDORA_PORT = 8080; protected static String FEDORA_REALM = null; // "FEDORA_REALM is actually Fedora or Fedora Repository Server" protected static String FEDORA_USER = null; protected static String FEDORA_PWD = null; protected static String SOLR_HOST = null; protected static int SOLR_PORT = 8080; private static String SOLR_REALM = null; private String FEDORA_DATASTREAM_GET_CMD = null; /** * Load the fedora host and solr host information from the program properties file.<br><br> * REQUIRES that FEDORA_HOST, * FEDORA_PORT, FEDORA_USER, FEDORA_PWD, SOLR_HOST and SOLR_PORT are defined * in the batchIngest.properties file!!<br> * * @see FedoraAppConstants#getProgramPropertiesURL() * @see FedoraAppConstants.PROPERTIES_FILE_NAME */ public ProxyController() { if (FEDORA_HOST == null || FEDORA_USER == null || FEDORA_PWD == null || SOLR_HOST == null) { FEDORA_HOST = ProgramProperties .getInstance( FedoraProxyConstants.getServletContextListener().getFedoraProxyProgramPropertiesURL()) .getProperty(FedoraProxyConstants.FedoraProxy_FEDORA_HOST_PROPERTY); FEDORA_PORT = Integer.valueOf(ProgramProperties .getInstance( FedoraProxyConstants.getServletContextListener().getFedoraProxyProgramPropertiesURL()) .getProperty(FedoraProxyConstants.FedoraProxy_FEDORA_PORT_PROPERTY)); FEDORA_USER = ProgramProperties .getInstance( FedoraProxyConstants.getServletContextListener().getFedoraProxyProgramPropertiesURL()) .getProperty(FedoraProxyConstants.FedoraProxy_FEDORA_USER_PROPERTY); FEDORA_PWD = ProgramProperties .getInstance( FedoraProxyConstants.getServletContextListener().getFedoraProxyProgramPropertiesURL()) .getProperty(FedoraProxyConstants.FedoraProxy_FEDORA_PWD_PROPERTY); SOLR_HOST = ProgramProperties .getInstance( FedoraProxyConstants.getServletContextListener().getFedoraProxyProgramPropertiesURL()) .getProperty(FedoraProxyConstants.SOLR_HOST_PROPERTY); SOLR_PORT = Integer.valueOf(ProgramProperties .getInstance( FedoraProxyConstants.getServletContextListener().getFedoraProxyProgramPropertiesURL()) .getProperty(FedoraProxyConstants.SOLR_PORT_PROPERTY)); } } /** * Get the collection pid based on the web-site portion of the URL. This is * then used to make sure that datastream's are only served up for objects * within the collection. The collection PID is mapped to the web site name * in the websiteCollection.Properties file. * * @param webSite * @return the collection pid or null if not found. */ protected String getCollectionPidForWebSite(String webSite) { ProgramProperties myFile = getWebsiteCollectionPropertesFile(); String collectionPid = myFile.getProperty(webSite); return collectionPid; } static public ProgramProperties getWebsiteCollectionPropertesFile() { if (websiteCollectionPropertiesFile == null) { websiteCollectionPropertiesFile = new ProgramFileProperties( new File(FedoraProxyConstants.getServletContextListener().getAppRealPath() + FedoraProxyServletContextListener.CONFIG_RELATIVE_URI_PATH + FedoraProxyConstants.WEBSITE_COLLECTION_FILE)); } return websiteCollectionPropertiesFile; } public static void setDefaultHeaders(HttpMethod method) { method.setRequestHeader("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); method.setRequestHeader("Connection", "keep-alive"); method.setRequestHeader("Accept-Encoding", "gzip,deflate,sdch"); method.setRequestHeader("Accept-Language", "en-US,en;q=0.8"); method.setRequestHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3"); method.setRequestHeader("Cache-Control", "max-age=0"); method.getParams().setCookiePolicy(CookiePolicy.RFC_2109); // response.setCharacterEncoding( "gzip,deflate" ); // response.setHeader( "Accept-Charset", // "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); // response.setHeader( "Accept-Language", "en-us,en;q=0.5" ); } /** * * @param theClient * @param authenicate true/false set preemptive authentication */ public static void setAdrCredentials(HttpClient theClient, boolean authenicate) { theClient.getState().setCredentials(new AuthScope(FEDORA_HOST, FEDORA_PORT, FEDORA_REALM), new UsernamePasswordCredentials(FEDORA_USER, FEDORA_PWD)); // method.setDoAuthentication(authenicate); theClient.getParams().setAuthenticationPreemptive(true); } /** * Call the HttpMethod and write all results and status to the HTTP response * object. * * THIS IS THE REQUEST WE NEED TO DUPLICATE GET * /fedora/get/codu:72/ECTD_test_1_access.pdf HTTP/1.1 Host: localhost:8080 * Connection: keep-alive Accept: * application/xml,application/xhtml+xml,text/ * html;q=0.9,text/plain;q=0.8,image/png,*;q=0.5 User-Agent: Mozilla/5.0 * (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) * Chrome/8.0.552.215 Safari/534.10 Accept-Encoding: gzip,deflate,sdch * Accept-Language: en-US,en;q=0.8 Accept-Charset: * ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: fez_list=YjowOw%3D%3D * * ACTUAL SENT GET /fedora/get/codu:72/ECTD_test_1_access.pdf HTTP/1.1 * Accept: * application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q * =0.8,image/png,*;q=0.5 Connection: keep-alive Accept-Encoding: * gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: * ISO-8859-1,utf-8;q=0.7,*;q=0.3 : User-Agent: Jakarta * Commons-HttpClient/3.1 Host: localhost:8080 * * @param proxyCommand * @param response * @param authenicate true to set Preemptive authentication */ public static void executeMethod(String proxyCommand, HttpServletResponse response, boolean authenicate) { HttpClient theClient = new HttpClient(); HttpMethod method = new GetMethod(proxyCommand); setDefaultHeaders(method); setAdrCredentials(theClient, authenicate); try { theClient.executeMethod(method); response.setStatus(method.getStatusCode()); // Set the content type, as it comes from the server Header[] headers = method.getResponseHeaders(); for (Header header : headers) { if ("Content-Type".equalsIgnoreCase(header.getName())) { response.setContentType(header.getValue()); } /** * Copy all headers, except Transfer-Encoding which is getting set * set elsewhere. At this point response.containsHeader( * "Transfer-Encoding" ) is false, however it is getting set twice * according to wireshark, therefore we do not set it here. */ if (!header.getName().equalsIgnoreCase("Transfer-Encoding")) { response.setHeader(header.getName(), header.getValue()); } } // Write the body, flush and close InputStream is = method.getResponseBodyAsStream(); BufferedInputStream bis = new BufferedInputStream(is); StringBuffer sb = new StringBuffer(); byte[] bytes = new byte[8192]; // reading as chunk of 8192 bytes int count = bis.read(bytes); while (count != -1 && count <= 8192) { response.getOutputStream().write(bytes, 0, count); count = bis.read(bytes); } bis.close(); response.getOutputStream().flush(); response.getOutputStream().close(); } catch (Exception e) { logger.error(e.getMessage()); } finally { method.releaseConnection(); } } /** * This is the top-level function for calling the proxy specified in the proxyCommand. All results and status are written to * the HTTP response object, which is returned to the calling client. * * @param webSite used to retrieve the webSite collection pid from the webSiteCollection.properties file, if not found a response status of 404 is returned. * @param objectPID optional, can be null, if set we verify the object is contained within the webSite collection. * if it isn't, a response status of 404 is returned. * @param proxyCommand * @param response the http response object. */ public void performProxyCall(String webSite, String objectPID, String proxyCommand, HttpServletResponse response) { String collectionPid = this.getCollectionPidForWebSite(webSite); boolean exists = true; if (objectPID != null) { exists = ResourceIndexUtils.isObjectInCollection(FEDORA_HOST, FEDORA_PORT, FEDORA_USER, FEDORA_PWD, collectionPid, objectPID); } if (collectionPid != null && exists) { logger.info("Proxy command recieved:" + proxyCommand); executeMethod(proxyCommand, response, true); } else { response.setStatus(404); } } }