IS-Notification

From Gcube Wiki
Revision as of 16:40, 23 November 2010 by Lucio.lelii (Talk | contribs) (How to register a producer for a topic)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Design

The IS-Notification is a library that provides a subscription/notification mechanism based on Remote Events. This library helps the clients to interact with the Notifier Service and allows:

  • for a Client or a Service (Subscriber) to subscribe for a Topic and receiving notifications
  • for a Service (producer) to register its own topic and sending notification.

Interface

  • public <T extends BaseNotificationConsumer> void registerToISNotification(T consumer,List<GCUBENotificationTopic> notifications, GCUBESecurityManager manager, GCUBEScope ... scope) throws ISNotifierException – this method registers a entity of type T (consumer) for a list of GCUBENotificationTopic in selected Scopes (scope) with a GCUBESecurityManager (manager) in the IS-Notifier;
  • public void unregisterFromISNotification( GCUBESecurityManager manager, List<GCUBENotificationTopic> notifications, GCUBEScope ... scope) throws ISNotifierException – this method unregisters the consumer for a list of GCUBENotificationTopic from the IS-Notifier in the selected scopes (scope) with a GCUBESecurityManager (manager);
  • public void registerISNotification (EndpointReferenceType producerEPR, List<? extends Topic> notifications, GCUBESecurityManager manager, GCUBEScope ... scope) throws ISNotifierException – this method registers the reference to a resource (producerEPR) that produces a list of topics (notifications) in the IS-Notifier in the selected scopes (scope) with a GCUBESecurityManager (manager);
  • public void unregisterISNotification (EndpointReferenceType producerEPR, List<? extends Topic> notifications, GCUBESecurityManager manager, GCUBEScope ... scope) throws ISNotifierException – this method unregister the reference to a resource (producerEPR) for a list of topics (notifications) in the IS-Notifier in the selected scopes (scope) with a GCUBESecurityManager (manager);
  • public boolean[] isTopicRegistered(GCUBESecurityManager securityManager, GCUBEScope scope, List<TopicData> topics) throws ISNotifierException - this methods checks if a topic (topic) registration is completed or not for a producer (producerEpr) in the IS-Notifier in the selected scopes (scope) with a GCUBESecurityManager (manager);

New Features

From version 1.4 this library contains new features:

  • the possibility to register for a client running outside a gcore container;
  • the possibility to register to a Topic specifying a 'precodition'. The 'precodition' is represented by an XPath specified at Topic creation time an evaluated producer-side. This feature reduces the number of messages exchanged between producer and consumer.

NOTE: in this release to receive past notification a flag renotifier should be set to true on the GCUBENotifcationTopic type (by default the past-notification are not sent)

How to configure clients running outside the gCore container

To register a Topic outside a gCore cotnainer this library requires 2 steps of configuration:

  • modify the file $GLOBUS_LOCATION/etc/globus_wsrf_core/client-server-config.wsdd adding in the globalConfiguration session the parameter logicalHost
     ...
<globalConfiguration>
        <parameter name="containerThreads" value="1"/>
        <parameter name="containerThreadsMax" value="3"/>
 
         <!-- add the following line --> 
        <parameter name="logicalHost" value="yourhost"/> 
 
        <parameter name="sendXsiTypes" value="true"/>
        <parameter name="authenticationService"
                value="gsi/AuthenticationService"/>
     ...
  • start the client setting the GLOBUS_LOCATION system property
       java -DGLOBUS_LOCATION=$GLOBUS_LOCATION RegistrationTest

How to register a producer for a topic

To make a GCUBEService capable to produce notifcation for a topic we have, first of all, to configure it.

In the deploy-server.wsdd for each port-type that represent a resource that will produce a notification add at the providers SubscribeProvider and GetCurrentMessageProvider:

<parameter name="providers" value="GCUBEProvider SubscribeProvider GetCurrentMessageProvider"/>

In the wsdl of such port-type add in the portType tag wsntw:NotificationProducer:

