While we have a JSR-181 Service Engine that allows us to work to EJBs/POJO's etc I have been wondering if we should provide a annotated POJO engine that is closer to the JBI infrastructure than the JSR181 (XFire) based one.

The idea would be to allow you to create more providers and consumes but writing POJO's in the Service Unit and then deploying with this servicemix-jbi-pojo engine which would scan the POJOs and create them performing some injection and setup of endpoints as we go.

The idea would be that Providers are stateless and Consumers are singletons - unless a Provider is also a consumer.

To have a look at how it might work I knocked up so good old (no code behind the scenes) examples:

First up - an example of a consumer service - this is basically where we have something at doesn't provide any services and simply consumes them - say a file poller for example.

package org.apache.servicemix.pojo.engine.examples;

import java.io.File;

import javax.jbi.JBIException;
import javax.jbi.component.ComponentContext;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.InOnly;
import javax.resource.spi.work.WorkManager;

import org.apache.servicemix.pojo.engine.ConsumerService;
import org.apache.servicemix.pojo.engine.LocalComponentContext;
import org.apache.servicemix.pojo.engine.LocalDeliveryChannel;
import org.apache.servicemix.pojo.engine.LocalWorkingArea;
import org.apache.servicemix.pojo.engine.LocalWorkmanager;
import org.apache.servicemix.pojo.engine.ProviderService;
import org.apache.servicemix.pojo.engine.ServiceShutdown;
import org.apache.servicemix.pojo.engine.ServiceStartup;
import org.apache.servicemix.pojo.engine.TargettedMessageExchange;
import org.apache.servicemix.pojo.engine.TargettedMessageExchangeFactory;

@Consumer
public class DemoConsumerService {

	/**
	 * We could inject a delivery channel
	 */
	@Resource DeliveryChannel channel;

	/**
	 * The Component Context could be handy
	 */
	@Resource ComponentContext context;

	/**
	 * Nothing like a jenck workmanager for that polling
	 */
	@Resource WorkManager myWorkmanager;

	/**
	 * The Service unit's directory is good for artifacts
	 */
	@LocalWorkingArea File myWorkspace;

	/**
	 * What about getting a targetted message exchange factory By doing this we
	 * can pulling out the consumes for the Service unit
	 */
	@TargettedMessageExchange(providerService = @ProviderService(targetNamespace = "http://www.blah.com", serviceName = "myDestinationService"))
	TargettedMessageExchangeFactory myTargetFactory; 	@Destination(uri="service:urn:service")	private Destination service1;

	/**
	 * Calls on SU init
	 *
	 */
	@PostConstruct
	public void init() {
		try {
			// ... do something
			InOnly inOnly = myTargetFactory.createInOnlyExchange();

			// .. do something with the exchange
			channel.send(inOnly);
			// ... do more
		} catch (JBIException exception) {

		}
	}

	/**
	 * Calls on SU shutdown
	 *
	 */
	@PreDestroy
	public void destroy() {

	}

}

Note that the idea is to provide the ability to inject useful stuff - also note that annotations provide the information on the service names etc - the idea here is that we don't need spring or anything else it is pure Java (no XML config) in the SU.

Not also that we can get a targetted exchange factory - this is to allow us to be able to pick up the consumes and provides from the SU during packaging (for tooling to use).

Next up lets look at a Provider

package org.apache.servicemix.pojo.engine.examples;

import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.MessageExchange;
import javax.xml.transform.Source;

import org.apache.servicemix.pojo.engine.ExchangeProcessor;
import org.apache.servicemix.pojo.engine.LocalDeliveryChannel;
import org.apache.servicemix.pojo.engine.MessageExchangePattern;
import org.apache.servicemix.pojo.engine.ParameterMapping;
import org.apache.servicemix.pojo.engine.ProviderService;

@ProviderService(targetNamespace = "http://servicemix.apache.org", serviceName = "myService")
public class DemoProviderService {

	@ExchangeProcessor
	public void myInOutProcessor(MessageExchange me) {
		// Do something here
	}

	@ExchangeProcessor
	public void myInOnlyProcessor(@InMessageContent Source payload) {
		// Do something here
	}
}

Note that we provider service can declare the provided endpoint - as a service or interface etc it can also get note that it can also map methods to exchange processors including the exchange patterns it wants to handle and also the parameters - so it can pick up the content or the payload.

Note that a ProviderService can also create targetted message exchanges through annotations and in essence become a consumer as well.

This is pure ideas and all edits are welcome