Skip to content

Instantly share code, notes, and snippets.

@danbev
Last active October 13, 2015 06:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danbev/4152998 to your computer and use it in GitHub Desktop.
Save danbev/4152998 to your computer and use it in GitHub Desktop.
AeroGear Controller/Camel Integration

AeroGear Camel/SwitchYard Integration

Currently one can already expose a service as a RESTful endpoint in Camel using Camel's CXFRS Component. The same goes for a service in SwitchYard that can be exposed using the RestEasy Component.
We are not suggesting to build yet another integration platform, but instead provide adapters which act as remote clients to utilize existing services.

So, a few reasons why users might opt to expose their services through AeroGear Controller:

  • Mobil Gateway
  • Backend integration
  • Thin logic layer
  • Caching
  • Security

SwitchYard Integration

As mentioned above, SwitchYard has a RemoveInvoker that could be used for invoking services from a remote client. This could be used in an AeroGear route:

public class Routes extends AbstractRoutingModule {
    
    @Override
    public void configuration() throws Exception {
        route()
               .from("/server1/{id}")
               .on(RequestMethod.GET)
               .to(SwitchYard.class).invoke(
                   "http://localhost:8080/switchyard-remote",
                   "CarService", 
                   param("id"));
    }
}

SwitchYard is again very simple:

public class SwitchYard {
    
    public static final String REMOTE_SERVICE = "urn:com.example.switchyard:remote";
    
    public Object invoke(final String url, 
                         final String serviceName, 
                         final Object payload) throws IOException {
        return new HttpInvoker(url).invoke(new RemoteMessage()
                .setContext(new DefaultContext())
                .setService(new QName(REMOTE_SERVICE, serviceName))
                .setContent(payload))
                .getContent();
    }   
}

Camel Integration

Using Camel to integrate with existing services is a great option as Camel has a huge number of components. There is a SwitchYard Camel component too, so integrating with SwitchYard would also be possible using Camel. SwitchYard also has a new RemoteInvoker which could be used for SwitchYard specific services and would be a separate controller class.

The goal here is to make things as flexibile as possible as it is difficult to try to account for different types of services. As a suggestion, an AeroGear Controller route that invokes a service using Camel might look like this:

public class Routes extends AbstractRoutingModule {
    
    @Override
    public void configuration() throws Exception {
        route()
               .from("/cars/{id}")
               .on(RequestMethod.GET)
               .to(CarServiceController.class).getCar("direct://input", param("id"));
    }
}

CarServiceController.class might look something like this:

public class CarServiceController extends CamelController {
    
    public String getCar(final String endpointUri, final String id) {
        return (String) producerTemplate().requestBody(endpointUri, Long.valueOf(id));
    }
}

CamelController is very simple and gets injected with a CdiCamelContext and creates the ProducerTemplate.

public abstract class CamelController {
    
    @Inject
    private CdiCamelContext camelContext; 
    private final ProducerTemplate producer;
    
    public CamelController() {
        producer = this.camelContext.createProducerTemplate();
    }
    
    protected ProducerTemplate producerTemplate() {
        return producer;
    }
}

We are simply making an instance of ProducerTemplate available to users, and they have access to all the methods of that interface. This will enable users to send one way messages, request/response messages, and also prepare the arguments to the service and process the result if needed.

A ProducerTemplate is created from a CamelContext. One can have multiple CamelContext's per application/deployment but the most common is that each deployment has one CamelContext. In this case we are injecting CdiCamelContext.

We could also add additional methods from ProducerTemplate to CamelController which just delegate, for example:

public abstract class CamelController {
    
    @Inject
    private CdiCamelContext camelContext; 
    private final ProducerTemplate producer;
    
    public CamelController() {
        producer = this.camelContext.createProducerTemplate();
    }
    
    protected ProducerTemplate producerTemplate() {
        return producer;
    }
    
    protected Object requestBody(final String endpointUri, final Object body) {
        return producer.requestBody(endpointUri, body);
    }
    //...more methods like requestBody
}

This would save subclasses from having to call producerTemplate().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment