View Javadoc

1   /* 
2    * Copyright (c) 2007, 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 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.ogf.graap.wsag.api.WsagConstants;
47  import org.ogf.graap.wsag.api.exceptions.NegotiationException;
48  import org.ogf.graap.wsag.api.exceptions.ResourceUnavailableException;
49  import org.ogf.graap.wsag.api.exceptions.ResourceUnknownException;
50  import org.ogf.schemas.graap.wsAgreement.AgreementTemplateType;
51  import org.ogf.schemas.graap.wsAgreement.ContinuingFaultDocument;
52  import org.ogf.schemas.graap.wsAgreement.negotiation.AdvertiseInputDocument;
53  import org.ogf.schemas.graap.wsAgreement.negotiation.AdvertiseInputType;
54  import org.ogf.schemas.graap.wsAgreement.negotiation.AdvertiseOutputType;
55  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiateInputDocument;
56  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiateInputType;
57  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiateOutputType;
58  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationContextType;
59  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationOfferType;
60  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationPropertiesType;
61  import org.ogf.schemas.graap.wsAgreement.negotiation.TerminateInputDocument;
62  import org.ogf.schemas.graap.wsAgreement.negotiation.TerminateResponseDocument;
63  import org.w3c.dom.Element;
64  import org.w3c.dom.Node;
65  
66  /**
67   * Default implementation of an negotiation service client.
68   * 
69   * @author hrasheed
70   * 
71   */
72  public class WsrfNegotiationService
73  {
74  
75      private static final Logger LOG = Logger.getLogger( WsrfNegotiationService.class );
76  
77      private final WsrfResourceClient client;
78  
79      /**
80       * @param client
81       *            the WSRF resource client to use
82       */
83      public WsrfNegotiationService( WsrfResourceClient client )
84      {
85          this.client = client;
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91      public NegotiationContextType getNegotiationContext()
92          throws ResourceUnknownException, ResourceUnavailableException
93      {
94  
95          try
96          {
97  
98              Element body =
99                  XmlUtils.createElement( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_QNAME,
100                     WsagConstants.WSAG_NEGOTIATION_PREFIX + ":" + "NegotiationContext" );
101             body.setAttribute( WsagConstants.WSAG_NEGOTIATION_PREFIX_DECLARATION,
102                 WsagConstants.WSAG_NEGOTIATION_NAMESPACE_URI );
103 
104             Element response = client.invoke( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_ACTION, body );
105 
106             NegotiationPropertiesType props =
107                 NegotiationPropertiesType.Factory.parse( response,
108                     new XmlOptions().setLoadReplaceDocumentElement( null ) );
109             NegotiationContextType respContext = props.getNegotiationContext();
110 
111             return respContext;
112 
113         }
114         catch ( SoapFault e )
115         {
116             handleSoapFault( e );
117             throw new ResourceUnavailableException( e );
118         }
119         catch ( XmlException e )
120         {
121             throw new ResourceUnavailableException( e );
122         }
123     }
124 
125     /**
126      * {@inheritDoc}
127      */
128     public AgreementTemplateType[] getNegotiableTemplates()
129         throws ResourceUnknownException, ResourceUnavailableException
130     {
131 
132         try
133         {
134 
135             Element body =
136                 XmlUtils.createElement( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_QNAME,
137                     WsagConstants.WSAG_NEGOTIATION_PREFIX + ":" + "NegotiableTemplate" );
138             body.setAttribute( WsagConstants.WSAG_NEGOTIATION_PREFIX_DECLARATION,
139                 WsagConstants.WSAG_NEGOTIATION_NAMESPACE_URI );
140 
141             Element response = client.invoke( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_ACTION, body );
142 
143             NegotiationPropertiesType props =
144                 NegotiationPropertiesType.Factory.parse( response,
145                     new XmlOptions().setLoadReplaceDocumentElement( null ) );
146 
147             return props.getNegotiableTemplateArray();
148 
149         }
150         catch ( SoapFault e )
151         {
152             handleSoapFault( e );
153             throw new ResourceUnavailableException( e );
154         }
155         catch ( XmlException e )
156         {
157             throw new ResourceUnavailableException( e );
158         }
159     }
160 
161     /**
162      * {@inheritDoc}
163      */
164     public NegotiationOfferType[] getNegotiationOffers()
165         throws ResourceUnknownException, ResourceUnavailableException
166     {
167 
168         try
169         {
170 
171             Element body =
172                 XmlUtils.createElement( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_QNAME,
173                     WsagConstants.WSAG_NEGOTIATION_PREFIX + ":" + "NegotiationOffer" );
174             body.setAttribute( WsagConstants.WSAG_NEGOTIATION_PREFIX_DECLARATION,
175                 WsagConstants.WSAG_NEGOTIATION_NAMESPACE_URI );
176 
177             Element response = client.invoke( WsagConstants.WSRF_GET_RESOURCE_PROPERTY_ACTION, body );
178 
179             NegotiationOfferType[] offers = null;
180 
181             NegotiationPropertiesType props =
182                 NegotiationPropertiesType.Factory.parse( response,
183                     new XmlOptions().setLoadReplaceDocumentElement( null ) );
184             offers =
185                 ( props.getNegotiationOfferArray() == null ) ? new NegotiationOfferType[0]
186                                 : props.getNegotiationOfferArray();
187 
188             return offers;
189 
190         }
191         catch ( SoapFault e )
192         {
193             handleSoapFault( e );
194             throw new ResourceUnavailableException( e );
195         }
196         catch ( XmlException e )
197         {
198             throw new ResourceUnavailableException( e );
199         }
200     }
201 
202     /**
203      * {@inheritDoc}
204      */
205     public NegotiationOfferType[] negotiate( NegotiationOfferType[] quotes )
206         throws NegotiationException, ResourceUnknownException, ResourceUnavailableException
207     {
208 
209         try
210         {
211 
212             NegotiateInputDocument inputDoc = NegotiateInputDocument.Factory.newInstance();
213             NegotiateInputType input = inputDoc.addNewNegotiateInput();
214             input.setNegotiationOfferArray( quotes );
215 
216             Element body = XmlUtils.createElement( WsagConstants.WSAG_NEGOTIATION_NEGOTIATE_QNAME );
217             Element inputType =
218                 XmlUtils.createElement( WsagConstants.WSAG_NEGOTIATION_NEGOTIATE_INPUT_QNAME,
219                     input.getDomNode() );
220             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
221             Element response = client.invoke( WsagConstants.WSAG_NEGOTIATION_NEGOTIATE_ACTION, body );
222 
223             NegotiationOfferType[] counterOffers = null;
224 
225             NegotiateOutputType output =
226                 NegotiateOutputType.Factory.parse( response,
227                     new XmlOptions().setLoadReplaceDocumentElement( null ) );
228             counterOffers =
229                 ( output.getNegotiationCounterOfferArray() == null ) ? new NegotiationOfferType[0]
230                                 : output.getNegotiationCounterOfferArray();
231 
232             return counterOffers;
233 
234         }
235         catch ( SoapFault e )
236         {
237             handleNegotiationFault( e );
238             throw new ResourceUnavailableException( e );
239         }
240         catch ( XmlException e )
241         {
242             throw new ResourceUnavailableException( e );
243         }
244         catch ( Exception e )
245         {
246             throw new ResourceUnavailableException( e );
247         }
248     }
249 
250     /**
251      * {@inheritDoc}
252      */
253     public void advertise( NegotiationOfferType[] quotes )
254         throws NegotiationException, ResourceUnknownException, ResourceUnavailableException
255     {
256 
257         try
258         {
259 
260             AdvertiseInputDocument inputDoc = AdvertiseInputDocument.Factory.newInstance();
261             AdvertiseInputType input = inputDoc.addNewAdvertiseInput();
262             input.setNegotiationOfferArray( quotes );
263 
264             Element body = XmlUtils.createElement( WsagConstants.WSAG_NEGOTIATION_ADVERTISE_QNAME );
265             Element inputType =
266                 XmlUtils.createElement( WsagConstants.WSAG_NEGOTIATION_ADVERTISE_INPUT_QNAME,
267                     input.getDomNode() );
268             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
269             Element response = client.invoke( WsagConstants.WSAG_NEGOTIATION_ADVERTISE_ACTION, body );
270 
271             AdvertiseOutputType.Factory.parse( response,
272                 new XmlOptions().setLoadReplaceDocumentElement( null ) );
273 
274         }
275         catch ( SoapFault e )
276         {
277             handleNegotiationFault( e );
278             throw new ResourceUnavailableException( e );
279         }
280         catch ( XmlException e )
281         {
282             throw new ResourceUnavailableException( e );
283         }
284         catch ( Exception e )
285         {
286             throw new ResourceUnavailableException( e );
287         }
288     }
289 
290     /**
291      * {@inheritDoc}
292      */
293     public void terminate() throws ResourceUnavailableException, ResourceUnknownException
294     {
295 
296         try
297         {
298 
299             Node terminateInput =
300                 TerminateInputDocument.Factory.newInstance().addNewTerminateInput().getDomNode();
301             Element inputType =
302                 XmlUtils.createElement( WsagConstants.WSAG_NEGOTIATION_TERMINATE_INPUT_QNAME, terminateInput );
303             Element body = XmlUtils.createElement( WsagConstants.WSAG_NEGOTIATION_TERMINATE_QNAME );
304             body.appendChild( body.getOwnerDocument().importNode( inputType, true ) );
305             Element response = client.invoke( WsagConstants.WSAG_NEGOTIATION_TERMINATE_ACTION, body );
306 
307             TerminateResponseDocument respDoc = TerminateResponseDocument.Factory.parse( response );
308             respDoc.getTerminateResponse();
309 
310         }
311         catch ( SoapFault e )
312         {
313             handleSoapFault( e );
314             throw new ResourceUnavailableException( e );
315         }
316         catch ( XmlException e )
317         {
318             throw new ResourceUnavailableException( e );
319         }
320     }
321 
322     /**
323      * {@inheritDoc}
324      */
325     public WsrfResourceClient getWebServiceClient()
326     {
327         return client;
328     }
329 
330     /**
331      * {@inheritDoc}
332      */
333     public void destroy() throws ResourceUnavailableException, ResourceUnknownException
334     {
335         try
336         {
337             client.destroy();
338         }
339         catch ( SoapFault e )
340         {
341             throw new ResourceUnavailableException( e );
342         }
343     }
344 
345     private void handleNegotiationFault( SoapFault e )
346         throws NegotiationException, ResourceUnavailableException
347     {
348 
349         LOG.error( e.getMessage() );
350 
351         Element detail = e.getDetail();
352 
353         try
354         {
355             // TODO we might need a more sophisticated error handling here
356             XmlObject ex = XmlObject.Factory.parse( detail );
357             if ( ex instanceof ContinuingFaultDocument )
358             {
359                 ContinuingFaultDocument result = (ContinuingFaultDocument) ex;
360                 throw new NegotiationException( result.getContinuingFault().xmlText() );
361             }
362 
363             if ( e.getSubCode().equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
364             {
365                 throw new NegotiationException( new ResourceUnknownException( e.getReason() ) );
366             }
367 
368             throw new ResourceUnavailableException( e );
369 
370         }
371         catch ( XmlException e1 )
372         {
373             throw new ResourceUnavailableException( e );
374         }
375     }
376 
377     private void handleSoapFault( SoapFault e ) throws ResourceUnavailableException, ResourceUnknownException
378     {
379 
380         LOG.error( e.getMessage() );
381         //
382         // TODO: We should parse for the ResourceUnknownFault document in the details section
383         //
384         if ( e.getSubCode().equals( new QName( WsaConstants.NAMESPACE_URI, "DestinationUnreachable" ) ) )
385         {
386             throw new ResourceUnknownException( e.getReason() );
387         }
388 
389         throw new ResourceUnavailableException( e );
390     }
391 
392 }