<portType name="ReadManagerPortType" wsdlpp:extends="wsntw:NotificationProducer provider:GCUBEProvider">

and import in the same file the namespace xmlns:wsntw="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"

<wsdl:import namespace="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl" 
		location="../wsrf/notification/WS-BaseN.wsdl"/>

Now the service is ready to produce both properties topics and custom topic.

How to produce notification for custom topics

First of all declare on the wsdl the type of your notification:

<xsd:element name="collectionID" type="xsd:string" />
<xsd:element name="cardinality" type="xsd:long" />
<xsd:element name="lastUpdate" type="xsd:dateTime" />
 
<xsd:complexType name="UpdateNotificationType">
     <xsd:sequence>
	<xsd:element ref="tns:collectionID" />
		<xsd:element ref="tns:cardinality" />
		<xsd:element ref="tns:lastUpdate" />
	</xsd:sequence>
     </xsd:complexType>
 
<xsd:element name="UpdateNotificationMessage" type="tns:UpdateNotificationType" />
 
<xsd:complexType name="UpdateNotificationTypeWrapper">
     <xsd:sequence>
	<xsd:element ref="tns:UpdateNotificationMessage" />
	</xsd:sequence>
     </xsd:complexType>

In your GCUBEWSResource declare the topic

... 
Resource extends GCUBEWSResource {
...
   private SimpleTopic updateTopic= new SimpleTopic(new QName(NS, "UpdateTopic");

add it to the list of topics of the GCUBEWSResource (it can be done on the overriding the initialiContainer() method)

..	
  @Override protected void initialiseContainers() throws Exception {
	super.initialiseContainers();
	...
	getTopicList().addTopic(updateTopic);
 
  }
...

In this way the topic is automatically registered by gcore at container start-up. After this we need to notify the event somewhere in the resource:

...
UpdateNotificationTypeWrapper message = new UpdateNotificationTypeWrapper(new  UpdateNotificationType(this.getCardinality(), this.getCollectionID(), this.getLastUpdate()));
this.updateTopic.notify(message);
...

Examples

registtration and unregistration:

ISNotifier notifier = GHNContext.getImplementation(ISNotifier.class);
//creating the topic object with the QName for GenericResource
GCUBENotificationTopic notificationTopic= new GCUBENotificationTopic(new QName("http://gcube-system.org/namespaces/informationsystem/registry",GCUBEGenericResource.TYPE));
//settign a precondition to get only the notification for Generic resource with SecondaryType ACTIVATIONRECORD_TYPE, name ACTIVATIONRECORD_NAME and the operationType create
//(the XPath MUST return a boolean)
notificationTopic.setPrecondition("//profile[contains(.,'<SecondaryType>"+Constants.ACTIVATIONRECORD_TYPE+"</SecondaryType>') and contains(.,'<Name>"+Constants.ACTIVATIONRECORD_NAME+</Name>')] and //operationType/text()='create'");		
//this parameter is set to true to receive past notification
notificationTopic.setUseRenotifier(true);
List<GCUBENotificationTopic> topics = Collections.singletonList(notificationTopic);
notifier.registerToISNotification(new Consumer(), topic, ServiceContext.getContext(), scope);
System.in.read();
notifier.unregisterFromISNotification( new GCUBESecurityManagerImpl(){
 
			@Override
			public boolean isSecurityEnabled() {
				// TODO Auto-generated method stub
				return false;
			}
		}, topics, scope);

where the consumer is:

public class Consumer extends BaseNotificationConsumer {
 
	private GCUBEClientLog log;
 
	public void onNotificationReceived(NotificationEvent event){
		log.debug(this.logid+"| notification received");
		try{
			UpdateNotificationType untw= (UpdateNotificationType) ObjectDeserializer.toObject((Element)event.getPayload().getMessageObject(),UpdateNotificationType.class);
			System.out.println(untw.getLastUpdate()+" "+untw.getCollectionID()+" "+untw.getCardinality() );
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}