Monthly Archives: October 2012

Publish Subscribe with vFabric RabbitMQ and Spring Integration using Spring AMQP

For people in hurry, get the latest code and steps to run the demo.

Introduction: Spring AMQP and vFabric RabbitMQ

vFabric RabbitMQ is a new offering from VMware that support AMQP standard. AMQP has been around for a long time, at a high level AMQP is yet another standard API to send and recieve messages between applications similar to JMS. The main difference being, AMQP is a wire-level protocal, JMS is a JAVA standard. There is a neutral blog comparing AMQP and JMS. As per this blog, AMQP is a standard that is popular among Python, RoR, C++ developers. Stomp and OpenWire are some of the implementation of AMQP. In the Spring world, we have Spring AMQP abstraction and vFabric RabbitMQ has the first implementation of Spring AMQP. This is a  good introduction of Spring AMQP with with vFabric RabbitMQ.

At a high level, RabbitMQ does not have a concept of Topics the way it is in JMS. It has a concept of Queues and Exchanges. The Exchanges can be of different types like Fanout, Topic. Refer to routing topologies used by RabbitMQ. There is also a good article in VMware about how vFabric RabbitMQ is used for a very large messaging implementation and Understanding AMQP, the protocol used by RabbitMQ.

Run Publish Subscribe with Spring Integration

In this example, we have built 2 Spring Integration component, Publisher component, that publishers messages to an RebbitMQ Exchange. The message is Fanout to multiple Queues. The Subscriber Spring Integration is listening to the Queue and process the messages. There are different ways of Publish/Subscribe messages in vFabric RabbitMQ, there is a good article on this in stackoverflow. There is also a good article on how Publisher/ Subscriber works in RabbitMQ.

In the example we have used Spring Integration configuration to define a subscriber as below,

<!-- A reference to the org.springframework.amqp.rabbit.connection.ConnectionFactory -->
<rabbit:connection-factory id="connectionFactory"/>

<!-- Creates a org.springframework.amqp.rabbit.core.RabbitTemplate for access to the broker -->
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>
<!-- Creates a org.springframework.amqp.rabbit.core.RabbitAdmin    to manage exchanges, queues and bindings -->
<rabbit:admin connection-factory="connectionFactory"/>
<!-- Queues -->
<rabbit:queue id="queue1" name="queue.1.name"/>
<rabbit:queue id="queue2" name="queue.2.name"/>

<!-- Exchanges -->
<rabbit:fanout-exchange name="fanout.exchange.1.name">
<rabbit:bindings>
<rabbit:binding queue="queue1"/>
<rabbit:binding queue="queue2"/>
</rabbit:bindings>
</rabbit:fanout-exchange>

<int:publish-subscribe-channel id="fanoutChannel" />

<int-amqp:outbound-channel-adapter channel="fanoutChannel"
amqp-template="amqpTemplate" exchange-name="fanout.exchange.1.name"/>

In our demo, you can start the vFabric RabbitMQ and run the test as below, the publisher will put the message in the 2 queues.


mvn -Dtest=com.goSmarter.amqp.PublisherSubscriberTest test

If you open the vFabric RabbitMQ management console, it will display that there is a message in the queue.

Subscriber Spring Integration configuration looks as below,

<!-- A reference to the org.springframework.amqp.rabbit.connection.ConnectionFactory -->
<rabbit:connection-factory id="connectionFactory" />

<!-- Creates a org.springframework.amqp.rabbit.core.RabbitTemplate for access   to the broker -->
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" />

<!-- Creates a org.springframework.amqp.rabbit.core.RabbitAdmin to manage   exchanges, queues and bindings -->
<rabbit:admin connection-factory="connectionFactory" />
<int:channel id="inbound-channel" />

<int-amqp:inbound-channel-adapter
channel="inbound-channel" queue-names="queue.1.name"
connection-factory="connectionFactory" />

