Difference between revisions of "Northwind Tutorial"

From RifidiWiki

Jump to: navigation, search
(Outline)
(Outline)
Line 29: Line 29:
 
#[[Northwind Esper: Alerts| Step 4: Esper: Alerts]]
 
#[[Northwind Esper: Alerts| Step 4: Esper: Alerts]]
 
#[[Northwind JMS Send | Step 5: Send Notifications Over JMS]]
 
#[[Northwind JMS Send | Step 5: Send Notifications Over JMS]]
#[[Northwind Creating the Web Application | Step 6: Create the Web Application
+
#[[Northwind Creating the Web Application | Step 6: Create the Web Application]]
  
 
=Writing A Web Application=
 
=Writing A Web Application=

Revision as of 19:18, 24 November 2009

This document provides step-by-step instructions on how to get started on developing your first application that runs on the Rifidi Edge Server. The application we will develop will use Esper to collect tag reads from a reader and put them on a JMS queue to be consumed by a client application. Many of the steps are applicable to many kinds of plugins for the edge server, including creating a sensor plugin.

The Scenario: Northwind Shipping

Congratulations! You are the proud new founder of Northwind Shipping Inc. -- "delivering packages faster than a caffeinated lightning bug"™. One of your core business strategies is to out perform your competitor -- Pony Express Shipping Inc. -- by capitalizing on increased efficiencies gained by your innovative use of technology. You have heard all the hype about RFID and want to employ in it your new, state-of-the-art distribution center. You have decided to use the Rifidi Edge Server to run the RFID applications you will need in your distribution center. This tutorial is a step-by-step guide on how to develop an RFID application and web UI using the Rifidi Edge Server API and deploy the application on the Rifidi Edge Server.

The Northwind distribution center has many complex processes, which should be automated as much as possible. Because you are new to RFID (and because too many processes would overwhelm this tutorial ;-) ) you have decided to start small and only implement a basic process with a few business rules. The first process you will automate using RFID is the receiving process (DC-Inbound). You have a dock door which will be receiving incoming shipments from trucks. The packages must be checked in at the dock door so that your ERP system knows the packages have arrived. Once this happens, the packages must be moved to a separate staging area where it needs to be weighed and prepared for further routing.

There are several goals for the application

  • Track the packages from the dock door (stage 1) to the weigh station (stage 2).
  • Send an alert if a package moves backwards (from stage 2 to stage 1).
  • Send an alert if a package arrives at the weigh station but was not seen at the dock door
  • Send an alert if a package departs the dock door and is not seen at the weigh station within five minutes

The Architecture

The solution that we will build will consist of two parts: the application bundle which will implement all the business rules, and the web application which will display the items. The two pieces will communicate using JMS.

Northwind.jpeg

Prerequisites

For this tutorial, we will use Eclipse to develop the application. While it would be possible to develop the application in any IDE that you are familiar with, Eclipse provides great tooling around OSGi application development and deployment, and thus makes this process much easier. If this is your first time developing with eclipse, there will be a learning curve. However, the payoff is worth it.

To get started see Setting up a Development Environment.

Source

You can download the source for this project here: File:Northwind 1.0.0.zip. Just unzip the project, open up eclipse and select import->existing projects into workspace.

Outline

  1. Step 1: Create the Application
  2. Step 2: Using Emulator
  3. Step 3: Esper: Track Packages
  4. Step 4: Esper: Alerts
  5. Step 5: Send Notifications Over JMS
  6. Step 6: Create the Web Application

Writing A Web Application

Set up Project

What you will learn

  • How to set up a web application project

Create the project

Just like when we created a new project for the Northwind application, we need to create a new project for the web application.

  1. Go to File-> New -> Project. Select "Plug-in Project" from the file chooser. Click "Next."
  2. Assign the project a name. For web applications, the application needs to end in 'war'. I chose com.northwind.rfid.shipping.war. Click next.
  3. Assign the plugin an ID, which is used to identify the bundle in the OSGi environment. Give it a descriptive name as well as the the name of the entity (company, person, project) that will maintain the bundle. For this bundle, we don't need the Activator, so uncheck that box.

