Package org.wso2.carbon.event.broker.subscriptions

Source Code of org.wso2.carbon.event.broker.subscriptions.AbstractRegistryBasedSubscriptionManager

package org.wso2.carbon.event.broker.subscriptions;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.impl.llom.util.AXIOMUtil;
import org.apache.axis2.AxisFault;
import org.apache.axis2.databinding.utils.ConverterUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.registry.core.Collection;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.CoreRegistry;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.registry.core.utils.RegistryUtils;
import org.wso2.carbon.core.RegistryResources;
import org.wso2.carbon.event.broker.BrokerConstants;
import org.wso2.carbon.event.broker.internal.EventBrokerServiceComponent;
import org.wso2.carbon.event.broker.utils.EventBrokerUtils;
import org.wso2.event.Event;
import org.wso2.event.EventDispatcher;
import org.wso2.event.EventFilterDesc;
import org.wso2.event.EventingConstants;
import org.wso2.event.Subscription;
import org.wso2.event.SubscriptionData;
import org.wso2.event.SubscriptionManager;
import org.wso2.event.Topic;
import org.wso2.event.TopicDetails;
import org.wso2.event.TopicNode;
import org.wso2.event.exceptions.EventException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import java.io.ByteArrayOutputStream;
import java.util.*;

/*
*  Copyright (c) 2005-2009, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*
*/

