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 Tomcat Web Container exposed as an OSGi
      HTTP Service, currently only available on the Maven repository.

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

Use Apache Maven: mvn clean install

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.