<int:service-activator input-channel="inbound-channel"
id="serviceActivator" ref="serviceActivatorBean" method="logXml" />

<bean id="serviceActivatorBean"
class="com.goSmarter.amqp.service.Subscriber1ServiceActivator">
</bean>

Now when you run the Subscriber Tomcat Instance within STS as “Run on Server” it will pick the message from the Queue and print it to the console.

Conclusion

In this blog, I have demonstrated a simple fanout based Publisher /Subscriber, where in a Publisher will publish a message and Subscriber will subscriber and print it. This will jumpstart you with a decent prototype on Spring AMQP. There are also few Spring AMQP samples on Stocks and other stuff.

I hope this blog helped you. Please leave me feedback.

Advertisements

Responsive Web Design using Twitter Bootstrap, Spring MVC

Introduction

Responsive Web Design is a new way of building web application. Once you build a application using Responsive Web Design, you will be easily able to make this web application work on any device including Mobile and Handheld devices. Twitter the company open sourced their Twitter Bootstrap framework which supports Responsive Web Design(RWD). Kickstrap is another variant of Twitter Bootstrap. In this blog, I will demonstrate how we will build a Spring MVC based application that uses jquery-tmpl to build a JSON based RWD.

The use case we cover is a simple Airline reservation system, where in for a given origin, destination, the start and end date, we return all the flights. When we select a flight, we show all the deals in the target location.

For people in hurry get the code and the steps from @ Github.

Responsive Web Design

There are 3 key technical features that are heart of Responsive Web design:

Flexible grid-based layout: When you are viewing the page on a mobile devices, when you change the device to landscape or portrait, the page layout automatically adjusts and flows to display within the layout, this is Flexible grid-based layout. In Twitter Bootstrap, it can be achieved using CSS tags as below,

<div class="row-fluid"><!-- put some HTML stuff --></div>

Flexible images: dynamic resizing of images

Media queries: This is CSS3 feature, where in the CSS is returned to the Browser based on querying the Media device. Typical HTML tag you use for this as below,

<!-- for iPad, this is how the media query looks like -->
<link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css">
<link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css">

Spring MVC and Twitter Bootstrap

The overall data flow is as below,

Responsive Web Design using Twitter Bootstrap, Spring MVC

Responsive Web Design using Twitter Bootstrap, Spring MVC

In this example we build a Single Page Website using Twitter Bootstrap and JQuery-tmpl. On the frontend side, the data is submitted as below,


