org.deegree.ogcwebservices.wass.wss.operation.DoServiceHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.deegree.ogcwebservices.wass.wss.operation.DoServiceHandler.java

Source

//$HeadURL$
/*----------------------------------------------------------------------------
 This file is part of deegree, http://deegree.org/
 Copyright (C) 2001-2009 by:
   Department of Geography, University of Bonn
 and
   lat/lon GmbH
    
 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.
 This library 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 Lesser General Public License for more
 details.
 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 Contact information:
    
 lat/lon GmbH
 Aennchenstr. 19, 53177 Bonn
 Germany
 http://lat-lon.de/
    
 Department of Geography, University of Bonn
 Prof. Dr. Klaus Greve
 Postfach 1147, 53001 Bonn
 Germany
 http://www.geographie.uni-bonn.de/deegree/
    
 e-mail: info@deegree.org
----------------------------------------------------------------------------*/

package org.deegree.ogcwebservices.wass.wss.operation;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.deegree.enterprise.WebUtils;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.CharsetUtils;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.i18n.Messages;
import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilities;
import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilitiesDocument;
import org.deegree.ogcwebservices.getcapabilities.HTTP;
import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
import org.deegree.ogcwebservices.getcapabilities.OGCCapabilitiesDocument;
import org.deegree.ogcwebservices.getcapabilities.Operation;
import org.deegree.ogcwebservices.wass.exceptions.DoServiceException;
import org.deegree.ogcwebservices.wcs.getcapabilities.WCSCapabilities;
import org.deegree.ogcwebservices.wcs.getcapabilities.WCSCapabilitiesDocument;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
import org.deegree.owscommon_new.DCP;
import org.xml.sax.SAXException;

/**
 * This base class will makes the connection to the requested service on the "hidden" machines.
 * Every Subclass must implement the handleRequest method to check the credentials. A call to
 * another service can only be made, if the requestAllowed values is true;
 *
 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
 *
 * @author last edited by: $Author$
 *
 * @version 2.0, $Revision$, $Date$
 *
 * @since 2.0
 */

public abstract class DoServiceHandler {

    private ILogger LOG = LoggerFactory.getLogger(DoServiceHandler.class);

    private boolean requestAllowed = false;

    /**
     * Each subclass must implement this method, appropriate to its needs. For example password
     * handling.
     *
     * @param request
     *            the request the client sent to the secured service
     * @throws DoServiceException
     *             if an error occured while processing the clients credentials.
     */
    public abstract void handleRequest(DoService request) throws DoServiceException;

    /**
     * @return Returns the requestAllowed.
     */
    public boolean requestAllowed() {
        return requestAllowed;
    }

    /**
     * @param isAllowed
     *            The requestAllowed to set.
     */
    public void setRequestAllowed(boolean isAllowed) {
        this.requestAllowed = isAllowed;
    }

