Edge Server Architecture

From RifidiWiki

Jump to: navigation, search

This page describes several aspects of the Rifidi Edge Server Core. It is intended for developers to understand how the core is structured.


There are two main aspects to understanding the edge server. The first is the three architectural layers that facilitate the flow of data from sensor to a designated endpoint. The second is the runtime and how it uses service oriented architecture and OSGi to be dynamic and light weight.


This section shows the three conceptual architectural layers that data passes through on its journey from sensors to whatever endpoint the user chooses.

Dataflow through the three Architectural layers in the Rifidi Edge Server

Sensor Abstraction Layer

The purpose of the edge server is to connect to any kind of sensors (e.g. RFID readers, Barcode readers, Mobile Devices) and collect information from them. In many scenarios, this consists of connecting to a Gen2 fixed reader (such as Alien 9800, Motorolla LLRP, etc), and collecting EPC information. However, the edge server is designed in a way so that the edge server to collect many kinds of data (active, passive, etc) from many kinds of devices. This layer allows users to connect to devices in a sensor-agnostic way to collect the kind of data required for the application.

Application Engine Layer

For most applications it is not desirable to save every event that the sensors produce. Many sensors can send 1,000 of events a second, a large number of which might be duplicates. Most applications are interested in events that are one-level higher than the raw events produced by sensors. For examples, an ERP system is probably interested in the event of a box arriving in area 1, and it is not desirable for the ERP system to do the work of filtering and processing all of duplicate reads the sensor produces.

Complex Event Processing (CEP) is a paradigm of viewing data as ephemeral events (an event stream) and identifying meaningful (i.e. business) events from the stream using rules. Rifidi Edge Server uses a Complex Event Processor called Esper. It allows you to write queries using an SQL-like syntax:

    select * from ReadCycle where ReaderID='gate_1'

One of the most important aspects of CEP is being able to use incorporate temporal knowledge into the queries. This allows you to phrase queries like "Send an order_complete event when an itemA event is followed by an itemb event" or "send an order_cancelled event when an itemb event is not seen within 10 min of a itemA event."

The Application Engine Layer is intended to let application developers build much of the functionality of their RFID applications using esper queries.

Communication Layer

