//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wass/wss/operation/DoServiceHandler.java,v 1.18 2006/10/17 20:31:20 poth Exp $ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/exse/ lat/lon GmbH http://www.lat-lon.de 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: Andreas Poth lat/lon GmbH Aennchenstraße 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Jens Fitzke lat/lon GmbH Aennchenstraße 19 53177 Bonn Germany E-Mail: jens.fitzke@uni-bonn.de ---------------------------------------------------------------------------*/ 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 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.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.framework.util.CharsetUtils; 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.common.Messages; 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.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: poth $ * * @version 2.0, $Revision: 1.18 $, $Date: 2006/10/17 20:31:20 $ * * @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 ) { LOG.entering(); 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.format( "ogcwebservices.wass.ERROR_INTERNAL", "WSS" ) ); } LOG.logDebug( "encoded proxyrequest: " + request.getPayload() + "\ndecoded proxy: " + proxyRequest ); String dcp = request.getDcp(); HttpClient client = new HttpClient(); 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.format( "ogcwebservices.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.format( "ogcwebservices.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.format( "ogcwebservices.wass.ERROR_GOT_NO_RESPONSE", "WSS" ) ); } catch ( HttpException e ) { LOG.logError( e.getMessage(), e ); throw new DoServiceException( Messages.format( "ogcwebservices.wass.ERROR_EXCEPTION_IN_RESPONSE", "WSS" ) ); } catch ( IOException e ) { LOG.logError( e.getMessage(), e ); throw new DoServiceException( Messages.format( "ogcwebservices.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() ); WMSCapabilities cap = (WMSCapabilities) doc.parseCapabilities(); operations = cap.getOperationMetadata().getOperations().toArray( new Operation[0] ); replaceFacadeURL( operations, 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.export( cap, null ); } body = new ByteArrayInputStream( doc.getAsString().getBytes() ); } } catch ( IOException e ) { LOG.logError( e.getMessage(), e ); e.printStackTrace(); throw new DoServiceException( Messages.format( "ogcwebservices.wass.ERROR_READING_BODY", "WSS" ) ); } catch ( InvalidCapabilitiesException e ) { LOG.logError( e.getMessage(), e ); e.printStackTrace(); throw new DoServiceException( Messages.format( "ogcwebservices.wass.ERROR_CAPABILITIES_RESPONSE", "WSS" ) ); } catch ( SAXException e ) { LOG.logError( e.getMessage(), e ); e.printStackTrace(); throw new DoServiceException( Messages.format( "ogcwebservices.wass.ERROR_FACADE_URL", "WSS" ) ); } DoServiceResponse doServiceResponse = new DoServiceResponse( headers, body, footers ); LOG.exiting(); return doServiceResponse; } return null; } private void replaceFacadeURL( Operation[] operations, URI FacadeURI ) { LOG.entering(); if ( operations != null ) { for ( int i = 0; i < operations.length; i++ ) { setNewOnlineResource( operations[i], FacadeURI ); } } LOG.exiting(); } /** * 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 ) { LOG.entering(); 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(); } } } LOG.exiting(); } } /*************************************************************************************************** * Changes to this class. What the people have been up to: $Log: DoServiceHandler.java,v $ * Changes to this class. What the people have been up to: Revision 1.18 2006/10/17 20:31:20 poth * Changes to this class. What the people have been up to: *** empty log message *** * Changes to this class. What the people have been up to: * Changes to this class. What the people have been up to: Revision 1.17 2006/08/24 06:42:16 poth * Changes to this class. What the people have been up to: File header corrected * Changes to this class. What the people have been up to: * Changes to this class. What the people have been up to: Revision 1.16 2006/08/22 10:25:01 schmitz * Changes to this class. What the people have been up to: Updated the WMS to use the new OWS common package. * Changes to this class. What the people have been up to: Updated the rest of deegree to use the new data classes returned * Changes to this class. What the people have been up to: by the updated WMS methods/capabilities. * Changes to this class. What the people have been up to: * Changes to this class. What the people have been up to: Revision 1.15 2006/07/07 15:36:21 mschneider * Changes to this class. What the people have been up to: Fixed wrong cast. * Changes to this class. What the people have been up to: * Changes to this class. What the people have been up to: Revision 1.14 2006/06/26 15:02:58 bezema * Changes to this class. What the people have been up to: Finished the wass * Changes to this class. What the people have been up to: * Changes to this class. What the people have been up to: Revision 1.13 2006/06/23 13:53:48 schmitz * Changes to this class. What the people have been up to: Externalized all Strings, fixed up some exceptions and messages, reviewed/fixed some code. * Changes to this class. What the people have been up to: Changes * to this class. What the people have been up to: Revision 1.12 2006/06/20 15:31:05 bezema Changes * to this class. What the people have been up to: It looks like the completion of wss. was needs * further checking in a tomcat environment. The Strings must still be externalized. Logging is * done, so is the formatting. Changes to this class. What the people have been up to: Changes to * this class. What the people have been up to: Revision 1.11 2006/06/19 10:24:11 bezema Changes to * this class. What the people have been up to: LIttle error message correction Changes to this * class. What the people have been up to: Changes to this class. What the people have been up to: * Revision 1.10 2006/06/16 15:01:05 schmitz Changes to this class. What the people have been up to: * Fixed the WSS to work with all kinds of operation tests. It checks out Changes to this class. * What the people have been up to: with both XML and KVP requests. Changes to this class. What the * people have been up to: Changes to this class. What the people have been up to: Revision 1.9 * 2006/06/13 15:19:11 bezema Changes to this class. What the people have been up to: Removed * includes -> lesser warnings Changes to this class. What the people have been up to: Changes to * this class. What the people have been up to: Revision 1.8 2006/06/13 15:16:18 bezema Changes to * this class. What the people have been up to: DoService Test seems to work Changes to this class. * What the people have been up to: Changes to this class. What the people have been up to: Revision * 1.7 2006/06/12 12:16:24 bezema Changes to this class. What the people have been up to: Little * rearanging of the GetSession classes, DoService should be ready updating some errors Changes to * this class. What the people have been up to: Changes to this class. What the people have been up * to: Revision 1.6 2006/06/06 15:28:05 bezema Changes to this class. What the people have been up * to: Added a "null" prefix check in xmltools so that it, added a characterset to the deegreeparams * and the WSS::DoService class is almost done Changes to this class. What the people have been up * to: Changes to this class. What the people have been up to: Revision 1.5 2006/05/30 15:11:28 * bezema Changes to this class. What the people have been up to: Working on the postclient from * apachecommons to place a request to the services behind the wss proxy Changes to this class. What * the people have been up to: Revision 1.4 2006/05/30 12:46:33 bezema DoService is now handled * **************************************************************************************************/