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)
        - libraries: bundles for CXF 2.2.2 with WS-RM patches, JAX-WS 2.1 with
          the WS-RS packages and jsch
    - 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-osgi-package: tests CXF and JMS then packages a Felix with all
          CAMEL-related bundles (that will be ready to accept our examples but
          also any other CAMEL route you'd develop)

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

To run and test this project, you need :
    - a JDK 5
    - Either :
        - An OSGi framework, for example Apache Felix
        or
        - 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

Running on Felix :
-----------------------------------

The camel-osgi-package module generates ZIP and TAR.GZ files that contain
Felix, all CAMEL bundles as well as common dependencies (CXF, etc.). Simply
decompress the archive and run camel-on-osgi.

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

First, you need to download JOnAS with the Tomcat Web Container exposed as an
OSGi HTTP Service. You can either:

    - Download a version that's been generated against a stable JOnAS build:
        http://maven.ow2.org/maven2/org/ow2/jonas/jonas-web-container-tomcat-6.0-with-http-service/
    or
    - Download a version that's been generated against a SNAPSHOT JOnAS build:
        http://maven.ow2.org/maven2-snapshot/org/ow2/jonas/jonas-web-container-tomcat-6.0-with-http-service/
    or
    - Generate the package by yourself by checking it out from the OW2 SVN and
      compiling it with Maven:
        svn://svn.forge.objectweb.org/svnroot/jonas/sandbox/jonas-tomcat-osgi-httpService

Then, run your JOnAS application server by using its start command:
    ${JONAS_ROOT}/bin/jonas start
feel free to use the "-gui" option to see the Apache Felix GUI.

Once the modules have been built, Maven will place them in your Maven
repository. JOnAS supports deployment plans that can automatically fetch these
bundles from your local Maven repository and from the Internet in the case you
don't have them.

The deployment-plans folder of this project contains all these deployment
plans. To use them:

    1 - Open the repositories.xml file and modify the maven-repository-local
        entry to your local Maven repository (else, JOnAS will try to download
        all bundles from the Internet; which can be slow).
    2 - Copy the repositories.xml file to your JONAS_BASE/deploy folder (this
        will add the listed repositories to JOnAS' dependency search path).
    3 - Copy the camel.xml file to your JONAS_BASE/deploy folder. This will
        start the JOnAS CAMEL service. Once the JOnAS CAMEL service is ready,
        your JOnAS console should print:
            CamelService.__initialize : Camel service started
    4 - Copy other CAMEL and example deployment plans to start associated
        routes. See the next two parts for details.

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

Once the camel.xml deployment plan is successfully deployed:

    1 - Copy the camel-jms.xml file to your JONAS_BASE/deploy folder. This will
        deploy all JMS-related bundles on JOnAS.
    2 - Copy the camel-jms-example.xml file to your JONAS_BASE/deploy folder.
        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 : From File: GenericFileMessage with body: Test Message: 0

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

The current JOnAS version uses CXF 2.0; which is not compatible with CAMEL's
CXF 2.2 requirements. See https://issues.apache.org/activemq/browse/CAMEL-1862
for details.

To overcome this problem, you have two options:

    - Open the jonas.properties file and disable the jaxws service
    or
    - Change the CXF version shipped with JOnAS

To do the latter, follow these steps:

    1 - Open the repositories/url-internal/jaxws-cxf.xml file in the JONAS_ROOT
    2 - Comment out the XML deployment element with id
            org.ow2.bundles:ow2-bundles-externals-cxf-2.0:jar
    3 - Right after that element that's been commented out, add:

            <!-- JAXWS 2.1 with WS-RS -->
            <deployment id="org.ow2.jonas.camel:camel-jonas5-jaxws:jar" xsi:type="m2:maven2-deploymentType">
              <m2:groupId>org.ow2.jonas.camel</m2:groupId>
              <m2:artifactId>camel-jonas5-jaxws</m2:artifactId>
              <m2:version>1.1.1</m2:version>
            </deployment>

            <!-- CXF 2.2.x with WS-RM patches -->
            <deployment id="org.ow2.jonas.camel:camel-jonas5-cxf:jar" xsi:type="m2:maven2-deploymentType">
              <m2:groupId>org.ow2.jonas.camel</m2:groupId>
              <m2:artifactId>camel-jonas5-cxf</m2:artifactId>
              <m2:version>1.1.1</m2:version>
            </deployment>

        Note: These two elements have been copied from the cxf-2.2.x.xml
              deployment plan file.
    4 - (Optional, only do it if you'll run JOnAS without Internet access)

        In the repositories/maven2-internal folder inside your JONAS_ROOT,
        create the appropriate tree structure (maven-like) and copy the
        following dependencies:
            org.ow2.jonas.camel:camel-jonas5-cxf
            org.ow2.jonas.camel:camel-jonas5-jaxws
    5 - Now, JOnAS is will be started with the Tomcat OSGi HTTPService Web
        Container and without CXF 2.0 but CXF 2.2. Save that configuration for
        later use, start JOnAS and deploy the camel.xml deployment plan.

You can then start JOnAS with the Tomcat Web Container exposed as an OSGi HTTP
Service and with and upgraded CXF 2.2. Once started, deploy the camel.xml
deployment plan on it and:

    1 - Copy the camel-cxf.xml file to your JONAS_BASE/deploy folder. This will
        deploy all CXF-related bundles on JOnAS.
    2 - Copy the camel-cxf-example.xml file to your JONAS_BASE/deploy folder.
        This will deploy the CAMEL-CXF example on JOnAS and send a few messages
        via CXF. It should print out messages such as:
            CamelService.__startNewContext : Starting a new camel context
        ...
            ExampleCXF$1$1.process : Message : 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.