Add the necessary files and folders

  1. Download and unzip this file: File:Tutorial-war-files.zip. It's a zip file that contains two files you will need.
  2. In the main project, make a new folder called 'WEB-INF'
  3. In the WEB-INF folder, make a new folder called 'jsp'
  4. In the WEB-INF folder, make a new file called 'web.xml'
  5. Put the file 'spring.tld' in the WEB-INF folder.
  6. In the META-INF folder, make a new folder called 'xsd'
  7. Put the file 'spring-beans-2.5.xsd' in the xsd folder.
  8. In the root folder, create a file called 'index.jsp'

Your project should now look like this:

Tutorial-war-structure.png

Configure the Manifest

Open up the Manifest.MF file. Click on the Dependencies tab.

  • On the Required Plug-ins Section, add the following bundles
    • com.northwind.rfid.shipping
    • com.springsource.org.apache.taglibs.standard
  • On the Imported Packages section, add the following packages
    • javax.jms
    • javax.servlet
    • javax.servlet.http
    • javax.servlet.jsp
    • javax.servlet.jsp.jstl.core
    • org.apache.activemq.command
    • org.apache.activemq.spring
    • org.springframework.jms.core
    • org.springframework.jms.listener
    • org.springframework.web.servlet
    • org.springframework.web.servlet.mvc
    • org.springframework.web.servlet.view
  • Click the Manifest.MF tab. Add the following line to the end. Make sure there is an blank line as the last line of the Manifest.MF (and make sure there is no leading whitespace for this line).
Web-ContextPath: NORTHWIND-DEMO

Modify the web.xml

Open up the Web.xml file. Modify it to look like this:

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<jsp-config>
		<taglib>
			<taglib-uri>/spring</taglib-uri>
			<taglib-location>/WEB-INF/spring.tld</taglib-location>
		</taglib>
	</jsp-config>
</web-app>

When building web applications in java, the web.xml file provides configuration and deployment information for the Web components. Initially, we supply two pieces of information:

  1. The welcome file is page that is loaded by default when you go to 127.0.0.1:8080/NORTHWIND-DEMO
  2. The jsp-config provides the location of some jsp tags provided by spring.

Add a include.jsp

Make a new file called include.jsp inside of the jsp folder. Modify it to look like this:

<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

This file simply includes some headers that we want on top of every JSP we will make. Therefore, in each JSP, we only have to have one include instead of several.

Modify index.jsp

Open up index.jsp. Modify it to look like this:

<%@ include file="/WEB-INF/jsp/include.jsp" %>

<jsp:useBean id="now" class="java.util.Date" />
Hello World at <fmt:formatDate value="${now}" pattern="MM.dd.yyyy" />

Here, we use some JSP tags to print out the date.

Run the web application

  1. Open up the run configuration and select the com.nortwind.rfid.shipping.war plugin. Run
  2. Point your browser to http://127.0.0.1:8080/NORTHWIND-DEMO/

If everything worked, you should see 'hello world' and the date.

Write a Hello World Servlet

What you will learn

  • How to use Spring's MVC Controller
  • How to write a servlet
  • How to write a JSP

Write a JSP

Create a new file in the jsp directory called taglocation.jsp. Edit it as follows:

<%@ include file="/WEB-INF/jsp/include.jsp" %>
Hello World at <fmt:formatDate value="${model.date}" pattern="MM.dd.yyyy" />

As you can see, this does the same thing as the index page, except it will get the date passed in from the Contoller in the "model" instead of getting it from a JSP tag.

Write a Controller

The next thing to do is to create the controller. The controller's purpose is to pass in a model to the view. In this case, our model is simply a date object. However, this will change when we hook up our web app to our RFID application. For now, create a new package called <tt?>com.northwind.rfid.shipping.war</tt>. Create a new Java class called TagLocationController. Edit it as follows:

package com.northwind.rfid.shipping.war;

import java.util.Date;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

/**
 * @author Kyle Neumeier - kyle@pramari.com
 *
 */
public class TagLocationController implements Controller{

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0,
			HttpServletResponse arg1) throws Exception {
		HashMap<String, Object> model = new HashMap<String, Object>();
		model.put("date", new Date(System.currentTimeMillis()));
		
		return new ModelAndView("/WEB-INF/jsp/taglocation.jsp", "model", model);
	}

}

