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.server.actions.impl;
36  
37  import java.text.MessageFormat;
38  import java.util.Map;
39  
40  import org.apache.log4j.Logger;
41  import org.apache.xmlbeans.XmlObject;
42  import org.ogf.graap.wsag.api.Agreement;
43  import org.ogf.graap.wsag.api.AgreementFactoryContext;
44  import org.ogf.graap.wsag.api.AgreementOffer;
45  import org.ogf.graap.wsag.api.exceptions.AgreementFactoryException;
46  import org.ogf.graap.wsag.api.exceptions.NegotiationException;
47  import org.ogf.graap.wsag.api.logging.LogMessage;
48  import org.ogf.graap.wsag.server.actions.ActionInitializationException;
49  import org.ogf.graap.wsag.server.actions.IAction;
50  import org.ogf.graap.wsag.server.actions.ICreateAgreementAction;
51  import org.ogf.graap.wsag.server.actions.IGetTemplateAction;
52  import org.ogf.graap.wsag.server.actions.INegotiationAction;
53  import org.ogf.graap.wsag.server.api.WsagSession;
54  import org.ogf.graap.wsag.server.api.WsagSessionManager;
55  import org.ogf.graap.wsag.server.engine.WsagEngine;
56  import org.ogf.graap.wsag4j.types.configuration.ImplementationConfigurationType;
57  import org.ogf.graap.wsag4j.types.engine.WSAG4JSessionDocument;
58  import org.ogf.graap.wsag4j.types.engine.WSAG4JSessionType;
59  import org.ogf.schemas.graap.wsAgreement.AgreementContextType;
60  import org.ogf.schemas.graap.wsAgreement.AgreementRoleType;
61  import org.ogf.schemas.graap.wsAgreement.AgreementTemplateType;
62  import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationOfferType;
63  import org.w3c.dom.Node;
64  
65  /**
66   * This class implements a WSAG4J agreement factory action. A factory action contains a set of strategies to
67   * generate an agreement template, to negotiate offers based on this template and to create agreements based
68   * on the template. The strategies are configured in the WSAG4J engine configuration file.
69   * 
70   * @see IGetTemplateAction
71   * @see INegotiationAction
72   * @see ICreateAgreementAction
73   * 
74   * @author Oliver Waeldrich
75   * 
76   */
77  public class AgreementFactoryAction
78      implements IAction
79  {
80  
81      private static final Logger LOG = Logger.getLogger( AgreementFactoryAction.class );
82  
83      private ICreateAgreementAction createAgreementAction;
84  
85      private IGetTemplateAction getTemplateAction;
86  
87      private INegotiationAction negotiationAction;
88  
89      private boolean useSession = false;
90  
91      private boolean supportsNegotiation = false;
92  
93      private String name;
94  
95      /**
96       * Creates a new {@link AgreementFactoryAction}.
97       * 
98       * @param templateAction
99       *            The {@link IGetTemplateAction} that is called to generate the agreement template for this
100      *            {@link AgreementFactoryAction}.
101      * 
102      * @param createAgreementAction
103      *            The {@link ICreateAgreementAction} that is called when an agreement is created based on the
104      *            template generated by this {@link AgreementFactoryAction}.
105      * 
106      * @param negotiationAction
107      *            The negotiation action that is called when a negotiation offer based on the agreement
108      *            template provided by this action was received.
109      */
110     public AgreementFactoryAction( IGetTemplateAction templateAction,
111                                    ICreateAgreementAction createAgreementAction,
112                                    INegotiationAction negotiationAction )
113     {
114         super();
115 
116         setGetTemplateAction( templateAction );
117         setCreateAgreementAction( createAgreementAction );
118         setNegotiationAction( negotiationAction );
119     }
120 
121     /**
122      * Indicates whether this action supports agreement negotiation or not. Negotiation is supported if the
123      * associated negotiation action is not null and not an instance of {@link NegotiationUnsupportedAction}
124      * 
125      * @return true, if negotiation is supported, otherwise false
126      * 
127      * @see #setNegotiationAction(INegotiationAction)
128      */
129     public boolean isNegotiationSupported()
130     {
131         return supportsNegotiation;
132     }
133 
134     /**
135      * Sets the template creation strategy for this factory action.
136      * 
137      * @param templateAction
138      *            the template creation strategy to set
139      */
140     public void setGetTemplateAction( IGetTemplateAction templateAction )
141     {
142         getTemplateAction = templateAction;
143     }
144 
145     /**
146      * Sets the SLA creation strategy for this factory action.
147      * 
148      * @param createAgreement
149      *            the agreement creation strategy to set
150      */
151     public void setCreateAgreementAction( ICreateAgreementAction createAgreement )
152     {
153         createAgreementAction = createAgreement;
154     }
155 
156     /**
157      * Sets the negotiation strategy for this factory action.
158      * 
159      * @param negotiationAction
160      *            the negotiation action to set
161      */
162     public void setNegotiationAction( INegotiationAction negotiationAction )
163     {
164         this.negotiationAction = negotiationAction;
165         if ( ( negotiationAction == null ) || ( negotiationAction instanceof NegotiationUnsupportedAction ) )
166         {
167             supportsNegotiation = false;
168         }
169         else
170         {
171             supportsNegotiation = true;
172         }
173     }
174 
175     /**
176      * {@inheritDoc}
177      * 
178      * @see org.ogf.graap.wsag.server.actions.IAction#initialize()
179      */
180     @Override
181     public void initialize() throws ActionInitializationException
182     {
183         if ( ( getTemplateAction == null ) || ( createAgreementAction == null ) )
184         {
185             throw new ActionInitializationException(
186                 "getTemplateAction and createAgreementAction must not be null." );
187         }
188 
189         try
190         {
191             getTemplateAction.initialize();
192             createAgreementAction.initialize();
193             negotiationAction.initialize();
194         }
195         catch ( Exception e )
196         {
197             //
198             // create error message and throw initialization exception
199             //
200             String detailsText =
201                 "Configured actions: GetTemplateAction [{0}], NegotiationAction: {1}), CreateAgreementAction: {2})";
202 
203             String details =
204                 LogMessage.format( detailsText, getTemplateAction.getClass().getName(),
205                     negotiationAction.getClass().getName(), createAgreementAction.getClass().getName() );
206 
207             String msgText = "Error while initializing AgreementFactoryAction. \nReason: {0} \nDetails: {1}";
208             String message = LogMessage.format( msgText, e.getMessage(), details );
209 
210             throw new ActionInitializationException( message, e );
211         }
212     }
213 
214     /**
215      * Returns the agreement template associated with this factory action.
216      * 
217      * @return the associated agreement template
218      * 
219      * @see AgreementTemplateType
220      */
221     public AgreementTemplateType getTemplate()
222     {
223 
224         AgreementTemplateType template = getTemplateAction.getTemplate();
225         template = (AgreementTemplateType) template.copy();
226 
227         if ( useSession )
228         {
229 
230             AgreementContextType context = template.getContext();
231 
232             //
233             // we create a new session for each time a template is requested
234             //
235             WsagSession session = WsagSessionManager.createSession();
236 
237             //
238             // If no context is defined in the template, we create a default context
239             //
240             if ( context == null )
241             {
242                 context = template.addNewContext();
243                 context.setTemplateId( template.getTemplateId() );
244                 context.setTemplateName( template.getName() );
245                 context.setServiceProvider( AgreementRoleType.AGREEMENT_RESPONDER );
246             }
247 
248             //
249             // finally, we create the session document and append it to the context
250             //
251             WSAG4JSessionDocument sessionDoc = WSAG4JSessionDocument.Factory.newInstance();
252             sessionDoc.addNewWSAG4JSession().setSessionID( session.getSessionId() );
253             Node imported =
254                 context.getDomNode().getOwnerDocument()
255                        .importNode( sessionDoc.getWSAG4JSession().getDomNode(), true );
256             context.getDomNode().appendChild( imported );
257         }
258 
259         return template;
260     }
261 
262     /**
263      * Invokes the create agreement strategy implemented by the {@link ICreateAgreementAction} which is set
264      * for this action
265      * 
266      * @param offer
267      *            the offer for which an agreement should be created
268      * @param context
269      *            factory invocation context
270      * 
271      * @return the agreement instance created by the {@link ICreateAgreementAction}
272      * 
273      * @throws AgreementFactoryException
274      *             the exception thrown by the {@link ICreateAgreementAction}
275      * 
276      * @see #setCreateAgreementAction(ICreateAgreementAction)
277      */
278     public Agreement createAgreement( AgreementOffer offer, Map<String, Object> context )
279         throws AgreementFactoryException
280     {
281         XmlObject[] sessionDocuments =
282             offer.getContext().selectChildren( WSAG4JSessionDocument.type.getDocumentElementName() );
283         if ( sessionDocuments.length > 0 )
284         {
285             if ( sessionDocuments.length > 1 )
286             {
287                 String message =
288                     "Found multiple wsag4j session documents in agreement context. Using the first, ignoring the rest.";
289                 LOG.warn( message );
290             }
291 
292             WSAG4JSessionType sessionToken = (WSAG4JSessionType) sessionDocuments[0];
293 
294             WsagSession session = WsagSessionManager.getSession( sessionToken.getSessionID() );
295             if ( session != null )
296             {
297                 createAgreementAction.getHandlerContext().setSession( session );
298             }
299             else
300             {
301                 Object[] filler = new Object[] { sessionToken.getSessionID() };
302                 String message = MessageFormat.format( "WSAG4J session with id [{0}] not found.", filler );
303                 LOG.error( message );
304             }
305         }
306 
307         return createAgreementAction.createAgreement( offer, context );
308     }
309 
310     /**
311      * Implements the negotiation strategy for offers that are based on the template associated with this
312      * action.
313      * 
314      * @param quote
315      *            the quote to negotiate
316      * 
317      * @param context
318      *            implementation specific context
319      * 
320      * @return the counter offers produced by the negotiation strategy
321      * 
322      * @throws NegotiationException
323      *             An exception thrown by the negotiation strategy. See
324      *             {@link #setNegotiationAction(INegotiationAction)}.
325      * 
326      * @see INegotiationAction
327      */
328     public NegotiationOfferType[] negotiate( NegotiationOfferType quote, Map<String, Object> context )
329         throws NegotiationException
330     {
331 
332         //
333         // An agreement factory does not need to support negotiation.
334         // If no negotiation action is set, we throw an unsupported
335         // operation exception.
336         //
337         if ( negotiationAction == null )
338         {
339             String message = "Negotiation is not supported by this agreement factory";
340             throw new UnsupportedOperationException( message );
341         }
342 
343         return negotiationAction.negotiate( quote, context );
344     }
345 
346     /**
347      * @return true - if this {@link AgreementFactoryAction} is session aware. false - otherwise
348      */
349     public boolean isUsingSession()
350     {
351         return useSession;
352     }
353 
354     /**
355      * @param useSession
356      *            Specifies whether an {@link AgreementFactoryAction} is session aware or not.
357      */
358     public void setUseSession( boolean useSession )
359     {
360         this.useSession = useSession;
361     }
362 
363     /**
364      * @return The name configured for this action.
365      */
366     public String getName()
367     {
368         if ( name == null )
369         {
370             return getClass().getName();
371         }
372 
373         return name;
374     }
375 
376     /**
377      * @param name
378      *            Sets the name for this {@link AgreementFactoryAction}.
379      */
380     public void setName( String name )
381     {
382         this.name = name;
383     }
384 
385     /**
386      * <!-- begin-UML-doc --> The configuration of this {@link AgreementFactoryAction}. <!-- end-UML-doc -->
387      * 
388      * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
389      */
390     private ImplementationConfigurationType actionConfiguration;
391 
392     /**
393      * <!-- begin-UML-doc --> Returns the configuration of this particular {@link AgreementFactoryAction}
394      * instance. <!-- end-UML-doc -->
395      * 
396      * @return The configuration of this {@link AgreementFactoryAction} instance.
397      * 
398      * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
399      */
400     @Override
401     public ImplementationConfigurationType getActionConfiguration()
402     {
403         // begin-user-code
404         return actionConfiguration;
405         // end-user-code
406     }
407 
408     /**
409      * <!-- begin-UML-doc --> Sets the configuration for this object. <!-- end-UML-doc -->
410      * 
411      * @param configuration
412      *            The {@link AgreementFactoryAction} configuration to set.
413      * 
414      * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
415      */
416     @Override
417     public void setActionConfiguration( ImplementationConfigurationType configuration )
418     {
419         // begin-user-code
420         this.actionConfiguration = configuration;
421         // end-user-code
422     }
423 
424     /**
425      * <!-- begin-UML-doc --> The context of the agreement factory where this action is deployed in. <!--
426      * end-UML-doc -->
427      * 
428      * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
429      */
430     private AgreementFactoryContext factoryContext;
431 
432     private WsagEngine engine;
433 
434     /**
435      * <!-- begin-UML-doc --> Allows implementations to access the context of the agreement factory in which
436      * this action was deployed. <!-- end-UML-doc -->
437      * 
438      * @return The context of the factory in which this action is deployed.
439      * 
440      * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
441      */
442     @Override
443     public AgreementFactoryContext getFactoryContext()
444     {
445         // begin-user-code
446         return factoryContext;
447         // end-user-code
448     }
449 
450     /**
451      * <!-- begin-UML-doc --> <!-- end-UML-doc -->
452      * 
453      * @param factoryContext
454      *            the factoryContext to set
455      * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
456      */
457     @Override
458     public void setFactoryContext( AgreementFactoryContext factoryContext )
459     {
460         // begin-user-code
461         this.factoryContext = factoryContext;
462         // end-user-code
463     }
464 
465     /**
466      * 
467      * @return the negotiation strategy for a particular template
468      */
469     public INegotiationAction getNegotiationAction()
470     {
471         return negotiationAction;
472     }
473 
474     /*
475      * (non-Javadoc)
476      * 
477      * @see org.ogf.graap.wsag.server.actions.IAction#getEngine()
478      */
479     @Override
480     public WsagEngine getEngine()
481     {
482         return engine;
483     }
484 
485     /*
486      * (non-Javadoc)
487      * 
488      * @see org.ogf.graap.wsag.server.actions.IAction#setEngine(org.ogf.graap.wsag.server.engine.WsagEngine)
489      */
490     @Override
491     public void setEngine( WsagEngine engine )
492     {
493         this.engine = engine;
494 
495     }
496 }