newton
Newton
 

Newton: Creating composites - Hello World

This page describes how to create a simple Newton composite, HelloWorld. Before you start, you should configure Ant for Building Composites.

Note
This article is not intended to introduce you to Newton composites in general. For this see the examples. The emphasis here is on writing your own composites.

Whilst the following is presented as a hands-on example of how component build process works, all of the code shown is also included in the Newton examples.

We will be creating two separate composites, one exposing the HelloWorld service and the other providing a command line extension called PrintHello which is used to test the HelloWorld service.

The HelloWorld interface looks like this:

package example.api;

public interface HelloWorld {
    String getGreeting();
}

Here is its implementation

package example.impl;

import example.api.HelloWorld;

public class HelloWorldImpl implements HelloWorld {
    public String getGreeting() {
        return "Hello World";
    }
}

The PrintHello class looks like this:

package example.cli;

import java.io.PrintWriter;

import org.cauldron.newton.command.CommandException;
import org.cauldron.newton.command.CommandRequest;
import org.cauldron.newton.command.CommandResponse;
import org.cauldron.newton.command.console.ConsoleCommandHandler;
import example.api.HelloWorld;

public class PrintHello extends ConsoleCommandHandler {

    private HelloWorld hello;

    public PrintHello() {
        super("printhello");
    }

    public void addHello(HelloWorld hello) {
        this.hello = hello;
    }

    public void removeHello(HelloWorld hello) {
        this.hello = null;
    }

    public void handle(CommandRequest request, CommandResponse response) throws CommandException {
        PrintWriter out = getOut(response);
        out.println(hello.getGreeting());
    }
}

We will now create two composite templates to wrap components based on the classes shown above.

Firstly the helloWorld template:

<?xml version="1.0"?>
<composite name="helloWorld">
  <description>An example hello world composite</description>

  <service name="hello-export">
    <interface.java 
      interface="org.cauldron.newton.example.helloworld.api.HelloWorld"/>
    <binding.osgi/>
  </service>

  <component name="hello">
    <implementation.java.callback 
      impl="org.cauldron.newton.example.helloworld.impl.HelloWorldImpl"/>
  </component>

  <wire>
    <source.uri>hello</source.uri>
    <target.uri>hello-export</target.uri>
  </wire>
</composite>

And secondly the Print Hello template:

<?xml version="1.0"?>
<composite name="printHello">
  <description>An example hello world component</description>

  <reference name="hello" multiplicity="1..1">
    <interface.java interface="org.cauldron.newton.example.helloworld.api.HelloWorld"/>
    <binding.osgi filter=""/>
  </reference>	 

  <service name="print-export">
    <interface.java interface="org.cauldron.newton.command.console.ConsoleCommandHandler"/>
    <binding.osgi/>
  </service>

  <component name="print">
    <reference name="hello"/>
    <implementation.java.callback impl="org.cauldron.newton.example.helloworld.impl.PrintHello"/>
  </component> 

  <wire>
    <source.uri>hello</source.uri>
    <target.uri>print/hello</target.uri>
  </wire>

  <wire>
    <source.uri>print</source.uri>
    <target.uri>print-export</target.uri>
  </wire>
</composite>

Save each of these xml documents in the files xml/helloworld-template.xml and xml/printhello-template.xml respectively.

We now need to build our composites into bundles so that they can be deployed by Newton. Here is a Buildfile that achieves this:

Note
Newton uses bld to generate a maven pom.xml from a Buildfile.
# helloworld
id:             helloworld
archetype:      NewtonBundle

tmpl.dir = xml
pkg = ${example.pkg}.helloworld

-depends:\
 command;org.cauldron.newton

-bundles:\
 api,\
 main,\
 cli

# api
api;name:       helloworld-api-bundle
api;-exports:   ${pkg}.api

# main
main;name:      helloworld-bundle
main;-exports:  ${pkg}.impl
main;-templates:\
 ${tmpl.dir}/helloworld-template.xml

# cli
cli;name:       printhello-bundle
cli;-contents:  ${pkg}.cli.*
cli;-templates:\
 ${tmpl.dir}/printhello-template.xml

# end

Having built the components we are almost ready to deploy them to the newton framework and test them out. In order to deploy the components we will need to create two further xml documents that describe an instance of each template.

<?xml version="1.0"?>
<composite name="helloworld">
  <bundle.root bundle="helloworld-bundle" version="1.0"/>
  <include name="helloWorld"/>
</composite>
<?xml version="1.0"?>
<composite name="helloworld">
  <bundle.root bundle="printhello-bundle" version="1.0"/>
  <include name="printHello"/>
</composite>

Save each of these composite documents in the files xml/helloworld.composite and xml/printhello.composite respectively. The build copies these files to target/xml and replaces the ${VERSION} tags.

Now we're ready, so startup the Newton framework and type in the following commands.

$ bin/container
> cds scan boot examples/helloworld/target
> installer install examples/helloworld/target/xml/printhello.composite
> installer install examples/helloworld/target/xml/helloworld.composite
> printhello
Hello World