[jboss-svn-commits] JBL Code SVN: r37218 - in labs/jbosstm/trunk/rest-tx/quickstarts: service and 7 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Jul 4 06:11:55 EDT 2011


Author: mmusgrov
Date: 2011-07-04 06:11:55 -0400 (Mon, 04 Jul 2011)
New Revision: 37218

Added:
   labs/jbosstm/trunk/rest-tx/quickstarts/service/
   labs/jbosstm/trunk/rest-tx/quickstarts/service/pom.xml
   labs/jbosstm/trunk/rest-tx/quickstarts/service/readme.txt
   labs/jbosstm/trunk/rest-tx/quickstarts/service/run.bat
   labs/jbosstm/trunk/rest-tx/quickstarts/service/run.sh
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/JaxrsServer.java
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/MultipleParticipants.java
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/TransactionAwareResource.java
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/test/
   labs/jbosstm/trunk/rest-tx/quickstarts/service/src/test/java/
   labs/jbosstm/trunk/rest-tx/quickstarts/simple/src/main/java/MultipleTransactions.java
Modified:
   labs/jbosstm/trunk/rest-tx/quickstarts/pom.xml
   labs/jbosstm/trunk/rest-tx/quickstarts/simple/pom.xml
Log:
[JBTM-856] Include an example showing transactional web services

Modified: labs/jbosstm/trunk/rest-tx/quickstarts/pom.xml
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/pom.xml	2011-07-04 09:04:21 UTC (rev 37217)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/pom.xml	2011-07-04 10:11:55 UTC (rev 37218)
@@ -41,27 +41,6 @@
     <build>
         <plugins>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>exec-maven-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>exec</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <configuration>
-                    <executable>java</executable>
-                    <workingDirectory>${project.build.directory}/exec-working-directory</workingDirectory>
-                    <arguments>
-                        <argument>-classpath</argument>
-                        <classpath />
-                        <argument>RestTransactionExample</argument>
-                    </arguments>
-                </configuration>
-            </plugin>
-
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
@@ -74,5 +53,6 @@
     
     <modules>
     	<module>simple</module>
+    	<module>service</module>
     </modules>
 </project>

Added: labs/jbosstm/trunk/rest-tx/quickstarts/service/pom.xml
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/service/pom.xml	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/service/pom.xml	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>quickstarts</artifactId>
+        <groupId>org.jboss.narayana.rts.quickstarts</groupId>
+        <version>5.0.0.M1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>service</artifactId>
+    <name>quickstart Participant Service</name>
+    <description>Examples show how a web service can participate in a transaction</description>
+
+    <repositories>
+        <!-- Jersey -->
+        <repository>
+            <id>maven2-repository.dev.java.net</id>
+            <name>Java.net Repository for Maven</name>
+            <url>http://download.java.net/maven/2/</url>
+            <layout>default</layout>
+        </repository>
+        <!-- end Jersey -->
+    </repositories>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <executable>java</executable>
+                    <workingDirectory>${project.build.directory}/exec-working-directory</workingDirectory>
+                    <arguments>
+                        <argument>-classpath</argument>
+                        <classpath />
+                        <argument>quickstart.MultipleParticipants</argument>
+                    </arguments>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <!-- the implementation of REST Atomic Transactions -->
+        <dependency>
+            <groupId>org.jboss.narayana.rts</groupId>
+            <artifactId>rest-tx-api</artifactId>
+            <version>5.0.0.M1-SNAPSHOT</version>
+        </dependency>
+
+        <!-- Jersey container for running participant services -->
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>1.5-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>1.5-SNAPSHOT</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>com.sun.grizzly</groupId>
+            <artifactId>grizzly-servlet-webserver</artifactId>
+            <version>1.9.18-i</version>
+        </dependency>
+        <!-- end Jersey -->
+    </dependencies>
+
+</project>

