Search

Appendix C. Endpoint Implementation Classes

download PDF
The example below is the demonstration application configuration mentioned in Section 19.3.2.1, “JAX-WS Service Context Handlers”.

Example C.1. Application Configuration (context-handlers.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!--
-->
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
    <handler-chain>
	<handler>
		<handler-name>ContextHandler</handler-name>
		<handler-class>com.arjuna.mw.wst11.service.JaxWSHeaderContextProcessor</handler-class>
	</handler>
    </handler-chain>
</handler-chains>


The following four code samples are demonstration implementations of the javax.jws.WebService and javax.jws.HandlerChain annotations which are discussed in Section 19.3.2.1, “JAX-WS Service Context Handlers”.

Example C.2. RestaurantServiceAT.java

package com.jboss.jbosstm.xts.demo.services.restaurant;

import com.arjuna.ats.arjuna.common.Uid;
import com.arjuna.mw.wst11.TransactionManagerFactory;
import com.arjuna.mw.wst11.UserTransactionFactory;
import com.jboss.jbosstm.xts.demo.restaurant.IRestaurantServiceAT;
import com.jboss.jbosstm.xts.demo.services.recovery.DemoATRecoveryModule;

import javax.jws.HandlerChain;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryManager;

/**
 * An adapter class that exposes the RestaurantManager business API as a
 * transactional Web Service. Also logs events to a RestaurantView object.
 *
 * @author Jonathan Halliday (jonathan.halliday@arjuna.com)
 * @version $Revision: 1.3 $
 */
@WebService(serviceName="RestaurantServiceATService", portName="RestaurantServiceAT",
        name = "IRestaurantServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Restaurant",
        wsdlLocation = "/WEB-INF/wsdl/RestaurantServiceAT.wsdl")
@HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")                  
@SOAPBinding(style=SOAPBinding.Style.RPC)
public class RestaurantServiceAT implements IRestaurantServiceAT
{
    /**
     * ensure that the recovery module for the dmeo is installed
     */
    @PostConstruct
    void postConstruct()
    {
        // ensure that the xts-demo AT recovery helper module is registered
        DemoATRecoveryModule.register();
    }

    /**
     * ensure that the recovery module for the dmeo is deinstalled
     */
    @PreDestroy
    void preDestroy()
    {
        // ensure that the xts-demo AT recovery helper module is registered
        DemoATRecoveryModule.unregister();
    }

    /**
     * Book a number of seats in the restaurant
     * Enrols a Participant if necessary, then passes
     * the call through to the business logic.
     *
     * @param how_many The number of seats to book
     */
    @WebMethod
    public void bookSeats(
            @WebParam(name = "how_many", partName = "how_many")
            int how_many)
    {
        RestaurantView restaurantView = RestaurantView.getSingletonInstance();
        RestaurantManager restaurantManager = RestaurantManager.getSingletonInstance();

        String transactionId = null;
        try
        {
            // get the transaction context of this thread:
            transactionId = UserTransactionFactory.userTransaction().toString();
            System.out.println("RestaurantServiceAT transaction id =" + transactionId);

            if (!restaurantManager.knowsAbout(transactionId))
            {
                System.out.println("RestaurantServiceAT - enrolling...");
                // enlist the Participant for this service:
                RestaurantParticipantAT restaurantParticipant = new RestaurantParticipantAT(transactionId);
                TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(restaurantParticipant, "org.jboss.jbossts.xts-demo:restaurantAT:" + new Uid().toString());
            }
        }
        catch (Exception e)
        {
            System.err.println("bookSeats: Participant enrolment failed");
            e.printStackTrace(System.err);
            return;
        }

        restaurantView.addMessage("******************************");

        restaurantView.addMessage("id:" + transactionId + ". Received a booking request for one table of " + how_many + " people");

        restaurantManager.bookSeats(transactionId, how_many);

        restaurantView.addMessage("Request complete\n");
        restaurantView.updateFields();
    }
}


Example C.3. TaxiServiceBA.java

package com.jboss.jbosstm.xts.demo.services.taxi;

import com.arjuna.ats.arjuna.common.Uid;
import com.arjuna.mw.wst11.BusinessActivityManagerFactory;
import com.arjuna.mw.wst11.BusinessActivityManager;
import com.arjuna.wst11.BAParticipantManager;
import com.arjuna.wst.SystemException;
import com.jboss.jbosstm.xts.demo.taxi.ITaxiServiceBA;

import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

/**
 * An adapter class that exposes the TaxiManager business API as a
 * transactional Web Service. Also logs events to a TaxiView object.
 *
 * @author Jonathan Halliday (jonathan.halliday@arjuna.com)
 * @version $Revision: 1.5 $
 */
@WebService(serviceName="TaxiServiceBAService", portName="TaxiServiceBA",
        name = "ITaxiServiceBA", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi",
        wsdlLocation = "/WEB-INF/wsdl/TaxiServiceBA.wsdl")
@HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
@SOAPBinding(style=SOAPBinding.Style.RPC)
public class TaxiServiceBA implements ITaxiServiceBA
{
    /**
     * Book a taxi
     * Enrols a Participant if necessary and passes
     * the call through to the business logic.
     *
     * @return true on success, false otherwise.
     */
    @WebMethod
    @WebResult(name = "bookTaxiBAResponse", partName = "bookTaxiBAResponse")
    public boolean bookTaxi()
    {
        TaxiView taxiView = TaxiView.getSingletonInstance();
        TaxiManager taxiManager = TaxiManager.getSingletonInstance();

        BusinessActivityManager activityManager = BusinessActivityManagerFactory.businessActivityManager();

        // get the transaction context of this thread:
        String transactionId = null;
        try
        {
            transactionId = activityManager.currentTransaction().toString();
        }
        catch (SystemException e)
        {
            System.err.println("bookTaxi: unable to obtain a transaction context!");
            e.printStackTrace(System.err);
            return false;
        }

        // log the event:
        System.out.println("TaxiServiceBA transaction id =" + transactionId);

        taxiView.addMessage("******************************");

        taxiView.addPrepareMessage("id:" + transactionId.toString() + ". Received a taxi booking request");
        taxiView.updateFields();

        // invoke the backend business logic:
        taxiManager.bookTaxi(transactionId);

        // attempt to finalise the booking
        if (taxiManager.prepareTaxi(transactionId))
        {
            taxiView.addMessage("id:" + transactionId + ". Seats prepared, trying to commit and enlist compensation Participant");
            taxiView.updateFields();

            // it worked, so now we need a participant enlisted in case of compensation:
            TaxiParticipantBA taxiParticipant = new TaxiParticipantBA(transactionId);
            // enlist the Participant for this service:
            BAParticipantManager participantManager = null;
            try
            {
                participantManager = activityManager.enlistForBusinessAgreementWithParticipantCompletion(taxiParticipant, "org.jboss.jbossts.xts-demo:restaurantBA:" + new Uid().toString());
            }
            catch (Exception e)
            {
                taxiView.addMessage("id:" + transactionId + ". Participant enrolement failed");
                taxiManager.cancelTaxi(transactionId);
                System.err.println("bookTaxi: Participant enrolment failed");
                e.printStackTrace(System.err);
                return false;
            }

            // finish the booking in the backend ensuring it is compensatable:
            taxiManager.commitTaxi(transactionId, true);

            try
            {
                // tell the manager we have finished our work:
                participantManager.completed();
            }
            catch (Exception e)
            {
                System.err.println("bookTaxi: 'completed' callback failed");
                taxiManager.cancelTaxi(transactionId);
                e.printStackTrace(System.err);
                return false;
            }
        }
        else
        {
            taxiView.addMessage("id:" + transactionId + ". Failed to reserve taxi. Cancelling.");
            taxiManager.cancelTaxi(transactionId);
            taxiView.updateFields();
            return false;
        }

        taxiView.addMessage("Request complete\n");
        taxiView.updateFields();

        return true;
    }
}

Example C.4. TaxiServiceAT.java

package com.jboss.jbosstm.xts.demo.services.taxi;

import com.arjuna.ats.arjuna.common.Uid;
import com.arjuna.mw.wst11.TransactionManagerFactory;
import com.arjuna.mw.wst11.UserTransactionFactory;
import com.jboss.jbosstm.xts.demo.taxi.ITaxiServiceAT;
import com.jboss.jbosstm.xts.demo.services.recovery.DemoATRecoveryModule;

import javax.jws.WebService;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * An adapter class that exposes the TaxiManager business API as a
 * transactional Web Service. Also logs events to a TaxiView object.
 *
 * @author Jonathan Halliday (jonathan.halliday@arjuna.com)
 * @version $Revision: 1.3 $
 */
@WebService(serviceName="TaxiServiceATService", portName="TaxiServiceAT",
        name = "ITaxiServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi",
        wsdlLocation = "/WEB-INF/wsdl/TaxiServiceAT.wsdl")
@HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
@SOAPBinding(style=SOAPBinding.Style.RPC)
public class TaxiServiceAT implements ITaxiServiceAT
{
    /**
     * ensure that the recovery module for the dmeo is installed
     */
    @PostConstruct
    void postConstruct()
    {
        // ensure that the xts-demo AT recovery helper module is registered
        DemoATRecoveryModule.register();
    }

    /**
     * ensure that the recovery module for the dmeo is deinstalled
     */
    @PreDestroy
    void preDestroy()
    {
        // ensure that the xts-demo AT recovery helper module is registered
        DemoATRecoveryModule.unregister();
    }

    /**
     * Book a taxi
     * Enrols a Participant if necessary, then passes
     * the call through to the business logic.
     */
    @WebMethod
    public void bookTaxi()
    {
        TaxiView taxiView = TaxiView.getSingletonInstance();
        TaxiManager taxiManager = TaxiManager.getSingletonInstance();

        String transactionId = null;
        try
        {
            // get the transaction context of this thread:
            transactionId = UserTransactionFactory.userTransaction().toString();
            System.out.println("TaxiServiceAT transaction id =" + transactionId);

            if (!taxiManager.knowsAbout(transactionId))
            {
                System.out.println("TaxiServiceAT - enrolling...");
                // enlist the Participant for this service:
                TaxiParticipantAT taxiParticipant = new TaxiParticipantAT(transactionId);
                TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(taxiParticipant, "org.jboss.jbossts.xts-demo:taxiAT:" + new Uid().toString());
            }
        }
        catch (Exception e)
        {
            System.err.println("bookTaxi: Participant enrolment failed");
            e.printStackTrace(System.err);
            return;
        }

        taxiView.addMessage("******************************");

        taxiView.addMessage("id:" + transactionId.toString() + ". Received a taxi booking request");

        TaxiManager.getSingletonInstance().bookTaxi(transactionId);

        taxiView.addMessage("Request complete\n");
        taxiView.updateFields();
    }
}

Example C.5. TheatreServiceAT.java

package com.jboss.jbosstm.xts.demo.services.theatre;

import com.arjuna.ats.arjuna.common.Uid;
import com.arjuna.mw.wst11.TransactionManagerFactory;
import com.arjuna.mw.wst11.UserTransactionFactory;
import com.jboss.jbosstm.xts.demo.theatre.ITheatreServiceAT;
import com.jboss.jbosstm.xts.demo.services.recovery.DemoATRecoveryModule;

import javax.jws.WebService;
import javax.jws.WebParam;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * An adapter class that exposes the TheatreManager business API as a
 * transactional Web Service. Also logs events to a TheatreView object.
 *
 * @author Jonathan Halliday (jonathan.halliday@arjuna.com)
 * @version $Revision: 1.3 $
 */
@WebService(serviceName="TheatreServiceATService", portName="TheatreServiceAT",
        name = "ITheatreServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Theatre",
        wsdlLocation = "/WEB-INF/wsdl/TheatreServiceAT.wsdl")
@HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
@SOAPBinding(style=SOAPBinding.Style.RPC)
public class TheatreServiceAT implements ITheatreServiceAT
{
    /**
     * ensure that the recovery module for the dmeo is installed
     */
    @PostConstruct
    void postConstruct()
    {
        // ensure that the xts-demo AT recovery helper module is registered
        DemoATRecoveryModule.register();
    }

    /**
     * ensure that the recovery module for the dmeo is deinstalled
     */
    @PreDestroy
    void preDestroy()
    {
        // ensure that the xts-demo AT recovery helper module is registered
        DemoATRecoveryModule.unregister();
    }

    /**
     * Book a number of seats in the Theatre
     * Enrols a Participant if necessary, then passes
     * the call through to the business logic.
     *
     * @param how_many   The number of seats to book
     * @param which_area The area of the theatre to book seats in
     */
    @WebMethod
    public void bookSeats(
        @WebParam(name = "how_many", partName = "how_many")
        int how_many,
        @WebParam(name = "which_area", partName = "which_area")
        int which_area)
    {
        TheatreView theatreView = TheatreView.getSingletonInstance();
        TheatreManager theatreManager = TheatreManager.getSingletonInstance();

        String transactionId = null;
        try
        {
            // get the transaction context of this thread:
            transactionId = UserTransactionFactory.userTransaction().toString();
            System.out.println("TheatreServiceAT transaction id =" + transactionId);

            if (!theatreManager.knowsAbout(transactionId))
            {
                System.out.println("theatreService - enrolling...");
                // enlist the Participant for this service:
                TheatreParticipantAT theatreParticipant = new TheatreParticipantAT(transactionId);
                TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(theatreParticipant, "org.jboss.jbossts.xts-demo:theatreAT:" + new Uid().toString());
            }
        }
        catch (Exception e)
        {
            System.err.println("bookSeats: Participant enrolment failed");
            e.printStackTrace(System.err);
            return;
        }

        theatreView.addMessage("******************************");

        theatreView.addMessage("id:" + transactionId.toString() + ". Received a theatre booking request for " + how_many + " seats in area " + which_area);

        TheatreManager.getSingletonInstance().bookSeats(transactionId, how_many, which_area);

        theatreView.addMessage("Request complete\n");
        theatreView.updateFields();
    }
}

Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.