public abstract class AbstractRegistryBasedSubscriptionManager<T>
    implements SubscriptionManager<T> {
    public Registry registry;
    private final Map<String, String> properties = new HashMap<String, String>();
    protected Resource resTopicIndex;
    private static final Log log = LogFactory.getLog(AbstractRegistryBasedSubscriptionManager.class);

    public static final String EPR_TYPE = "application/vnd.epr";
    public static final String SEQUENCE_TYPE = "application/vnd.sequence";
    public static final String SUBSCRIPTION_COLLECTION_NAME = "system.subscriptions";
    public static final String MEDIATION_SEQUENCE_NAME = "_sequence.xml";
    public static final String DEFAULT_EVENTING_ROOT = RegistryResources.ROOT + "eventing";
    public static final String TOPIC_INDEX = "/index/TopicIndex";

    public static final String SUBSCRIPTION = "subscription";
    public static final String ENDPOINT = "endpoint";
    public static final String ADDRESS = "address";
    public static final String URI = "uri";
    public static final String EXPIRES = "expires";
    public static final String STATIC_FLAG = "staticFlag";
    public static final String SUB_MANAGER_URI = "subManagerURI";
    public static final String SUBSCRIPTION_DATA = "subscriptionData";
    public static final String FILTER_VALUE = "filterValue";
    public static final String FILTER_DIALECT = "filterDialect";
    public static final String PERSISTANT = "persistant";
    public static final String OWNER = "owner";
    public static final String CREATED_TIME = "CreatedTime";
    public static final String FORMATTER = "formatter";

    public static final String SUB_STORE_CTX = "subscriptionStoragePath";
   
    private static final String TOPIC_NAME = "topicName";
    private static final String TOPIC_OWNER = "topicOwner";


   
   
    public AbstractRegistryBasedSubscriptionManager() throws EventException {
    super();
    List<Subscription> subscriptions = getAllSubscriptions(null);
   
    //remove unpersistent subscriptions from the registry
    for(Subscription subscription:subscriptions){
      if(!subscription.isPersistant()){
        unsubscribe(subscription.getId());
      }
    }
  }

  /**
     * {@inheritDoc}
     */
    public String subscribe(Subscription subscription) throws EventException {
        //Check whether there is already a subscription available for this topic + serverURL
        Subscription existingSubscription = getExistingSubscription(subscription);
        if(existingSubscription != null){
            //A subscription already exists. return that subscription id
            return existingSubscription.getId();
        }
       
        //No subscription available. so create a new subscription
        try {
            Resource resource = registry.newResource();
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            OMElement subElem = subscriptionToRegStorage(subscription, resource, true);
            subElem.serialize(outStream);
            resource.setContent(outStream.toByteArray());
            resource.setMediaType(EPR_TYPE);
            String topic = subscription.getFilterDesc().getFilterValue();
            if (!topic.startsWith("/")) {
                topic = "/" + topic;
            }
            String subStorePath = getSubscriptionStoragePath();
            if (subStorePath != null) {
                subStorePath = subStorePath + topic;
            } else {
                subStorePath = topic;
            }
            registry.put(
                    subStorePath + "/" + SUBSCRIPTION_COLLECTION_NAME + "/" + subscription.getId(),
                    resource);
            // add to the index call the sync method
            updateTopicIndex(true, subscription.getId(), topic);
            log.debug("Subscribed to topic: " + topic);
        } catch (RegistryException e) {
            log.error("Unable to add the subscriptio to the registry" + e.toString());
        } catch (XMLStreamException e) {
            log.error("Unable to serialize the subscription endpoint" + e.toString());
        }
        return subscription.getId();
    }

    /**
     * @param subscription
     * @return existing subscription
     */
    private Subscription getExistingSubscription(Subscription subscription) {
        String topic = subscription.getFilterDesc().getFilterValue();
        String endpointUrl = subscription.getEndpointUrl();
        List<Subscription> subscriptions = getMatchingSubscriptions(topic);
        for(Subscription existingSubscription : subscriptions){
            if(endpointUrl.equalsIgnoreCase(existingSubscription.getEndpointUrl())){
                //we have a matching subscription
                return existingSubscription;
            }
        }
        return null;
    }

    /**
     * {@inheritDoc}
     */
    public boolean unsubscribe(String id) throws EventException {
        try {
            if (!registry.resourceExists(getTopicIndexPath())) {
                log.warn("No subscription found by the given id: " + id);
                return false;
            }
            resTopicIndex = registry.get(getTopicIndexPath());
            String topic = resTopicIndex.getProperty(id);
            String subStorePath = getSubscriptionStoragePath();
            if (subStorePath != null) {
                subStorePath = subStorePath + topic;
            } else {
                subStorePath = topic;
            }
            String regPath = subStorePath + "/" + id;
            registry.delete(regPath);
            // remove from the index call the sync method
            updateTopicIndex(false, id, null);
        } catch (RegistryException e) {
            log.error("Resource cannot remove from the registry", e);
            return false;
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public boolean renew(Subscription subscription) throws EventException {
        Subscription subscriptionOrig = getSubscription(subscription.getId());
        if (subscriptionOrig.getId() != null) {
            try {
                if (!registry.resourceExists(getTopicIndexPath())) {
                    log.warn("No subscription found by the given id: " + subscriptionOrig.getId());
                    return false;
                }
                resTopicIndex = registry.get(getTopicIndexPath());
                String topic = resTopicIndex.getProperty(subscription.getId());
                String subStorePath = getSubscriptionStoragePath();
                if (subStorePath != null) {
                    subStorePath = subStorePath + topic;
                } else {
                    subStorePath = topic;
                }
                String regPath = subStorePath + "/" + subscription.getId();
                Resource resource = registry.get(regPath);
                subscriptionOrig.setExpires(subscription.getExpires());
                // set the new content
                OMElement subElem = subscriptionToRegStorage(subscriptionOrig, resource, false);
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                subElem.serialize(outStream);
                resource.setContent(outStream.toByteArray());
                resource.setMediaType(EPR_TYPE);
                registry.put(regPath, resource);
            } catch (RegistryException e) {
                log.error("Unable to update the registry", e);
                return false;
            } catch (XMLStreamException e) {
                log.error("Unable to process the XML info set", e);
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public List<Subscription> getSubscriptions() throws EventException {
        return getAllSubscriptions(null);
    }

    /**
     * {@inheritDoc}
     */
    public List<Subscription> getAllSubscriptions(String searchStr) throws EventException {
        //EventBrokerServiceComponent.getConfigurationRegistry().executeQuery(path, parameters);
        LinkedList<Subscription> subscriptionList = new LinkedList<Subscription>();
        try {
            if (registry != null && registry.resourceExists(getTopicIndexPath())) {
                resTopicIndex = registry.get(getTopicIndexPath());
                if(searchStr != null){
                    String[] tokens = searchStr.split(",");
                    String subStorePath = getSubscriptionStoragePath();
                    HashMap<String,String> map = new HashMap<String,String>();
                    map.put("query", "SELECT R.REG_PATH_ID, R.REG_NAME FROM REG_RESOURCE R, REG_PROPERTY PP, REG_RESOURCE_PROPERTY RP WHERE"
                            + " R.REG_VERSION=RP.REG_VERSION AND RP.REG_PROPERTY_ID=PP.REG_ID AND PP.REG_NAME=? AND PP.REG_VALUE=?");
                    for(String token:tokens){
                        String[] nameVal = token.split("=");
                        if(nameVal.length != 2){
                            throw new EventException("searchStr "+ searchStr + " is not formatted correctly");
                        }
                        map.put("1", nameVal[0]);
                        map.put("2", nameVal[1]);  
                    }               
                   
                    Collection results = registry.executeQuery(null, map);
                    for(String path:results.getChildren()){
                       if(path.startsWith(subStorePath)){
                            Subscription sub = regStorageToSubscription(registry.get(path));
                            String id = path.substring(path.indexOf('/'));
                            sub.setId(id);
                            subscriptionList.add(sub);
                       }
                    }
                }else{
                    Properties property = resTopicIndex.getProperties();
                    if (property != null) {
                        if (!property.isEmpty()) {
                            for (Enumeration e = property.propertyNames() ; e.hasMoreElements() ;) {
                                String id = (String)e.nextElement();
                                if (RegistryUtils.isHiddenProperty(id)) {
                                    continue;
                                }
                                String topic = resTopicIndex.getProperty(id);
                                String subStorePath = getSubscriptionStoragePath();
                                if (subStorePath != null) {
                                    subStorePath = subStorePath + topic;
                                } else {
                                    subStorePath = topic;
                                }
                                String regPath = subStorePath + "/" + id;
                                if (registry.resourceExists(regPath)) {
                                    Resource resource = registry.get(regPath);
                                    if (resource != null) {
                                        Subscription sub;
                                        if (EPR_TYPE.equals(resource.getMediaType())) {
                                            sub = regStorageToSubscription(resource);
                                            sub.setId(id);
                                            subscriptionList.add(sub);
                                        }
                                    }
                                }
                            }
                        }
                    }

                }
            }
        } catch (RegistryException e) {
            throw new EventException("Error reading subscription" + e.toString());
        } catch (XMLStreamException e) {
            throw new EventException("Error processing subscription" + e.toString());
        }
        return subscriptionList;
    }

    /**
     * {@inheritDoc}
     */
    public List<Subscription> getMatchingSubscriptions(Event<T> event)
            throws EventException {
        String topic = event.getTopic();
        return getMatchingSubscriptions(topic);
    }

    /**
     * @param topic
     * @return
     */
    private List<Subscription> getMatchingSubscriptions(String topic) {
        List<Subscription> subscriptions = new ArrayList<Subscription>();
        if (topic == null) {
            log.error("Topic was not found for the given event.");
            return subscriptions;
        }
        if (!topic.startsWith("/")) {
            topic = "/" + topic;
        }
        String subStorePath = getSubscriptionStoragePath();
        if (subStorePath != null) {
            subStorePath = subStorePath + topic;
        } else {
            subStorePath = topic;
        }
        while (subStorePath != null) {
            subscriptions.addAll(getSubscribersOfTopic(subStorePath));
            subStorePath = RegistryUtils.getParentPath(subStorePath);
        }
        log.debug("Found " + subscriptions.size() + " subscribers");
        return subscriptions;
    }

    /**
     * {@inheritDoc}
     */
    public Subscription getSubscription(String id) throws EventException {
        Subscription sub = null;
        try {
            if (!registry.resourceExists(getTopicIndexPath())) {
                log.warn("No subscription found by the given id: " + id);
                return sub;
            }
            resTopicIndex = registry.get(getTopicIndexPath());
            String topic = resTopicIndex.getProperty(id);
            String subStorePath = getSubscriptionStoragePath();
            if (subStorePath != null) {
                subStorePath = subStorePath + topic;
            } else {
                subStorePath = topic;
            }
            Resource resource = registry.get(subStorePath + "/" + id);
            if (resource != null) {
                if (EPR_TYPE.equals(resource.getMediaType())) {
                    sub = regStorageToSubscription(resource);
                    sub.setId(id);
                }
            }
        } catch (RegistryException e) {
            log.error("Error reading subscription" + e.toString());
        } catch (XMLStreamException e) {
            log.error("Error processing subscription" + e.toString());
        }
        return sub;
    }

    /**
     * {@inheritDoc}
     */
    public Subscription getStatus(String s) throws EventException {
        return null//To change body of implemented methods use File | Settings | File Templates.
    }


    /**
     * {@inheritDoc}
     */
    public List<Subscription> getStaticSubscriptions() {

        LinkedList<Subscription> subscriptionList = null;
        try {
            subscriptionList = (LinkedList<Subscription>) getSubscriptions();
        } catch (EventException e) {
            handleException("Get subscription error", e);
        }
        LinkedList<Subscription> staticSubscriptionList =
                new LinkedList<Subscription>();
        for (Subscription subscription : subscriptionList) {
            if (subscription.isStaticEntry()) {
                staticSubscriptionList.add(subscription);
            }
        }
        return staticSubscriptionList;
    }

    /**
     * {@inheritDoc}
     */


    private void handleException(String message, Exception e) {
        log.error(message, e);
        throw new RuntimeException(message, e);
    }

    private void handleException(String message) {
        log.error(message);
        throw new RuntimeException(message);
    }

    /**
     * Generate the XML document use to store the subscription in the registry
     *
     * @param subscription
     * @param resource
     * @param mode         - true = insert false = update
     * @return OMElement Registry storage
     */
    private OMElement subscriptionToRegStorage(Subscription subscription,
                                               Resource resource, boolean mode) {
        OMFactory factory = OMAbstractFactory.getOMFactory();
        OMElement subElem = factory.createOMElement(SUBSCRIPTION, null);
        //try {
        /*EndpointReference endpointReference = new EndpointReference(subscription.getEndpointUrl());
        EndpointReferenceHelper.fromString(subscription.getEndpointUrl());
OMElement epElem = EndpointReferenceHelper.toOM(factory, endpointReference,
        new QName(EventingConstants.WSE_EVENTING_NS,
                EventingConstants.WSE_EN_SUBSCRIPTION_MANAGER,
                EventingConstants.WSE_EVENTING_PREFIX),
        AddressingConstants.Submission.WSA_NAMESPACE);
        ;*/
        //TODO: Make the implementation namespace aware
        OMElement epElem = factory.createOMElement(ENDPOINT, EventingConstants.WSE_EVENTING_NS,
                EventingConstants.WSE_EVENTING_PREFIX);
        OMElement addrElem = factory.createOMElement(ADDRESS, EventingConstants.WSE_EVENTING_NS,
                EventingConstants.WSE_EVENTING_PREFIX);
        addrElem.addAttribute(URI, subscription.getEndpointUrl(), null);
        epElem.addChild(addrElem);
        subElem.addChild(epElem);
        //} catch (AxisFault axisFault) {
        //handleException("EPR creation failure", axisFault);
        //}
        if (subscription.getExpires() != null) {
            if (mode) {
                resource.addProperty(EXPIRES,
                        ConverterUtil.convertToString(subscription.getExpires()));
            } else {
                resource.setProperty(EXPIRES,
                        ConverterUtil.convertToString(subscription.getExpires()));
            }
        } else {
            if (mode) {
                resource.addProperty(EXPIRES, "*");
            } else {
                resource.setProperty(EXPIRES, "*");
            }
        }

        if (subscription.isStaticEntry()) {
            resource.addProperty(STATIC_FLAG, "true");
        } else {
            resource.addProperty(STATIC_FLAG, "false");
        }
        SubscriptionData subscriptionData = subscription.getSubscriptionData();
        if (subscriptionData != null && subscriptionData.getProperties() != null) {
            Map properties = subscriptionData.getProperties();
            if (properties.size() > 0) {
                Set<Map.Entry<String, Object>> entries = properties.entrySet();
                for (Map.Entry<String, Object> e : entries) {
                    if (e.getKey() != null) {
                        resource.addProperty(e.getKey(), (String) e.getValue());
                    }
                }
            }
        }
        resource.addProperty(SUB_MANAGER_URI, subscription.getSubManUrl());
        EventFilterDesc filterDesc = subscription.getFilterDesc();
        resource.addProperty(FILTER_VALUE, filterDesc.getFilterValue());
        resource.addProperty(FILTER_DIALECT, filterDesc.getFilterDialect());
        resource.addProperty(PERSISTANT, String.valueOf(subscription.isPersistant()));
        resource.addProperty(OWNER, subscription.getOwner());
        resource.addProperty(CREATED_TIME, String.valueOf(subscription.getCreatedTime().getTime()));
        if(subscription.getFormatter() != null){
            resource.addProperty(FORMATTER, subscription.getFormatter());   
        }
        return subElem;
    }

    /**
     * Create the subscription from the registry storage
     *
     * @param resource
     * @return
     */
    private Subscription regStorageToSubscription(Resource resource)
            throws RegistryException, XMLStreamException {
        Subscription subscription = new Subscription();
        SubscriptionData subscriptionData = new SubscriptionData();
        String eprContent = new String((byte[]) resource.getContent());
        OMElement payload = AXIOMUtil.stringToOM(eprContent);
        if (payload.getFirstElement() != null) {
            OMElement element = payload.getFirstElement();
            try {
                if (element.getFirstElement() == null) {
                    handleException("EPR creation failure");
                }
                String url = element.getFirstElement().getAttributeValue(new QName(URI));
                subscription.setEndpointUrl(url);
                subscription.setAddressUrl(url);
            } catch (Exception e) {
                handleException("EPR creation failure", e);
            }
        }
        Properties property = resource.getProperties();
        if (property != null) {
            if (!property.isEmpty()) {
                for (Enumeration e = property.propertyNames() ; e.hasMoreElements() ;) {
                    String propName = (String)e.nextElement();
                    if (RegistryUtils.isHiddenProperty(propName)) {
                        continue;
                    }
                    if (propName.equals(EXPIRES)) {
                        if (resource.getProperty(EXPIRES).equals("*")) {
                            subscription.setExpires(null); // never expire subscription
                        } else {
                            subscription.setExpires(ConverterUtil.convertToDateTime(
                                    resource.getProperty(EXPIRES)));
                        }
                    } else if (propName.equals(SUB_MANAGER_URI)) {
                        subscription
                                .setSubManUrl(resource.getProperty(SUB_MANAGER_URI));
                    } else if (propName.equals(FILTER_VALUE)) {
                        subscription.getFilterDesc().setFilterValue(resource.getProperty(FILTER_VALUE));
                    } else if (propName.equals(FILTER_DIALECT)) {
                        subscription.getFilterDesc().setFilterDialect(resource.getProperty(FILTER_DIALECT));
                    } else if (propName.equals(PERSISTANT)) {
                        subscription.setPersistant(Boolean.valueOf(resource.getProperty(PERSISTANT)));      
                    } else if (propName.equals(OWNER)) {
                        subscription.setOwner(resource.getProperty(OWNER));       
                    } else if (propName.equals(FORMATTER)) {
                        subscription.setFormatter(resource.getProperty(FORMATTER));
                    } else if (propName.equals(CREATED_TIME)) {
                        subscription.setCreatedTime(new Date(Long.valueOf(resource.getProperty(CREATED_TIME))));
                    } else {
                        subscriptionData.setProperty(propName, resource.getProperty(propName));
                    }
                }
            }
        }
        subscription.setSubscriptionData(subscriptionData);
        return subscription;
    }


    /**
     * Update the topic index by holding the thread
     *
     * @param mode  Insert | Delete
     * @param id    subscription id
     * @param topic topic name
     * @throws Exception RegistryException
     */
    private synchronized void updateTopicIndex(boolean mode, String id, String topic)
            throws RegistryException {
        if (mode) {
            resTopicIndex = registry.get(getTopicIndexPath());
            resTopicIndex.addProperty(id, topic + "/" + SUBSCRIPTION_COLLECTION_NAME);
            registry.put(getTopicIndexPath(), resTopicIndex);
        } else {
            resTopicIndex = registry.get(getTopicIndexPath());
            resTopicIndex.removeProperty(id);
            registry.put(getTopicIndexPath(), resTopicIndex);
        }
    }

    /**
     * Get the subscriptions by topic
     *
     * @param topic name
     * @return subscriptions
     */
    private List<Subscription> getSubscribersOfTopic(String topic) {
        List<Subscription> subscriptions = new ArrayList<Subscription>();
        try {
            if (registry.resourceExists(topic)) {
                String subscriptionsCollection = topic + "/" + SUBSCRIPTION_COLLECTION_NAME;
                if (registry.resourceExists(subscriptionsCollection)) {
                    Collection subs = (Collection) registry.get(subscriptionsCollection);
                    String[] subsPaths = (String[]) subs.getContent();
                    for (String subsPath : subsPaths) {
                        Resource resource = registry.get(subsPath);
                        String id = resource.getId();
                        Subscription sub = new Subscription();
                        if (EPR_TYPE.equals(resource.getMediaType())) {
                            sub = regStorageToSubscription(resource);
                        }
                        // check for expiration
                        Calendar current =
                                Calendar.getInstance(); //Get current date and time
                        if (sub.getExpires() != null) {
                            if (current.before(sub.getExpires())) {
                                // add only valid subscriptions by checking the expiration
                                subscriptions.add(sub);
                            }
                        } else {
                            // If a expiration dosen't exisits treat it as a never expire subscription, valid till unsubscribe
                            subscriptions.add(sub);
                        }
                    }
                } else {
                    log.debug("Couldn't find the subscription endpoint collection");
                }
            } else if (log.isDebugEnabled()) {
                log.warn("Couldn't find the specified topic in the registry");
            }
        } catch (RegistryException e) {
            log.error("Couldn't retrieve the subscription information for the topic " + topic, e);
        } catch (XMLStreamException e) {
            log.error("Error on processing the stored subscription " + topic, e);
        }
        return subscriptions;
    }

    public void addProperty(String name, String value) {
        properties.put(name, value);
    }

    public java.util.Collection<String> getPropertyNames() {
        return properties.keySet();
    }

    public String getPropertyValue(String name) {
        return properties.get(name);
    }

    /**
     * Get the userdefine subscription storage path
     *
     * @return path
     */
    private String getSubscriptionStoragePath() {
        String subStoreCtx = this.getPropertyValue(SUB_STORE_CTX);
        if (subStoreCtx != null) {
            if (!subStoreCtx.startsWith("/")) {
                subStoreCtx = "/" + subStoreCtx;
            }
            if (subStoreCtx.endsWith("/")) {
                subStoreCtx = subStoreCtx
                        .substring(0, subStoreCtx.length() - "/".length()); // remove the final /
            }
        }
        return subStoreCtx;
    }

    /**
     * Get the topic index path
     *
     * @return
     */
    protected String getTopicIndexPath() {
        String topicIndexPath = null;
        String subStoreCtx = getSubscriptionStoragePath();
        if (subStoreCtx != null) {
            topicIndexPath = subStoreCtx + TOPIC_INDEX;
        } else {
            topicIndexPath = DEFAULT_EVENTING_ROOT + TOPIC_INDEX;
        }
        return topicIndexPath;
    }

  public String subscribeNonPersistantly(Subscription subscription,
      EventDispatcher<T> dispatcher) throws EventException {
    subscription.setEventDispatcher(dispatcher);
    return subscribe(subscription);
   
  }
   
    public TopicNode getTopicTree() throws EventException {
        try {
            String topicIndexPath = getSubscriptionStoragePath();
            Resource root = registry.get(topicIndexPath);
            TopicNode rootTopic = new TopicNode(new Topic("/", false));
            buildTopicTree(rootTopic, (Collection)root);
            return rootTopic;
        } catch (RegistryException e) {
            throw new EventException(e.getMessage(),e);
        }
    }
   
  private void buildTopicTree(TopicNode node, Collection resource) throws EventException{
      try {
            String[] children = resource.getChildren();
            if(children != null){
                List<TopicNode> nodes = new ArrayList<TopicNode>();
                for(String c:children){
                    Resource childResource = registry.get(c);
                    if(childResource instanceof Collection){
                        if(c.endsWith("/")){
                            c = c.substring(0,c.length()-2);
                        }
                        String nodeName = c.substring(c.lastIndexOf("/")+1);
                        if(!nodeName.equals("system.subscriptions")){
                            String topicName = EventBrokerUtils.subsctractPath(c,getSubscriptionStoragePath());
                            TopicNode childNode = new TopicNode(new Topic(nodeName,
                                    EventBrokerUtils.isSecureTopic(topicName)));
                            nodes.add(childNode);
                            buildTopicTree(childNode,(Collection)childResource);
                        }
                    }           
                }
                node.setTopicNodes(nodes.toArray(new TopicNode[0]));
            }
        } catch (RegistryException e) {
            throw new EventException(e.getMessage(),e);
        } catch (AxisFault e) {
            throw new EventException(e.getMessage(),e);
        }
  }
 
    public TopicDetails getTopicDetails(String topicName) throws EventException {
           try {
            String subStorePath = getSubscriptionStoragePath();
               if (subStorePath != null) {
                   subStorePath = subStorePath + topicName;
               } else {
                   subStorePath = topicName;
               }
               String topicInfo = subStorePath+ "/topicInfo";
               if(registry.resourceExists(topicInfo)){
                   TopicDetails topicDetails = new TopicDetails();
                   Resource resource = registry.get(topicInfo);
                   topicDetails.setTopicName(resource.getProperty("topicName"));
                   topicDetails.setDescription(resource.getProperty("description"));
                   topicDetails.setSchemaDescription(resource.getProperty("schemaDescription"));
                   topicDetails.setOwner(resource.getProperty(OWNER));
                   String isSecureTopicStr = resource.getProperty("isSecureTopic");
                   if(isSecureTopicStr != null){
                       topicDetails.setSecureTopic(Boolean.parseBoolean(isSecureTopicStr));      
                   }
                   return topicDetails;
               }else{
                   return null;   
               }
        } catch (RegistryException e) {
            throw new EventException("Error getting topic details "+ e.getMessage(), e);
        }
    }

    public void updateTopic(TopicDetails topicDetails) throws EventException {
        try {
            String topicInfo = getTopicInfoPath(topicDetails.getTopicName());
            if(registry.resourceExists(topicInfo)){
                TopicDetails currentTopicDetails = getTopicDetails(topicDetails.getTopicName());
                Resource resource = registry.get(topicInfo);
                if(currentTopicDetails.isSecureTopic() && !currentTopicDetails.getOwner().equals(EventBrokerUtils.getLoggedInUserName())){
                    throw new EventException("Current user do not have permission to change this topic");
                }
                resource.setProperty("topicName", topicDetails.getTopicName());
                if(topicDetails.getDescription() != null){
                    resource.setProperty("description", topicDetails.getDescription());   
                }
                if(topicDetails.getSchemaDescription() != null){
                    resource.setProperty("schemaDescription", topicDetails.getSchemaDescription());   
                }
                if(topicDetails.isSecureTopic()){
                    resource.setProperty("isSecureTopic", String.valueOf(topicDetails.isSecureTopic()));   
                }
                registry.put(topicInfo,resource);
            }else{
                Resource resource = registry.newResource();
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                resource.setContent(outStream.toByteArray());
               
                resource.setProperty("topicName", topicDetails.getTopicName());
                if(topicDetails.getDescription() != null){
                    resource.setProperty("description", topicDetails.getDescription());   
                }
                if(topicDetails.getSchemaDescription() != null){
                    resource.setProperty("schemaDescription", topicDetails.getSchemaDescription());   
                }
                if(topicDetails.isSecureTopic()){
                    resource.setProperty("isSecureTopic", String.valueOf(topicDetails.isSecureTopic()));   
                }
                resource.setProperty(OWNER,EventBrokerUtils.getLoggedInUserName());
                registry.put(topicInfo,resource);
            }
        } catch (RegistryException e) {
            throw new EventException("Error getting topic details "+ e.getMessage(), e);
        }
    }
   
   
    public void defineSecureTopic(String topicName) throws EventException {
        TopicDetails topicDetails = new TopicDetails();
        topicDetails.setTopicName(topicName);
        topicDetails.setSecureTopic(true);
        updateTopic(topicDetails);
    }

    public void deleteSecureTopic(String topicName) throws EventException{
        TopicDetails topicDetails = new TopicDetails();
        topicDetails.setTopicName(topicName);
        topicDetails.setSecureTopic(false);
        updateTopic(topicDetails);
    }
   
    private String getTopicInfoPath(String topicName){
        String subStorePath = getSubscriptionStoragePath();
        if (subStorePath != null) {
            subStorePath = subStorePath + topicName;
        } else {
            subStorePath = topicName;
        }
        return subStorePath + "/topicInfo";
    }
   
    public boolean isSecureTopic(String topicName)throws EventException{
        try {
            String path = getTopicInfoPath(topicName);
            if(!registry.resourceExists(path)){
                return false;
            }
            return "true".equals(registry.get(path).getProperty("isSecureTopic"));
        } catch (RegistryException e) {
            throw new EventException(e.getMessage(), e);
        }
    }
}
TOP

Related Classes of org.wso2.carbon.event.broker.subscriptions.AbstractRegistryBasedSubscriptionManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.