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

The main goal of this project is to adapt the Apache Camel lightweight 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, which uses iPOJO to provides services on the OSGi gateway
        - camel-xml-registry: Camel component that implements a simple
          XML-based registry/repository service
        - camel-component-for-jonas: iPOJO CAMEL component for JOnAS, which
          internally handles many aspects:
            - All registry*.properties files are read from JONAS_BASE/conf
            - All registry*.xml files are read from JONAS_BASE/conf
            - The properties are injected into the XML files
            - XML files are injected into the Camel context
            - The good class loader is placed before calling configure()
            - Adds the tracing components, that can even send Camel route logs
              to any given destination (for example, JMS)
    - 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
    - Packaging:
        - package-camel: packaging containing CAMEL 2.6.0, the JOnAS-CAMEL
          service as well as the deployment plans for deploying CAMEL on JOnAS
        - package-with-jonas: a full JONAS_ROOT and JONAS_BASE with all
          required bundles, deploymant plans and a "camel" service in
          jonas.properties. 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
    - Examples:
        - example-cxf: simple CXF example route. Uses the camel-service,
          camel-xml-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-xml-registry

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

To run and test this project, you need :
    - A JDK 5 or 6
    - Apache Maven
    - The OW2 JOnAS Application Server, version 5.2.0 or newer

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.2.0
    - Camel 2.6.0 with support for core, CXF, FTP, JDBC, JMS and mail

Run on JOnAS as a deployment plan :
-----------------------------------

Maven will generate an archive in the package-camel module, which contains
deployment plans for JOnAS as well as all bundle dependencies. In order to
deploy it on JOnAS:

    1 - Download JOnAS 5.2.0 or newer
    2 - Extract the package-camel archive into your JONAS_ROOT. This will
        add-in some CAMEL-related deployment plans into url-internals and
        CAMEL-related bundles into maven2-internal
    3 - Place the camel.xml deployment plan into the deploy folder, in your
        JONAS_BASE

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.

Run on JOnAS as a service :
---------------------------

The Maven command also generates an archive in its package-with-jonas module.
That module contains JOnAS 5.2.0 with the CAMEL-related deployment plans
and bundles.

It also adds a new service in the jonas.properties file, called camel. This
guarantees that CAMEL will be started as a service, and therefore you can
directly place your route bundles in the JONAS_BASE/deploy directory.

To run it:

    1 - Decompress one of these archive
    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:

    1 - Copy the JMS example's registry XML file, registry-example-jms.xml,
        into JONAS_BASE/conf
    2 - Copy the JMS example's bundle JAR file, example-jms-1.6.0.jar,
        into JONAS_BASE/deploy

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

It will also create a file named the same as the message in the JONAS_BASE/logs
folder (you should therefore avoid "weird" names).

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

Once the JOnAS with Camel has successfully started:

    1 - Copy the CXF example's registry XML file, registry-example-cxf.xml,
        into JONAS_BASE/conf
    2 - Copy the CXF example's bundle JAR file, example-cxf-1.6.0.jar,
        into JONAS_BASE/deploy

This will deploy the CAMEL-CXF example on JOnAS and send a few messages via Web
Service. 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 :

    * The Camel context.
    * The registry/repository wrapper 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 bundles) 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:sampleQueue").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.
