camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jesús Castillo <jesus.a.casti...@gmail.com>
Subject Re: How to setup a dynamic route using beans in Java w/o having a spring ref to them?
Date Tue, 08 Nov 2011 03:51:18 GMT
Hi Klaus,

the main problem with the solutions proposed is that either you need
to modify the
OSGi service registry or you need to make some changes in the Camel
bean component.


What I did was decouple the Camel route from the the bean registered in OSGi by
using the Observer pattern. The Observable or Subject is added to the
Camel route and the Observers are exposed as OSGi services and injected
dynamically by Spring to the list of Observers. In this way, Camel
knows about the
bean in Advance but does not anything about the services registered in OSGi.

By the same token, the OSGi services don't know anything about Camel Routes.

This is a sample test code:

The Observable:

{code}

package example;

public class RouteServiceProvider {

    private static final Logger LOG =
LoggerFactory.getLogger(RouteServiceProvider.class);
	
	List<Provider> providers = new ArrayList<Provider>();

	protected final Provider defaultProvider = new DefaultProvider();
	
	/**
	 * @return the providers
	 */
	public List<Provider> getProviders() {
		return providers;
	}

	/**
	 * @param providers the providers to set
	 */
	public void setProviders(List<Provider> providers) {
		this.providers = providers;
	}
	
	public final void handleRequest(Map<String,String> headers) {
		LOG.debug("RouteServiceProvider :: handleRequest() invoked");
		doHandleRequest(headers);
		// Call Providers
		for (Provider provider : providers) {
			if (provider.requestReceived(headers)){
				return;
			}				
		}	
		// Invoke the Default provider if not provider found
		LOG.info("RouteServiceProvider :: No Provider was suitable. Calling
the Default provider");
		defaultProvider.requestReceived(headers);
	}	
	
	protected void doHandleRequest(Map<String,?> headers) {
		//	Do some actions before calling providers		
	}
	
{code}

The providers(observers):

{code}
public interface Provider {
	public boolean requestReceived(Map<String, String> headers);
}

public class DefaultProvider implements Provider {

    private static final Logger LOG =
LoggerFactory.getLogger(DefaultProvider.class);
	
	@Override
	public boolean requestReceived(Map<String, String> headers) {
		LOG.info("Default provider is handling the request");
		headers.put("requestType", "DEFAULT");
		return false;
	}

}

public class LocalProvider implements Provider {

    private static final Logger LOG =
LoggerFactory.getLogger(LocalProvider.class);
	
	@Override
	public boolean requestReceived(Map<String, String> headers) {
		LOG.debug("Local provider is handling the request");
		headers.put("requestType", "LOCAL");
		return false; //true means I managed the request.
	}

}

{code}

The service is registered in OSGi as.

  <bean id="localProvider" class="example.impl.LocalProvider">
  </bean>

  <osgi:service ref="localProvider" interface="example.Provider"/>



The services are referenced as as:

  <bean id="routeServiceProvider" class="example.RouteServiceProvider">
    <property name="providers" ref="providers"/>
  </bean>

  <osgi:list id="providers"
  	interface="example.Provider" cardinality="0..N" />

The Camel route looks like:

		from("direct:start")
			.to("bean:routeServiceProvider?method=handleRequest")
	                .to("mock:result");		


This solution is purely based on POJO classes and no need to
create special components in OSGi or Camel.

Regards,

Jesus.

Mime
View raw message