What happens now is that anytime a web page that is controlled by this controller is loaded, the handleRequest method will be invoked. This method simply passes in a model object to the proper jsp.

Modify the web.XML

Now we need to modify the web.xml so that the controller will be loaded at the proper time. The web.xml should now look like this:

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<jsp-config>
		<taglib>
			<taglib-uri>/spring</taglib-uri>
			<taglib-location>/WEB-INF/spring.tld</taglib-location>
		</taglib>
	</jsp-config>
	
	<servlet>
		<servlet-name>NorthwindDemo</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>NorthwindDemo</servlet-name>
		<url-pattern>/taglocation.htm</url-pattern>
	</servlet-mapping>
	
</web-app>

The two things we did here:

  1. Told the web application about a servlet called NorthwindDemo.
  2. Told the web application to invoke the NorthwindDemo servlet whenever a page called 'taglocation.htm' is requested.

Create a servlet xml

Now we need to create a servlet XML that controls how the NorthwindDemo servlet behaves. Create a new file called NorthwindDemo-servlet.xml in the WEB-INF folder (the name of the file must be the name of the servlet with "-servlet.xml" appended to it). Make the servlet xml look like this:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
	xmlns:amq="http://activemq.apache.org/schema/core"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	META-INF/xsd/spring-beans-2.5.xsd
    http://www.springframework.org/schema/osgi 
    http://www.springframework.org/schema/osgi/spring-osgi.xsd">

	<bean name="/taglocation.htm" class="com.northwind.rfid.shipping.war.TagLocationController" />

</beans>

Modify index.jsp

The last thing to do is to modify our welcome file so that we are redirected to 'taglocation.htm' by default

<%@ include file="/WEB-INF/jsp/include.jsp" %>

<%-- Redirected because we can't set the welcome page to a virtual URL. --%>
<c:redirect url="/taglocation.htm"/>

Run It!

When you run the web application again (or use the 'update' trick) and point your browser to http://127.0.0.1:8080/NORTHWIND-DEMO, you should see the same Hello World message as last time. This time however, the back end is using Spring's Web MVC framework.

Write at TagLocation Service

Now that we have all the MVC plumbing working, we need to hook up the RFID application with the web application. We will do this by creating a service that the controller can use to find out the list of tags at each stage. Then we will write a JMS listener who will update the service with the latest information. Finally we will inject the service into the contoller.

Write a Service Interface

  • Create a new package called com.northwind.rfid.shipping.war.service
  • Create a new Interface called TagLocationService
package com.northwind.rfid.shipping.war.service;

import java.util.List;
import com.northwind.rfid.shipping.notifications.AlertNotification;

/**
 * This service provides the current list of tags at the Dock Door and the Weigh
 * Station, as well as all the alerts that have happened so far
 * 
 * @author Kyle Neumeier - kyle@pramari.com
 * 
 */
public interface TagLocationService {
	/**
	 * Get a list of all packages at the dock door
	 * 
	 * @return
	 */
	List<String> getDockDoorItems();

	/**
	 * Get a list of all packages at the Weigh Station
	 * 
	 * @return
	 */
	List<String> getWeighStationItems();

	/**
	 * Get a list of all the alerts
	 * 
	 * @return
	 */
	List<AlertNotification> getAlerts();
}

Write a Manager Interface

The TagLocationService interface allows a component to consume information. We also need the ability to add data to the service as it arrives. As such, let's create a second interface with the required methods.

  • Create a new package called com.northwind.rfid.shipping.war.service.impl
  • Create a new Interface called TagLocationServiceManager
package com.northwind.rfid.shipping.war.service.impl;

import com.northwind.rfid.shipping.notifications.AlertNotification;

/**
 * The manager of the TagLocationService. It allows a component to add data.
 * 
 * @author Kyle Neumeier - kyle@pramari.com
 * 
 */
public interface TagLocationServiceManager {

	/**
	 * Called when a new package has arrived at the dockdoor
	 * 
	 * @param item
	 */
	void PackageArrivedAtDockDoor(String item);

