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.remote;
36  
37  import javax.xml.namespace.QName;
38  
39  import org.apache.log4j.Logger;
40  import org.apache.muse.util.xml.XmlUtils;
41  import org.apache.muse.ws.addressing.WsaConstants;
42  import org.apache.muse.ws.addressing.soap.SoapFault;
43  import org.apache.xmlbeans.XmlException;
44  import org.apache.xmlbeans.XmlObject;
45  import org.apache.xmlbeans.XmlOptions;
46  import org.apache.xmlbeans.XmlString;
47  import org.ogf.graap.wsag.api.AgreementOffer;
48  import org.ogf.graap.wsag.api.WsagConstants;
49  import org.ogf.graap.wsag.api.client.AgreementClient;
50  import org.ogf.graap.wsag.api.client.AgreementFactoryService;
51  import org.ogf.graap.wsag.api.client.NegotiationClient;
52  import org.ogf.graap.wsag.api.client.WsClient;
53  import org.ogf.graap.wsag.api.exceptions.AgreementFactoryException;
54  import org.ogf.graap.wsag.api.exceptions.NegotiationFactoryException;
55  import org.ogf.graap.wsag.api.exceptions.ResourceUnavailableException;
56  import org.ogf.graap.wsag.api.exceptions.ResourceUnknownException;
57  import org.ogf.graap.wsag.api.security.ISecurityProperties;
58  import org.ogf.schemas.graap.wsAgreement.AgreementFactoryPropertiesType;
59  import org.ogf.schemas.graap.wsAgreement.AgreementTemplateType;
60  import org.ogf.schemas.graap.wsAgreement.AgreementType;
61  import org.ogf.schemas.graap.wsAgreement.ContinuingFaultDocument;
62  import org.ogf.schemas.graap.wsAgreement.CreateAgreementInputType;
63  import org.ogf.schemas.graap.wsAgreement.CreateAgreementResponseDocument;
64  import org.ogf.schemas.graap.wsAgreement.CreatePendingAgreementInputType;
65  import org.ogf.schemas.graap.wsAgreement.CreatePendingAgreementResponseDocument;
66  import org.ogf.schemas.graap.wsAgreement.NoncriticalExtensionType;
67  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationContextType;
68  import org.ogf.schemas.graap.wsAgreement.negotiation.protocol.InitiateNegotiationInputDocument;
69  import org.ogf.schemas.graap.wsAgreement.negotiation.protocol.InitiateNegotiationInputType;
70  import org.ogf.schemas.graap.wsAgreement.negotiation.protocol.InitiateNegotiationOutputDocument;
71  import org.w3.x2005.x08.addressing.EndpointReferenceType;
72  import org.w3c.dom.Element;
73  
74  /**
75   * Default implementation of an agreement factory service client.
76   * 
77   * @see AgreementFactoryService
78   * @author Oliver Waeldrich
79   * 
80   */
81  public class RemoteAgreementFactoryServiceImpl extends WsrfResourceClient
82      implements AgreementFactoryService
83  {
84  
85      private static final Logger LOG = Logger.getLogger( RemoteAgreementFactoryServiceImpl.class );
86  
87      /**
88       * Instantiates an agreement factory service client for the given EPR.
89       * 
90       * @param epr
91       *            the agreement factory service endpoint reference
92       * 
93       * @param securityProperties
94       *            the security properties to use
95       */
96      public RemoteAgreementFactoryServiceImpl( EndpointReferenceType epr,
97                                                ISecurityProperties securityProperties )
98      {
99          super( epr, securityProperties );
100     }
101 
102     /**
103      * {@inheritDoc}
104      */
105     public WsClient getWebServiceClient()
106     {
107         return this;
108     }
109 
110     /**
111      * {@inheritDoc}
112      */
113     public AgreementClient createAgreement( AgreementOffer offer )
114         throws AgreementFactoryException, ResourceUnavailableException, ResourceUnknownException
115     {
116         try
117         {
118             CreateAgreementInputType request = CreateAgreementInputType.Factory.newInstance();
119 
120             if ( offer.getInitiatorEPR() != null )
121             {
122                 request.setInitiatorAgreementEPR( offer.getInitiatorEPR() );
123             }
124 
125             AgreementType agreement = request.addNewAgreementOffer();
126             agreement.setName( offer.getName() );
127             agreement.setContext( offer.getContext() );
128             agreement.setTerms( offer.getTerms() );
129 
130             Element inputType =
131                 XmlUtils.createElement( WsagConstants.WSAG_CREATE_AGREEMENT_INPUT_QNAME, request.getDomNode() );
132             Element body = XmlUtils.createElement( WsagConstants.WSAG_CREATE_AGREEMENT_QNAME );
133             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
134             Element response = invoke( WsagConstants.WSAG_CREATE_AGREEMENT_ACTION, body );
135 
136             CreateAgreementResponseDocument respDoc =
137                 CreateAgreementResponseDocument.Factory.parse( response );
138 
139             AgreementClient createdAgreement =
140                 new RemoteAgreementClientImpl( respDoc.getCreateAgreementResponse().getCreatedAgreementEPR(),
141                     getSecurityProperties().clone() );
142 
143             return createdAgreement;
144         }
145         catch ( SoapFault e )
146         {
147             handleCreateAgreementFault( e );
148             throw new ResourceUnavailableException( e );
149         }
150         catch ( XmlException e )
151         {
152             throw new ResourceUnavailableException( e );
153         }
154         catch ( Exception e )
155         {
156             throw new ResourceUnavailableException( e );
157         }
158     }
159 
160     /**
161      * {@inheritDoc}
162      */
163     public AgreementClient createPendingAgreement( AgreementOffer offer )
164         throws AgreementFactoryException, ResourceUnknownException, ResourceUnavailableException
165     {
166         return createPendingAgreement( offer, null );
167     }
168 
169     /**
170      * {@inheritDoc}
171      */
172     public AgreementClient createPendingAgreement( AgreementOffer offer, EndpointReferenceType acceptanceEPR )
173         throws AgreementFactoryException, ResourceUnknownException, ResourceUnavailableException
174     {
175         try
176         {
177             CreatePendingAgreementInputType request = CreatePendingAgreementInputType.Factory.newInstance();
178 
179             if ( offer.getInitiatorEPR() != null )
180             {
181                 request.setInitiatorAgreementEPR( offer.getInitiatorEPR() );
182             }
183 
184             if ( acceptanceEPR != null )
185             {
186                 request.setAgreementAcceptanceEPR( acceptanceEPR );
187             }
188 
189             AgreementType agreement = request.addNewAgreementOffer();
190             agreement.setName( offer.getName() );
191             agreement.setContext( offer.getContext() );
192             agreement.setTerms( offer.getTerms() );
193 
194             Element inputType =
195                 XmlUtils.createElement( WsagConstants.WSAG_CREATE_PENDING_AGREEMENT_INPUT_QNAME,
196                     request.getDomNode() );
197             Element body = XmlUtils.createElement( WsagConstants.WSAG_CREATE_PENDING_AGREEMENT_QNAME );
198             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
199             Element response = invoke( WsagConstants.WSAG_CREATE_PENDING_AGREEMENT_ACTION, body );
200 
201             CreatePendingAgreementResponseDocument respDoc =
202                 CreatePendingAgreementResponseDocument.Factory.parse( response );
203 
204             AgreementClient createdAgreement =
205                 new RemoteAgreementClientImpl( respDoc.getCreatePendingAgreementResponse()
206                                                       .getCreatedAgreementEPR(),
207                     getSecurityProperties().clone() );
208 
209             return createdAgreement;
210         }
211         catch ( SoapFault e )
212         {
213             //
214             // the handleFault method will throw an exception
215             //
216             handleCreateAgreementFault( e );
217             throw new ResourceUnavailableException( e );
218         }
219         catch ( XmlException e )
220         {
221             throw new ResourceUnavailableException( e );
222         }
223         catch ( Exception e )
224         {
225             throw new ResourceUnavailableException( e );
226         }
227     }
228 
229     /**
230      * {@inheritDoc}
231      */
232     public NegotiationClient initiateNegotiation( NegotiationContextType context )
233         throws NegotiationFactoryException, ResourceUnknownException, ResourceUnavailableException
234     {
235         return initiateNegotiation( context, WsrfResourceClient.ANONYMOUS_EPR );
236     }
237 
238     /**
239      * Initiates a new negotiation process with a wsag4j server.
240      * 
241      * @param context
242      *            the negotiation context
243      * @param initiatorEPR
244      *            the endpoint of the wsag4j server
245      * 
246      * @return a new negotiation client
247      * 
248      * @throws NegotiationFactoryException
249      *             The negotiation process was not initiated.
250      * 
251      * @throws ResourceUnknownException
252      *             the remote resource is unknown
253      * 
254      * @throws ResourceUnavailableException
255      *             the remote resource is unavailable
256      */
257     public NegotiationClient initiateNegotiation( NegotiationContextType context,
258                                                   EndpointReferenceType initiatorEPR )
259         throws NegotiationFactoryException, ResourceUnknownException, ResourceUnavailableException
260     {
261 
262         try
263         {
264 
265             InitiateNegotiationInputDocument requestDoc =
266                 InitiateNegotiationInputDocument.Factory.newInstance();
267 
268             InitiateNegotiationInputType request = requestDoc.addNewInitiateNegotiationInput();
269 
270             request.setNegotiationContext( context );
271             request.setNoncriticalExtensionArray( new NoncriticalExtensionType[0] );
272             request.setInitiatorNegotiationEPR( initiatorEPR );
273 
274             Element body = XmlUtils.createElement( WsagConstants.WSAG_INITIATE_NEGOTIATION_QNAME );
275             Element inputType =
276                 XmlUtils.createElement( WsagConstants.WSAG_INITIATE_NEGOTIATION_INPUT_QNAME,
277                     request.getDomNode() );
278             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
279             Element response = invoke( WsagConstants.WSAG_INITIATE_NEGOTIATION_ACTION, body );
280 
281             InitiateNegotiationOutputDocument responseDoc =
282                 InitiateNegotiationOutputDocument.Factory.parse( response );
283 
284             NegotiationClient createdNegotiation =
285                 new RemoteNegotiationClientImpl( responseDoc.getInitiateNegotiationOutput()
286                                                             .getCreatedNegotiationEPR(),
287                     getSecurityProperties().clone() );
288 
289             return createdNegotiation;
290 
291         }
292         catch ( SoapFault e )
293         {
294 
295             LOG.error( e.getMessage() );
296 
297             Element detail = e.getDetail();
298 
299             try
300             {
301                 // TODO we might need a more sophisticated error handling here
302                 XmlObject ex = XmlObject.Factory.parse( detail );
303                 if ( ex instanceof ContinuingFaultDocument )
304                 {
305                     ContinuingFaultDocument result = (ContinuingFaultDocument) ex;
306                     throw new NegotiationFactoryException( result.getContinuingFault().xmlText() );
307                 }
308                 if ( e.getSubCode()
309                       .equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
310                 {
311                     throw new NegotiationFactoryException( new ResourceUnknownException( e.getReason() ) );
312                 }
313 
314                 throw new ResourceUnavailableException( e );
315             }
316             catch ( XmlException e1 )
317             {
318                 throw new ResourceUnavailableException( e );
319             }
320         }
321         catch ( XmlException e )
322         {
323             throw new ResourceUnavailableException( e );
324         }
325         catch ( Exception e )
326         {
327             throw new ResourceUnavailableException( e );
328         }
329     }
330 
331     /**
332      * {@inheritDoc}
333      */
334     public AgreementTemplateType[] getTemplates()
335         throws ResourceUnavailableException, ResourceUnknownException
336     {
337         try
338         {
339             Element body =
340                 XmlUtils.createElement( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_QNAME, WsagConstants.PREFIX
341                     + ":" + "Template" );
342             body.setAttribute( WsagConstants.WSAG_PREFIX_DECLARATION, WsagConstants.NAMESPACE_URI );
343 
344             Element response = invoke( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_ACTION, body );
345 
346             AgreementTemplateType[] result = null;
347             AgreementFactoryPropertiesType props =
348                 AgreementFactoryPropertiesType.Factory.parse( response,
349                     new XmlOptions().setLoadReplaceDocumentElement( null ) );
350             result =
351                 ( props.getTemplateArray() == null ) ? new AgreementTemplateType[0]
352                                 : props.getTemplateArray();
353 
354             return result;
355         }
356         catch ( SoapFault e )
357         {
358             handleSoapFault( e );
359             throw new ResourceUnavailableException( e );
360         }
361         catch ( XmlException e )
362         {
363             throw new ResourceUnavailableException( e );
364         }
365     }
366 
367     /**
368      * {@inheritDoc}
369      */
370     public String getResourceId() throws ResourceUnknownException, ResourceUnavailableException
371     {
372         try
373         {
374 
375             Element body =
376                 XmlUtils.createElement( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_QNAME,
377                     WsagConstants.WSDM_MUWS_PREFIX + ":" + "ResourceId" );
378             body.setAttribute( WsagConstants.WSDM_MUWS_PREFIX_DECLARATION,
379                 WsagConstants.WSDM_MUWS_NAMESPACE_URI );
380 
381             Element response = invoke( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_ACTION, body );
382 
383             String result = XmlString.Factory.parse( response ).getStringValue();
384             result = ( result == null ) ? "" : result.trim();
385 
386             return result;
387 
388         }
389         catch ( SoapFault e )
390         {
391             throw new ResourceUnavailableException( e );
392         }
393         catch ( XmlException e )
394         {
395             throw new ResourceUnavailableException( e );
396         }
397     }
398 
399     private void handleSoapFault( SoapFault e ) throws ResourceUnavailableException, ResourceUnknownException
400     {
401         LOG.error( e.getMessage() );
402 
403         //
404         // TODO: We should parse for the ResourceUnknownFault document
405         // in the details section
406         //
407         if ( e.getSubCode().equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
408         {
409             throw new ResourceUnknownException( e.getReason() );
410         }
411 
412         throw new ResourceUnavailableException( e );
413     }
414 
415     private void handleCreateAgreementFault( SoapFault e )
416         throws AgreementFactoryException, ResourceUnavailableException
417     {
418         LOG.error( e.getMessage() );
419 
420         Element detail = e.getDetail();
421 
422         try
423         {
424             // TODO we might need a more sophisticated error handling here
425             XmlObject ex = XmlObject.Factory.parse( detail );
426             if ( ex instanceof ContinuingFaultDocument )
427             {
428                 ContinuingFaultDocument result = (ContinuingFaultDocument) ex;
429                 AgreementFactoryException afx =
430                     new AgreementFactoryException( e.getMessage(), result.getContinuingFault() );
431 
432                 Throwable cause = afx.getCause();
433 
434                 while ( cause != null )
435                 {
436                     LOG.error( cause.getMessage() );
437                     cause = cause.getCause();
438                 }
439 
440                 throw afx;
441             }
442 
443             if ( e.getSubCode().equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
444             {
445                 throw new AgreementFactoryException( new ResourceUnknownException( e.getReason() ) );
446             }
447 
448             throw new ResourceUnavailableException( e );
449 
450         }
451         catch ( XmlException e1 )
452         {
453             throw new ResourceUnavailableException( e );
454         }
455     }
456 
457 }