$('#searchResults').click(function(){
var origin =  $("#origin option:selected").val();
var destination = $("#destination option:selected").val();
var startDate= $("#startDate").val();
var endDate = $("#endDate").val();

$.get("resources/datatemplates/flightList.html", function (template){
$.get("/air/searchResultsJson?leavingFrom=" + origin + "&goingTo=" + destination + "&startDate=" + startDate + "&endDate=" + endDate, function (data){
$("#dataRegion").html("");
$.tmpl(template, data).appendTo("#dataRegion");
});
});
return false;
}

This executes a JQuery and gets the list of flights in the form as JSon objects.

The JQuery-tmpl plugin is used to bind the flightList.html to achieve Single Page Webpage design. The flightList.html looks as below,

<tr>
<td>${startTime}</td>
<td>${startAirport}</td>
<td>${endTime}</td>
<td><a href="#" onclick="return getDetails('${endAirport}')">${endAirport}</a></td>
</tr>

On the Spring MVC side, we need to add the Maven dependency and call the method, refer this link for more details.

The controller code looks as below,

@RequestMapping(value = "searchResultsJson", method = RequestMethod.GET)
public @ResponseBody
List searchResultsJson(@RequestParam String leavingFrom,
@RequestParam String goingTo, @RequestParam String startDate,
@RequestParam String endDate) {
Form form = new Form();

form.setOrigin(leavingFrom);
form.setDestination(goingTo);
form.setStartDate(startDate);
form.setReturnDate(endDate);

return locationService.selectFlights(form);
}

In the above example @ResponseBody help in returning the JSon response to the client.

Conclusion

In this blog I demonstrated, how we can build a web application, that can be adapted to work on any device. It also show how to return JSon response from a Spring MVC based web application.

I hope it helps you.

Publisher, Subscriber using vFabric Spring Integration, Gemfire

As part of vFabric you get SpringSource Tool Suite (STS), vFabric tc Server, Spring AMQP to incorporate vFabric RabbitMQ messaging, and Spring Data project that simplifies access to vFabric GemFire, SQLFire and Postgres.

In the next few blogs, I will be discussing how each pieces tie in together. In this blog I will be demonstrating how Spring Integration and vFabric Gemfire participate in a typical Publisher/ Subscriber EIP pattern, where in data is picked from source system and delivered to 1 or many target systems.

For people who are in hurry, here is the code and the steps to execute.

Details: Publisher, Subscriber using vFabric Spring Integration, Gemfire

This demo is the continuation of my earlier blog on Claimcheck pattern. I will implement an end to end flow as below

Publisher Subscriber ESB using Spring Integration, Gemfire and ActiveMQ

Publisher Subscriber ESB using Spring Integration, Gemfire and ActiveMQ

For Demo purpose, on the publisher side, the message that comes in from claimcheck output is directly bridged to the jms outbound channel adapter. But in an enterprise application, in reality there can be a spring integration flow which can do an entire workflow/ transformation/ mapping, before it puts the message onto the Topic.

Again for demo purpose, on the subscriber side, I just directly took the payload output from claimcheck and passed to a console based service activator. But in an enterprise application, it can be sending this to a target system.

The technology stack I used for this is, hsqldb database, ActiveMQ JMS along with vFabric TC Server and vFabric Gemfire.

On the publisher side, the JDBC listener is configured in the Spring Integration as below,

<int-jdbc:inbound-channel-adapter
query="select * from notification where status=2" channel="jdbc.inbound"
data-source="dataSource" update="update notification set status=10 where id in (:id)">
<int:poller fixed-rate="1000" />
</int-jdbc:inbound-channel-adapter>

and you bridge this to the claimcheck channel as below,

<!-- for convenience sake we are bridging the jdbc to directly claimcheck in reality we will be going thru a SI flow
<int:bridge input-channel="jdbc.inbound"
output-channel="common.claimcheck.in.inputChannel" />

<!-- Bridge the claimcheck output directly to JMS -->
<int:bridge input-channel="common.claimcheck.in.outputChannel"
output-channel="jms-channel.out" />

On the subscriber side, the payload is pushed to the vFabric Gemfire and a GUID is created on the vFabric Gemfire side and it is pushed to the Topic. The Subscriber component picks up the payload and prints to the console. This blog explains this more in detail.

Conclusion

vFabric infrastructure provides a good support for developing Integration components by the way of STS IDE, vFabric TC Server, vFabric Gemfire. I have clearly demonstrated how you can build a Publisher/subscriber components which can integrate a source system to target system.

I hope this blog helped you.

JUnit testing Spring Security, Spring MVC and Activiti BPM

Spring Test MVC is a good framework for JUnit testing Spring MVC based application. In this sample, we demonstrated a simple LoanRequest application where in we test the Spring Security, Spring MVC and Activiti BPM Spring Support.

For people in hurry,

  • Get the latest Spring Test MVC code base
  • run “mvn clean install” on the above codebase
  • Get the loanrequest codebase latest code from @ Github
  • At the command prompt type “mvn test”, if the tests are successful, you are all set.

Details: JUnit testing Spring Security, Spring MVC and Activiti BPM

Spring Test MVC is an awesome framework to test the Spring MVC backend code. Spring Test MVC framework has a built in Spring MVC web container. You can point it to the webapp folder, and the spring application context and it will configure the buildin container to work with the JUnit test. You can also configure the Spring Security as below,

//You need to define a class as below,
class WebContextLoader extends GenericWebContextLoader {
public WebContextLoader() {
super("src/main/webapp", false);
}
}

//In your test case you need to configure the WebContexLoader as below with the Spring context files
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = WebContextLoader.class, value = {
"classpath:META-INF/spring/applicationContext-activiti.xml",
"classpath:META-INF/spring/applicationContext-security.xml",
"classpath:META-INF/spring/applicationContext.xml",
"classpath:META-INF/spring/test-datasource-config.xml"})
public class LoanRequestControllerTest {

//this FilterChainProxy configures the Spring Security feature
@Autowired
private FilterChainProxy springSecurityFilterChain;

@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webApplicationContextSetup(this.wac)
.addFilters(this.springSecurityFilterChain).build();
}