Added: labs/jbosstm/trunk/rest-tx/quickstarts/service/readme.txt
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/service/readme.txt	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/service/readme.txt	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,52 @@
+OVERVIEW
+--------
+This example shows how you can make your web services transactional. [The example uses Jersey and Grizzly
+for deploying the participant web services but any conforming web container will do].
+
+
+USAGE
+-----
+Deploy the rest-tx war (rest-tx-web-5.0.0.M1-SNAPSHOT.war) into a running AS7 (or AS6) application server listening
+for http requests on localhost (if you use a different host/port change the url in MultipleParticipants.TXN_MGR_URK).
+
+mvn compile exec:exec
+
+
+EXPECTED OUTPUT
+---------------
+1. You will see 2 lines of output showing the service enlisting into the transaction.
+2. A message showing the client committing transaction.
+3. Two resouces will output two messages during the transaction committment protocol. One
+saying that it has prepared and the other reporting that it has committed.
+4. And finally the build will report success or failure:
+
+	[INFO] BUILD SUCCESS
+
+indicates a successful outcome.
+
+
+WHAT JUST HAPPENED?
+-------------------
+1. We deployed a JAX-RS servlet that implements a RESTful interface to the Narayana transaction manager (TM)
+(running in an AS7 or AS6 container).
+
+2. The client (MultipleParticpants.java) started an embedded web server (JaxrsServer.java) for hosting web services.
+
+3 The client then started a REST Atomic Transaction and got back two urls: one for completing the transaction
+and one for use with enlisting durable participants (implemented by the class TransactionAwareResource.java)
+into the transaction.
+
+4. The client then made two HTTP requests to a web service and passed the participant enlistment url as part
+of the context of the request (using a query parameter).
+
+5. The participants used the enlistment url to join the transaction. In this naive example we assumes that
+each request is for a separate unit of transactional work and in this way we end up with multiple participants
+beining involved in the transaction. Having more than one participant means we can demonstrate that either all
+participants will commit or none them will.
+
+6. The client commits the transaction using the resource url it got back when it created the transaction.
+
+7. The transaction manager implementation knows that there are two resources involved and asks them both to
+prepare their work (using the resource urls it got from the participants when they enlisted into the transaction).
+If the particpant resources respond with the correct HTTP status code and body then the transaction manager
+proceeds to request committment. Refer to the REST Atomic Transactions spec for full details.

Added: labs/jbosstm/trunk/rest-tx/quickstarts/service/run.bat
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/service/run.bat	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/service/run.bat	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,6 @@
+ at echo off
+
+echo "Running service quickstart"
+
+mvn compile exec:exec
+IF %ERRORLEVEL% NEQ 0 exit -1


Property changes on: labs/jbosstm/trunk/rest-tx/quickstarts/service/run.bat
___________________________________________________________________
Added: svn:executable
   + *

Added: labs/jbosstm/trunk/rest-tx/quickstarts/service/run.sh
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/service/run.sh	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/service/run.sh	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,9 @@
+# ALLOW JOBS TO BE BACKGROUNDED
+set -m
+
+echo "Running service quickstart"
+
+mvn compile exec:exec
+if [ "$?" != "0" ]; then
+	exit -1
+fi


Property changes on: labs/jbosstm/trunk/rest-tx/quickstarts/service/run.sh
___________________________________________________________________
Added: svn:executable
   + *

