Saturday, August 10, 2013

Spring Integration to Consume and Publish REST


Spring Integration using gateways makes it possible to consume services from multiple sources and expose them as api's . API's can be exposed with or without further processing .  Lets look at an example without Processing .

If you need a code ref you can find it here https://github.com/arun2dot0/spring-integration-example

getFoo is a Restful service  consumed by Spring and exposes back as service .
First thing to define is the publish-subscribe-channel ,then configure the input-channel with all the mappings .Example shows the method  getFoo but there can be many mappings added for each of the service .

Next step is to specify the gateway to accept the incoming request to the channel . Service interface with the list of interface methods is specified .

Finally the http-oubound gateway is defined with the url , http-method with the transformer.
Transformer can be easily implemented by json-to-object trasnfromation as show.

Update :
It can be done using Java DSL as well and you can find the implementation here
https://github.com/arun2dot0/spring-integration-example-dsl
DSL uses newer version of spring integration and http library .


Spring Configuration
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
 xmlns:int="http://www.springframework.org/schema/integration"  
 xmlns:http="http://www.springframework.org/schema/integration/http"
 xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
 http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-2.1.xsd 
http://www.springframework.org/schema/integration   
http://www.springframework.org/schema/integration/spring-integration-2.1.xsd">  
  
<!-- Channel for incoming request-->
<int:publish-subscribe-channel id="pubsubChannel"></int:publish-subscribe-channel>
 
 <!-- Define header with all the necessary mapping--> 
<int:header-value-router input-channel="pubsubChannel" header-name="REQUEST_TYPE">
 <int:mapping value="getFoo" channel="getFooChannel"/>
</int:header-value-router> 

<int:channel id="getFooChannel"/>

<!-- Simple facade method which accepts messages into channel -->
<int:gateway  id="firstGatewayID" service-interface="services.api.FirstGatewayService"     default-request-channel="pubsubChannel" >
  <!--Provide method in the gateway -->
 <int:method name="getFoo">
   <int:header name="REQUEST_TYPE" value="getFoo"/>
  </int:method>
</int:gateway>  


 <!--outbound gateway to get data from url-->
<http:outbound-gateway id="getFooGateway" 
                   url="http://somehost.com/GetFoo" 
                request-channel="getFooChannel" 
                reply-channel="getFooChannel_response"
                http-method="GET" 
                expected-response-type="java.lang.String">
 </http:outbound-gateway>
 
 <int:json-to-object-transformer input-channel="getFooChannel_response" type="model.FooResponse"/>  
</beans>

Java Code

Gateway Service
package services.api;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Payload;
public interface FirstGatewayService {
 @Payload("new java.util.Date()")
 public FooResponse getFoo();
}

Response
package model;
import org.codehaus.jackson.annotate.JsonProperty;
public class FooResponse {
 @JsonProperty("status")
 boolean status;
 @JsonProperty("data")
 String data;
 public boolean isStatus() {
  return status;
 }
 public void setStatus(boolean status) {
  this.status = status;
 }
 public String getData() {
  return data;
 }
 public void setData(String data) {
  this.data = data;
 }
}
Controller
@Autowired
private FirstGatewayService gatewayService;
@Override
 @RequestMapping(value = <url to access>, method = RequestMethod.GET)
 public @ResponseBody BaseResponse getFoo() {
  return gatewayService.getFoo();
 }

3 comments:

abdul rahman said...

Very great tutorial, i've been looking for this entire week, but i'm a bit confuse in configuration. Can I have the source code of this particular project? Or link for github? Thank you..

Unknown said...

The prefix "http" for element "http:outbound-gateway" is not bound.
This is what i get when i copy paste your xml code please help me

Arun said...

Http schema URL was missing and its fixed now