The API syntax is simple and expresses technical functionality closely, for example if the LoanRequest usecase is as below,

  • The accountant logged in and submitted the LoanRequest. The Server will return the HTTP Status as ok, and you can also assert if the Submitting went thru
  • Once the Accountant submitted the LoanRequest, the Management can review it and approve the Loan request

The above flow can be expressed by the below code using the TDD methodology,


@Test
public void testApprove() throws Exception {
mockMvc.perform(
post("/loanrequests/create").param("id", "4")
.param("customerName", "krishna").param("amount", "26")
.with(userDeatilsService("fozzie")))
.andExpect(status().isOk()).andExpect(redirectedUrl("/list"))
.andExpect(model().attribute("loanRequests", any(List.class)));

mockMvc.perform(
get("/loanrequestsapproval/approve/4").with(userDeatilsService("kermit")))
.andExpect(status().isOk());
}

If you notice, the http actions like Post and Get are demonstrated here. Also it has demonstrated how the user logging happens.

This container is configured to work with Spring Security, for example, if an accountant logs into to approval page, it will be forbidden. We write the test using TDD as below,


@Test
public void testApproveForbidden() throws Exception {
mockMvc.perform(
get("/loanrequestsapproval/approve/2").with(userDeatilsService("fozzie")))
.andExpect(status().isForbidden());
}

This sample also demonstrates the capability of Activiti BPM and how it can participate in JUnit testing.

You can configure the inmemory Activity Process Engine Configuration along with the deployed Bpmns as below,

<!-- <bean id="processEngineConfiguration"> -->
<bean id="processEngineConfiguration">
<property name="dataSource" ref="dataSource-activiti" />
<property name="databaseSchemaUpdate" value="true" />
<property name="transactionManager" ref="transactionManager" />
<property name="jpaHandleTransaction" value="false" />
<property name="jpaCloseEntityManager" value="false" />
<property name="jobExecutorActivate" value="false" />
<property name="deploymentResources" value="classpath*:/org/activiti/spring/test/usertask/LoanProcess.bpmn20.xml" />
</bean>

In the JUnit test TDD you can autowire this as below and populate some sample users,


@Autowired
SpringProcessEngineConfiguration processEngineConfiguration;

@Before
public void setup() {
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();

IdentityService identityService = processEngine.getIdentityService();
User user = identityService.newUser("fozzie");
user.setPassword("fozzie");
identityService.saveUser(user);
user = identityService.newUser("kermit");
user.setPassword("kermit");
identityService.saveUser(user);

identityService.saveGroup(identityService.newGroup("accountancy"));
identityService.saveGroup(identityService.newGroup("management"));

identityService.createMembership("fozzie", "accountancy");
identityService.createMembership("kermit", "management");
}

In your controller, you can autowire the inmemory Activity Process Engine Configuration and start a process, approve a task and mark it as complete. For more details refer the LoanRequestController code.

Conclusion

In this example, I have demonstrated a Activiti BPM based workflow initiated from a Spring MVC container and goes thru a lifecycle. I also demonstrated how Spring Security is used to authorize the Activiti BPM users.

I hope this example helps.