Chapter 19. Notification Service
19 The JacORB Notification Service
The JacORB Notification Service is a partial implementation of the Notification Service specified by the OMG.
19.1 Unsupported Features
The JacORB Notification Service does not support persistent connections or events.
19.2 Installation
19.2.1 JDK 1.3
If you’re using JDK 1.3 and want to use the JacORB Notification Service you’ll need to download the additional library gnu.regexp from http://www.cacas.org/java/gnu/regexp and put it in your classpath. This is necessary because the JacORB Notification Service uses regular expressions. Regular expressions are available in the JDK since version 1.4. Alternatively you can download Jakarta Regexp http://jakarta.apache.org/regexp.
19.2.2 JDK 1.5
The JacORB Notification Service uses the backport of JSR 166. If you are using JDK 1.5 you don’t need
to use this extra library. Instead you can use the standardized java.util.concurrent package. By simply
changing the package names inside the sources and recompiling you can switch between the two versions.
Change to the directory src/org/jacorb/notification and invoke the command ant convert.jdk5. After that you have to recompile JacORB. The target ant convert.jdk4 allows to switch back to backport-util-concurrent (These targets will simply replace all occurences of the string edu.emory.mathcs.backport.java.util.concurrent with java.util.concurrent and vice versa).
19.3 Running the Notification Service
Before the JacORB Notification Service can be accessed, a server process must be started. Starting the notification server is done by running
$ ntfy [-printIOR] [-printCorbaloc] [-writeIOR filename]
[-registerName nameID[.nameKind]] [-port oaPort] [-channels channels]
[-help]
-printIOR print the IOR to STDOUT
-printCorbaloc print the Corbaloc to STDOUT
-writeIOR filename write the IOR to a file
-registerName nameId[.nameKind] make a Name Service entry for the EventChannelFactory.
The Notification Service will resolve the Name Service
by invoking
resolve_initial_references("NameService").
Ensure that your environment is set up properly.
-port oaport start the Notification Service on the specified port.
-channels channels create a number of EventChannels.
19.3.1 Running as a NT Service or an UNIX Daemon
With a little help from the Java Service Wrapper it is easy to run the JacORB notification service as a NT Service or as an UNIX daemon.
Note for JDK 1.3 Users
As noted if you are running JDK 1.3 you need to provide an additional library. If you use the wrapper you also need to add a classpath entry to the wrapper configuration file.
Edit bin/NotifyService-Wrapper.conf and add a classpath entry:
# Java Classpath (include wrapper.jar) Add class path elements as
# needed starting from 1
wrapper.java.classpath.1=../lib/wrapper-3.x.y.jar
...
wrapper.java.classpath.6=../lib/avalon-framework-4.1.5.jar
wrapper.java.classpath.7=../lib/gnu.regexp.jar
Installing and Running as a NT Service
The necessary wrapper configuration files are located in the JacORB/bin directory.
The notification service can be installed as a NT service by double clicking on the NotifyService-Install-NT.bat batch file which is located in the JacORB/bin directory. Alternatively you can open a Command Window and then run the install script from the command prompt.
C:\JacORB\bin>NotifyService-Install-NT.bat
wrapper | JacORB Notification Service installed.
Once the service has been installed, it can be started by opening up the Service Control Panel, selecting the service, and then pressing the start button.
The service can also be started and stopped from within a Command Window by using the net start JacORB-Notify and net stop JacORB-Notify commands, or by passing commands to the wrapper.exe executable.
The wrapper is set up to start the JacORB Notification Service whenever the machine is rebooted. The service can be uninstalled by running the NotifyService-Uninstall-NT.bat batch file. See the Windows specific wrapper documentation for more details.
Installing and Running as an UNIX Daemon
JacORB is shipped with a sh script which can be used to start and stop the JacORB Notification Service controlled by the Java Service Wrapper.
First you need to download the appropiate binary for your system from http://wrapper.tanukisoftware.org. The Java Service Wrapper is supported on Windows, Linux, Solaris, AIX, HP-UX, Macintosh OS X, DEC OSF1, FreeBSD, and SGI Irix systems (Note: You don’t need to download anything if you are running Windows. All necessary stuff is shipped with the JacORB distribution).
Install the Java Service Wrapper to a appropiate place by unzipping it (WRAPPER_HOME). Add WRAPPER_HOME/bin to your PATH variable. If you don’t want to modify your PATH variable you can put a link to WRAPPER_HOME/bin/wrapper in one of the directories that’s already in your PATH environment (e.g. ln -s /usr/local/wrapper/bin/wrapper /usr/local/bin).
Ensure that the shell-script JacORB/bin/ntfy-wrapper has the executable bit set. Note that the .sh script will attempt to create a pid file in the directory specified by the property PIDDIR in the script. If the user used to launch the Wrapper does not have permission to write to this directory then this will result in an error. An alternative that will work in most cases is to write the pid file to another directory. To make this change, edit the .sh script and change the following setting:
PIDDIR="."
to something more appropiate:
PIDDIR="/var/run"
Running in the console
The JacORB notification service can now be run by simply executing bin/ntfy-wrapper console. When running using the console command, output from the notification service will be visible in the console. The notification service can be terminated by hitting CTRL-C in the command window. This will cause the Wrapper to shut down the service cleanly.
If you omit the command the scripts prints the available commands. The script accepts the commands start, stop, restart and dump. The start, stop, and restart commands are common to most daemon scripts and are used to control the wrapper and the notification service as a daemon process. The console command will launch the wrapper in the current shell, making it possible to kill the application with CTRL-C. Finally the command dump will send a kill -3 signal to the wrapper causing its JVM to do a full thread dump.
Running as a Daemon Process
The application can be run as a detatched daemon process by executing the script using the start command.
When running using the start command, output from the JVM will only be visible by viewing the logfile NotifyService-Wrapper.log using tail -f NotifyService-Wrapper.log. The location of the logfile can be configured in the wrapper configuration file bin/NotifyService-Wrapper.conf
Because the application is running as a detatched process, it can not be terminated using CTRL-C and will continue to run even if the console is closed.
To stop the application rerun the script using the stop command.
Installing The Notification Service To Start on Reboot
This is system specific. See the UNIX specific wrapper documentation for instructions for some platforms.
19.3.2 Running as a JBoss Service
The JacORB notification service can also be run as a jboss service.
As first step the jacorb.jar that is shipped with jboss (JBOSS_HOME/server/all/lib) needs to be replaced to the current version (v2.2.3). As next step the jboss-cosnotification.sar file can be deployed into jboss by copying it to JBOSS_HOME/server/all/deploy.
After starting jboss a mbean for the notification service will show up in the jboss jmx management console.
19.4 Accessing the Notification Service
Configuring a default notification service as the ORB’s default is done by adding the URL that points to the service to the properties files .jacorb_properties. A valid URL can be obtained in various ways:
By specifying the option -printIOR as you start the notification service a stringified IOR is printed out to the console. From there you can copy it to a useful location.
Usually the stringified IOR makes most sense inside a file. Use the option -writeIOR <filename> to write the IOR to the specified file.
A more compact URL can be obtained by using the option -printCorbaloc. In conjunction with the option -port you can use the simplified corbaloc: URL of the form corbaloc::ip-address:port/NotificationService. This means all you need to know to construct an object reference to your notification service is the IP address of the machine and the port number the server process ist listening on (the one specified using -port).
Add the property ORBInitRef.NotificationService to your properties file. The value can be a corbaloc: URL or alternatively the file name where you saved the IOR.
The JacORB notification service is accessed using the standard CORBA defined interface:
// get a reference to the notification service
ORB orb = ORB.init(args, null);
org.omg.CORBA.Object obj;
obj = orb.resolve_initial_references("NotificationService");
// get a reference to the notification service
ORB orb = ORB.init(args, null);
org.omg.CORBA.Object obj;
obj = orb.resolve_initial_references("NotificationService");
EventChannelFactory ecf = EventChannelFactoryHelper.narrow( o );
IntHolder ih = new IntHolder();
Property[] p1 = new Property[0];
Property[] p2 = new Property[0];
EventChannel ec = ecf.create_channel(p1, p2, ih);
...
19.5 Configuration
Following is a brief description of the properties that control Notification Service behaviour.
The Notification Service uses up to three Thread Pools with a configurable size. The first Thread Pool is used to process the filtering of the Messages. The second Thread Pool is used to deliver the Messages to the Consumers. The third Thread Pool us used to pull Messages from PullSuppliers.
Table 19.1: Notification Service Properties
Property
|
Description
|
Type
|
DEF
|
filter.thread_pool_size
|
This is the Size of the Thread Pool used to process the filters. Increasing this value on a Multiprocessor machine or if Filters are on a different machine than the Channel could increase the Filtering Performance as multiple events can be processed concurrently.
|
int0
|
2
|
proxysupplier.thread_pool_size
|
This is the Size of the Thread Pool used to deliver the Messages to the Consumers. By using the property proxysupplier.threadpolicy2 it is also possible to use one Thread per ProxySupplier.
|
int0
|
4
|
proxyconsumer.thread_pool_size
|
Specifies the Size of the Thread Pool used to pull Messages from PullSuppliers
|
int>=0
|
2
|
proxysupplier.threadpolicy
|
Specify which thread policy the ProxySuppliers should use to deliver the Messages to its Consumers. Valid values are:
|
string
|
Thread-
Pool
|
supplier.poll_intervall
|
Specifies how often Messages should be pulled from a PullSupplier. The value specifies the intervall between two pull-Operations.
|
milli seconds
|
1000
|
supplier.max_number
|
Specify the maximum number of Suppliers that may be connected to a Channel at a time. If a Supplier tries to connect, while this limit is exceeded, AdminLimitExceeded is raised. Note that this property can also be set programatically via the set_admin operation.
|
int>0
|
maximum int value
|
consumer.max_number
|
Specify the maximum number of Consumers that may be connected to a Channel at a time. If a Consumer tries to connect, while this limit is exceeded, AdminLimitExceeded is raised. Note that this property can also be set programatically via the set_admin operation.
|
int>0
|
maximum int value
|
max_events_per_consumer
|
Specifies how many Events a ProxySupplier at most should queue for a consumer. If this number is exceeded Events are discarded according to the DiscardPolicy configured for the ProxySupplier.
|
int>0
|
100
|
max_batch_size
|
Specifies the maximal number of Messages a SequencePushSupplier should queue before a delivery to its connected SequencedPushConsumer is forced.
|
int>=0
|
1
|
order_policy
|
Specify how events that are queued should be ordered. Valid values are:
AnyOrder
PriorityOrder
DeadlineOrder
FifoOrder
|
string
|
Priority-Order
|
discard_policy
|
Specifies which Events are discarded if more than the maximal number of events are queued for a consumer. Valid values are:
AnyOrder
PriorityOrder
DeadlineOrder
FifoOrder
LifoOrder
|
string
|
Priority-Order
|
consumer.backout_interval
|
After a delivery to a Consumer has failed the Channel will pause delivery to that Consumer for a while before retrying. This property specifies how long a consumer should stay disabled.
|
milli seconds
|
1000
|
consumer.error_threshold
|
Each failed delivery to a consumer increments an errorcounter. If this errorcounter exceeds the specified value the consumer is disconnected from the channel.
|
int>=0
|
3
|
default_filter_factory
|
Specify which FilterFactory (CosNotifyFilter::FilterFactory) the attribute EventChannel::default_filter_factory should be set to. Default value is builtin. This special value implies that a FilterFactory will be created during start of the EventChannel. Its possible to set this property to a URL that points to another CosNotifyFilter::FilterFactory object. In this case no FilterFactory is started by the EventChannel. The URL is resolved by a call to ORB::string_to_object.
|
URL
|
builtin
|
proxy.destroy_causes_disconnect
|
Specify if a destroyed Proxy should call the disconnect
operation of its consumer/supplier.
|
boolean
|
on
|
19.5.1 Setting up Bidirectional GIOP
If you have set the ORBInitializer property as described in Section 12.1.1 the Notification will automatically
configure its POA to use Bidirectional GIOP.
19.6 Monitoring the Notification Service
The JacORB Notification Service provides JMX MBean interfaces which make it possible to monitor and control the Service using a JMX console. This section will describe how to start a JMX enabled Notification Service and how to configure your JMX console to access the exposed MBeans.
19.6.1 Download MX4J
MX4J is an Open Source implementation of the JMX specification. You need to download the current release of MX4J (currently 3.0.1) from the JMX project page mx4j.sourceforge.net and install MX4J in an appropriate place.
19.6.2 Edit Java Service Wrapper configuration
The configuration file NotifyService-Wrapper-MX4J.conf.template contains the necessary settings to start the JMX enabled Notification Service. You have to edit the classpath. Replace the token @MX4J HOME@ with the concrete path to your MX4J installation.
# Java Classpath (include wrapper.jar) Add class path elements as
# needed starting from 1
wrapper.java.classpath.1=../lib/wrapper-3.x.y.jar
...
wrapper.java.classpath.8=@MX4J_HOME@/lib/mx4j.jar
wrapper.java.classpath.9=@MX4J_HOME@/lib/mx4j-remote.jar
wrapper.java.classpath.10=@MX4J_HOME@/lib/mx4j-tools.jar
After customization of the configuration file it must be renamed to NotifyService-Wrapper.conf as the start script reads its configuration from the so called file.
19.6.3 Start the Service
consult section 19.3.1 for further details to start the Service.
19.6.4 Connecting to the management console
The Notification Service web management console will be available at http://localhost:8001. A JSR 160 RMI connector allows a management console to connect to the Notification Service. The Service URL is service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jndi/COSNotification.
19.7 Extending the JacORB Notification Service
19.7.1 Adding custom Filters
The JacORB Notification Service supports the full ETCL filter grammar. If you need to use your own specialized filters you have to provide an implementation of the Filter Interface. You can extend the class org/jacorb/notification/filter/AbstractFilter.java that provides generic filter management. See the class org/jacorb/notification/filter/bsh/BSHFilter.java for an example of an Beanshell based custom filter. Additionally to the standard ETCL grammar the FilterFactory will try to load all filter grammars specified in jacorb.properties. An entry must have the following form: jacorb.notification.filter.plugin.GRAMMAR=CLASSNAME where GRAMMAR
should be replaced by the name of the grammar and CLASSNAME should be replaced by the classname of the custom filter implementation.
custom filters can then be created by invoking FilterFactory::create_filter or FilterFactory::create_mapping_filter and specifying GRAMMAR as parameter.