    /**
     * This method does the actual request to the secured service. It returns the response of the
     * secured service as an inputstream. It also replace the GetCapabilities request - responses
     * with the facadeurl given by the client.
     *
     * @param request
     *            send by the client a DoService Request.
     * @param securedService
     *            the service for which this wss is proxying, must be put in the deegreeparams of
     *            the configuration file.
     * @param requestedCharset
     *            this wss uses, also read from the deegreeparams in the configuration file.
     * @param timeout
     *            how long to wait for a response. Service dependable therefor also read from the
     *            deegreeparams in the config file.
     * @param securedServiceName
     *            the name of the service for which we are proxying -> config.
     * @return the http response of the secured service as an inputstream.
     * @throws DoServiceException
     *             if an error occurs wile sending the request or treating the response. see
     *             org.deegree.ogcwebservices.csw.manager.CatalogueHarvester#getNextMetadataRecord
     */
    public DoServiceResponse sendRequest(DoService request, URL securedService, String requestedCharset,
            int timeout, String securedServiceName) throws DoServiceException {
        if (requestAllowed) {

            Header[] headers = null;
            InputStream body = null;
            Header[] footers = null;
            String proxyRequest = null;
            try {
                proxyRequest = URLDecoder.decode(request.getPayload(), CharsetUtils.getSystemCharset());
            } catch (UnsupportedEncodingException e) {
                LOG.logError(e.getMessage(), e);
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_INTERNAL", "WSS"));
            }
            LOG.logDebug("encoded proxyrequest: " + request.getPayload() + "\ndecoded proxy: " + proxyRequest);
            String dcp = request.getDcp();
            HttpClient client = new HttpClient();
            client = WebUtils.enableProxyUsage(client, securedService);
            StringRequestEntity requestEntity = null;
            HttpClientParams params = client.getParams();
            params.setSoTimeout(timeout);
            HttpMethod requestMethod = null;
            try {
                String contentType = null;
                for (RequestParameter param : request.getRequestParameters()) {
                    if (param.getId().toLowerCase().trim().contains("mime-type"))
                        contentType = param.getParameter();
                }
                requestEntity = new StringRequestEntity(proxyRequest, contentType, requestedCharset);
            } catch (UnsupportedEncodingException e1) {
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_ENCODING_NOT_SUPPORTED", "WSS"));
            }
            if (dcp.equalsIgnoreCase("http_post")) {

                // the url to the service must be written in the deegreeparams in the configuration
                // xml
                requestMethod = new PostMethod(securedService.toExternalForm());
                ((PostMethod) requestMethod).setRequestEntity(requestEntity);
            } else if (dcp.equalsIgnoreCase("http_get")) {
                requestMethod = new GetMethod(securedService.toExternalForm());
                requestMethod.setQueryString(proxyRequest);
            } else {
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_NOT_POST_OR_GET", "WSS"));
            }
            // getDataRequest
            try {
                // make header parameters of the requestParameters.
                for (RequestParameter param : request.getRequestParameters()) {
                    if (!param.getId().toLowerCase().trim().contains("mime-type"))// Contenttype
                        requestMethod.addRequestHeader(param.getId(), param.getParameter());
                }
                // Call the secured service
                client.executeMethod(requestMethod);
                headers = requestMethod.getResponseHeaders();
                footers = requestMethod.getResponseFooters();
                body = requestMethod.getResponseBodyAsStream();

                if (body == null)
                    throw new DoServiceException(Messages.getMessage("WASS_ERROR_GOT_NO_RESPONSE", "WSS"));
            } catch (HttpException e) {
                LOG.logError(e.getMessage(), e);
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_EXCEPTION_IN_RESPONSE", "WSS"));
            } catch (IOException e) {
                LOG.logError(e.getMessage(), e);
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_IN_TRANSPORT", "WSS"));
            }
            try {
                // Replace the given urls with the facadeurls if it is a GetCapabilities request
                if (proxyRequest.trim().contains("GetCapabilities")) {
                    Operation[] operations = null;
                    OGCCapabilitiesDocument doc = null;
                    /*
                     * For now just check these service, others may be "secured" in the future.
                     */
                    if ("WFS".equals(securedServiceName)) {
                        doc = new WFSCapabilitiesDocument();
                        doc.load(body, securedService.toExternalForm());
                        WFSCapabilities cap = (WFSCapabilities) doc.parseCapabilities();
                        operations = cap.getOperationsMetadata().getOperations();
                        replaceFacadeURL(operations, request.getFacadeURL());
                        doc = org.deegree.ogcwebservices.wfs.XMLFactory.export(cap);
                    } else if (("WMS").equals(securedServiceName)) {
                        doc = new WMSCapabilitiesDocument();
                        doc.load(body, securedService.toExternalForm());
                        doc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument(doc.getRootElement());
                        WMSCapabilities cap = (WMSCapabilities) doc.parseCapabilities();
                        org.deegree.owscommon_new.Operation[] ops = cap.getOperationMetadata().getOperations()
                                .toArray(new org.deegree.owscommon_new.Operation[0]);
                        replaceFacadeURL(ops, request.getFacadeURL());
                        doc = org.deegree.ogcwebservices.wms.XMLFactory.export(cap);
                    } else if (("WCS").equals(securedServiceName)) {
                        doc = new WCSCapabilitiesDocument();
                        doc.load(body, securedService.toExternalForm());
                        WCSCapabilities cap = (WCSCapabilities) doc.parseCapabilities();
                        operations = cap.getCapabilitiy().getOperations().getOperations();
                        replaceFacadeURL(operations, request.getFacadeURL());
                        doc = org.deegree.ogcwebservices.wcs.XMLFactory.export(cap);
                    } else if (("CSW").equals(securedServiceName)) {
                        doc = new CatalogueCapabilitiesDocument();
                        doc.load(body, securedService.toExternalForm());
                        CatalogueCapabilities cap = (CatalogueCapabilities) doc.parseCapabilities();
                        operations = cap.getOperationsMetadata().getOperations();
                        replaceFacadeURL(operations, request.getFacadeURL());
                        doc = org.deegree.ogcwebservices.csw.XMLFactory_2_0_0.export(cap, null);
                    }

                    body = new ByteArrayInputStream(doc.getAsString().getBytes());
                }
            } catch (IOException e) {
                LOG.logError(e.getMessage(), e);
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_READING_BODY", "WSS"));
            } catch (InvalidCapabilitiesException e) {
                LOG.logError(e.getMessage(), e);
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_CAPABILITIES_RESPONSE", "WSS"));
            } catch (SAXException e) {
                LOG.logError(e.getMessage(), e);
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_FACADE_URL", "WSS"));
            } catch (XMLParsingException e) {
                LOG.logError(e.getMessage(), e);
                throw new DoServiceException(Messages.getMessage("WASS_ERROR_READING_BODY", "WSS"));
            }
            return new DoServiceResponse(headers, body, footers);
        }

        return null;
    }

