About this project :
--------------------

The main goal of this project is to adapt the Apache Camel ESB on a JOnAS 5
OSGi platform and to provide an easy to use and easy to integrate Camel OSGi
service.

Feel free to report all the issues/comments you may have on the project to the
JOnAS users list.

Content :
---------

In this project, you will find :
    - Camel-related modules:
        - camel-service: a bundle for an OSGi platform that provides a Camel
          service. It uses iPOJO to provides services on the OSGi gateway.
        - camel-registry: Camel component that implements a simple
          registry/repository service (with an XML file implementation)
    - Utility modules:
        - cxf-servlet-deployer: deploys CXF servlets on the OSGi HTTP Service
          (instead of the default embedded Jetty Web server)
        - cxf-servlet-deployer-starter: starts the cxf-servlet-deployer iPOJO
          component on servletPath /services with a busName set to cxfBus
    - Usage-oriented modules (examples, tests and packaging):
        - example-cxf: simple CXF example route. Uses the camel-service,
          camel-registry and the CXF-related services
        - example-jms: simple JMS example route, that uses camel-jms through
          JORAM (via JNDI lookups). Uses the camel-service and camel-registry
        - camel-jonas5-test-and-package: creates a JONAS_ROOT and JONAS_BASE
          with all required bundles. It automatically:
            - Downloads JOnAS
            - Adds all required bundles on it
            - Configures (creates a JONAS_BASE)
            - Starts it up and deploys the test bundles
            - Run some tests
            - Generates ZIP and TAR.GZ files that can directly be reused for
              launching JOnAS with Camel installed.

Requirements :
--------------

To run and test this project, you need :
    - a JDK 5
    - Apache Maven
    - The OW2 JOnAS 5.1 AS with:
        * The standard Spring bundle
        * The JAX-2.1 and CXF 2.2 upgrade
        * The Tomcat Web Container exposed as an OSGi HTTP Service
      That version is currently only available as source form on the JOnAS SVN
      and is downloadable from Maven repositories (OW2 and Central)

Build the project and run the tests :
-------------------------------------

Use Apache Maven: mvn clean install

The Maven build project will automatically download the good JOnAS versions
from the repositories and once the tests pass create a package with:
    - JOnAS 5.1
    - JAX-WS 2.1 + CXF 2.2
    - Tomcat OSGi HTTPService
    - Camel 2.0.0 with support for core, CXF, FTP, JMS and mail

Run on JOnAS :
--------------

The Maven command generates a ZIP and TAR.GZ file in the target folder of the
camel-jonas5-test-and-package module. These two files contain the JONAS_ROOT
and JONAS_BASE preconfigured for working with Camel (core, CXF, FTP and JMS).
Simply:

    1 - Unzip one of these files
    2 - Set the JONAS_ROOT and JONAS_BASE accordingly, making sure the camel
        service is enabled in the jonas.services list
    3 - Start JOnAS: jonas start

JOnAS will then start with the Camel service. The Camel service will print:
            Activator.start : Camel activator starting
            Activator.start : Camel activator started
            CamelService.__initialize : Camel service started
after being initialized. Look for them in the JOnAS logs when starting.

Running the CAMEL-JMS examples on JOnAS :
-----------------------------------------

Once the JOnAS with Camel has successfully started, copy the bundle (JAR file)
in the example-jms/target folder to your JONAS_BASE. This will deploy the
CAMEL-JMS example on JOnAS and send a few messages via JMS. It should print out
messages such as:
            CamelService.__startNewContext : Starting a new camel context
        ...
            ExampleJMS$1$1.process : Received JMS message Test Message: 0

Running the CAMEL-CXF examples on JOnAS :
-----------------------------------------

Once the JOnAS with Camel has successfully started, copy the bundle (JAR file)
in the example-jms/target folder to your JONAS_BASE. This will deploy the
CAMEL-CXF example on JOnAS and send a few messages via JMS. It should print out
messages such as:
            CamelService.__startNewContext : Starting a new camel context
        ...
            ExampleCXF$1$1.process : Received CXF message guillaume
            ExampleCXF.test : Got CXF response hello, guillaume

Features provided by this package :
-----------------------------------

  -- The Camel wrapper --

