001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wass/wss/operation/DoServiceHandler.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 037 package org.deegree.ogcwebservices.wass.wss.operation; 038 039 import java.io.ByteArrayInputStream; 040 import java.io.IOException; 041 import java.io.InputStream; 042 import java.io.UnsupportedEncodingException; 043 import java.net.MalformedURLException; 044 import java.net.URI; 045 import java.net.URL; 046 import java.net.URLDecoder; 047 import java.util.ArrayList; 048 import java.util.List; 049 050 import org.apache.commons.httpclient.Header; 051 import org.apache.commons.httpclient.HttpClient; 052 import org.apache.commons.httpclient.HttpException; 053 import org.apache.commons.httpclient.HttpMethod; 054 import org.apache.commons.httpclient.methods.GetMethod; 055 import org.apache.commons.httpclient.methods.PostMethod; 056 import org.apache.commons.httpclient.methods.StringRequestEntity; 057 import org.apache.commons.httpclient.params.HttpClientParams; 058 import org.deegree.enterprise.WebUtils; 059 import org.deegree.framework.log.ILogger; 060 import org.deegree.framework.log.LoggerFactory; 061 import org.deegree.framework.util.CharsetUtils; 062 import org.deegree.framework.xml.XMLParsingException; 063 import org.deegree.i18n.Messages; 064 import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilities; 065 import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilitiesDocument; 066 import org.deegree.ogcwebservices.getcapabilities.HTTP; 067 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException; 068 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilitiesDocument; 069 import org.deegree.ogcwebservices.getcapabilities.Operation; 070 import org.deegree.ogcwebservices.wass.exceptions.DoServiceException; 071 import org.deegree.ogcwebservices.wcs.getcapabilities.WCSCapabilities; 072 import org.deegree.ogcwebservices.wcs.getcapabilities.WCSCapabilitiesDocument; 073 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; 074 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument; 075 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities; 076 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument; 077 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory; 078 import org.deegree.owscommon_new.DCP; 079 import org.xml.sax.SAXException; 080 081 /** 082 * This base class will makes the connection to the requested service on the "hidden" machines. 083 * Every Subclass must implement the handleRequest method to check the credentials. A call to 084 * another service can only be made, if the requestAllowed values is true; 085 * 086 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a> 087 * 088 * @author last edited by: $Author: mschneider $ 089 * 090 * @version 2.0, $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 091 * 092 * @since 2.0 093 */ 094 095 public abstract class DoServiceHandler { 096 097 private ILogger LOG = LoggerFactory.getLogger( DoServiceHandler.class ); 098 099 private boolean requestAllowed = false; 100 101 /** 102 * Each subclass must implement this method, appropriate to its needs. For example password 103 * handling. 104 * 105 * @param request 106 * the request the client sent to the secured service 107 * @throws DoServiceException 108 * if an error occured while processing the clients credentials. 109 */ 110 public abstract void handleRequest( DoService request ) 111 throws DoServiceException; 112 113 /** 114 * @return Returns the requestAllowed. 115 */ 116 public boolean requestAllowed() { 117 return requestAllowed; 118 } 119 120 /** 121 * @param isAllowed 122 * The requestAllowed to set. 123 */ 124 public void setRequestAllowed( boolean isAllowed ) { 125 this.requestAllowed = isAllowed; 126 } 127 128 /** 129 * This method does the actual request to the secured service. It returns the response of the 130 * secured service as an inputstream. It also replace the GetCapabilities request - responses 131 * with the facadeurl given by the client. 132 * 133 * @param request 134 * send by the client a DoService Request. 135 * @param securedService 136 * the service for which this wss is proxying, must be put in the deegreeparams of 137 * the configuration file. 138 * @param requestedCharset 139 * this wss uses, also read from the deegreeparams in the configuration file. 140 * @param timeout 141 * how long to wait for a response. Service dependable therefor also read from the 142 * deegreeparams in the config file. 143 * @param securedServiceName 144 * the name of the service for which we are proxying -> config. 145 * @return the http response of the secured service as an inputstream. 146 * @throws DoServiceException 147 * if an error occurs wile sending the request or treating the response. see 148 * org.deegree.ogcwebservices.csw.manager.CatalogueHarvester#getNextMetadataRecord 149 */ 150 public DoServiceResponse sendRequest( DoService request, URL securedService, String requestedCharset, int timeout, 151 String securedServiceName ) 152 throws DoServiceException { 153 if ( requestAllowed ) { 154 155 Header[] headers = null; 156 InputStream body = null; 157 Header[] footers = null; 158 String proxyRequest = null; 159 try { 160 proxyRequest = URLDecoder.decode( request.getPayload(), CharsetUtils.getSystemCharset() ); 161 } catch ( UnsupportedEncodingException e ) { 162 LOG.logError( e.getMessage(), e ); 163 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_INTERNAL", "WSS" ) ); 164 } 165 LOG.logDebug( "encoded proxyrequest: " + request.getPayload() + "\ndecoded proxy: " + proxyRequest ); 166 String dcp = request.getDcp(); 167 HttpClient client = new HttpClient(); 168 client = WebUtils.enableProxyUsage( client, securedService ); 169 StringRequestEntity requestEntity = null; 170 HttpClientParams params = client.getParams(); 171 params.setSoTimeout( timeout ); 172 HttpMethod requestMethod = null; 173 try { 174 String contentType = null; 175 for ( RequestParameter param : request.getRequestParameters() ) { 176 if ( param.getId().toLowerCase().trim().contains( "mime-type" ) ) 177 contentType = param.getParameter(); 178 } 179 requestEntity = new StringRequestEntity( proxyRequest, contentType, requestedCharset ); 180 } catch ( UnsupportedEncodingException e1 ) { 181 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_ENCODING_NOT_SUPPORTED", "WSS" ) ); 182 } 183 if ( dcp.equalsIgnoreCase( "http_post" ) ) { 184 185 // the url to the service must be written in the deegreeparams in the configuration 186 // xml 187 requestMethod = new PostMethod( securedService.toExternalForm() ); 188 ( (PostMethod) requestMethod ).setRequestEntity( requestEntity ); 189 } else if ( dcp.equalsIgnoreCase( "http_get" ) ) { 190 requestMethod = new GetMethod( securedService.toExternalForm() ); 191 requestMethod.setQueryString( proxyRequest ); 192 } else { 193 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_NOT_POST_OR_GET", "WSS" ) ); 194 } 195 // getDataRequest 196 try { 197 // make header parameters of the requestParameters. 198 for ( RequestParameter param : request.getRequestParameters() ) { 199 if ( !param.getId().toLowerCase().trim().contains( "mime-type" ) )// Contenttype 200 requestMethod.addRequestHeader( param.getId(), param.getParameter() ); 201 } 202 // Call the secured service 203 client.executeMethod( requestMethod ); 204 headers = requestMethod.getResponseHeaders(); 205 footers = requestMethod.getResponseFooters(); 206 body = requestMethod.getResponseBodyAsStream(); 207 208 if ( body == null ) 209 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_GOT_NO_RESPONSE", "WSS" ) ); 210 } catch ( HttpException e ) { 211 LOG.logError( e.getMessage(), e ); 212 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_EXCEPTION_IN_RESPONSE", "WSS" ) ); 213 } catch ( IOException e ) { 214 LOG.logError( e.getMessage(), e ); 215 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_IN_TRANSPORT", "WSS" ) ); 216 } 217 try { 218 // Replace the given urls with the facadeurls if it is a GetCapabilities request 219 if ( proxyRequest.trim().contains( "GetCapabilities" ) ) { 220 Operation[] operations = null; 221 OGCCapabilitiesDocument doc = null; 222 /* 223 * For now just check these service, others may be "secured" in the future. 224 */ 225 if ( "WFS".equals( securedServiceName ) ) { 226 doc = new WFSCapabilitiesDocument(); 227 doc.load( body, securedService.toExternalForm() ); 228 WFSCapabilities cap = (WFSCapabilities) doc.parseCapabilities(); 229 operations = cap.getOperationsMetadata().getOperations(); 230 replaceFacadeURL( operations, request.getFacadeURL() ); 231 doc = org.deegree.ogcwebservices.wfs.XMLFactory.export( cap ); 232 } else if ( ( "WMS" ).equals( securedServiceName ) ) { 233 doc = new WMSCapabilitiesDocument(); 234 doc.load( body, securedService.toExternalForm() ); 235 doc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( doc.getRootElement() ); 236 WMSCapabilities cap = (WMSCapabilities) doc.parseCapabilities(); 237 org.deegree.owscommon_new.Operation[] ops = cap.getOperationMetadata().getOperations().toArray( 238 new org.deegree.owscommon_new.Operation[0] ); 239 replaceFacadeURL( ops, request.getFacadeURL() ); 240 doc = org.deegree.ogcwebservices.wms.XMLFactory.export( cap ); 241 } else if ( ( "WCS" ).equals( securedServiceName ) ) { 242 doc = new WCSCapabilitiesDocument(); 243 doc.load( body, securedService.toExternalForm() ); 244 WCSCapabilities cap = (WCSCapabilities) doc.parseCapabilities(); 245 operations = cap.getCapabilitiy().getOperations().getOperations(); 246 replaceFacadeURL( operations, request.getFacadeURL() ); 247 doc = org.deegree.ogcwebservices.wcs.XMLFactory.export( cap ); 248 } else if ( ( "CSW" ).equals( securedServiceName ) ) { 249 doc = new CatalogueCapabilitiesDocument(); 250 doc.load( body, securedService.toExternalForm() ); 251 CatalogueCapabilities cap = (CatalogueCapabilities) doc.parseCapabilities(); 252 operations = cap.getOperationsMetadata().getOperations(); 253 replaceFacadeURL( operations, request.getFacadeURL() ); 254 doc = org.deegree.ogcwebservices.csw.XMLFactory_2_0_0.export( cap, null ); 255 } 256 257 body = new ByteArrayInputStream( doc.getAsString().getBytes() ); 258 } 259 } catch ( IOException e ) { 260 LOG.logError( e.getMessage(), e ); 261 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_READING_BODY", "WSS" ) ); 262 } catch ( InvalidCapabilitiesException e ) { 263 LOG.logError( e.getMessage(), e ); 264 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_CAPABILITIES_RESPONSE", "WSS" ) ); 265 } catch ( SAXException e ) { 266 LOG.logError( e.getMessage(), e ); 267 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_FACADE_URL", "WSS" ) ); 268 } catch ( XMLParsingException e ) { 269 LOG.logError( e.getMessage(), e ); 270 throw new DoServiceException( Messages.getMessage( "WASS_ERROR_READING_BODY", "WSS" ) ); 271 } 272 return new DoServiceResponse( headers, body, footers ); 273 } 274 275 return null; 276 } 277 278 private void replaceFacadeURL( Operation[] operations, URI facadeURI ) { 279 280 if ( operations != null && facadeURI != null ) { 281 for ( int i = 0; i < operations.length; i++ ) { 282 setNewOnlineResource( operations[i], facadeURI ); 283 } 284 } 285 } 286 287 private void replaceFacadeURL( org.deegree.owscommon_new.Operation[] operations, URI facadeURI ) { 288 289 if ( operations != null && facadeURI != null ) { 290 for ( int i = 0; i < operations.length; i++ ) { 291 setNewOnlineResource( operations[i], facadeURI ); 292 } 293 } 294 } 295 296 /** 297 * Resets all the url in the response body with the facade urls 298 * 299 * @param op 300 * the operation which has the secured service url in it 301 * @param facadeURI 302 * the url of this wss. 303 */ 304 private void setNewOnlineResource( Operation op, URI facadeURI ) { 305 306 if ( op.getDCPs() != null ) { 307 for ( int i = 0; i < op.getDCPs().length; i++ ) { 308 HTTP http = (HTTP) op.getDCPs()[i].getProtocol(); 309 try { 310 if ( http.getGetOnlineResources().length > 0 ) { 311 URL urls[] = new URL[http.getGetOnlineResources().length]; 312 for ( int k = 0; k < http.getGetOnlineResources().length; ++k ) 313 urls[k] = facadeURI.toURL(); 314 315 http.setGetOnlineResources( urls ); 316 } 317 if ( http.getPostOnlineResources().length > 0 ) { 318 URL urls[] = new URL[http.getPostOnlineResources().length]; 319 for ( int k = 0; k < http.getPostOnlineResources().length; ++k ) { 320 urls[k] = facadeURI.toURL(); 321 } 322 323 http.setPostOnlineResources( urls ); 324 } 325 } catch ( MalformedURLException e1 ) { 326 e1.printStackTrace(); 327 } 328 } 329 } 330 331 } 332 333 private void setNewOnlineResource( org.deegree.owscommon_new.Operation op, URI facadeURI ) { 334 335 if ( op.getDCP() != null ) { 336 for ( DCP dcp : op.getDCP() ) { 337 // assuming HTTP here, SOAP won't work! 338 org.deegree.owscommon_new.HTTP http = (org.deegree.owscommon_new.HTTP) dcp; 339 try { 340 if ( http.getGetOnlineResources().size() > 0 ) { 341 List<URL> urls = http.getGetOnlineResources(); 342 List<URL> urlsnew = new ArrayList<URL>( urls.size() ); 343 for ( int i = 0; i < urls.size(); ++i ) { 344 urlsnew.add( facadeURI.toURL() ); 345 } 346 347 http.setGetOnlineResources( urlsnew ); 348 } 349 if ( http.getPostOnlineResources().size() > 0 ) { 350 List<URL> urls = http.getPostOnlineResources(); 351 List<URL> urlsnew = new ArrayList<URL>( urls.size() ); 352 for ( int i = 0; i < urls.size(); ++i ) { 353 urlsnew.add( facadeURI.toURL() ); 354 } 355 356 http.setPostOnlineResources( urls ); 357 } 358 } catch ( MalformedURLException e1 ) { 359 e1.printStackTrace(); 360 } 361 } 362 } 363 364 } 365 }