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