You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2008/06/09 20:35:50 UTC

svn commit: r665820 - in /servicemix/smx3/trunk/common/servicemix-common: ./ src/main/java/org/apache/servicemix/common/ src/main/java/org/apache/servicemix/common/osgi/ src/main/java/org/apache/servicemix/common/xbean/ src/test/java/org/apache/service...

Author: gnodet
Date: Mon Jun  9 11:35:49 2008
New Revision: 665820

URL: http://svn.apache.org/viewvc?rev=665820&view=rev
Log:
SM-1386, SM-1387: make servicemix components smx4 friendly and osgi friendly

Added:
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Container.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/SyncLifeCycleWrapper.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointExporter.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointTracker.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapper.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapperImpl.java
    servicemix/smx3/trunk/common/servicemix-common/src/test/java/org/apache/servicemix/common/NewTransactionsTest.java
Modified:
    servicemix/smx3/trunk/common/servicemix-common/   (props changed)
    servicemix/smx3/trunk/common/servicemix-common/pom.xml
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseBootstrap.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseComponent.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseLifeCycle.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultBootstrap.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultComponent.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Endpoint.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointDeliveryChannel.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointSupport.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/PersistentConfiguration.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/ServiceMixComponent.java
    servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/SimpleBeanFactory.java

Propchange: servicemix/smx3/trunk/common/servicemix-common/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Jun  9 11:35:49 2008
@@ -1,7 +1,9 @@
 target
+*.iml
+*.ipr
+*.iws
 .classpath
 .project
-.wtpmodules
 .settings
-cobertura.ser
-*.iml
+
+

Modified: servicemix/smx3/trunk/common/servicemix-common/pom.xml
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/pom.xml?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/pom.xml (original)
+++ servicemix/smx3/trunk/common/servicemix-common/pom.xml Mon Jun  9 11:35:49 2008
@@ -72,6 +72,20 @@
       <artifactId>activemq-ra</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>1.0.0</version>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+  <dependency>
+    <groupId>org.springframework.osgi</groupId>
+    <artifactId>spring-osgi-core</artifactId>
+    <version>1.0</version>
+    <scope>provided</scope>
+      <optional>true</optional>
+  </dependency>
   </dependencies>
 
   <build>
@@ -92,6 +106,45 @@
           </excludes>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>1.4.0</version>
+        <configuration>
+          <instructions>
+            <Bundle-Name>${project.name}</Bundle-Name>
+            <Bundle-SymbolicName>${artifactId}</Bundle-SymbolicName>
+            <Export-Package>org.apache.servicemix*</Export-Package>
+            <Import-Package>
+              com.ibm.wsdl*;resolution:=optional,
+              javax.resource.spi.work;resolution:=optional,
+              org.apache.servicemix;resolution:=optional,
+              org.apache.servicemix.jbi*;resolution:=optional,
+              org.apache.servicemix.components*;resolution:=optional,
+              *
+            </Import-Package>
+          </instructions>
+        </configuration>
+        <executions>
+          <execution>
+            <id>bundle-manifest</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>manifest</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.1</version>
+        <configuration>
+          <archive>
+            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+          </archive>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
   

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java Mon Jun  9 11:35:49 2008
@@ -34,6 +34,7 @@
 import javax.transaction.Status;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
+import javax.transaction.SystemException;
 import javax.xml.namespace.QName;
 
 import org.apache.commons.logging.Log;
@@ -87,6 +88,8 @@
     
     protected String currentState = LifeCycleMBean.UNKNOWN;
 
