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 }