Actors in Java: Coding The Surveillance And Security Application Part 2
In this post we will be looking at code for a system designed to integrate all of the devices used to provide surveillance and security to extensive physical premises such as malls, campuses, and industrial parks. The approach I am taking involves the actor paradigm and the Java programming language. The selection of actors for this type of application is based on a number of characteristics of actor based systems that make this technology an excellent fit. The actors we will be using can, by simple change of a configuration file, be hosted anywhere the Internet reaches. The design supports actors being deployed to remote hosts from a central command station. This straight forward built-in ability to have remote agents and be able to deploy them remotely gives the site administrator great freedom to design the site's protection. The layout can all be done from a configuration file with no need to write code. The geographical reach and ease with which an actor based system can geographically extend comport very well with a growing physical site. The built-in ability for actors to belong to hierarchies of supervision is especially pertinent because of the reporting requirements of security applications that endeavor to control and protect a complex of distributed resources from a central command station. A surveillance and security system must be robust. It must be designed to withstand a hostile environment. The actor framework we will be using has a very easy to use monitoring feature that allows one actor to watch the life cycle of another actor. This is a very powerful feature that gives a managing actor the ability to intervene and help when a worker actor raises an exception or unexpectedly dies. It confers on the managing actor the advantage of being in a very flexible position where, depending on the type of problem, it can resume the operation of a worker actor that experienced an exception, it can restart a fresh instance of the worker actor that died, or it can escalate the intervention to its own supervisor.
What You Will Need
To work with the code that comes with this post you will need to have the following installed on all of the machines you intend to use.
Java 7 Standard Edition Development Kit ( JDK )
Akka Actors Framework 2.2.3
Attached to this post.
Because we will be creating a distributed system with remote deployment be aware that you must have all of the akka provided jar files visible to each JVM on all of the machines that you will be using. Set classpaths accordingly in your IDEs or scripts. The scripts that come with the source for SurveilSecure are a guide to what you will need in your own custom setup.
This first cut at the code for the system lays down the basic management structure and starts development of a robust self aware messaging base. It is made up of an initiator actor, four managing actors, one monitoring actor, and a transient actor to stop the system.
|StartGuardian||This is the system launcher. It constructs Control.|
|Control||This is the top level manager.|
|Surveil||Manager of all surveillance cameras.|
|Secure||Manager of all entry protection devices.|
|Alarm||Manager of all notification subsystems.|
|Heartbeat||Monitors to see if Control remains alive.|
|Stop||Shuts down all or some of the SurveilSecure system.|
The StartGuardian object launches the SurveilSecure Premises Guardian system. This object constructs a single actor of the Control class. The actor created is the highest level manager in the SurveilSecure application. After creating the Control manager the initiator does not have a role. See file StartGuardian.java.
The Control actor creates and watches its three subordinate managers, Surveil, Secure, and Alarm. An example of how it does this is seen below. Note that it creates a unique actor system for Surveil. It does this for each of the three subordinate managing actors giving them the ability to be moved about independently. Another thing to note is the third statement. This sets up a death watch on the Surveil actor. If Surveil terminates for any reason Control receives notification of this event.
// Create the remote actor system used for supervising surveillance.
surveilSystem = ActorSystem.create( "Surveil", ConfigFactory.load().getConfig("Surveil"));
// Create the actor that manages surveillance.
surveilRef = surveilSystem.actorOf(Props.create( Surveil.class ), "Surveil" );
// Set up life cycle monitoring of the surveillance manager for restart of this actor.
this.getContext().watch( surveilRef );
The notice of the death of a watched actor arrives in the receive loop as a message. Control will examine the conditions of the failure and decide upon a course of action that may involve restarting the actor that has died. The code below shows how to wait for termination message.
// TERMINATION OF WATCHED ACTOR
if ( messageRecv instanceof Terminated )
System.out.println("\nControl: Life cycle monitoring detected death of watched actor.");
final Terminated t = (Terminated) messageRecv;
ActorRef deadActorRef = t.getActor();
if ( deadActorRef.equals( surveilRef ))
System.out.println("\nControl: 'Surveil' manager has terminated unexpectedly. ");
Develop code here for investigating causes of actor death and determining
a strategy that includes restarting the actor, fatal exit as alternatives.
Same applies to the termination of the other two managing actors that are
subordinates of Control.
The ability of an actor system to detect the death of a supervised actor opens vast possibilities for creating a robust resilient system.
The actors of SurveilSecure can be deployed on any machine that has a JVM and can be reached via Internet. This ability to be remote and to be deployed remotely is achieved by settings in the configuration file application.conf. An excerpt is taken from this file to show how to set up for remote creation and remote deployment of actors.
# Configuration for the manager having overall responsibility for surveilling the site.
actor.provider = "akka.remote.RemoteActorRefProvider"
actor.deployment ./surveil .remote = "akka.tcp://surveilSystem@127.0.0.1:4001"
remote.transport = "akka.remote.netty.NettyRemoteTransport"
remote.netty.tcp.hostname = "127.0.0.1"
remote.netty.tcp.port = 4001
stdout-loglevel = "OFF"
loglevel = "OFF"
#loglevel = "INFO" # "DEBUG" for more information
Let's go through the important lines here.
First there is actor.provider. This configuration variable contains a value that is the fully qualified class name of a class that will start up an actor and produce an actor reference used for communicating with the actor. In the case above we are using the actor provider that is needed for remote actors. All of the actors in SurveilSecure are remote actors but you may still choose to have them all on one machine.
Next the is actor.deployment ./surveli is the id .remote = gives the value of the
path to remotely deployed system. In the case above we have
Akka.tcp - This system will use tcp protocol.
surveilSystem -The name of the actor system.
@127.0.0.1 - The host address of the actor system.
:4001 -The port address for this actor system.
Next the line remote.transport = "akka.remote.netty.NettyRemoteTransport"
The akka class named as remote.transport is responsible for initializing the underlying transport provided by the operating system. In the case given above this means initialization involving TCP.
Next remote.netty.tcp.hostname = "127.0.0.1"
Netty is an asynchronous event-driven network application framework.
The akka actor framework makes use of netty as its framework for asynchronous communications.
The line above specifies to netty that the remote hostname is 127.0.0.1, the local address.
The next line remote.netty.tcp.port = 4001
specifies to netty the port we will use for this actor system.
The Other Actors
The other actors are the three subordinate managers, Surveil, Secure, and Alarm, At this point in development all that they are doing is echoing a message to show that they are alive and responding to a stop message. The other two actors are fully functional. They are Heartbeat which talks to Control once a minute to make sure it can still function and puts a message on the console at that moment to show that the system is still running. The Stop actor is a transient actor that can send a Stop message to any of the manager actors.
The basic infrastructure and techniques are in place for the SurveilSecure system. Configuration and code for remote actor creation and remote actor deployment is in place and tested. Life cycle monitoring (death watch ) of subordinate managing actors using built-in Akka framework functionality is running as well as a proprietary heartbeat mechanism for the highest level managing actor.
Whether you are interested or not in building a surveillance and security system this work can be a model of many things that can be done with actors using the Akka framework with Java. Techniques such as remote creation and remote deployment of actors and implementing supervision of actors through their entire life cycle are very powerful and universal techniques.
I will be adding more functionality to the SurrveilSecure system in my next post to be published December 10th, 2013.