+    protected Container container;
+
     public AsyncBaseLifeCycle() {
         this.running = new AtomicBoolean(false);
         this.polling = new AtomicBoolean(false);
@@ -189,6 +192,7 @@
             if (logger.isDebugEnabled()) {
                 logger.debug("Component initialized");
             }
+            container = Container.detect(context);
         } catch (JBIException e) {
             throw e;
         } catch (Exception e) {
@@ -315,7 +319,7 @@
                 if (exchange != null) {
                     final Transaction tx = (Transaction) exchange
                                     .getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME);
-                    if (tx != null) {
+                    if (tx != null && container.handleTransactions()) {
                         if (transactionManager == null) {
                             throw new IllegalStateException(
                                             "Exchange is enlisted in a transaction, but no transaction manager is available");
@@ -400,14 +404,8 @@
     }
 
     public Object getSmx3Container() {
-        try {
-            Method getContainerMth = context.getClass().getMethod("getContainer", new Class[0]);
-            Object container = getContainerMth.invoke(context, new Object[0]);
-            return container;
-        } catch (Throwable t) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("JBI container is not ServiceMix 3 (" + t + ")");
-            }
+        if (container instanceof Container.Smx3Container) {
+            return ((Container.Smx3Container) container).getSmx3Container();
         }
         return null;
     }
@@ -438,9 +436,13 @@
             try {
                 // If we are transacted, check if this exception should
                 // rollback the transaction
-                if (transactionManager != null && transactionManager.getStatus() == Status.STATUS_ACTIVE
-                                && exceptionShouldRollbackTx(e)) {
-                    transactionManager.setRollbackOnly();
+                if (transactionManager != null && transactionManager.getStatus() == Status.STATUS_ACTIVE) {
+                    if (exceptionShouldRollbackTx(e)) {
+                        transactionManager.setRollbackOnly();
+                    }
+                    if (!container.handleTransactions()) {
+                        transactionManager.suspend();
+                    }
                 }
                 exchange.setError(e);
                 channel.send(exchange);
@@ -475,6 +477,35 @@
         return false;
     }
 
+    public void onMessageExchange(MessageExchange exchange) {
+        if (!container.handleTransactions()) {
+            final Transaction tx = (Transaction) exchange.getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME);
+            processExchangeInTx(exchange, tx);
+            return;
+        }
+        try {
+            processExchange(exchange);
+        } catch (Exception e) {
+            logger.error("Error processing exchange " + exchange, e);
+            try {
+                // If we are transacted and this is a runtime exception
+                // try to mark transaction as rollback
+                if (transactionManager != null &&
+                    transactionManager.getStatus() == Status.STATUS_ACTIVE &&
+                    exceptionShouldRollbackTx(e)) {
+                    transactionManager.setRollbackOnly();
+                    if (!container.handleTransactions()) {
+                        transactionManager.suspend();
+                    }
+                }
+                exchange.setError(e);
+                channel.send(exchange);
+            } catch (Exception inner) {
+                logger.error("Error setting exchange status to ERROR", inner);
+            }
+        }
+    }
+
     protected void processExchange(MessageExchange exchange) throws Exception {
         if (logger.isDebugEnabled()) {
             logger.debug("Received exchange: status: " + exchange.getStatus() + ", role: "
@@ -557,60 +588,45 @@
         }
     }
 
-    /**
-     * 
-     * @param exchange
-     * @param processor
-     * @throws MessagingException
-     * @deprecated use sendConsumerExchange(MessageExchange, Endpoint) instead
-     */
-    public void sendConsumerExchange(MessageExchange exchange, ExchangeProcessor processor) throws MessagingException {
-        // If the exchange is not ACTIVE, no answer is expected
-        if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
-            processors.put(exchange.getExchangeId(), processor);
-        }
-        channel.send(exchange);
-    }
-
-    /**
-     * This method allows the component to keep no state in memory so that
-     * components can be clustered and provide fail-over and load-balancing.
-     * 
-     * @param exchange
-     * @param endpoint
-     * @throws MessagingException
-     */
-    public void sendConsumerExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException {
-        prepareConsumerExchange(exchange, endpoint);
-        // Send the exchange
-        channel.send(exchange);
-    }
-    
-    public void prepareConsumerExchange(MessageExchange exchange, Endpoint endpoint) {
-        // Check if a correlation id is already set on the exchange, otherwise create it
-        String correlationIDValue = (String) exchange.getProperty(JbiConstants.CORRELATION_ID);
-        if (correlationIDValue == null) {
-            // Retrieve correlation id from thread local variable, if exist
-            correlationIDValue = correlationId.get();
+    public void prepareExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException {
+        if (exchange.getRole() == Role.CONSUMER) {
+            // Check if a correlation id is already set on the exchange, otherwise create it
+            String correlationIDValue = (String) exchange.getProperty(JbiConstants.CORRELATION_ID);
             if (correlationIDValue == null) {
-                // Set a correlation id property that have to be propagated in all components
-                // to trace the process instance
-                correlationIDValue = exchange.getExchangeId();
-                exchange.setProperty(JbiConstants.CORRELATION_ID, exchange.getExchangeId());
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Created correlation id: " + correlationIDValue);
+                // Retrieve correlation id from thread local variable, if exist
+                correlationIDValue = correlationId.get();
+                if (correlationIDValue == null) {
+                    // Set a correlation id property that have to be propagated in all components
+                    // to trace the process instance
+                    correlationIDValue = exchange.getExchangeId();
+                    exchange.setProperty(JbiConstants.CORRELATION_ID, exchange.getExchangeId());
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Created correlation id: " + correlationIDValue);
+                    }
+                } else {
+                    // Use correlation id retrieved from previous message exchange
+                    exchange.setProperty(JbiConstants.CORRELATION_ID, correlationIDValue);
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Correlation id retrieved from ThreadLocal: " + correlationIDValue);
+                    }
                 }
-            } else {
-                // Use correlation id retrieved from previous message exchange
-                exchange.setProperty(JbiConstants.CORRELATION_ID, correlationIDValue);
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Correlation id retrieved from ThreadLocal: " + correlationIDValue);
+            }
+            // Set the sender endpoint property
+            String key = EndpointSupport.getKey(endpoint);
+            exchange.setProperty(JbiConstants.SENDER_ENDPOINT, key);
+        }
+        // Handle transaction
+        if (!container.handleTransactions()) {
+            try {
+                if ((exchange.getRole() == Role.CONSUMER && exchange.getStatus() == ExchangeStatus.ACTIVE) || exchange.getRole() == Role.PROVIDER) {
+                    if (transactionManager != null && transactionManager.getStatus() == Status.STATUS_ACTIVE) {
+                        exchange.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, transactionManager.suspend());
+                    }
                 }
+            } catch (SystemException e) {
+                throw new MessagingException("Error handling transaction", e);
             }
         }
-        // Set the sender endpoint property
-        String key = EndpointSupport.getKey(endpoint);
-        exchange.setProperty(JbiConstants.SENDER_ENDPOINT, key);
     }
 
     /**

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseBootstrap.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseBootstrap.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseBootstrap.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseBootstrap.java Mon Jun  9 11:35:49 2008
@@ -37,6 +37,7 @@
  * @deprecated
  * @since 3.0
  */
+@Deprecated
 public class BaseBootstrap implements Bootstrap {
 
     protected final transient Log logger = LogFactory.getLog(getClass());

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseComponent.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseComponent.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseComponent.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseComponent.java Mon Jun  9 11:35:49 2008
@@ -194,12 +194,8 @@
         return lifeCycle.getSmx3Container();
     }
 
-    public void sendConsumerExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException {
-        lifeCycle.sendConsumerExchange(exchange, endpoint);
-    }
-
-    public void prepareConsumerExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException {
-        lifeCycle.prepareConsumerExchange(exchange, endpoint);
+    public void prepareExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException {
+        lifeCycle.prepareExchange(exchange, endpoint);
     }
 
     public QName getEPRElementName() {

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseLifeCycle.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseLifeCycle.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseLifeCycle.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/BaseLifeCycle.java Mon Jun  9 11:35:49 2008
@@ -28,6 +28,7 @@
  * @author Guillaume Nodet
  * @version $Revision$
  * @since 3.0
+ * @deprecated use SyncLifeCycleWrapper instead
  */
 public class BaseLifeCycle extends AsyncBaseLifeCycle implements MessageExchangeListener {
 
@@ -38,28 +39,4 @@
         super(component);
     }
     
-    /* (non-Javadoc)
-     * @see org.apache.servicemix.common.AsyncBaseLifeCycle#onMessageExchange(javax.jbi.messaging.MessageExchange)
-     */
-    public void onMessageExchange(MessageExchange exchange) {
-        try {
-            processExchange(exchange);
-        } catch (Exception e) {
-            logger.error("Error processing exchange " + exchange, e);
-            try {
-                // If we are transacted and this is a runtime exception
-                // try to mark transaction as rollback
-                if (transactionManager != null && 
-                    transactionManager.getStatus() == Status.STATUS_ACTIVE && 
-                    exceptionShouldRollbackTx(e)) {
-                    transactionManager.setRollbackOnly();
-                }
-                exchange.setError(e);
-                channel.send(exchange);
-            } catch (Exception inner) {
-                logger.error("Error setting exchange status to ERROR", inner);
-            }
-        }
-    }
-    
 }

Added: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Container.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Container.java?rev=665820&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Container.java (added)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Container.java Mon Jun  9 11:35:49 2008
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common;
+
+import java.lang.reflect.Method;
+
+import javax.jbi.component.ComponentContext;
+
+public abstract class Container {
+
+    public enum Type {
+        ServiceMix3,
+        ServiceMix4,
+        Unknown
+    }
+
+    protected final ComponentContext context;
+
+    protected Container(ComponentContext context) {
+        this.context = context;
+    }
+
+    public String toString() {
+        return getType().toString();
+    }
+
+    public abstract Type getType();
+
+    public abstract boolean handleTransactions();
+
+    public static Container detect(ComponentContext context) {
+        try {
+            String clName = context.getClass().getName();
+            if ("org.apache.servicemix.jbi.framework.ComponentContextImpl".equals(clName)) {
+                return new Smx3Container(context);
+            }
+            if ("org.apache.servicemix.jbi.runtime.impl.ComponentContextImpl".equals(clName)) {
+                return new Smx4Container(context);
+            }
+        } catch (Throwable t) {
+        }
+        return new UnknownContainer(context);
+    }
+
+    public static class Smx3Container extends Container {
+        public Smx3Container(ComponentContext context) {
+            super(context);
+        }
+        public Type getType() {
+            return Type.ServiceMix3;
+        }
+        public boolean handleTransactions() {
+            try {
+                Object container = getSmx3Container();
+                Method isUseNewTransactionModelMth = container.getClass().getMethod("isUseNewTransactionModel", new Class[0]);
+                Boolean b = (Boolean) isUseNewTransactionModelMth.invoke(container, new Object[0]);
+                return !b;
+            } catch (Throwable t) {
+            }
+            return true;
+        }
+        public Object getSmx3Container() {
+            try {
+                Method getContainerMth = context.getClass().getMethod("getContainer", new Class[0]);
+                Object container = getContainerMth.invoke(context, new Object[0]);
+                return container;
+            } catch (Throwable t) {
+            }
+            return null;
+        }
+    }
+
+    public static class Smx4Container extends Container {
+        public Smx4Container(ComponentContext context) {
+            super(context);
+        }
+        public Type getType() {
+            return Type.ServiceMix4;
+        }
+        public boolean handleTransactions() {
+            return false;
+        }
+    }
+
+    public static class UnknownContainer extends Container {
+        public UnknownContainer(ComponentContext context) {
+            super(context);
+        }
+        public Type getType() {
+            return Type.Unknown;
+        }
+        public boolean handleTransactions() {
+            return false;
+        }
+    }
+
+}

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultBootstrap.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultBootstrap.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultBootstrap.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultBootstrap.java Mon Jun  9 11:35:49 2008
@@ -33,6 +33,7 @@
  *    use this class directly, but copy it, or rely on the maven-jbi-plugin
  *    to provide a default implementation.
  */
+@Deprecated
 public class DefaultBootstrap implements Bootstrap
 {
 

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultComponent.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultComponent.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultComponent.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/DefaultComponent.java Mon Jun  9 11:35:49 2008
@@ -43,13 +43,14 @@
  *
  * @version $Revision$
  */
-public abstract class DefaultComponent extends BaseLifeCycle implements ServiceMixComponent {
+public abstract class DefaultComponent extends AsyncBaseLifeCycle implements ServiceMixComponent {
 
     protected final transient Log logger = LogFactory.getLog(getClass());
 
     protected Registry registry;
     protected BaseServiceUnitManager serviceUnitManager;
     protected ServiceUnit serviceUnit;
+    protected ComponentLifeCycle lifeCycle;
 
     public DefaultComponent() {
         setComponent(this);
@@ -61,7 +62,16 @@
      * @see javax.jbi.component.Component#getLifeCycle()
      */
     public ComponentLifeCycle getLifeCycle() {
-        return this;
+        if (lifeCycle == null) {
+            try {
+                // This should fail if not inside smx3
+                lifeCycle = new SyncLifeCycleWrapper(this);
+            } catch (Throwable t) {
+                // In such a case, just not wrap the lifecycle
+                lifeCycle = this;
+            }
+        }
+        return lifeCycle;
     }
 
     /* (non-Javadoc)
@@ -315,23 +325,27 @@
     }
 
 
-    /**
-     * Provides a hook to validate the statically configured endpoint
-     */
-    protected void validateEndpoint(Endpoint endpoint) throws DeploymentException {
+    public boolean isKnownEndpoint(Endpoint endpoint) {
         Class[] endpointClasses = getEndpointClasses();
         if (endpointClasses != null) {
-            boolean valid = false;
             for (int i = 0; i < endpointClasses.length; i++) {
                 Class endpointClass = endpointClasses[i];
                 if (endpointClass.isInstance(endpoint)) {
-                    valid = true;
+                    return true;
                 }
             }
-            if (!valid) {
-                throw new DeploymentException("The endpoint: " + endpoint
-                        + " is not an instance of any of the allowable types: " + Arrays.asList(endpointClasses));
-            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Provides a hook to validate the statically configured endpoint
+     */
+    protected void validateEndpoint(Endpoint endpoint) throws DeploymentException {
+        if (!isKnownEndpoint(endpoint)) {
+            throw new DeploymentException("The endpoint: " + endpoint
+                    + " is not an instance of any of the allowable types: " + Arrays.asList(getEndpointClasses()));
         }
     }
 

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Endpoint.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Endpoint.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Endpoint.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/Endpoint.java Mon Jun  9 11:35:49 2008
@@ -121,8 +121,8 @@
         return true;
     }
 
-    public void prepareConsumerExchange(MessageExchange exchange) throws MessagingException {
-        getServiceUnit().getComponent().prepareConsumerExchange(exchange, this);
+    public void prepareExchange(MessageExchange exchange) throws MessagingException {
+        getServiceUnit().getComponent().prepareExchange(exchange, this);
     }
 
     public abstract void activate() throws Exception;

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointDeliveryChannel.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointDeliveryChannel.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointDeliveryChannel.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointDeliveryChannel.java Mon Jun  9 11:35:49 2008
@@ -16,8 +16,6 @@
  */
 package org.apache.servicemix.common;
 
-import java.util.List;
-
 import javax.jbi.component.ComponentContext;
 import javax.jbi.messaging.DeliveryChannel;
 import javax.jbi.messaging.ExchangeStatus;
@@ -97,10 +95,7 @@
     }
 
     protected void prepareExchange(MessageExchange exchange) throws MessagingException {
-        if (exchange.getStatus() == ExchangeStatus.ACTIVE && exchange.getRole() == Role.CONSUMER) {
-            Endpoint ep = getEndpoint();
-            getEndpoint().prepareConsumerExchange(exchange);
-        }
+        getEndpoint().prepareExchange(exchange);
     }
 
     protected Endpoint getEndpoint() {

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointSupport.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointSupport.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointSupport.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/EndpointSupport.java Mon Jun  9 11:35:49 2008
@@ -23,11 +23,18 @@
 public class EndpointSupport {
 
     public static String getKey(QName service, String endpoint) {
-        return org.apache.servicemix.jbi.servicedesc.EndpointSupport.getKey(service, endpoint);
+        StringBuffer sb = new StringBuffer();
+        sb.append("{");
+        sb.append(service.getNamespaceURI());
+        sb.append("}");
+        sb.append(service.getLocalPart());
+        sb.append(":");
+        sb.append(endpoint);
+        return sb.toString();
     }
     
     public static String getKey(ServiceEndpoint endpoint) {
-        return org.apache.servicemix.jbi.servicedesc.EndpointSupport.getKey(endpoint);
+        return getKey(endpoint.getServiceName(), endpoint.getEndpointName());
     }
     
     public static String getKey(Endpoint endpoint) {

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/PersistentConfiguration.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/PersistentConfiguration.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/PersistentConfiguration.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/PersistentConfiguration.java Mon Jun  9 11:35:49 2008
@@ -31,9 +31,9 @@
  * configuration.
  * 
  * @author Guillaume Nodet
- * @deprecated
  * @since 3.0
  */
+@Deprecated
 public class PersistentConfiguration {
     
     public final static String CONFIG_FILE = "component.properties"; 

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/ServiceMixComponent.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/ServiceMixComponent.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/ServiceMixComponent.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/ServiceMixComponent.java Mon Jun  9 11:35:49 2008
@@ -64,24 +64,14 @@
     public String getComponentName();
     
     /**
-     * Prepare a consumer exchange from the given endpoint.
+     * Prepare an exchange sent from the given endpoint.
      * The caller need to send / sendSync the exchange. 
      * 
      * @param exchange the exchange to send
      * @param endpoint the endpoint sending the exchange
      * @throws MessagingException
      */
-    public void prepareConsumerExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException;
-
-    /**
-     * Sends a consumer exchange from the given endpoint. 
-     * 
-     * @param exchange the exchange to send
-     * @param endpoint the endpoint sending the exchange
-     * @throws MessagingException
-     * @deprecated use prepareConsumerExchange
-     */
-    public void sendConsumerExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException;
+    public void prepareExchange(MessageExchange exchange, Endpoint endpoint) throws MessagingException;
 
     /**
      * @return the QName of the element used in EPR

Added: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/SyncLifeCycleWrapper.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/SyncLifeCycleWrapper.java?rev=665820&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/SyncLifeCycleWrapper.java (added)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/SyncLifeCycleWrapper.java Mon Jun  9 11:35:49 2008
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common;
+
+import javax.jbi.component.ComponentLifeCycle;
+import javax.jbi.component.ComponentContext;
+import javax.jbi.JBIException;
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.management.ObjectName;
+
+import org.apache.servicemix.MessageExchangeListener;
+
+/**
+ * Wrap an AsyncBaseLifeCycle into a lifecycle implementing MessageExchangeListener
+ */
+public class SyncLifeCycleWrapper implements ComponentLifeCycle, MessageExchangeListener {
+
+    private AsyncBaseLifeCycle lifeCycle;
+
+    public SyncLifeCycleWrapper(AsyncBaseLifeCycle lifeCycle) {
+        this.lifeCycle = lifeCycle;
+    }
+
+    public ObjectName getExtensionMBeanName() {
+        return lifeCycle.getExtensionMBeanName();
+    }
+
+    public void init(ComponentContext componentContext) throws JBIException {
+        lifeCycle.init(componentContext);
+    }
+
+    public void shutDown() throws JBIException {
+        lifeCycle.shutDown();
+    }
+
+    public void start() throws JBIException {
+        lifeCycle.start();
+    }
+
+    public void stop() throws JBIException {
+        lifeCycle.stop();
+    }
+
+    public void onMessageExchange(MessageExchange messageExchange) throws MessagingException {
+        lifeCycle.onMessageExchange(messageExchange);
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointExporter.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointExporter.java?rev=665820&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointExporter.java (added)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointExporter.java Mon Jun  9 11:35:49 2008
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common.osgi;
+
+import java.util.Dictionary;
+import java.util.Properties;
+import java.util.Collection;
+
+import org.springframework.osgi.context.BundleContextAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationContext;
+import org.osgi.framework.BundleContext;
+import org.apache.servicemix.common.Endpoint;
+
+public class EndpointExporter implements BundleContextAware, ApplicationContextAware, InitializingBean {
+
+    private BundleContext bundleContext;
+    private ApplicationContext applicationContext;
+    private Collection<Endpoint> endpoints;
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+    }
+
+    public void setEndpoints(Collection<Endpoint> endpoints) {
+        this.endpoints = endpoints;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Collection<Endpoint> eps = this.endpoints;
+        if (eps == null) {
+            eps = this.applicationContext.getBeansOfType(Endpoint.class).values();
+        }
+        for (Endpoint ep : eps) {
+            EndpointWrapper wrapper = new EndpointWrapperImpl(ep);
+            Dictionary props = new Properties();
+            bundleContext.registerService(EndpointWrapper.class.getName(), wrapper, props);
+        }
+    }
+
+}

Added: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointTracker.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointTracker.java?rev=665820&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointTracker.java (added)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointTracker.java Mon Jun  9 11:35:49 2008
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common.osgi;
+
+import java.util.Map;
+
+import org.apache.servicemix.common.Endpoint;
+import org.apache.servicemix.common.DefaultComponent;
+
+public class EndpointTracker {
+
+    protected DefaultComponent component;
+
+    public DefaultComponent getComponent() {
+        return component;
+    }
+
+    public void setComponent(DefaultComponent component) {
+        this.component = component;
+    }
+
+    public void register(EndpointWrapper wrapper, Map properties) throws Exception {
+        System.out.println("Endpoint registered with properties: " + properties);
+        Endpoint endpoint = wrapper.getEndpoint();
+        if (component.isKnownEndpoint(endpoint)) {
+	        System.out.println("Endpoint recognized");
+            component.addEndpoint(endpoint);
+        }
+    }
+
+    public void unregister(EndpointWrapper wrapper, Map properties) throws Exception {
+        System.out.println("Endpoint unregistered with properties: " + properties);
+        Endpoint endpoint = wrapper.getEndpoint();
+        if (component.isKnownEndpoint(endpoint)) {
+	        System.out.println("Endpoint recognized");
+            component.removeEndpoint(endpoint);
+        }
+    }
+
+}

Added: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapper.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapper.java?rev=665820&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapper.java (added)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapper.java Mon Jun  9 11:35:49 2008
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common.osgi;
+
+import org.apache.servicemix.common.Endpoint;
+
+/**
+ * The EndpointWrapper is a very simple interface that wraps an Endpoint.
+ * The main purpose of this wrapper is that Spring-DM creates proxy when using
+ * collections, so that we don't have access to the real class anymore and can not
+ * do anything based on the clas itself.  Going through a wrapper works around
+ * this problem.
+ */
+public interface EndpointWrapper {
+
+    Endpoint getEndpoint();
+
+}

Added: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapperImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapperImpl.java?rev=665820&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapperImpl.java (added)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/osgi/EndpointWrapperImpl.java Mon Jun  9 11:35:49 2008
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common.osgi;
+
+import org.apache.servicemix.common.Endpoint;
+
+public class EndpointWrapperImpl implements EndpointWrapper {
+
+    private final Endpoint endpoint;
+
+    public EndpointWrapperImpl(Endpoint endpoint) {
+        this.endpoint = endpoint;
+    }
+
+    public Endpoint getEndpoint() {
+        return endpoint;
+    }
+}

Modified: servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/SimpleBeanFactory.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/SimpleBeanFactory.java?rev=665820&r1=665819&r2=665820&view=diff
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/SimpleBeanFactory.java (original)
+++ servicemix/smx3/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/xbean/SimpleBeanFactory.java Mon Jun  9 11:35:49 2008
@@ -22,6 +22,7 @@
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
 
 /**
  * A simple BeanFactory containing a set of predefined beans which can be used
@@ -47,7 +48,7 @@
         return new String[0];
     }
     public Object getBean(String name) throws BeansException {
-        return getBean(name, null);
+        return getBean(name, (Class) null);
     }
     public Object getBean(String name, Class requiredType) throws BeansException {
         Object bean = beans.get(name);
@@ -59,6 +60,12 @@
         }
         return bean;
     }
+    public Object getBean(String name, Object[] args) throws BeansException {
+        if (args != null) {
+            throw new BeanDefinitionStoreException("Bean is not a prototype");
+        }
+        return getBean(name, (Class) null);
+    }
     public Class getType(String name) throws NoSuchBeanDefinitionException {
         Object bean = beans.get(name);
         if (bean == null) {

Added: servicemix/smx3/trunk/common/servicemix-common/src/test/java/org/apache/servicemix/common/NewTransactionsTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-common/src/test/java/org/apache/servicemix/common/NewTransactionsTest.java?rev=665820&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-common/src/test/java/org/apache/servicemix/common/NewTransactionsTest.java (added)
+++ servicemix/smx3/trunk/common/servicemix-common/src/test/java/org/apache/servicemix/common/NewTransactionsTest.java Mon Jun  9 11:35:49 2008
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common;
+
+import javax.jbi.messaging.InOnly;
+import javax.jbi.messaging.ExchangeStatus;
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.component.Component;
+import javax.xml.namespace.QName;
+import javax.transaction.Status;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.apache.servicemix.jbi.container.JBIContainer;
+import org.apache.servicemix.jbi.nmr.flow.Flow;
+import org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow;
+import org.apache.servicemix.client.ServiceMixClient;
+import org.apache.servicemix.client.DefaultServiceMixClient;
+import org.apache.servicemix.common.endpoints.ProviderEndpoint;
+import org.jencks.GeronimoPlatformTransactionManager;
+import junit.framework.TestCase;
+
+public class NewTransactionsTest extends TestCase {
+
+    protected JBIContainer jbi;
+    protected TransactionManager txManager;
+    protected Component component;
+    protected ServiceMixClient client;
+    protected Exception exceptionToThrow;
+    protected boolean exceptionShouldRollback;
+
+    protected void setUp() throws Exception {
+        exceptionToThrow = null;
+        exceptionShouldRollback = false;
+
+        txManager = new GeronimoPlatformTransactionManager();
+
+        jbi = new JBIContainer();
+        jbi.setFlows(new Flow[] { new SedaFlow() });
+        jbi.setEmbedded(true);
+        jbi.setUseMBeanServer(false);
+        jbi.setTransactionManager(txManager);
+        jbi.setAutoEnlistInTransaction(true);
+        jbi.setUseNewTransactionModel(true);
+        jbi.init();
+        jbi.start();
+        component = new TestComponent();
+        jbi.activateComponent(component, "test");
+        client = new DefaultServiceMixClient(jbi);
+    }
+
+    protected void tearDown() throws Exception {
+        jbi.shutDown();
+    }
+
+    public void testTxOkAsync() throws Exception {
+        txManager.begin();
+        InOnly me = client.createInOnlyExchange();
+        me.setService(new QName("service"));
+        me.getInMessage().setContent(new StringSource("<hello>world</hello>"));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        me.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, txManager.suspend());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        client.send(me);
+        me = (InOnly) client.receive(1000);
+        assertNotNull(me);
+        assertEquals(ExchangeStatus.DONE, me.getStatus());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        txManager.resume((Transaction) me.getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        txManager.commit();
+    }
+
+    public void testTxOkSync() throws Exception {
+        txManager.begin();
+        InOnly me = client.createInOnlyExchange();
+        me.setService(new QName("service"));
+        me.getInMessage().setContent(new StringSource("<hello>world</hello>"));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        me.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, txManager.suspend());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        boolean ok = client.sendSync(me, 1000);
+        assertTrue(ok);
+        assertEquals(ExchangeStatus.DONE, me.getStatus());
+        txManager.resume((Transaction) me.getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        txManager.commit();
+    }
+
+    public void testTxExceptionAsync() throws Exception {
+        exceptionToThrow = new Exception("Business exception");
+        txManager.begin();
+        InOnly me = client.createInOnlyExchange();
+        me.setService(new QName("service"));
+        me.getInMessage().setContent(new StringSource("<hello>world</hello>"));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        me.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, txManager.suspend());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        client.send(me);
+            me = (InOnly) client.receive(1000);
+        assertNotNull(me);
+        assertEquals(ExchangeStatus.ERROR, me.getStatus());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        txManager.resume((Transaction) me.getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        txManager.commit();
+    }
+
+    public void testTxExceptionSync() throws Exception {
+        exceptionToThrow = new Exception("Business exception");
+        txManager.begin();
+        InOnly me = client.createInOnlyExchange();
+        me.setService(new QName("service"));
+        me.getInMessage().setContent(new StringSource("<hello>world</hello>"));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        me.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, txManager.suspend());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        boolean ok = client.sendSync(me, 1000);
+        assertTrue(ok);
+        assertEquals(ExchangeStatus.ERROR, me.getStatus());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        txManager.resume((Transaction) me.getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        txManager.commit();
+    }
+
+    public void testTxExceptionRollbackAsync() throws Exception {
+        exceptionToThrow = new Exception("Business exception");
+        exceptionShouldRollback = true;
+        txManager.begin();
+        InOnly me = client.createInOnlyExchange();
+        me.setService(new QName("service"));
+        me.getInMessage().setContent(new StringSource("<hello>world</hello>"));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        me.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, txManager.suspend());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        client.send(me);
+        me = (InOnly) client.receive(10000);
+        assertNotNull(me);
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        txManager.resume((Transaction) me.getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME));
+        assertEquals(Status.STATUS_MARKED_ROLLBACK, txManager.getStatus());
+        txManager.rollback();
+    }
+
+    public void testTxExceptionRollbackSync() throws Exception {
+        exceptionToThrow = new RuntimeException("Runtime exception");
+        exceptionShouldRollback = true;
+        txManager.begin();
+        InOnly me = client.createInOnlyExchange();
+        me.setService(new QName("service"));
+        me.getInMessage().setContent(new StringSource("<hello>world</hello>"));
+        assertEquals(Status.STATUS_ACTIVE, txManager.getStatus());
+        me.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, txManager.suspend());
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        boolean ok = client.sendSync(me, 1000);
+        assertTrue(ok);
+        assertEquals(Status.STATUS_NO_TRANSACTION, txManager.getStatus());
+        txManager.resume((Transaction) me.getProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME));
+        assertEquals(Status.STATUS_MARKED_ROLLBACK, txManager.getStatus());
+        assertEquals(ExchangeStatus.ERROR, me.getStatus());
+        txManager.rollback();
+    }
+
+    protected class TestComponent extends BaseComponent {
+        public TestComponent() {
+            super();
+        }
+        protected BaseLifeCycle createLifeCycle() {
+            return new TestLifeCycle();
+        }
+
+        protected class TestLifeCycle extends BaseLifeCycle {
+            protected ServiceUnit su;
+            public TestLifeCycle() {
+                super(TestComponent.this);
+            }
+            protected void doInit() throws Exception {
+                super.doInit();
+                su = new ServiceUnit();
+                su.setComponent(component);
+                TestEndpoint ep = new TestEndpoint();
+                ep.setService(new QName("service"));
+                ep.setEndpoint("endpoint");
+                ep.setServiceUnit(su);
+                su.addEndpoint(ep);
+                getRegistry().registerServiceUnit(su);
+            }
+            protected void doStart() throws Exception {
+                super.doStart();
+                su.start();
+            }
+            protected void doStop() throws Exception {
+                super.doStop();
+                su.stop();
+            }
+            protected boolean exceptionShouldRollbackTx(Exception e) {
+                return exceptionShouldRollback;
+            }
+        }
+
+        protected class TestEndpoint extends ProviderEndpoint {
+            public void process(MessageExchange exchange) throws Exception {
+                if (exceptionToThrow != null) {
+                    throw exceptionToThrow;
+                }
+                exchange.setStatus(ExchangeStatus.DONE);
+                send(exchange);
+            }
+        }
+    }
+
+}