View Javadoc
1   /*
2    * JBoss, Home of Professional Open Source
3    * Copyright 2014, Red Hat, Inc. and/or its affiliates, and individual
4    * contributors by the @authors tag. See the copyright.txt in the
5    * distribution for a full listing of individual contributors.
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * http://www.apache.org/licenses/LICENSE-2.0
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.jboss.as.quickstarts.wsba.participantcompletion.simple;
18  
19  import com.arjuna.mw.wst11.BusinessActivityManager;
20  import com.arjuna.mw.wst11.BusinessActivityManagerFactory;
21  import com.arjuna.wst11.BAParticipantManager;
22  import org.jboss.as.quickstarts.wsba.participantcompletion.simple.jaxws.SetServiceBA;
23  
24  import javax.jws.HandlerChain;
25  import javax.jws.WebMethod;
26  import javax.jws.WebService;
27  import javax.jws.soap.SOAPBinding;
28  import javax.servlet.annotation.WebServlet;
29  import java.util.UUID;
30  
31  /**
32   * An adapter class that exposes a set as a transactional Web Service.
33   * 
34   * @author Paul Robinson (paul.robinson@redhat.com)
35   */
36  @WebService(serviceName = "SetServiceBAService", portName = "SetServiceBA", name = "SetServiceBA", targetNamespace = "http://www.jboss.org/jboss-jdf/jboss-as-quickstart/helloworld/wsba/participantcompletion/set")
37  @HandlerChain(file = "/context-handlers.xml", name = "Context Handlers")
38  @SOAPBinding(style = SOAPBinding.Style.RPC)
39  @WebServlet("/SetServiceBA")
40  public class SetServiceBAImpl implements SetServiceBA {
41      /**
42       * Add an item to a set Enrolls a Participant if necessary and passes the call through to the business logic.
43       * 
44       * @param value the value to add to the set.
45       * @throws AlreadyInSetException if value is already in the set
46       * @throws SetServiceException if an error occurred when attempting to add the item to the set.
47       */
48      @WebMethod
49      public void addValueToSet(String value) throws AlreadyInSetException, SetServiceException {
50  
51          System.out.println("[SERVICE] invoked addValueToSet('" + value + "')");
52  
53          BAParticipantManager participantManager;
54  
55          try {
56              // enlist the Participant for this service:
57              SetParticipantBA participant = new SetParticipantBA(value);
58              BusinessActivityManager activityManager = BusinessActivityManagerFactory.businessActivityManager();
59              System.out.println("[SERVICE] Enlisting a participant into the BA");
60              participantManager = activityManager.enlistForBusinessAgreementWithParticipantCompletion(participant,
61                      "SetServiceBAImpl:" + UUID.randomUUID());
62          } catch (Exception e) {
63              System.err.println("Participant enlistment failed");
64              e.printStackTrace(System.err);
65              throw new SetServiceException("Error enlisting participant", e);
66          }
67  
68          // invoke the back-end business logic
69          System.out.println("[SERVICE] Invoking the back-end business logic");
70          MockSetManager.add(value);
71  
72          /*
73           * this service employs the participant completion protocol which means it decides when it wants to commit local
74           * changes. If the local changes (adding the item to the set) succeeded, we notify the coordinator that we have
75           * completed. Otherwise, we notify the coordinator that we cannot complete. If any other participant fails or the client
76           * decides to cancel we can rely upon being told to compensate.
77           */
78          System.out
79                  .println("[SERVICE] Prepare the backend resource and if successful notify the coordinator that we have completed our work");
80          if (MockSetManager.prepare()) {
81              try {
82                  // tell the coordinator manager we have finished our work
83                  System.out.println("[SERVICE] Prepare successful, notifying coordinator of completion");
84                  participantManager.completed();
85              } catch (Exception e) {
86                  /*
87                   * Failed to notify the coordinator that we have finished our work. Compensate the work and throw an Exception
88                   * to notify the client that the add operation failed.
89                   */
90                  MockSetManager.rollback(value);
91  
92                  System.err.println("[SERVICE]  'completed' callback failed");
93                  throw new SetServiceException("Error when notifying the coordinator that the work is completed", e);
94              }
95          } else {
96              try {
97                  /*
98                   * tell the participant manager we cannot complete. this will force the activity to fail
99                   */
100                 System.out.println("[SERVICE] Prepare failed, notifying coordinator that we cannot complete");
101                 participantManager.cannotComplete();
102             } catch (Exception e) {
103                 System.err.println("'cannotComplete' callback failed");
104                 throw new SetServiceException("Error when notifying the coordinator that the work is cannot be completed", e);
105             }
106             throw new SetServiceException("Unable to prepare the back-end resource");
107         }
108 
109     }
110 
111     /**
112      * Query the set to see if it contains a particular value.
113      * 
114      * @param value the value to check for.
115      * @return true if the value was present, false otherwise.
116      */
117     @WebMethod
118     public boolean isInSet(String value) {
119         return MockSetManager.isInSet(value);
120     }
121 
122     /**
123      * Empty the set
124      * <p/>
125      * Note: To simplify this example, this method is not part of the compensation logic, so will not be undone if the BA is
126      * compensated. It can also be invoked outside of an active BA.
127      */
128     @WebMethod
129     public void clear() {
130         MockSetManager.clear();
131     }
132 }