Added: labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/JaxrsServer.java
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/JaxrsServer.java	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/JaxrsServer.java	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,56 @@
+package quickstart;
+
+import com.sun.grizzly.http.SelectorThread;
+import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
+
+import javax.ws.rs.core.UriBuilder;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Start a simple embedded web server for hosting web services that will participate in
+ * REST Atomic transactions.
+ *
+ * We use Grizzly since it is the reference implementation and it supports JAX-RS.
+ * Using JAX-RS make our web service example is trivial to implement.
+ */
+public class JaxrsServer {
+   private static SelectorThread threadSelector = null;
+
+/*   public static void startTJWS(String host, int port) {
+        org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer server;
+        server = new org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer();
+        server.setPort(port);
+        server.start();
+
+        org.jboss.resteasy.spi.Registry registry = server.getDeployment().getRegistry();
+
+        registry.addPerRequestResource(TransactionAwareResource.class);
+    }*/
+
+    public static void startGrizzly(String host, int port) {
+        final URI baseUri= UriBuilder.fromUri("http://" + host + ':' + port + '/').build();
+        final Map<String, String> initParams = new HashMap<String, String>();
+        String packages = TransactionAwareResource.class.getPackage().getName();
+        initParams.put("com.sun.jersey.config.property.packages", packages);
+
+        try {
+            threadSelector = GrizzlyWebContainerFactory.create(baseUri, initParams);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void startServer(String host, int port) {
+         startGrizzly(host, port);
+    }
+
+    public static void stopServer() {
+        if (threadSelector != null)
+            threadSelector.stopEndpoint();
+
+        threadSelector = null;
+    }
+}

Added: labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/MultipleParticipants.java
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/MultipleParticipants.java	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/MultipleParticipants.java	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,42 @@
+package quickstart;
+
+import org.jboss.jbossts.star.util.TxSupport;
+import java.net.HttpURLConnection;
+
+public class MultipleParticipants {
+    private static final int host = 0;
+    private static final String[] hosts = {"localhost:8080", "184.72.71.236", "jbossapp1-mmusgrov1.dev.rhcloud.com"};
+    private static final String TXN_MGR_URL = "http://" + hosts[host] + "/rest-tx/tx/transaction-manager";
+
+    private static final int SERVICE_PORT = 58082;
+    private static final String SERVICE_URL =  "http://localhost:" + SERVICE_PORT + '/' + TransactionAwareResource.PSEGMENT;
+
+    public static void main(String[] args) {
+        // the example uses an embedded JAX-RS server for running the service that will take part in a transaction
+        JaxrsServer.startServer("localhost", SERVICE_PORT);
+
+        // get a helper for using RESTful transactions passing in the resource endpoint for the transaction manager
+        TxSupport txn = new TxSupport(TXN_MGR_URL);
+
+        // start a RESTful transaction
+        txn.startTx();
+
+        /*
+         * Send two web service requests. Include the resource url for registering durable participation
+         * in the transaction with the request
+         */
+        String serviceRequest = SERVICE_URL + "?enlistURL=" + txn.enlistUrl();
+
+        txn.httpRequest(new int[] {HttpURLConnection.HTTP_OK}, serviceRequest, "GET", TxSupport.PLAIN_MEDIA_TYPE, null, null);
+        txn.httpRequest(new int[] {HttpURLConnection.HTTP_OK}, serviceRequest, "GET", TxSupport.PLAIN_MEDIA_TYPE, null, null);
+
+        // commit the transaction
+        System.out.println("committing transaction");
+        txn.commitTx();
+
+        // the web service should have received prepare and commit requests from the transaction manager (TXN_MGR_URL)
+
+        // shutdown the embedded JAX-RS server
+        JaxrsServer.stopServer();
+    }
+}

Added: labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/TransactionAwareResource.java
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/TransactionAwareResource.java	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/service/src/main/java/quickstart/TransactionAwareResource.java	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,66 @@
+package quickstart;
+
+import org.jboss.jbossts.star.util.TxSupport;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.net.HttpURLConnection;
+
+/**
+ * An example of how a REST resource can act as a participant in a RESTful transaction.
+ * For a complete implementation of a participant please refer to the test suite, in particular the inner class:
+ * org.jboss.jbossts.star.test.BaseTest$TransactionalResource implements all the responsibilities of a participant
+ *
+ * The example sends a service request which is handled by the method someServiceRequest. The request includes the
+ * URL for registering durable participants within the transaction. This naive implementation assumes every request
+ * with a valid enlistment URL is a request a new unit of transactional work and enlists a new URL into the transaction.
+ * Thus if a client makes two http requests to the method someServiceRequest then the participant is enlisted twice
+ * into the transaction but with different completion URLs.
+ */
+ at Path("service")
+public class TransactionAwareResource {
+    public static final String PSEGMENT = "service";
+    private static int workId = 0;
+
+    @GET
+    public String someServiceRequest(@Context UriInfo info, @QueryParam("enlistURL") @DefaultValue("")String enlistUrl) {
+        if (enlistUrl == null || enlistUrl.length() == 0)
+            return ("non transactional request");
+
+        String serviceURL = info.getBaseUri() + info.getPath();
+        String workURL = serviceURL + "/1/" + ++workId;
+
+        String terminator = workURL + "/terminate";
+        String participant = workURL + "/terminator";
+
+        String pUrls = TxSupport.getParticipantUrls(terminator, participant);
+        System.out.println("enlisting " + pUrls);
+
+        return new TxSupport().httpRequest(new int[] {HttpURLConnection.HTTP_CREATED}, enlistUrl,
+                "POST", TxSupport.POST_MEDIA_TYPE, pUrls, null);
+    }
+
+    /*
+     * this method handles PUT requests to the url that the participant gave to the REST Atomic Transactions implementation
+     * (in the someServiceRequest method). This is the endpoint that the transaction manager interacts with when it needs
+     * participants to prepare/commit/rollback their transactional work.
+     */
+    @PUT
+    @Path("{pId}/{wId}/terminate")
+    public Response terminate(@PathParam("pId") @DefaultValue("")String pId, @PathParam("wId") @DefaultValue("")String wId, String content) {
+        System.out.println("participant terminate resource: PUT request: wId=" + wId + ", status:=" + content);
+        String status = TxSupport.getStatus(content);
+
+        if (TxSupport.isPrepare(status)) {
+            return Response.ok(TxSupport.toStatusContent(TxSupport.PREPARED)).build();
+        } else if (TxSupport.isCommit(status)) {
+            return Response.ok(TxSupport.toStatusContent(TxSupport.COMMITTED)).build();
+        } else if (TxSupport.isAbort(status)) {
+            return Response.ok(TxSupport.toStatusContent(TxSupport.ABORTED)).build();
+        } else {
+            return Response.status(HttpURLConnection.HTTP_BAD_REQUEST).build();
+        }
+    }
+}

Modified: labs/jbosstm/trunk/rest-tx/quickstarts/simple/pom.xml
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/simple/pom.xml	2011-07-04 09:04:21 UTC (rev 37217)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/simple/pom.xml	2011-07-04 10:11:55 UTC (rev 37218)
@@ -26,8 +26,34 @@
     <artifactId>simple</artifactId>
     <version>5.0.0.M1-SNAPSHOT</version>
     <name>RESTful Atomic Transaction Quickstarts</name>
-    <description>Provides examples of how to use transactions with web applications</description>
+    <description>Basic example of how to start and stop a REST Atomic transaction</description>
 
+    <build>
+        <plugins>
+             <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <executable>java</executable>
+                    <workingDirectory>${project.build.directory}/exec-working-directory</workingDirectory>
+                    <arguments>
+                        <argument>-classpath</argument>
+                        <classpath />
+                        <argument>RestTransactionExample</argument>
+                        <argument>MultipleTransactions</argument>
+                    </arguments>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
     <dependencies>
         <dependency>
             <groupId>org.jboss.narayana.rts</groupId>

Added: labs/jbosstm/trunk/rest-tx/quickstarts/simple/src/main/java/MultipleTransactions.java
===================================================================
--- labs/jbosstm/trunk/rest-tx/quickstarts/simple/src/main/java/MultipleTransactions.java	                        (rev 0)
+++ labs/jbosstm/trunk/rest-tx/quickstarts/simple/src/main/java/MultipleTransactions.java	2011-07-04 10:11:55 UTC (rev 37218)
@@ -0,0 +1,36 @@
+import org.jboss.jbossts.star.util.TxSupport;
+
+public class MultipleTransactions {
+    private static final String[] hosts = {"localhost:8080", "184.72.71.236", "jbossapp1-mmusgrov1.dev.rhcloud.com"};
+    private static final String TXN_MGR_URL = "http://" + hosts[1] + "/rest-tx/tx/transaction-manager";
+
+    public static void main(String args[]) throws Exception {
+        // create a helper with the desired transaction manager resource endpoint
+        TxSupport[] txns = { new TxSupport(TXN_MGR_URL), new TxSupport(TXN_MGR_URL)};
+
+        // start transactions
+        for (TxSupport txn: txns)
+            txn.startTx();
+
+        // verify that all the transactions are active
+        for (TxSupport txn: txns)
+            if (!txn.txStatus().equals(TxSupport.TX_ACTIVE))
+                throw new RuntimeException("A transaction should be active: " + txn.txStatus());
+
+        // see how many RESTful transactions are running (there should be at least one)
+        int txnCount = txns[0].txCount();
+
+        if (txns[0].txCount() != 2)
+            throw new RuntimeException("At least one transaction did not start");
+
+        // end the transaction
+        for (TxSupport txn: txns)
+            txn.commitTx();
+
+        // there should now be one fewer transactions
+        if (txns[0].txCount() >= txnCount)
+            throw new RuntimeException("At least one transaction did not complete");
+
+        System.out.println("Success");
+    }
+}



More information about the jboss-svn-commits mailing list