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