	/**
	 * Called when a package departs from the dock door
	 * 
	 * @param item
	 */
	void PackageDepartedFromDockDoor(String item);

	/**
	 * Called when an item arrives at the weigh station
	 * 
	 * @param item
	 */
	void PackageArrivedAtWeighStation(String item);

	/**
	 * Called when an item departs from the weigh station
	 * 
	 * @param item
	 */
	void PackageDepartedFromWeighStation(String item);

	/**
	 * Called when a new alert happens
	 * 
	 * @param notification
	 */
	void Alert(AlertNotification notification);
}

Implement the Service

Create a class called TagLocationServiceImpl in the com.northwind.rfid.shipping.war.service.impl package. There are a few considerations to take into account:

  1. The class needs to be thread-safe, since multiple threads might access the class. In our case, there are two: The JMS thread will call the manager methods, while the servlet thread will call the service methods. In order to prevent any race conditions, I wrapped the three data structures in synchronized collections. I also made sure to copy the collections before I returned them.
  2. We probably want to preserve the ordering that tags were inserted into the lists, however we don't want to store one tag more than once in each data structure. Therefore, I used a LinkedHashSet.
package com.northwind.rfid.shipping.war.service.impl;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import com.northwind.rfid.shipping.notifications.AlertNotification;
import com.northwind.rfid.shipping.war.service.TagLocationService;

/**
 * Thread-safe implementation of TagLocationService and TagLocationServiceManager
 * interfaces.
 * 
 * @author Kyle Neumeier - kyle@pramari.com
 * 
 */
