WS-Notification Guide
Accessing topic subscriptions through the WS-Notification standard
Copyright © 2011-2014 Red Hat, Inc. and/or its affiliates.
Abstract
Chapter 1. Introduction to WS-Notification
1.1. WS-Notification Standard
Overview
- WS-Topics
- WS-BaseNotification
- WS-BrokeredNotification
WS-Topics
- Topic hierarchy—a hierarchical naming scheme, which can be defined using an XML document associated with the notification broker.
- Topic set—a standardized XML schema, which can optionally be used to define the hierarchy of topic names.
- Topic dialect—a particular type of name expression that is used to specify one topic or to select multiple topics. The following dialects are defined by the WS-Topics specification:
- Simple
- Concrete
- Full
- XPath
WS-BaseNotification
NotificationPublisher
- Must be implemented by the entity that wants to publish messages. This interfaces exposes the
subscribe
operation, which enables consumers to register their interest in receiving notifications from this publisher. NotificationConsumer
- Must be implemented by the entity that wants to receive messages. This interface exposes the
notify
operation, which enables the consumer to receive message notifications directly from the publisher.
CreatePullPoint
- Exposes the
createPullPoint
operation, which creates aPullPoint
object that can be used to accumulates messages. PullPoint
- Exposes the
notify
operation, which enables the pull-point to accumulate notification messages, and thegetMessages
operation, which enables a pull-style consumer to retrieve the accumulated messages when it is ready.
WS-BrokeredNotification
NotificationBroker
- Combines the
NotificationPubisher
,NotificationConsumer
, andCreatePullPoint
interfaces, enabling you to provide the full range of notification services in a single application.TheNotificationBroker
interface defines one additional operation, theregisterPublisher
operation, which can optionally be used to register publishers with the broker. In particular, this operation can be useful when constructing a federation of brokers. RegisterPublisher
- The notification broker also implements the
RegisterPublisher
interface, which defines one additional operation,registerPublisher
. A publisher can optionally use theregisterPublisher
operation itsNotificationPublisher
object with the broker.NoteIt is also possible for publishers to send messages to the broker straightaway, by invokingnotify
, without needing to register in advance. PublisherRegistrationManager
- The return value of the
registerPublisher
operation is a reference to aPublisherRegistrationManager
object, which can be used to destroy a registration.
References
1.2. Consumer Client Scenario
Overview
Figure 1.1. A Consumer Client Scenario
Clients in this scenario
- Publisher client—generates notification messages and publishes the messages on a specific topic, by sending them to the notification broker.
- Consumer client—a client that implements a consumer callback object (exposing a Web service endpoint of
NotificationConsumer
type), which is capable of receiving notifications directly from the notification broker.
Scenario steps
- The consumer client instantiates a consumer callback object, which implements the
NotificationConsumer
interface and is capable of receiving notifications from the broker. - The consumer client creates a subscription by invoking the
subscribe
operation on the broker, passing the following operation arguments:- Topic name—specifies the topic that the client wants to subscribe to.
- Callback reference—a reference to the consumer callback object that will receive the notifications, where the service reference has the format of a WS-Addressing Endpoint Reference (EPR).
- A publisher client sends a notification message on a specific topic, by invoking the
notify
operation on the broker. - If the message topic matches the consumer client's subscription, the broker will forward the message to the consumer client by invoking the
notify
operation on the consumer callback service.
1.3. PullPoint Client Scenario
Overview
PullPoint
object (which acts as a message drop-box) and retrieves the messages from time to time by invoking the getMessages
operation on the PullPoint
. Figure 1.2, “A PullPoint Client Scenario” provides an overview of this scenario.
Figure 1.2. A PullPoint Client Scenario
Clients in this scenario
- Publisher client—generates notification messages and publishes the messages on a specific topic, by sending them to the notification broker.
- PullPoint client—a client that uses a polling strategy to get notification messages. Instead of receiving notification messages directly from the broker, this client creates a remote
PullPoint
instance. Messages that accumulate in thePullPoint
can be retrieved at any time by invoking thegetMessages
operation on thePullPoint
.
Scenario steps
- The pull-point client creates a remote
PullPoint
instance by invoking thecreate
operation on theCreatePullPoint
interface in the broker. The return value from this operation contains a WS-Addressing reference to the remote pull-point. - The pull-point client creates a subscription by invoking the
subscribe
operation on the broker, passing the following operation arguments:- Topic name—specifies the topic that the client wants to subscribe to.
- Callback reference—a reference to the remote
PullPoint
instance that will receive the notifications on behalf of the client.
- A publisher client sends a notification message on a specific topic, by invoking the
notify
operation on the broker. - At any time, the pull-point client can retrieve messages that have accumulated in the
PullPoint
instance by invoking thegetMessages
operation on thePullPoint
.
1.4. Implementation of WS-Notification
Overview
Figure 1.3. Notification Broker Architecture
Notification broker as wrapper around ActiveMQ broker
OSGi container deployment
cxf-wsn
.
Supported WS-Notification interfaces
NotificationBroker
- The main notification broker interface enables you to create subscriptions (
subscribe
operation), send notification messages (notify
operation), and register Publisher services (registerPublisher
operation). CreatePullPoint
- The create pull-point interface enables you to create new pull-point endpoints on the notification broker, which are used to accumulate messages until a consumer client is ready to retrieve them.
Qualities of service
Topics
- Only the SIMPLE dialect is supported (of the dialects described in the WS-Notification specification).
- In a WS-Notification client, you can specify a topic name as the
String
type or as theQName
type. - A notification topic name maps directly to an ActiveMQ topic name.
- Topic hierarchies are not supported in JBoss A-MQ, but something very similar is supported by the underlying ActiveMQ broker. In Apache ActiveMQ, you can define a topic to have a segmented structure, where each segment is delimited by the
.
character—for example,STOCKS.NYSE.REDHAT
. Within the ActiveMQ configuration, you can exploit this structure to match multiple topics—for example,STOCKS.NYSE.>
matches all topics starting withSTOCKS.NYSE.
. - Topics are ad-hoc—in other words, there is no need to pre-define any topic hierarchy in XML. Topics are created dynamically: if you use them, they are automatically created in the broker. This is the standard approach supported in the underlying ActiveMQ broker.
Configuration of the notification broker
etc/org.apache.cxf.wsn.cfg
- Configures the wrapper component of the notification broker. For details about the properties you can set in this file, see the section called “org.apache.cxf.wsn.cfg settings”.
etc/org.fusesource.mq.fabric.server-default.cfg
- Customizes the OSGi deployment of the Apache ActiveMQ broker. A couple of important properties can be set in this file—for example, the broker name.
etc/activemq.xml
- Configures the Apache ActiveMQ broker. Most of the broker features and properties can be configured in this file. For example, you can configure message persistence and fine tune broker performance in this file.
1.5. Client API
Overview
Figure 1.4. Client APIs
WS-Notification standard API
Simplified client API
API reference
org.apache.cxf.wsn.client
Chapter 2. WS-Notification Tutorial
2.1. Install and Configure the Notification Broker
Overview
Prerequisites
Steps to install the notification broker
- Make sure you have already configured some user accounts in the
etc/users.properties
file. If necessary, create a user account by adding lines in the following format:Username=Password[,Role1][,Role2]...
For example, this tutorial assumes that the followingadmin
user account is defined (which has privileges defined by theadmin
role):admin=admin,admin
- Create the notification broker configuration file,
InstallDir/etc/org.apache.cxf.wsn.cfg
, and use a text editor to add the following property settings:cxf.wsn.activemq=vm://amq?create=false&waitForStart=10000 cxf.wsn.activemq.username=admin cxf.wsn.activemq.password=admin
The following aspects of the notification broker are configured in this file:- Connection to the ActiveMQ broker—the
vm://amq
URL connects through the Java Virtual Machine to access the broker namedamq
(where the broker's name is defined by thebroker-name
setting in theetc/org.fusesource.mq.fabric.server-default.cfg
file). The following options are specified on this URL:create
- By setting
create=false
, you can ensure that the notification broker does not try to create its own (embedded) instance of a broker, but always tries to connect to the existing broker instance namedamq
. waitForStart
- To compensate for any delays that might occur during the container's start-up sequence, this endpoint defines a grace period, during which it waits for the broker to start.
- Credentials for the connection—because authentication is enabled by default in the broker, you must provide credentials (username and password) for connecting to the broker. The credentials must refer to one of the user accounts defined in
etc/users.properties
.
- Start up the JBoss A-MQ container, by entering the following command from the
InstallDir/bin
directory:./amq
- Install and start up the notification broker using the
features:install
console command, as follows:JBossA-MQ:karaf@root> features:install cxf-wsn
- Check that broker has started up by navigating to the following URL in your Web browser (querying the WSDL contract from the Web service endpoint):
http://localhost:8182/wsn/NotificationBroker?wsdl
NoteYour browser should display the NotificationBroker WSDL contract in response to this URL, but this does not work in all browsers. For example, the Safari browser just displays a blank page.
Troubleshooting
osgi:list
- If you run
osgi:list
at the console prompt, you should see some output like the following:JBossA-MQ:karaf@root> osgi:list ... [ 149] [Active ] [Created ] [ 40] Apache CXF API (2.6.0.redhat-60024) [ 150] [Active ] [Created ] [ 40] Apache CXF Runtime Core (2.6.0.redhat-60024) [ 151] [Active ] [ ] [ 40] Apache CXF Runtime Management (2.6.0.redhat-60024) [ 152] [Active ] [Created ] [ 40] Apache CXF Karaf Commands (2.6.0.redhat-60024) [ 153] [Active ] [ ] [ 30] Apache Neethi (3.0.2) [ 154] [Active ] [Created ] [ 40] Apache CXF Runtime WS Policy (2.6.0.redhat-60024) [ 155] [Active ] [ ] [ 40] Apache CXF Runtime XML Binding (2.6.0.redhat-60024) [ 156] [Active ] [Created ] [ 40] Apache CXF Runtime SOAP Binding (2.6.0.redhat-60024) [ 157] [Active ] [Created ] [ 40] Apache CXF Runtime WS Addressing (2.6.0.redhat-60024) [ 158] [Active ] [ ] [ 40] Apache CXF Runtime JAXB DataBinding (2.6.0.redhat-60024) [ 159] [Active ] [Created ] [ 40] Apache CXF Runtime HTTP Transport (2.6.0.redhat-60024) [ 160] [Active ] [Created ] [ 40] Apache CXF Runtime Simple Frontend (2.6.0.redhat-60024) [ 161] [Active ] [Created ] [ 40] Apache CXF Runtime JAX-WS Frontend (2.6.0.redhat-60024) [ 162] [Active ] [ ] [ 60] Apache CXF WSN API (2.6.0.redhat-60024) [ 163] [Active ] [Created ] [ 40] Apache CXF Runtime HTTP Jetty Transport (2.6.0.redhat-60024) [ 166] [Active ] [Created ] [ 60] Apache CXF WSN Core (2.6.0.redhat-60024)
In particular, the Apache CXF WSN Core bundle (which deploys the notification broker server) must have the statusActive
andCreated
. log:display
- Run the
log:display
command at the console prompt to search the container log for errors and warnings.
org.apache.cxf.wsn.cfg settings
etc/org.apache.cxf.wsn.cfg
configuration file:
cxf.wsn.activemq
- Specifies the URI for connecting to the ActiveMQ broker (must be an ActiveMQ client URL). Default is
vm:localhost
. cxf.wsn.activemq.username
- Specifies the username credentials for logging on to the ActiveMQ broker. Default is
user
. cxf.wsn.activemq.password
- Specifies the password credentials for logging on to the ActiveMQ broker. Default is
password
. cxf.wsn.rootUrl
- Specifies the host and IP port of the notification broker's Web service endpoints. Default is
http://0.0.0.0:8182
. cxf.wsn.context
- Defines the servlet context for notification broker's Web service endpoints. Default is
/wsn
.By default, the notification broker constructs itsNotificationBroker
endpoint address and itsCreatePullPoint
endpoint address as follows:${cxf.wsn.rootUrl}${cxf.wsn.context}/NotificationBroker ${cxf.wsn.rootUrl}${cxf.wsn.context}/CreatePullPoint
Advanced configuration
etc/activemq.xml
file. For example, through the settings in this file you can configure persistent storage and you can optimize the broker for optimum performance.
2.2. Create a Publisher Client
Overview
Prerequisites
fusesource
repository to Maven's settings.xml
file. Maven looks for your settings.xml
file in the following standard location:
- UNIX:
home/User/.m2/settings.xml
- Windows:
Documents and Settings\User\.m2\settings.xml
settings.xml
file at this location, you need to create a new settings.xml
file. Modify the settings.xml
file by adding the repository
element for fusesource
, as highlighted in the following example:
<settings> <profiles> <profile> <id>my-profile</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>fusesource</id> <url>http://repo.fusesource.com/nexus/content/groups/public/</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> ... </repositories> </profile> </profiles> ... </settings>
Sample publisher client code
Hello World!
message to the MyTopic
topic on the notification broker.
Example 2.1. Publisher Client Code
// Java package org.jboss.fuse.example.wsn.publisher.client; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import org.w3c.dom.Element; import org.apache.cxf.wsn.client.Consumer; import org.apache.cxf.wsn.client.NotificationBroker; import org.apache.cxf.wsn.client.Subscription; import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType; /** * */ public final class Client { private Client() { //not constructed } /** * @param args */ public static void main(String[] args) throws Exception { String wsnPort = "8182"; if (args.length > 0) { wsnPort = args[0]; } // Create a NotificationBroker proxy NotificationBroker notificationBroker = new NotificationBroker("http://localhost:" + wsnPort + "/wsn/NotificationBroker"); for (int i=0; i<120; i++) { // Send notifications on the Topic notificationBroker.notify( "MyTopic", new JAXBElement<String>( new QName("urn:test:org", "foo"), String.class, "Hello World!" ) ); // Sleep for 1s between notifications Thread.sleep(1000); } // Cleanup and exit System.exit(0); } }
NotificationBroker proxy class
NotificationBroker
proxy class to connect to the remote notification broker and to publish notifications to the broker. In this example, the following NotificationBroker
methods are invoked:
NotificationBroker(String address, Class<?>... cls)
- The
NotificationBroker
constructor normally takes a single argument, which is the URL of the remote notification broker Web service. notify(String topic, Object msg)
- Sends a message,
msg
, on the topic,topic
, to the notification broker, where the format of themsg
argument is an XML document. For example, you can use the JAX-B API to create a single XML element containing a string for the message, as shown in Example 2.1, “Publisher Client Code”.
NotificationBroker
proxy class belongs to the simplified client API provided by the Apache CXF implementation of WS-Notification; it is not an instance of the standard NotificationBroker
SEI defined by JAX-WS (although the standard SEI is also available and could be used instead).
Steps to create a publisher client
- You can create a Maven project directly from the command line, by invoking the
archetype:generate
goal. First of all, create a directory to hold the WS-Notification client projects. Open a command prompt, navigate to a convenient location in your file system, and create thewsn
directory, as follows:mkdir wsn cd wsn
You can now use thearchetype:generate
goal to invoke theservicemix-cxf-code-first-osgi-bundle
archetype, which generates a simple Apache CXF demonstration, as follows:mvn archetype:generate \ -DarchetypeGroupId=org.apache.servicemix.tooling \ -DarchetypeArtifactId=servicemix-cxf-code-first-osgi-bundle \ -DarchetypeVersion=2013.01.0.redhat-610379 \ -DgroupId=org.jboss.fuse.example \ -DartifactId=wsn-publisher \ -Dversion=1.0-SNAPSHOT \ -Dpackage=org.jboss.fuse.example.wsn.publisher
NoteThe backslash characters at the end of each line are effective as line-continuation characters on UNIX and LINUX platforms. If you are entering the command on a Windows platform, however, you must enter the entire command on a single line.You will be prompted to confirm the project settings, with a message similar to this one:Confirm properties configuration: groupId: org.jboss.fuse.example artifactId: wsn-publisher version: 1.0-SNAPSHOT package: org.jboss.fuse.example.wsn.publisher Y: :
Type Return to accept the settings and generate the project. When the command finishes, you should find a new Maven project in thewsn/wsn-publisher
directory. - Some of the generated project files are not needed for this tutorial. Under the
wsn/wsn-publisher
directory, delete the following files and directories:src/main/resources/META-INF/spring/beans.xml src/main/java/org/jboss/fuse/example/wsn/publisher/Person.java src/main/java/org/jboss/fuse/example/wsn/publisher/PersonImpl.java src/main/java/org/jboss/fuse/example/wsn/publisher/UnknownPersonFault.java src/main/java/org/jboss/fuse/example/wsn/publisher/types
- Edit the
pom.xml
file in thewsn-publisher
directory, and add the dependency required for WS-Notification clients:<?xml version="1.0" encoding="UTF-8"?> <project ...> ... <dependencies> ... <!-- Needed for WS-Notification --> <dependency> <groupId>org.apache.cxf.services.wsn</groupId> <artifactId>cxf-services-wsn-api</artifactId> <version>2.7.0.redhat-610379</version> </dependency> </dependencies> ... </project>
- Edit the
Client.java
file in thewsn-publisher/src/main/java/org/jboss/fuse/example/wsn/publisher/client/
directory, remove the existing content, and replace it with the code from Example 2.1, “Publisher Client Code”. - You can now run the publisher client from the
wsn-publisher
directory by entering the following command:mvn -Pclient
In the command window, you should see some output like the following:INFO: Creating Service {http://cxf.apache.org/wsn/jaxws}NotificationBrokerService from WSDL: jar:file:/Users/fbolton/.m2/repository/org/apache/cxf/services/wsn/ cxf-services-wsn-api/2.6.0.redhat-60024/cxf-services-wsn-api-2.6.0.redhat-60024.jar !/org/apache/cxf/wsn/wsdl/wsn.wsdl
Notification messages are now accumulating in the broker, but you will not be able to receive the messages until you create a consumer client.
2.3. Create a Consumer Client
Overview
Sample consumer client code
MyTopic
topic.
Example 2.2. Consumer Client Code
// Java package org.jboss.fuse.example.wsn.consumer.client; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import org.w3c.dom.Element; import org.apache.cxf.wsn.client.Consumer; import org.apache.cxf.wsn.client.NotificationBroker; import org.apache.cxf.wsn.client.Subscription; import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType; /** * */ public final class Client { private Client() { //not constructed } /** * @param args */ public static void main(String[] args) throws Exception { String wsnPort = "8182"; if (args.length > 0) { wsnPort = args[0]; } // Start a consumer that will listen for notification messages // We'll just print the text content out for now. Consumer consumer = new Consumer(new Consumer.Callback() { public void notify(NotificationMessageHolderType message) { Object o = message.getMessage().getAny(); System.out.println(message.getMessage().getAny()); if (o instanceof Element) { System.out.println(((Element)o).getTextContent()); } } }, "http://localhost:9001/MyConsumer"); // Create a subscription for a Topic on the broker NotificationBroker notificationBroker = new NotificationBroker("http://localhost:" + wsnPort + "/wsn/NotificationBroker"); Subscription subscription = notificationBroker.subscribe(consumer, "MyTopic"); // Just sleep for a bit to pick up some incoming messages Thread.sleep(60000); // Cleanup and exit subscription.unsubscribe(); consumer.stop(); System.exit(0); } }
Creating a consumer callback object
org.apache.cxf.wsn.client.Consumer
class from the simplified client API, which enables you to define a callback as follows:
// Start a consumer that will listen for notification messages // We'll just print the text content out for now. Consumer consumer = new Consumer(new Consumer.Callback() { public void notify(NotificationMessageHolderType message) { Object o = message.getMessage().getAny(); System.out.println(message.getMessage().getAny()); if (o instanceof Element) { System.out.println(((Element)o).getTextContent()); } } }, "http://localhost:9001/MyConsumer");
Consumer
constructor is a reference to the consumer callback object, which is defined inline. The second argument specifies the URL of the consumer callback endpoint, which can receive messages from the notification broker.
Subscribing to a topic
subscribe
method on the NotificationBroker
proxy object:
Subscription subscribe(Referencable consumer, String topic)
Consumer
object (which is capable of returning a WS-Addressing endpoint reference to the consumer callback through the Referencable.getEpr()
method). The second argument is the name of the topic you want to subscribe to.
Subscription
object, which you can use to manage the subscription (for example, pause, resume, or unsubscribe).
Threading in the consumer client
Thread.sleep(60000)
), so that the thread context can switch to the background thread, where the callback Web service is running. This makes it possible for the consumer callback to receive some messages.
Steps to create a consumer client
- Use the
archetype:generate
goal to invoke theservicemix-cxf-code-first-osgi-bundle
archetype. Under thewsn
directory, invoke the Maven archetype as follows:mvn archetype:generate \ -DarchetypeGroupId=org.apache.servicemix.tooling \ -DarchetypeArtifactId=servicemix-cxf-code-first-osgi-bundle \ -DarchetypeVersion=2013.01.0.redhat-610379 \ -DgroupId=org.jboss.fuse.example \ -DartifactId=wsn-consumer \ -Dversion=1.0-SNAPSHOT \ -Dpackage=org.jboss.fuse.example.wsn.consumer
NoteThe backslash characters at the end of each line are effective as line-continuation characters on UNIX and LINUX platforms. If you are entering the command on a Windows platform, however, you must enter the entire command on a single line.You will be prompted to confirm the project settings, with a message similar to this one:Confirm properties configuration: groupId: org.jboss.fuse.example artifactId: wsn-consumer version: 1.0-SNAPSHOT package: org.jboss.fuse.example.wsn.consumer Y: :
Type Return to accept the settings and generate the project. When the command finishes, you should find a new Maven project in thewsn/wsn-consumer
directory. - Some of the generated project files are not needed for this tutorial. Under the
wsn/wsn-consumer
directory, delete the following files and directories:src/main/resources/META-INF/spring/beans.xml src/main/java/org/jboss/fuse/example/wsn/consumer/Person.java src/main/java/org/jboss/fuse/example/wsn/consumer/PersonImpl.java src/main/java/org/jboss/fuse/example/wsn/consumer/UnknownPersonFault.java src/main/java/org/jboss/fuse/example/wsn/consumer/types
- Edit the
pom.xml
file in thewsn-consumer
directory, and add the following dependencies, as required by the consumer client:<?xml version="1.0" encoding="UTF-8"?> <project ...> ... <dependencies> ... <!-- Needed for HTTP callback endpoint --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>2.7.0.redhat-610379</version> </dependency> <!-- Needed for WS-Notification --> <dependency> <groupId>org.apache.cxf.services.wsn</groupId> <artifactId>cxf-services-wsn-api</artifactId> <version>2.7.0.redhat-610379</version> </dependency> </dependencies> ... </project>
- Edit the
Client.java
file in thewsn-consumer/src/main/java/org/jboss/fuse/example/wsn/consumer/client/
directory, remove the existing content, and replace it with the code from Example 2.2, “Consumer Client Code”.
Test the consumer client
- If the JBoss A-MQ container is not already running (with the notification broker installed), start it up now:
./amq
- Run the publisher client at the command line. Open a new command prompt, and enter the following commands:
cd wsn/wsn-publisher mvn -Pclient
In the command window, you should see some output like the following:... INFO: Creating Service {http://cxf.apache.org/wsn/jaxws}NotificationBrokerService from WSDL: jar:file:/Users/fbolton/.m2/repository/org/apache/cxf/services/wsn/ cxf-services-wsn-api/2.6.0.redhat-60024/cxf-services-wsn-api-2.6.0.redhat-60024.jar !/org/apache/cxf/wsn/wsdl/wsn.wsdl
You now have approximately two minutes before the publisher client times out. - Run the consumer client at the command line. Open a new command prompt and enter the following commands:
cd wsn/wsn-consumer mvn -Pclient
In the command window, you should see some output like the following:... Jun 25, 2013 4:13:47 PM org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL INFO: Creating Service {http://cxf.apache.org/wsn/jaxws}PausableSubscriptionManagerService from WSDL: jar:file:/Users/fbolton/.m2/repository/org/apache/cxf/services/wsn /cxf-services-wsn-api/2.6.0.redhat-60024/cxf-services-wsn-api-2.6.0.redhat-60024.jar !/org/apache/cxf/wsn/wsdl/wsn.wsdl [ns8:foo: null] Hello World! ...
- To inspect the state of the notification broker, you can connect to the JMX port of the ActiveMQ broker. Start up a JMX console by entering the following command at the command line:
jconsole
In the JConsole: New Connection dialog, select Remote Process and enter the following URL in the accompanying text field:service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-root
In the Username and Password fields, enter one of the user credentials you created at the start of this tutorial. When you are connected to the JMX port, you can inspect the state of the broker by clicking on the MBeans tab and drilling down the object tree in the JConsole.
2.4. Create a PullPoint Client
Overview
Sample PullPoint client code
MyTopic
topic.
Example 2.3. PullPoint Client Code
// Java package org.jboss.fuse.example.wsn.pullpoint.client; import java.util.List; import java.util.Iterator; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import org.w3c.dom.Element; import org.apache.cxf.wsn.client.PullPoint; import org.apache.cxf.wsn.client.NotificationBroker; import org.apache.cxf.wsn.client.CreatePullPoint; import org.apache.cxf.wsn.client.Subscription; import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType; /** * */ public final class Client { private Client() { //not constructed } /** * @param args */ public static void main(String[] args) throws Exception { String wsnPort = "8182"; if (args.length > 0) { wsnPort = args[0]; } // Create a PullPoint CreatePullPoint createPullPoint = new CreatePullPoint("http://localhost:" + wsnPort + "/wsn/CreatePullPoint"); PullPoint pullPoint = createPullPoint.create(); // Create a PullPoint style subscription NotificationBroker notificationBroker = new NotificationBroker("http://localhost:" + wsnPort + "/wsn/NotificationBroker"); Subscription subscription = notificationBroker.subscribe(pullPoint, "MyTopic"); // Wait for some messages to accumulate in the pull point Thread.sleep(10000); // Now retrieve messages from the pull point List<NotificationMessageHolderType> messages = pullPoint.getMessages(10); if (!messages.isEmpty()) { Iterator<NotificationMessageHolderType> messageIterator = messages.iterator(); while (messageIterator.hasNext()) { NotificationMessageHolderType messageH = messageIterator.next(); Object o = messageH.getMessage().getAny(); System.out.println(messageH.getMessage().getAny()); if (o instanceof Element) { System.out.println(((Element)o).getTextContent()); } } } else { System.out.println("Warn: message list is empty!"); } subscription.unsubscribe(); pullPoint.destroy(); System.exit(0); } }
Steps to create a pullpoint client
- Use the
archetype:generate
goal to invoke theservicemix-cxf-code-first-osgi-bundle
archetype. Under thewsn
directory, invoke the Maven archetype as follows:mvn archetype:generate \ -DarchetypeGroupId=org.apache.servicemix.tooling \ -DarchetypeArtifactId=servicemix-cxf-code-first-osgi-bundle \ -DarchetypeVersion=2013.01.0.redhat-610379 \ -DgroupId=org.jboss.fuse.example \ -DartifactId=wsn-pullpoint \ -Dversion=1.0-SNAPSHOT \ -Dpackage=org.jboss.fuse.example.wsn.pullpoint
NoteThe backslash characters at the end of each line are effective as line-continuation characters on UNIX and LINUX platforms. If you are entering the command on a Windows platform, however, you must enter the entire command on a single line.You will be prompted to confirm the project settings, with a message similar to this one:Confirm properties configuration: groupId: org.jboss.fuse.example artifactId: wsn-pullpoint version: 1.0-SNAPSHOT package: org.jboss.fuse.example.wsn.pullpoint Y: :
Type Return to accept the settings and generate the project. When the command finishes, you should find a new Maven project in thewsn/wsn-pullpoint
directory. - Some of the generated project files are not needed for this tutorial. Under the
wsn/wsn-pullpoint
directory, delete the following files and directories:src/main/resources/META-INF/spring/beans.xml src/main/java/org/jboss/fuse/example/wsn/pullpoint/Person.java src/main/java/org/jboss/fuse/example/wsn/pullpoint/PersonImpl.java src/main/java/org/jboss/fuse/example/wsn/pullpoint/UnknownPersonFault.java src/main/java/org/jboss/fuse/example/wsn/pullpoint/types
- Edit the
pom.xml
file in thewsn-pullpoint
directory, and add the following dependency required for WS-Notification clients:<?xml version="1.0" encoding="UTF-8"?> <project ...> ... <dependencies> ... <!-- Needed for WS-Notification --> <dependency> <groupId>org.apache.cxf.services.wsn</groupId> <artifactId>cxf-services-wsn-api</artifactId> <version>2.7.0.redhat-610379</version> </dependency> </dependencies> ... </project>
- Edit the
Client.java
file in thewsn-pullpoint/src/main/java/org/jboss/fuse/example/wsn/pullpoint/client/
directory, remove the existing content, and replace it with the code from Example 2.3, “PullPoint Client Code”.
Test the PullPoint client
- If the JBoss A-MQ container is not already running (with the notification broker installed), start it up now:
./amq
- Run the publisher client at the command line. Open a new command prompt, and enter the following commands:
cd wsn/wsn-publisher mvn -Pclient
In the command window, you should see some output like the following:... INFO: Creating Service {http://cxf.apache.org/wsn/jaxws}NotificationBrokerService from WSDL: jar:file:/Users/fbolton/.m2/repository/org/apache/cxf/services/wsn/ cxf-services-wsn-api/2.6.0.redhat-60024/cxf-services-wsn-api-2.6.0.redhat-60024.jar !/org/apache/cxf/wsn/wsdl/wsn.wsdl
You now have approximately two minutes before the publisher client times out. - Run the PullPoint client at the command line. Open a new command prompt and enter the following commands:
cd wsn/wsn-pullpoint mvn -Pclient
After a ten second delay, you should see some output like the following:... INFO: Creating Service {http://cxf.apache.org/wsn/jaxws}PausableSubscriptionManagerService from WSDL: jar:file:/Users/fbolton/.m2/repository/org/apache/cxf/services/wsn/cxf-services-wsn-api/2.6.0.redhat-60024/cxf-services-wsn-api-2.6.0.redhat-60024.jar!/org/apache/cxf/wsn/wsdl/wsn.wsdl [ns8:foo: null] Hello World! [ns8:foo: null] Hello World! ...
- To inspect the state of the notification broker, you can connect to the JMX port of the ActiveMQ broker. Start up a JMX console by entering the following command at the command line:
jconsole
In the JConsole: New Connection dialog, select Remote Process and enter the following URL in the accompanying text field:service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-root
In the Username and Password fields, enter one of the user credentials you created at the start of this tutorial. When you are connected to the JMX port, you can inspect the state of the broker by clicking on the MBeans tab and drilling down the object tree in the JConsole.
Legal Notice
Trademark Disclaimer
Legal Notice
Third Party Acknowledgements
- JLine (http://jline.sourceforge.net) jline:jline:jar:1.0License: BSD (LICENSE.txt) - Copyright (c) 2002-2006, Marc Prud'hommeaux
mwp1@cornell.edu
All rights reserved.Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of JLine nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - Stax2 API (http://woodstox.codehaus.org/StAX2) org.codehaus.woodstox:stax2-api:jar:3.1.1License: The BSD License (http://www.opensource.org/licenses/bsd-license.php)Copyright (c) <YEAR>, <OWNER> All rights reserved.Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - jibx-run - JiBX runtime (http://www.jibx.org/main-reactor/jibx-run) org.jibx:jibx-run:bundle:1.2.3License: BSD (http://jibx.sourceforge.net/jibx-license.html) Copyright (c) 2003-2010, Dennis M. Sosnoski.All rights reserved.Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of JiBX nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - JavaAssist (http://www.jboss.org/javassist) org.jboss.javassist:com.springsource.javassist:jar:3.9.0.GA:compileLicense: MPL (http://www.mozilla.org/MPL/MPL-1.1.html)
- HAPI-OSGI-Base Module (http://hl7api.sourceforge.net/hapi-osgi-base/) ca.uhn.hapi:hapi-osgi-base:bundle:1.2License: Mozilla Public License 1.1 (http://www.mozilla.org/MPL/MPL-1.1.txt)