View Javadoc

1   /* 
2    * Copyright (c) 2005-2011, Fraunhofer-Gesellschaft
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are
7    * met:
8    * 
9    * (1) Redistributions of source code must retain the above copyright
10   *     notice, this list of conditions and the disclaimer at the end.
11   *     Redistributions in binary form must reproduce the above copyright
12   *     notice, this list of conditions and the following disclaimer in
13   *     the documentation and/or other materials provided with the
14   *     distribution.
15   * 
16   * (2) Neither the name of Fraunhofer nor the names of its
17   *     contributors may be used to endorse or promote products derived
18   *     from this software without specific prior written permission.
19   * 
20   * DISCLAIMER
21   * 
22   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   *  
34   */
35  package org.ogf.graap.wsag.client.wsrf.impl;
36  
37  import java.util.Properties;
38  
39  import javax.xml.namespace.QName;
40  
41  import org.apache.log4j.Logger;
42  import org.apache.muse.util.xml.XmlUtils;
43  import org.apache.muse.ws.addressing.WsaConstants;
44  import org.apache.muse.ws.addressing.soap.SoapFault;
45  import org.apache.xmlbeans.XmlException;
46  import org.apache.xmlbeans.XmlObject;
47  import org.apache.xmlbeans.XmlOptions;
48  import org.apache.xmlbeans.XmlString;
49  import org.ogf.graap.wsag.api.AgreementOffer;
50  import org.ogf.graap.wsag.api.WsagConstants;
51  import org.ogf.graap.wsag.api.exceptions.AgreementFactoryException;
52  import org.ogf.graap.wsag.api.exceptions.NegotiationFactoryException;
53  import org.ogf.graap.wsag.api.exceptions.ResourceUnavailableException;
54  import org.ogf.graap.wsag.api.exceptions.ResourceUnknownException;
55  import org.ogf.graap.wsag.api.security.ISecurityProperties;
56  import org.ogf.graap.wsag.client.api.AgreementClient;
57  import org.ogf.graap.wsag.client.api.NegotiationClient;
58  import org.ogf.graap.wsag.client.wsrf.WsrfAgreementClient;
59  import org.ogf.graap.wsag.client.wsrf.WsrfNegotiationClient;
60  import org.ogf.schemas.graap.wsAgreement.AgreementFactoryPropertiesType;
61  import org.ogf.schemas.graap.wsAgreement.AgreementTemplateType;
62  import org.ogf.schemas.graap.wsAgreement.AgreementType;
63  import org.ogf.schemas.graap.wsAgreement.ContinuingFaultDocument;
64  import org.ogf.schemas.graap.wsAgreement.CreateAgreementInputType;
65  import org.ogf.schemas.graap.wsAgreement.CreateAgreementResponseDocument;
66  import org.ogf.schemas.graap.wsAgreement.CreatePendingAgreementInputType;
67  import org.ogf.schemas.graap.wsAgreement.CreatePendingAgreementOutputType;
68  import org.ogf.schemas.graap.wsAgreement.CreatePendingAgreementResponseDocument;
69  import org.ogf.schemas.graap.wsAgreement.NoncriticalExtensionType;
70  import org.ogf.schemas.graap.wsAgreement.negotiation.InitiateNegotiationInputDocument;
71  import org.ogf.schemas.graap.wsAgreement.negotiation.InitiateNegotiationInputType;
72  import org.ogf.schemas.graap.wsAgreement.negotiation.InitiateNegotiationOutputDocument;
73  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationContextType;
74  import org.w3.x2005.x08.addressing.EndpointReferenceType;
75  import org.w3c.dom.Element;
76  
77  /**
78   * Default implementation of an agreement factory service client.
79   * 
80   * @see AgreementFactoryService
81   * @author Oliver Waeldrich
82   * 
83   */
84  public class WsrfAgreementFactoryService extends WsrfResourceClient
85  {
86  
87      private static final Logger LOG = Logger.getLogger( WsrfAgreementFactoryService.class );
88  
89      /**
90       * Instantiates an agreement factory service client for the given EPR.
91       * 
92       * @param epr
93       *            the agreement factory service endpoint reference
94       * 
95       * @param securityProperties
96       *            the security properties to use
97       */
98      public WsrfAgreementFactoryService( EndpointReferenceType epr, Properties properties,
99                                                ISecurityProperties securityProperties )
100     {
101         super( epr, properties, securityProperties );
102     }
103 
104     /**
105      * {@inheritDoc}
106      */
107     public WsrfResourceClient getWebServiceClient()
108     {
109         return this;
110     }
111 
112     /**
113      * {@inheritDoc}
114      */
115     public AgreementClient createAgreement( AgreementOffer offer )
116         throws AgreementFactoryException, ResourceUnavailableException, ResourceUnknownException
117     {
118         try
119         {
120             CreateAgreementInputType request = CreateAgreementInputType.Factory.newInstance();
121 
122             if ( offer.getInitiatorEPR() != null )
123             {
124                 request.setInitiatorAgreementEPR( offer.getInitiatorEPR() );
125             }
126 
127             AgreementType agreement = request.addNewAgreementOffer();
128             agreement.setName( offer.getName() );
129             agreement.setContext( offer.getContext() );
130             agreement.setTerms( offer.getTerms() );
131 
132             Element inputType =
133                 XmlUtils.createElement( WsagConstants.WSAG_CREATE_AGREEMENT_INPUT_QNAME, request.getDomNode() );
134             Element body = XmlUtils.createElement( WsagConstants.WSAG_CREATE_AGREEMENT_QNAME );
135             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
136             Element response = invoke( WsagConstants.WSAG_CREATE_AGREEMENT_ACTION, body );
137 
138             CreateAgreementResponseDocument respDoc =
139                 CreateAgreementResponseDocument.Factory.parse( response );
140 
141             EndpointReferenceType agreementEPR =
142                 respDoc.getCreateAgreementResponse().getCreatedAgreementEPR();
143             ISecurityProperties securityProperties = getSecurityProperties().clone();
144 
145             AgreementClient createdAgreement =
146                 new WsrfAgreementClient( agreementEPR, getProperties(), securityProperties );
147 
148             return createdAgreement;
149         }
150         catch ( SoapFault e )
151         {
152             handleCreateAgreementFault( e );
153             throw new ResourceUnavailableException( e );
154         }
155         catch ( XmlException e )
156         {
157             throw new ResourceUnavailableException( e );
158         }
159         catch ( Exception e )
160         {
161             throw new ResourceUnavailableException( e );
162         }
163     }
164 
165     /**
166      * {@inheritDoc}
167      */
168     public AgreementClient createPendingAgreement( AgreementOffer offer )
169         throws AgreementFactoryException, ResourceUnknownException, ResourceUnavailableException
170     {
171         return createPendingAgreement( offer, null );
172     }
173 
174     /**
175      * {@inheritDoc}
176      */
177     public AgreementClient createPendingAgreement( AgreementOffer offer, EndpointReferenceType acceptanceEPR )
178         throws AgreementFactoryException, ResourceUnknownException, ResourceUnavailableException
179     {
180         try
181         {
182             CreatePendingAgreementInputType request = CreatePendingAgreementInputType.Factory.newInstance();
183 
184             if ( offer.getInitiatorEPR() != null )
185             {
186                 request.setInitiatorAgreementEPR( offer.getInitiatorEPR() );
187             }
188 
189             if ( acceptanceEPR != null )
190             {
191                 request.setAgreementAcceptanceEPR( acceptanceEPR );
192             }
193 
194             AgreementType agreement = request.addNewAgreementOffer();
195             agreement.setName( offer.getName() );
196             agreement.setContext( offer.getContext() );
197             agreement.setTerms( offer.getTerms() );
198 
199             Element inputType =
200                 XmlUtils.createElement( WsagConstants.WSAG_CREATE_PENDING_AGREEMENT_INPUT_QNAME,
201                     request.getDomNode() );
202             Element body = XmlUtils.createElement( WsagConstants.WSAG_CREATE_PENDING_AGREEMENT_QNAME );
203             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
204             Element response = invoke( WsagConstants.WSAG_CREATE_PENDING_AGREEMENT_ACTION, body );
205 
206             CreatePendingAgreementResponseDocument respDoc =
207                 CreatePendingAgreementResponseDocument.Factory.parse( response );
208 
209             ISecurityProperties securityProperties = getSecurityProperties().clone();
210             CreatePendingAgreementOutputType agreementEPR = respDoc.getCreatePendingAgreementResponse();
211 
212             AgreementClient createdAgreement =
213                 new WsrfAgreementClient( agreementEPR.getCreatedAgreementEPR(), getProperties(),
214                     securityProperties );
215 
216             return createdAgreement;
217         }
218         catch ( SoapFault e )
219         {
220             //
221             // the handleFault method will throw an exception
222             //
223             handleCreateAgreementFault( e );
224             throw new ResourceUnavailableException( e );
225         }
226         catch ( XmlException e )
227         {
228             throw new ResourceUnavailableException( e );
229         }
230         catch ( Exception e )
231         {
232             throw new ResourceUnavailableException( e );
233         }
234     }
235 
236     /**
237      * {@inheritDoc}
238      */
239     public NegotiationClient initiateNegotiation( NegotiationContextType context )
240         throws NegotiationFactoryException, ResourceUnknownException, ResourceUnavailableException
241     {
242         return initiateNegotiation( context, WsrfResourceClient.ANONYMOUS_EPR );
243     }
244 
245     /**
246      * Initiates a new negotiation process with a wsag4j server.
247      * 
248      * @param context
249      *            the negotiation context
250      * @param initiatorEPR
251      *            the endpoint of the wsag4j server
252      * 
253      * @return a new negotiation client
254      * 
255      * @throws NegotiationFactoryException
256      *             The negotiation process was not initiated.
257      * 
258      * @throws ResourceUnknownException
259      *             the remote resource is unknown
260      * 
261      * @throws ResourceUnavailableException
262      *             the remote resource is unavailable
263      */
264     public NegotiationClient initiateNegotiation( NegotiationContextType context,
265                                                   EndpointReferenceType initiatorEPR )
266         throws NegotiationFactoryException, ResourceUnknownException, ResourceUnavailableException
267     {
268 
269         try
270         {
271 
272             InitiateNegotiationInputDocument requestDoc =
273                 InitiateNegotiationInputDocument.Factory.newInstance();
274 
275             InitiateNegotiationInputType request = requestDoc.addNewInitiateNegotiationInput();
276 
277             request.setNegotiationContext( context );
278             request.setNoncriticalExtensionArray( new NoncriticalExtensionType[0] );
279             request.setInitiatorNegotiationEPR( initiatorEPR );
280 
281             Element body = XmlUtils.createElement( WsagConstants.WSAG_INITIATE_NEGOTIATION_QNAME );
282             Element inputType =
283                 XmlUtils.createElement( WsagConstants.WSAG_INITIATE_NEGOTIATION_INPUT_QNAME,
284                     request.getDomNode() );
285             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
286             Element response = invoke( WsagConstants.WSAG_INITIATE_NEGOTIATION_ACTION, body );
287 
288             InitiateNegotiationOutputDocument responseDoc =
289                 InitiateNegotiationOutputDocument.Factory.parse( response );
290 
291             ISecurityProperties securityProperties = getSecurityProperties().clone();
292             EndpointReferenceType negotiationEPR =
293                 responseDoc.getInitiateNegotiationOutput().getCreatedNegotiationEPR();
294 
295             NegotiationClient createdNegotiation =
296                 new WsrfNegotiationClient( negotiationEPR, getProperties(), securityProperties );
297 
298             return createdNegotiation;
299 
300         }
301         catch ( SoapFault e )
302         {
303 
304             LOG.error( e.getMessage() );
305 
306             Element detail = e.getDetail();
307 
308             try
309             {
310                 // TODO we might need a more sophisticated error handling here
311                 XmlObject ex = XmlObject.Factory.parse( detail );
312                 if ( ex instanceof ContinuingFaultDocument )
313                 {
314                     ContinuingFaultDocument result = (ContinuingFaultDocument) ex;
315                     throw new NegotiationFactoryException( result.getContinuingFault().xmlText() );
316                 }
317                 if ( e.getSubCode()
318                       .equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
319                 {
320                     throw new NegotiationFactoryException( new ResourceUnknownException( e.getReason() ) );
321                 }
322 
323                 throw new ResourceUnavailableException( e );
324             }
325             catch ( XmlException e1 )
326             {
327                 throw new ResourceUnavailableException( e );
328             }
329         }
330         catch ( XmlException e )
331         {
332             throw new ResourceUnavailableException( e );
333         }
334         catch ( Exception e )
335         {
336             throw new ResourceUnavailableException( e );
337         }
338     }
339 
340     /**
341      * {@inheritDoc}
342      */
343     public AgreementTemplateType[] getTemplates()
344         throws ResourceUnavailableException, ResourceUnknownException
345     {
346         try
347         {
348             Element body =
349                 XmlUtils.createElement( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_QNAME, WsagConstants.PREFIX
350                     + ":" + "Template" );
351             body.setAttribute( WsagConstants.WSAG_PREFIX_DECLARATION, WsagConstants.NAMESPACE_URI );
352 
353             Element response = invoke( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_ACTION, body );
354 
355             AgreementTemplateType[] result = null;
356             AgreementFactoryPropertiesType props =
357                 AgreementFactoryPropertiesType.Factory.parse( response,
358                     new XmlOptions().setLoadReplaceDocumentElement( null ) );
359             result =
360                 ( props.getTemplateArray() == null ) ? new AgreementTemplateType[0]
361                                 : props.getTemplateArray();
362 
363             return result;
364         }
365         catch ( SoapFault e )
366         {
367             handleSoapFault( e );
368             throw new ResourceUnavailableException( e );
369         }
370         catch ( XmlException e )
371         {
372             throw new ResourceUnavailableException( e );
373         }
374     }
375 
376     /**
377      * {@inheritDoc}
378      */
379     public String getResourceId() throws ResourceUnknownException, ResourceUnavailableException
380     {
381         try
382         {
383 
384             Element body =
385                 XmlUtils.createElement( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_QNAME,
386                     WsagConstants.WSDM_MUWS_PREFIX + ":" + "ResourceId" );
387             body.setAttribute( WsagConstants.WSDM_MUWS_PREFIX_DECLARATION,
388                 WsagConstants.WSDM_MUWS_NAMESPACE_URI );
389 
390             Element response = invoke( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_ACTION, body );
391 
392             String result = XmlString.Factory.parse( response ).getStringValue();
393             result = ( result == null ) ? "" : result.trim();
394 
395             return result;
396 
397         }
398         catch ( SoapFault e )
399         {
400             throw new ResourceUnavailableException( e );
401         }
402         catch ( XmlException e )
403         {
404             throw new ResourceUnavailableException( e );
405         }
406     }
407 
408     private void handleSoapFault( SoapFault e ) throws ResourceUnavailableException, ResourceUnknownException
409     {
410         LOG.error( e.getMessage() );
411 
412         //
413         // TODO: We should parse for the ResourceUnknownFault document
414         // in the details section
415         //
416         if ( e.getSubCode().equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
417         {
418             throw new ResourceUnknownException( e.getReason() );
419         }
420 
421         throw new ResourceUnavailableException( e );
422     }
423 
424     private void handleCreateAgreementFault( SoapFault e )
425         throws AgreementFactoryException, ResourceUnavailableException
426     {
427         LOG.error( e.getMessage() );
428 
429         Element detail = e.getDetail();
430 
431         try
432         {
433             // TODO we might need a more sophisticated error handling here
434             XmlObject ex = XmlObject.Factory.parse( detail );
435             if ( ex instanceof ContinuingFaultDocument )
436             {
437                 ContinuingFaultDocument result = (ContinuingFaultDocument) ex;
438                 AgreementFactoryException afx =
439                     new AgreementFactoryException( e.getMessage(), result.getContinuingFault() );
440 
441                 Throwable cause = afx.getCause();
442 
443                 while ( cause != null )
444                 {
445                     LOG.error( cause.getMessage() );
446                     cause = cause.getCause();
447                 }
448 
449                 throw afx;
450             }
451 
452             if ( e.getSubCode().equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
453             {
454                 throw new AgreementFactoryException( new ResourceUnknownException( e.getReason() ) );
455             }
456 
457             throw new ResourceUnavailableException( e );
458 
459         }
460         catch ( XmlException e1 )
461         {
462             throw new ResourceUnavailableException( e );
463         }
464     }
465 
466 }