public class TagLocationServiceImpl implements TagLocationService,
		TagLocationServiceManager {

	/** All the items that can be seen at dock door */
	private final Set<String> dockDoor = Collections
			.synchronizedSet(new LinkedHashSet<String>());
	/** All the items that can be seen at the weigh station */
	private final Set<String> weighstation = Collections
			.synchronizedSet(new LinkedHashSet<String>());
	/** All the alerts that have been created */
	private final List<AlertNotification> alerts = Collections
			.synchronizedList(new LinkedList<AlertNotification>());

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.northwind.rfid.shipping.war.service.TagLocationService#getAlerts()
	 */
	@Override
	public List<AlertNotification> getAlerts() {
		return new LinkedList<AlertNotification>(alerts);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.northwind.rfid.shipping.war.service.TagLocationService#getDockDoorItems
	 * ()
	 */
	@Override
	public List<String> getDockDoorItems() {
		return new LinkedList<String>(dockDoor);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seecom.northwind.rfid.shipping.war.service.TagLocationService#
	 * getWeighStationItems()
	 */
	@Override
	public List<String> getWeighStationItems() {
		return new LinkedList<String>(weighstation);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.northwind.rfid.shipping.war.service.impl.TagLocationServiceManager
	 * #Alert(com.northwind.rfid.shipping.notifications.AlertNotification)
	 */
	@Override
	public void Alert(AlertNotification notification) {
		this.alerts.add(notification);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.northwind.rfid.shipping.war.service.impl.TagLocationServiceManager
	 * #PackageArrivedAtDockDoor(java.lang.String)
	 */
	@Override
	public void PackageArrivedAtDockDoor(String item) {
		this.dockDoor.add(item);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.northwind.rfid.shipping.war.service.impl.TagLocationServiceManager
	 * #PackageArrivedAtWeighStation(java.lang.String)
	 */
	@Override
	public void PackageArrivedAtWeighStation(String item) {
		this.weighstation.add(item);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.northwind.rfid.shipping.war.service.impl.TagLocationServiceManager
	 * #PackageDepartedFromDockDoor(java.lang.String)
	 */
	@Override
	public void PackageDepartedFromDockDoor(String item) {
		this.dockDoor.remove(item);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.northwind.rfid.shipping.war.service.impl.TagLocationServiceManager
	 * #PackageDepartedFromWeighStation(java.lang.String)
	 */
	@Override
	public void PackageDepartedFromWeighStation(String item) {
		this.weighstation.remove(item);
	}
}

Write a JMS Listener

Create a new class called MessageReceiever in the com.northwind.rfid.shipping.war pacakge.

package com.northwind.rfid.shipping.war;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;

import com.northwind.rfid.shipping.notifications.AlertNotification;
import com.northwind.rfid.shipping.notifications.EZone;
import com.northwind.rfid.shipping.notifications.ItemArrivalNotification;
import com.northwind.rfid.shipping.notifications.ItemDepartureNotification;
import com.northwind.rfid.shipping.war.service.impl.TagLocationServiceManager;

/**
 * The class that implements the logic of receiving a notification from JMS
 * using the TagLocationServiceManager to update the TagLocationService
 * 
 * @author Kyle Neumeier - kyle@pramari.com
 * 
 */
public class MessageReceiver implements MessageListener {

	/** The TagLocationServiceManager to use */
	private volatile TagLocationServiceManager TLSManager;

	/**
	 * Called by spring
	 * 
	 * @param TLSManager
	 *            The TagLocationServiceManager
	 */
	public void setTLSManager(TagLocationServiceManager TLSManager) {
		this.TLSManager = TLSManager;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
	 */
	@Override
	public void onMessage(Message arg0) {
		if (arg0 instanceof BytesMessage) {
			try {
				// deserialize the message
				Object message = deserialize((BytesMessage) arg0);
				if (message instanceof ItemArrivalNotification) {
					// If the message is an ItemArrival
					ItemArrivalNotification notification = (ItemArrivalNotification) message;
					if (notification.getZone() == EZone.DOCK_DOOR) {
						// If it arrived at the dock door
						TLSManager.PackageArrivedAtDockDoor(notification
								.getTag_Id());
					} else {
						// otherwise it arrived at the weigh station
						TLSManager.PackageArrivedAtWeighStation(notification
								.getTag_Id());
					}
				} else if (message instanceof ItemDepartureNotification) {
					// if the message is an Item Departure
					ItemDepartureNotification notification = (ItemDepartureNotification) message;
					if (notification.getZone() == EZone.DOCK_DOOR) {
						// If it departed from the dock door
						TLSManager.PackageDepartedFromDockDoor(notification
								.getTag_Id());
					} else {
						// otherwise it departed from the weigh station
						TLSManager.PackageDepartedFromWeighStation(notification
								.getTag_Id());
					}
				} else if (message instanceof AlertNotification) {
					// if the message is an alert
					TLSManager.Alert((AlertNotification) message);
				} else {
					System.out.println("Notification type not recognized");
				}
			} catch (JMSException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	/***
	 * A private helper method that deserializes the incoming JMS notifications
	 * 
	 * @param message
	 *            The message to deserialize
	 * @return
	 * @throws JMSException
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	private Object deserialize(BytesMessage message) throws JMSException,
			IOException, ClassNotFoundException {
		int length = (int) message.getBodyLength();
		byte[] bytes = new byte[length];
		message.readBytes(bytes);
		ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
				bytes));
		return in.readObject();
	}
}

Create the Northwind webpage

What you will learn

  • How to use the JSP standard tag library to create a dynamic web page

Create a JSP

Modify the taglocation.jsp file to the following:

<%@ include file="/WEB-INF/jsp/include.jsp" %>

<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
		<title>Northwind Shipping</title>
		<meta name="generator" content="Amaya, see http://www.w3.org/Amaya/" />
	</head>

	<body>
		<table border="0"
			style="width: 80%;border-collapse: collapse;table-layout: fixed">
			<tr>
				<td valign="top">
					<table border="1"
						style="width:90%;background-color:#93D2FF;border-collapse: collapse">
						<tr>
							<td style="text-align:center">
								<h3>Dock Door</h3>
							</td>
						</tr>
						<tr>
							<td>
								<strong>EPC</strong>
							</td>
						</tr>
						<c:forEach items="${model.dockdoor}" var="tag">
							<tr>
								<td style="font-family:monospace;">${tag}</td>
							</tr>
						</c:forEach>
					</table>
				</td>
				<td valign="top">
					<table border="1"
						style="width:90%;background-color:#93D2FF;border-collapse: collapse;float:right">
						<tr>
							<td colspan="4" style="text-align:center">
								<h3>Weigh Station</h3>
							</td>
						</tr>
						<tr>
							<td>
								<strong>EPC</strong>
							</td>
						</tr>
						<c:forEach items="${model.weighstation}" var="tag">
							<tr>
								<td style="font-family:monospace">${tag}</td>
							</tr>
						</c:forEach>
					</table>
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<p />
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<table border="1"
						style="width:100%;background-color:#FFA69C;border-collapse: collapse">
						<tr>
							<td>
								<h3 style="text-align:center">Alerts</h3>
							</td>
						</tr>
						<c:forEach items="${model.alerts}" var="alert">
							<tr>
								<td> Tag:<span style="font-family:monospace">${alert.tag_Id}</span>: ${alert.message}
								</td>
							</tr>
						</c:forEach>
					</table>
				</td>
			</tr>
		</table>
	</body>
</html>

Putting it all together

Now that we have a TagLocationService which is receiving notifications from our RFID application, and we have a JSP that will display the information, we need to hook up the Controller with the TagLocationService.

Modify the Controller

We first need to modify the controller to do two things:

  1. Spring needs to inject the TagLocationService into it
  2. We need to modify the handleRequest method to use the TagLocationService.
package com.northwind.rfid.shipping.war;

import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.northwind.rfid.shipping.war.service.TagLocationService;

/**
 * @author Kyle Neumeier - kyle@pramari.com
 * 
 */
public class TagLocationController implements Controller {

	/** The Tag Location Service */
	private volatile TagLocationService tagLocationService;

	/**
	 * Called by Spring
	 * 
	 * @param tagLocationService
	 *            the tagLocationService to set
	 */
	public void setTagLocationService(TagLocationService tagLocationService) {
		this.tagLocationService = tagLocationService;
	}

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0,
			HttpServletResponse arg1) throws Exception {
		HashMap<String, Object> model = new HashMap<String, Object>();
		model.put("dockdoor", tagLocationService.getDockDoorItems());
		model.put("weighstation", tagLocationService.getWeighStationItems());
		model.put("alerts", tagLocationService.getAlerts());

		return new ModelAndView("/WEB-INF/jsp/taglocation.jsp", "model", model);
	}
}

Modify the servlet xml

The next thing is to modify the servlet xml so that it will

  1. Create the TagLocationService
  2. Create the JMS Listener and inject the TagLocationServiceManager into it
  3. Inject the TagLocationService into the Controller.

Modify the NorthwindDemo-servlet.xml to look as follows:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
	xmlns:amq="http://activemq.apache.org/schema/core"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	META-INF/xsd/spring-beans-2.5.xsd
    http://www.springframework.org/schema/osgi 
    http://www.springframework.org/schema/osgi/spring-osgi.xsd">

	<!-- Create the Controller -->
	<bean name="/taglocation.htm" class="com.northwind.rfid.shipping.war.TagLocationController" >
		<property name="tagLocationService" ref = "tagLocService"/>
	</bean>
	
	<!-- Create the TagLocationService -->
	<bean id="tagLocService" class="com.northwind.rfid.shipping.war.service.impl.TagLocationServiceImpl" />
	
	<!-- Create the JMS Message Receiver-->
	<bean id="messageReceiver" class="com.northwind.rfid.shipping.war.MessageReceiver">
		<property name="TLSManager" ref="tagLocService" />
	</bean>
	
	<!-- Create the topic to connect to -->
	<bean id="NorthwindTopic" class="org.apache.activemq.command.ActiveMQTopic">
		<property name="physicalName" value="com.northwind.rfid.shipping.topic" />
	</bean>
	
	<!-- JMS Connection Factory -->
	<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
		<property name="brokerURL" value="vm://externalBroker?create=false" />
	</bean>
	
	<!-- Spring Helper to listen to a JMS Destination -->
	<bean id="jmsContainer"
		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="NorthwindTopic" />
		<property name="messageListener" ref="messageReceiver" />
	</bean>

</beans>

Run The Application

Now you can run the whole application. You can point your browser to the web application, start emulator and place tags on the readers. As you move tags around, you can hit the refresh button on your browser to see the tags.

Personal tools