The Hello World web Application is designed to show the minimal configuration and code necessary to integrate a Spring MVC app with OpenSpaces. For that reason, it has a very simple set of use-cases:
1) display the number of messages that pass through the system
2) display a random message that has been processed
3) display a random message that has had its content - a String - reversed. (this last use case almost identical in construction to the second use-case and is deliberately left unfinished as an exercise to the new user to complete.)
The work flow exhibited by the application involves two main sub-systems:
1) the Space and surrounding services
2) the web server with its JSPs and Spring beans
The 1st subsystem - the space and services- has two fully implemented services:
1) the MessageFeed service that writes new messages into the space
2) the MessageProcessor service that adds a timestamp to the messages as they arrive and changes their status to 'TIMESTAMPED'
The second subsystem - the web server with the JSPs and Spring Beans - has a single controller class the 'IntegrationController' that has two active methods:
1) showMessageCount - which returns the number of messages that have passed through the space
2) getMessage - which returns a random message form the space
The views for each of the above methods are the JSP pages in the WEB-INF/jsp folder called:
showMessageCount, and displayMessage, respectively.
The information flows from the MessageFeed through to the displayMessage.jsp as a result of the following mechanisms:
1) The MessageFeed has a proxy to the space injected into it via the Spring configuration file called pu.xml which is located in the META-INF/spring directory of the helloSpaceAndSpringPublisher project
<bean id="MessageFeed" class="org.openspaces.example.integration.publisher.MessageFeed">
<constructor-arg ref="gigaspace"/>
</bean>
The MessageFeed bean then proceeds to call space.write(Message) and in that fashion, deliberately write new messages into the space
2) The MessageProcessor has Messages passed into its messageProcessed(Message obj) method by the Spring container configuration file pu.xml located in the META-INF/spring directory of the helloSpringAndSpaceSystem project (this is implemented through the configuration of an EventContainer that is bound to the space, registers a template with it and then proceeds to take matching Objects out of the space and pass them into the messageProcessed method of the MessageProcessor (the delegate-ref in the following configuration snippet))
<os-events:polling-container id="messageNeedsProcessingEventContainer" giga-space="gigaspace">
<os-events:tx-support tx-manager="transactionManager"/>
<os-core:template>
<bean class="org.openspaces.example.integration.common.Message">
<property name="processedStage" value="NONE"/>
</bean>
</os-core:template>
<os-events:listener>
<os-events:annotation-adapter>
<os-events:delegate ref="MessageProcessor"/>
</os-events:annotation-adapter>
</os-events:listener>
</os-events:polling-container>
The code for the messageProcessed method is as follows:
@SpaceDataEvent
public Message messageProcessed(Message obj) {
obj.setContent(obj.getContent()+" processed by: "+this.getClass().getSimpleName()+" at: "+new Timestamp(System.currentTimeMillis()));
obj.setProcessedStage(""+Message.ProcessedStage.TIMESTAMPED);
System.out.println(this.getClass().getSimpleName()+" processed message #"+obj.getId());
return obj;
}
Once the Message is timestamped it is visible to the web layer and our attention moves to that sub-system.
The IntegrationController has the space injected into it through Spring auto-wiring that recognizes the type within the same context. The Space is configured using the gsApplicationContext.xml file found in the WEB-INF folder of the helloSpringAndSpaceWeb project.
<\!-- here we create the binding to the space through openspaces \-->
<os-core:space id="space" url="jini:/>
<os-core:giga-space id="gigaspace" space="space"/>
The corresponding injection of the space into the IntegrationController constructor is shown below:
@Autowired
public IntegrationController(GigaSpace in)
{
this.space = in;
}
Now that the space is available to the web controller, it can use it to satisfy the two use-cases mentioned earlier: (note that the extension '.os' was mapped to this controller and stands for OpenSpaces - this could be '.do' or any other standard mapping if you prefer)
@RequestMapping("/showMessageCount.os")
public void showMessageCount(ModelMap model){
logger.info("processing request showMessageCount..");
String result = ""+space.count(new Message());
model.put("count", result);
}
and
@RequestMapping("/displayMessage.os")
public void getMessage(@RequestParam(value = "selector", required = false)String messageID, ModelMap model){
logger.info("processing request getMessage..");
Message template = new Message();
template.setProcessedStage(""+Message.ProcessedStage.TIMESTAMPED);
if (messageID \!= null){
template.setId(messageID);
}
logger.info("Template =="+template);
Message result = space.read(template);
if(result==null){
result = new Message();
result.setContent("There are no messages that match your search");
}
model.put("message", result);
logger.info("Result =="+result);
}
The two JSP pages that provide the view for each of these use-cases are shown next:
<title>how many processed...</title>
</head>
<body>
As of right now, <c:out value="${count}"/> messages have been processed:
<p />
</body>
</html>
and
<title>A random Message for you...</title>
</head>
<body>
Displaying message:<c:out value="${message.id}"/>
<p />
<c:out value="${message}"/>
</body>
</html>
and that completes our journey.