    private void replaceFacadeURL(Operation[] operations, URI facadeURI) {

        if (operations != null && facadeURI != null) {
            for (int i = 0; i < operations.length; i++) {
                setNewOnlineResource(operations[i], facadeURI);
            }
        }
    }

    private void replaceFacadeURL(org.deegree.owscommon_new.Operation[] operations, URI facadeURI) {

        if (operations != null && facadeURI != null) {
            for (int i = 0; i < operations.length; i++) {
                setNewOnlineResource(operations[i], facadeURI);
            }
        }
    }

    /**
     * Resets all the url in the response body with the facade urls
     *
     * @param op
     *            the operation which has the secured service url in it
     * @param facadeURI
     *            the url of this wss.
     */
    private void setNewOnlineResource(Operation op, URI facadeURI) {

        if (op.getDCPs() != null) {
            for (int i = 0; i < op.getDCPs().length; i++) {
                HTTP http = (HTTP) op.getDCPs()[i].getProtocol();
                try {
                    if (http.getGetOnlineResources().length > 0) {
                        URL urls[] = new URL[http.getGetOnlineResources().length];
                        for (int k = 0; k < http.getGetOnlineResources().length; ++k)
                            urls[k] = facadeURI.toURL();

                        http.setGetOnlineResources(urls);
                    }
                    if (http.getPostOnlineResources().length > 0) {
                        URL urls[] = new URL[http.getPostOnlineResources().length];
                        for (int k = 0; k < http.getPostOnlineResources().length; ++k) {
                            urls[k] = facadeURI.toURL();
                        }

                        http.setPostOnlineResources(urls);
                    }
                } catch (MalformedURLException e1) {
                    e1.printStackTrace();
                }
            }
        }

    }

    private void setNewOnlineResource(org.deegree.owscommon_new.Operation op, URI facadeURI) {

        if (op.getDCP() != null) {
            for (DCP dcp : op.getDCP()) {
                // assuming HTTP here, SOAP won't work!
                org.deegree.owscommon_new.HTTP http = (org.deegree.owscommon_new.HTTP) dcp;
                try {
                    if (http.getGetOnlineResources().size() > 0) {
                        List<URL> urls = http.getGetOnlineResources();
                        List<URL> urlsnew = new ArrayList<URL>(urls.size());
                        for (int i = 0; i < urls.size(); ++i) {
                            urlsnew.add(facadeURI.toURL());
                        }

                        http.setGetOnlineResources(urlsnew);
                    }
                    if (http.getPostOnlineResources().size() > 0) {
                        List<URL> urls = http.getPostOnlineResources();
                        List<URL> urlsnew = new ArrayList<URL>(urls.size());
                        for (int i = 0; i < urls.size(); ++i) {
                            urlsnew.add(facadeURI.toURL());
                        }

                        http.setPostOnlineResources(urls);
                    }
                } catch (MalformedURLException e1) {
                    e1.printStackTrace();
                }
            }
        }

    }
}