Saturday, August 10, 2013

Spring Mongo Integration

Setting up and using MongoDB in the Spring application is a simple two step process.Specify the Mongo template in the application configuration , then customize the ApplicationConfig . Step 1 Include the Mongo configuration in the application context

<mongo:db-factory id="mongoDbFactory" dbname="my-store" />
 
 <mongo:mapping-converter id="mongoConverter" base-package="springdata.mongodb">
  <mongo:custom-converters base-package="springdata.mongodb" />
 </mongo:mapping-converter>
 
 <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
  <constructor-arg ref="mongoDbFactory" />
  <constructor-arg ref="mongoConverter" />
  <property name="writeConcern" value="SAFE" />
 </bean>
 
 <mongo:repositories base-package="springdata.mongodb" />
Step2 Setup the ApplicationConfig in the base-package
@ComponentScan
@EnableMongoRepositories
class ApplicationConfig extends AbstractMongoConfiguration {

 
 @Override
 protected String getDatabaseName() {
 return "my-store";
 
 }

 
 @Override
 public Mongo mongo() throws Exception {

  Mongo mongo = new Mongo();
  mongo.setWriteConcern(WriteConcern.SAFE);

  return mongo;
 }

}
After the two steps the Mongo can be included in the application by simply autowiring
@Autowired Mongo mongo;

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();
 }

Thursday, August 12, 2010

Embedding images in E-Mail





We have been using XML XSL transformation for generating the emails and it was working well . XML Provides the data and Styling is provided in XSL . It becomes tricky when including images . One easy way to do is to include images as URL . This may not be the right approach as the user may not be online when looking a the email and can be lost during forwarding .

Best way is to use javax.mail.internet.MimeMultipart and set the images as header .
Here is the example
XSL to include images will look like this

<img>
<xsl:attribute name="src">cid:image1</xsl:attribute>
<xsl:attribute name="border">0</xsl:attribute>
</img>


Include the images in the email service after the transformation


MimeMultipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();

messageBodyPart.setContent("All Email contents from Transformation", "text/html");
multipart.addBodyPart(messageBodyPart);

// add first image
messageBodyPart = new MimeBodyPart();
DataSource fds = new FileDataSource
("C:\\image_path");
messageBodyPart.setHeader("Content-ID","<image1>");
messageBodyPart.setDataHandler(new DataHandler(fds));
multipart.addBodyPart(messageBodyPart);

//add another image
messageBodyPart = new MimeBodyPart();
DataSource fds1 = new FileDataSource
("C:\\image-path");
messageBodyPart.setHeader("Content-ID","<image2>");
messageBodyPart.setDataHandler(new DataHandler(fds1));
multipart.addBodyPart(messageBodyPart);

message.setContent(multipart);


You will see the image replaced .Images are downloaded with the message and is replaced where the tag is used . It's solves all the issues related to using them as URL.