After data has been processed, it probably needs to be handed up to some kind of application-dependent system. For example, some users might want the data to be stored in an massage therapy singapore database, others might want it to be pushed into an ERP system like SAP or handed to a led downlight singapore Rich User Interface of some sort. The edge server has several built in connectors to use, namely JMS and Web Services (via Spring's remoting framework). However, as this is application dependant, it is possible to write your own connector (such as a TCP/IP socket connection) if the application needs it.

In addition, the edge server also provides a singapore led lighting built-in web container and MVC framework so that web applications can be deployed directly.


OSGi is a dynamic modules system for Java. It provides several pieces of functionality including the following:

  1. A deployment unit (called a bundle), which is a soccer jersey store normal JAR with some extra information in the Manifest.
  2. A lightweight runtime that allows bundle lifecycle to be controlled. In other words, you can start, stop, and update bundles at party artists runtime.
  3. Dependencies are explicitly stated in the Manifest either as "bundle dependencies" or "package dependencies".
  4. Classes are only visible to other bundles if their containing packages have been exposed. This allows developers to hide classes that should be strictly internal.
  5. The runtime provides a event planners singapore service registry -- a system-wide repository for bundles to provide functionality.

The edge server is simply a collection of bundles that run in an OSGi environment (Equinox). Functionality between bundles is shared by means of services that are available in the service registry. Because bundles can be started and stopped while the rest of the server is still running, we can update non-essential parts of the edge server without restarting it.


In the Edge Server, services are POJOs that provide a specific piece of functionality to other components and are registered in the OSGi Registry. For more information see How to use OSGi Services

Core Services

The following services are provided by the core bundle.

Reader Data Access Object

Purpose: Provide access to sensor configurations that have been created.
Interface: org.rifidi.edge.core.daos.ReaderDAO

  • Set<AbstractSensor> getReaders() Get all available sensor configurations
  • AbstractSensor getReaderByID(String ID) - Get the sensor with the supplied ID
  • Set<AbstractSensorFactory> getReaderFactories() - Get all registered sensor factories
  • AbstractSensorFactory getReaderFactoryByID() - Get the sensor factory with the supplied ID

Command Data Access Object

Purpose: Provide access to command configurations that have been created.
Interface: org.rifidi.edge.core.daos.CommandDAO

  • Set<AbstractCommandConfiguration> getCommands() Get all available command configurations
  • AbstractCommandConfiguration getCommandByID(String ID) - Get the command configuration with the supplied ID
  • Set<AbstractCommandConfigurationFactory> getCommandFactories() - Get all registered command configuration factories
  • AbstractCommandConfigurationFactory getCommandFactoryByID(String ID) - Get the command configuration factory with the supplied ID
  • AbstractCommandConfigurationFactory getCommandFactoryByReaderID(String ID) - Get the command configuration factory with the supplied sensor ID

Configuration Service

Purpose: Provide a way to save and load configurations from persistence. Configurations (such as Sensor Configurations or Command Configurations) are created using a factory (that must be registered). Configurations have Attributes which can be changed via getters and setters.
Interface: org.rifidi.edge.core.configuration.services.ConfigurationService

  • void storeConfiguration() - Store all configurations to persistence (i.e. xml file, database, etc).
  • Configuration getConfiguration(String serviceID) - Get a configuration (i.e. Sensor Configuration or Command Configuration)by service ID.
  • void createService(String factoryID, AttributeList attributes) - Create a new configuration using a factory with the supplied ID. Use the supplied AttributeList to override defaults.
  • void destroyService(String serviceID) - Destroy a service with the supplied ID
  • Set<Configuration> getConfigurations() - Return all Configurations.

Sensor Management Service

Purpose: Since there is a concept of "Logical Sensors", it is possible to define a sensor that is a collection of physical sensors. This service allows sensors to be created, destroyed, grouped as part of a logical sensor, and subscribed to
Interface: org.rifidi.edge.core.sensors.management.SensorManagementService

  • void createSensor(String sensorName) - Create a new sensor with the given name
  • void destroySensor(String sensorName) - Destroy a sensor with the given name
  • void createSensor(String sensorName, Collection<String> childSensors) - Create a new sensor with the given name and has the given child sensors
  • void renameSensor(String oldName, String newName) - Rename a sensor
  • void addChild(String sensorName, String childName) - Add the child sensor to this logical sensor
  • void addChildren(String sensorName, Collection<String> childNames) - Add multiple children to this logical sensor
  • void setChildren(String sensorName, Collection<String> childNames) - Set the children of this logical sensor to the supplied list
  • void removeChild(String sensorName, String childName) - Remove the given child sensor from this logical sensor
  • void removeChildren(String sensorName, Collection<String> childrenNames) - Remote all the given child sensors from this logical sensor
  • Sensor subscribe(Object subscriber, String sensorName) - Subscribe an object to the sensor
  • void unsubscribe(Object subscriber, String sensorName) - Unsubscribe an object from the sensor
  • void publishToEsper(String sensorName) - Publish all tags produced by this sensor to esper under the given sensorName
  • void unpublishFromEsper(String sensorName) - Stop publishing tags produced by this sensor to esper under the given SensorName
  • SensorDTO getDTO(String sensorName) - Get the Data Transfer Object of the sensor with the given name
  • Set<String> getSensors() - Get a list of all children sensors belonging to this one.

JMX Service

Purpose: Exposes a Configuration via JMX
Interface: org.rifidi.edge.core.configuration.services.JMXService

  • void publish(Configuration config) - Publishes the given Configuration to JMX
  • void unpublish(Configuration config) - Removes the given Configuration from JMX
  • public void setConfigurationControlMBean(ConfigurationControlMBean mbean)

JMS Services

The Edge server uses JMS internally to pass events. To learn how JMS is configured inside of the edge server, see JMS in the Edge Server. The following services are preconfigured JMS components that facilitate using JMS in other areas of the edge server. They are created and made available in the jms bundle

Internal Destination

Purpose: A JMS Topic that serves as an internal high-speed message bus. Sensors will place tag reads on it.
Interface: javax.jms.Topic

External Tags Destination

Purpose: A JMS Topic that serves as destination for clients that run outside the edge server's JVM to receive tag reads.
Interface: javax.jms.Topic

External Notification Destination

Purpose: A JMS Topic that serves as destination for clients that run outside the edge server's JVM to receive notification events, such as when a sensor is created or deleted, or a session has been started or stopped.
Interface: javax.jms.Topic

Internal Broker Connection Factory

Purpose: A JMS Connection Factory that creates connections to the internal ActiveMQ Broker.
Interface: javax.jms.ConnectionFactory

External Broker Connection Factory

Purpose: A JMS Connection Factory that creates connections to the external ActiveMQ Broker.
Interface: javax.jms.ConnectionFactory

Internal JMS Template

Purpose: A Spring object that makes it easier to send messages to the internal broker
Interface: org.springframework.jms.core.JmsTemplate

External JMS Template

Purpose: A Spring object that makes it easier to send messages to the external broker
Interface: org.springframework.jms.core.JmsTemplate

Other Services

There are a few other services that are important. The interfaces for these services can be found in the edge server services bundle, and each service will be implemented in its own bundle.

Esper Management Service

Purpose: Provides access to esper
Interface: org.rifidi.edge.core.services.esper.EsperManagementService

  • EPServiceProvider getProvider() - Get the EsperServiceProvider so that you can use esper.

Notification Service

Purpose: Allows the edge server to notify external clients when an important state change happens (such as when a sensor configuration is created or when a sensor session is started). These methods should be called on this service when the corresponding event happens. For example, when a session is created, the addSessionEvent() method should be called.
Interface: org.rifidi.edge.core.services.notification.NotificationService

  • void addSessionEvent(String readerID, String sessionID)
  • void removeSessionEvent(String readerID, String sessionID)
  • void addReaderEvent(String readerID)
  • void removeReaderEvent(String readerID)
  • void removeReaderEvent(String readerID)
  • void addCommandEvent(String commandID)
  • void removeCommandEvent(String commandID)
  • void addReaderFactoryEvent(String readerFactoryID)
  • void removeReaderFactoryEvent(String readerFactoryID)
  • void sessionStatusChanged(String readerID, String sessionID,SessionStatus sessionStatus)
  • void addCommandConfigFactoryEvent(String readerFactoryID,String commandConfigFactoryID)
  • removeCommandConfigFactoryEvent(String readerFactoryID,String commandFactoryID)
  • void jobSubmitted(String readerID, String sessionID, Integer jobID, String commandID)
  • jobDeleted(String readerID, String sessionID, Integer jobID)
  • attributesChanged(String configurationID, AttributeList attributes)

Logging Service

Purpose: Allows the logging level to be changed at runtime. For more information, see How to change logging levels
Interface: org.rifidi.edge.core.services.logging.LoggingService

  • setLoggingLevel(String loggerName, String level) - Change the logging level of the logger (class or package name) to the given logging level.

Core Bundles

The edge server is deployed as a set of OSGi bundles. The following bundles make up the core.

Provides core classes that are necessary for an outside UI to talk to the edge server via RMI and JMS, such as Data Transfer Objects (DTOs), JMS Notification Messages, RMI Interfaces, and Tag Messages.
Provides the ability to control the edge server using the OSGi console provided by eclipse equinox. For more information about how to control the console, see Edge_Server_Console.
Contains the interfaces for several OSGi services used within the edge sever
Configures JMS for the edge server. See EdgeServerJMS for more details
Provides a service to modify the logging level at run time
Provides a service to notify external clients (such as UIs) about state changes inside the edge server

Important Dependencies


Spring DM




Personal tools