The service implementation contains a wrapper of a Camel context, which is
instantiated by the service when an application requires one. This wrapper
contains :

    * A DefaultCamelContext object. This is the Camel context.
    * A String that contains the name of the Camel context. This name is used
      to identify the context in the applications that are using it.
    * A FileRegistryComponent object. This is a camel component automatically
      associated with each Camel context instantiated by the service. It
      provides a registry that allows bindings between a logical endpoint name
      and technical one. Instead of typing an entire endpoint definition to
      configure a route, it is just needed to give the logical entry in the
      registry.

Example:

   this.from("registry:cxfEndpoint")

which is a lot easier to write and read than:

    this.from("cxf://http://localhost:9000/SayHello" +
        "?serviceClass=org.ow2.jonas.camel.example.cxf.webservice.api.ISayHello" +
        "&dataFormat=POJO")

These entries are set from an xml file, that matches the following XSD :

    <schema targetNamespace="org.ow2.jonas.camel.registry.impl.file:FileRegistry"
      elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema"
      xmlns:tns="org.ow2.jonas.camel.registry.impl.file:FileRegistry">
      <element name="registry" type="tns:registry"></element>

      <complexType name="registry">
        <sequence maxOccurs="unbounded" minOccurs="0">
          <element name="entry" type="tns:entry"></element>
        </sequence>
      </complexType>

      <complexType name="entry">
        <sequence maxOccurs="1" minOccurs="1">
          <element name="logicalName" type="string"></element>
          <element name="technicalName" type="string"></element>
        </sequence>
      </complexType>
    </schema>

Therefore, the file that allows the developer to use the previous example is :

    <registry xmlns="org.ow2.jonas.camel.registry.impl.file:FileRegistry"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="org.ow2.jonas.camel.registry.impl.file:FileRegistry FileRegistry.xsd">
      <entry>
        <logicalName>cxfEndpoint</logicalName>
        <technicalName>
        <![CDATA[
            cxf://
            http://localhost:9000/SayHello?
            serviceClass=org.ow2.jonas.camel.example.cxf.webservice.api.ISayHello&
            dataFormat=POJO
        ] ]>
        </technicalName>
      </entry>
    </registry>

    -- The Camel service --

The Camel service (the only service provided by the Camel service bundle) is
able of triggering useful actions on the Camel contexts it owns:

    * Start a Camel context:

        // Start a new context for the application
        this.camelContextName = this.camelService.startNewContext();

    * Stop a Camel context:

        // Stop a Camel context
        this.camelService.stop(this.camelContextName);;

    * Add entries to the registry from an xml file:

        // Add the registry entries
        ClassLoader cl = this.getClass().getClassLoader();
        InputStream input = cl.getResourceAsStream("registry.xml");
        this.camelService.addRegistry(input, this.camelContextName);

    * Add routes on a given Camel context. Example :

        // Prepare a route to add in the created context
        RouteBuilder builder = new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                this.from("registry:InboundJMSQueue").to("registry:OutboundFile");
            }
        };

        // Add the route in the camel context.
        this.camelService.addRoutes(builder, this.camelContextName);

    * Add component on a given Camel context. For example, add a JMSComponent
      that uses a JORAM factory, and then use it in a route:

        // Add the JORAM component
        JmsComponent joram = new JmsComponent();
        ConnectionFactory connectionFactory;

        connectionFactory = (ConnectionFactory) new InitialContext().lookup("CF");

        joram.setConnectionFactory(connectionFactory);
        JndiDestinationResolver jndiDestinationResolver = new JndiDestinationResolver();
        jndiDestinationResolver.setCache(true);

        joram.setDestinationResolver(jndiDestinationResolver);

        this.camelService.addComponent("joram", joram, this.camelContextName);

        // Prepare a route to add in the created context
        RouteBuilder builder = new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                this.from("joram:queue:queueSample").to("file:///tmp/test");
            }
        };

    * Remove entries from the registry. Example :

        // Remove entries from the registry
        ClassLoader cl = this.getClass().getClassLoader();
        InputStream input = cl.getResourceAsStream("registry.xml");
        this.camelService.removeRegistry(input, this.camelContextName);

Please see the Javadoc of the service and the examples for more details.
