org.ow2.petals.ws.notification.WsnManager Maven / Gradle / Ivy
/**
* PETALS - PETALS Services Platform.
* Copyright (c) 2007 EBM Websourcing, http://www.ebmwebsourcing.com/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* -------------------------------------------------------------------------
* $Id$
* -------------------------------------------------------------------------
*/
package org.ow2.petals.ws.notification;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPEnvelope;
import org.ow2.petals.ws.addressing.EndpointReference;
import org.ow2.petals.ws.client.SoapClient;
import org.ow2.petals.ws.fault.WsnFault;
import org.ow2.petals.ws.notification.handlers.request.WSNHandler;
import org.ow2.petals.ws.topic.Topic;
import org.ow2.petals.ws.topic.TopicNamespace;
import org.ow2.petals.ws.topic.TopicSet;
import org.ow2.petals.ws.topic.WstConstants;
import org.ow2.petals.ws.topic.WstHelper;
/**
* The WebService notification manager
*
* @author chamerling - eBM WebSourcing
*
*/
public class WsnManager {
/**
* It's me !
*/
protected EndpointReference producerEPR;
/**
* All the topics names
*/
protected Set allTopicNames;
protected String subscriptionPath = null;
/**
* Map of EPR to current subscriptions
*/
protected Map subscriptionsByEPR;;
/**
* Hierarchical topic
*/
protected TopicSet topicSet;
/**
* The persistence manager to be used. Can be null, in this case nothing
* will be persisted.
*/
private WsnPersistance persistance;
/**
* Map of handlers which are used to handle requests
*/
protected Map wsnHandlers;
/**
* FIXME : Use apache commons with a wrapper
*/
private Logger logger;
/**
* Creates a new instance of {@link WsnManager}
*
* @param logger
*
*/
public WsnManager(Logger logger) {
super();
this.allTopicNames = new HashSet();
this.subscriptionsByEPR = new Hashtable();
this.topicSet = new TopicSet();
this.wsnHandlers = new HashMap();
this.logger = logger;
}
/**
* Add a handler
*
* @param wsnHandler
*/
public void addHandler(WSNHandler wsnHandler) {
logger.fine("Adding handler for action " + wsnHandler.getActionURI());
wsnHandler.setManager(this);
this.wsnHandlers.put(wsnHandler.getActionURI(), wsnHandler);
}
/**
* Get handler for specified action.
*
* @param actionURI
* @return the {@link WSNHandler} or nulll if not found
*/
public WSNHandler getHandler(String actionURI) {
logger.fine("Get handler for action " + actionURI);
return this.wsnHandlers.get(actionURI);
}
/**
* Reload the subscriptions for the given topic, the subscriptions are
* persisted in files.
*
* @param topicName
* @throws WsnFault
*/
public void reloadSubscriptions(QName topicName) throws WsnFault {
logger.fine("Reloading subscriptions for topic " + topicName);
if (persistance == null) {
throw new WsnFault(
"The subscriptions can not be reloaded since persistance manager is null");
}
WSNHandler subHandler = wsnHandlers.get(WsnConstants.SUBSCRIBE_URI);
if (subHandler == null) {
throw new WsnFault("The subscription handler can not be found");
}
// retrieve persisted envelopes (initial messages from WSN consumers)
List envelopes = this.persistance.getSubscriptionEnvelopesForTopic(topicName);
// remove old persistence files
if (envelopes.size() > 0) {
this.persistance.cleanSubscriptions(topicName);
}
for (SOAPEnvelope envelope : envelopes) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Reload subscription for initial envelope : " + envelope.toString());
}
// call handler
SOAPEnvelope response = subHandler.handle(envelope);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Subscription reloaded, response of the handler is : "
+ response.toString());
}
}
}
/**
* Add a subscription
*
* @param subscription
*/
public synchronized void addSubscription(Subscription subscription) throws WsnFault {
logger.fine("Adding subscription for consumer " + subscription.getConsumerEPR()
+ " on topic " + subscription.getFilter().getTopicName());
EndpointReference epr = subscription.getConsumerEPR();
this.subscriptionsByEPR.put(epr, subscription);
if (this.persistance != null) {
try {
this.persistance.persist(subscription);
} catch (Exception e) {
throw new WsnFault("Can not persist subscription");
}
}
}
/**
* Add a new topic.
*
* @param topicName
* @return
* @throws WsnFault
*/
public Topic addTopic(QName topicName) throws WsnFault {
logger.fine("Creating new topic " + topicName);
String namespace = topicName.getNamespaceURI();
TopicNamespace topicSpace = getTopicNamespace(namespace);
// no topic namespace has been found, create it
if (topicSpace == null) {
topicSpace = addTopicNamespace(namespace);
}
String localName = topicName.getLocalPart();
Topic topic = new Topic(localName, topicSpace);
// save to topic space
topicSpace.addTopic(topic);
// save topic name in set
allTopicNames.add(topicName);
// persist
if (persistance != null) {
persistance.persist(topic);
}
return topic;
}
/**
*
* @param topicName
* @return
* @throws WsnFault
*/
public boolean deleteTopic(QName topicName) throws WsnFault {
logger.fine("Deleting topic " + topicName);
boolean result = true;
Topic topic = null;
String name = WstHelper.getRootTopicName(topicName);
TopicNamespace topicSpace = getTopicNamespace(topicName.getNamespaceURI());
if (topicSpace == null) {
logger.fine("Topic has not been found");
result = false;
} else {
// remove topic from the topic space
topic = topicSpace.getTopic(name);
if (topic != null) {
result = topicSpace.removeTopic(name);
}
}
// look if a topic is available in the set
if (allTopicNames.contains(topicName)) {
logger.fine("Topic has been found, delete it...");
result = (result && allTopicNames.remove(topicName));
}
return result;
}
/**
* Clean topic is removing the persistance directory...
*
* @return
*/
public boolean cleanTopic(QName topicName) {
logger.fine("Cleaning Topic " + topicName);
boolean result = false;
if (topicName != null && persistance != null) {
logger.fine("Delete the persistance directory for the topic " + topicName);
result = persistance.delete(WstHelper.getRootTopicName(topicName));
}
return result;
}
/**
*
* @param namespace
* @return
* @throws WsnFault
*/
public TopicNamespace addTopicNamespace(String namespace) throws WsnFault {
TopicNamespace tns = new TopicNamespace(namespace);
tns.setName("ResourcePropertiesTopicSpace");
topicSet.addTopicNamespace(tns);
return tns;
}
/**
* Get the current notification message for the given topic
*
* @param topicPath
* @return the current message of the topic
*/
public NotificationMessage getCurrentMessage(QName topicPath) throws WsnFault {
logger.fine("Getting current message on topic " + topicPath);
Topic topic = getTopic(topicPath);
if (topic == null) {
throw new WsnFault("Topic not found");
}
NotificationMessage message = topic.getCurrentMessage();
if (message == null) {
throw new WsnFault("No message in topic");
}
return message;
}
/**
* Get the topic
*
* @param topicName
* @return
*/
public Topic getTopic(QName topicName) {
TopicNamespace topicSpace = getTopicNamespace(topicName.getNamespaceURI());
if (topicSpace == null)
return null;
return topicSpace.getTopic(topicName.getLocalPart());
}
/**
*
* @return
*/
public QName[] getTopicExpression() {
QName[] array = new QName[allTopicNames.size()];
return (QName[]) allTopicNames.toArray(array);
}
/**
*
* @return
*/
public String[] getTopicExpressionDialect() {
return new String[] { WstConstants.CONCRETE_TOPIC_URI };
}
public TopicNamespace getTopicNamespace(String namespace) {
return getTopicSet().getTopicNamespace(namespace);
}
public TopicSet getTopicSet() {
return topicSet;
}
/**
* There is already a subcriber for the given EPR ?
*
* @param subscriptionEPR
* @return
*/
public boolean hasSubscription(EndpointReference subscriptionEPR) {
return this.subscriptionsByEPR.containsKey(subscriptionEPR);
}
/**
* There is already a topic with the given name ?
*
* @param topicName
* @return
*/
public boolean hasTopic(QName topicName) {
return allTopicNames.contains(topicName);
}
/**
* Publish a message to a topic
*
* @param topicName
* @param content
* @param soapClient
* @throws WsnFault
*/
public void publish(QName topicName, OMElement content, SoapClient soapClient) throws WsnFault {
publish(topicName, new OMElement[] { content }, soapClient);
}
/**
* Public a message to a topic
*
* @param topicName
* @param content
* @param soapClient
* @throws WsnFault
*/
public void publish(QName topicName, OMElement[] content, SoapClient soapClient)
throws WsnFault {
logger.fine("Publishing new notification message on topic " + topicName);
NotificationMessage message = new NotificationMessage();
for (OMElement element : content) {
message.addMessageContent(element);
}
message.setTopic(topicName);
// give the message to each subscription so it can decide if it
// should be sent or not
Iterator i = getSubscriptions().iterator();
while (i.hasNext()) {
Subscription sub = i.next();
logger.fine("Send notification to consumer " + sub.getConsumerEPR().getAddress());
SOAPEnvelope env = sub.publish(message, soapClient);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Notification result : " + env.toString());
}
}
//
// if a topic was used, record the message as the 'current' message
// for the topic (will be returned by getCurrentMessage())
//
if (topicName != null) {
Topic topic = getTopic(topicName);
if (topic != null) {
topic.setCurrentMessage(message);
}
}
}
/**
* Get the subscriptions
*
* @return
*/
public synchronized Collection getSubscriptions() {
return Collections.unmodifiableCollection(subscriptionsByEPR.values());
}
/**
* Removing a subscription from its EPR will remove all the subscriptions
* for this EPR since a notification consumer can subscribe several times.
*
* @param epr
*/
public synchronized void removeSubscription(EndpointReference epr) {
URI address = epr.getAddress();
logger.fine("Removing subscription(s) for " + epr.getAddress());
Iterator iter = subscriptionsByEPR.keySet().iterator();
while (iter.hasNext()) {
EndpointReference tmp = iter.next();
if (tmp.getAddress().equals(address)) {
Subscription subscription = subscriptionsByEPR.get(tmp);
iter.remove();
if (persistance != null && subscription != null) {
try {
persistance.delete(subscription);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* @return the producerEPR
*/
public EndpointReference getProducerEPR() {
return this.producerEPR;
}
/**
* @param producerEPR
* the producerEPR to set
*/
public void setProducerEPR(EndpointReference producerEPR) {
this.producerEPR = producerEPR;
}
/**
*
* @return
*/
public WsnPersistance getPersistance() {
return persistance;
}
/**
*
* @param persistance
*/
public void setPersistance(WsnPersistance persistance) {
this.persistance = persistance;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy