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 }