Package org.wso2.carbon.event.core.internal.subscription.registry

Source Code of org.wso2.carbon.event.core.internal.subscription.registry.RegistrySubscriptionManager

/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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.
*/

package org.wso2.carbon.event.core.internal.subscription.registry;

import org.apache.axis2.databinding.utils.ConverterUtil;
import org.wso2.carbon.event.core.exception.EventBrokerConfigurationException;
import org.wso2.carbon.event.core.exception.EventBrokerException;
import org.wso2.carbon.event.core.util.EventBrokerConstants;
import org.wso2.carbon.event.core.internal.util.EventBrokerHolder;
import org.wso2.carbon.event.core.internal.util.JavaUtil;
import org.wso2.carbon.event.core.subscription.Subscription;
import org.wso2.carbon.event.core.subscription.SubscriptionManager;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;

import java.util.*;

/**
* subscription manager implementation using registry.
* this subscription manager stores the subscriptions in the registry patch calcuated
* as given
*  subscriptionStoragePath(read from the configuration file) + "/" + topicName
*  + "/system.subscriptions/" + subscriptionID
*
* inorder to get the subscriptions quickly it also stores the subscription details in a
* resouce called topicIndex.
* topic index resource contains
* subscriptionID , topicName
* when getting the subscriptions we callcualte the subscription stored path using above two
* parameters.
*/
public class RegistrySubscriptionManager implements SubscriptionManager {

    /**
     * registry service to access the registry. this is get from the EBBrokerHolder
     */
    private RegistryService registryService;

    /**
     * root patch which used to start the subscription related deatils.
     */
    private String topicStoragePath;

    /**
     * topic index resource path.
     */
    private String indexStoragePath;

    public RegistrySubscriptionManager(String topicStoragePath, String indexStoragePath)
            throws EventBrokerConfigurationException {

        this.registryService = EventBrokerHolder.getInstance().getRegistryService();
        this.topicStoragePath = topicStoragePath;
        this.indexStoragePath = indexStoragePath;

        // creates the the subscription intex
        // when creating subscriptions we going to add entries to this this resource
        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());

            //create the topic storage path if it does not exists
            if (!userRegistry.resourceExists(this.topicStoragePath)) {
                userRegistry.put(this.topicStoragePath, userRegistry.newCollection());
            }
            //allow permissions to root topic
            //put the permissions to the user store. here we create the resource name from
            //the topic storage path of the registry.
            //here we allow permissions at each start up since some times user managers
            //may have changed.
            UserRealm userRealm =
                    EventBrokerHolder.getInstance().getRealmService().getTenantUserRealm(EventBrokerHolder.getInstance().getTenantId());
            for (String role : userRealm.getUserStoreManager().getRoleNames()) {
                userRealm.getAuthorizationManager().authorizeRole(
                        role, this.topicStoragePath, EventBrokerConstants.EB_PERMISSION_SUBSCRIBE);
                userRealm.getAuthorizationManager().authorizeRole(
                        role, this.topicStoragePath, EventBrokerConstants.EB_PERMISSION_PUBLISH);

            }
            // we need to create the index here only it is not exists.
            if (!userRegistry.resourceExists(this.indexStoragePath)) {
                userRegistry.put(this.indexStoragePath, userRegistry.newResource());
            }

        } catch (RegistryException e) {
            throw new EventBrokerConfigurationException("Can not access the registry ", e);
        } catch (UserStoreException e) {
            throw new EventBrokerConfigurationException("Can not access the user registry", e);
        }
    }

    /**
     * When adding a subscription first it stores in the registry as as set of property values
     * then add the subscription details to the topic index
     * @param subscription
     * @throws org.wso2.carbon.event.core.exception.EventBrokerException
     */
    public void addSubscription(Subscription subscription) throws EventBrokerException {


        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            String resourcePath = getResourcePath(subscription.getId(), subscription.getTopicName());

            Resource resource = userRegistry.newResource();
            resource.setProperty(EventBrokerConstants.EB_RES_SUBSCRIPTION_URL, subscription.getEventSinkURL());
            resource.setProperty(EventBrokerConstants.EB_RES_EVENT_DISPATCHER_NAME, subscription.getEventDispatcherName());

            if (subscription.getExpires() != null){
               resource.setProperty(EventBrokerConstants.EB_RES_EXPIRS, ConverterUtil.convertToString(subscription.getExpires()));
            }
            resource.setProperty(EventBrokerConstants.EB_RES_OWNER, subscription.getOwner());
            resource.setProperty(EventBrokerConstants.EB_RES_TOPIC_NAME, subscription.getTopicName());
            resource.setProperty(EventBrokerConstants.EB_RES_CREATED_TIME, System.currentTimeMillis()+"");
            resource.setProperty(EventBrokerConstants.EB_RES_MODE, JavaUtil.getSubscriptionMode(subscription.getTopicName()));

            //set the other properties of the subscription.
            Map<String, String> properties = subscription.getProperties();
            for (String key : properties.keySet()){
                resource.setProperty(key, properties.get(key));
            }

            userRegistry.put(resourcePath, resource);

            // add the subscription index
            String fullPath = this.indexStoragePath;
            Resource topicIndexResource;
            if(userRegistry.resourceExists(fullPath)){
                topicIndexResource = userRegistry.get(fullPath);
                topicIndexResource.addProperty(subscription.getId(), subscription.getTopicName());
            }else{
               topicIndexResource = userRegistry.newResource();
               topicIndexResource.addProperty(subscription.getId(), subscription.getTopicName());               
            }
            userRegistry.put(fullPath, topicIndexResource);

        } catch (RegistryException e) {
            throw new EventBrokerException("Can not save to registry ", e);
        }

    }

    /**
     * calcualtes the resouce stored path using subscription id and the topic name
     * @param subscriptionID
     * @param topicName
     * @return
     */
    private String getResourcePath(String subscriptionID, String topicName) {
        String resourcePath = this.topicStoragePath;

        // first convert the . to /
        topicName = topicName.replaceAll("\\.", "/");

        if (!topicName.startsWith("/")) {
            resourcePath += "/";
        }

        // this topic name can have # and * marks if the user wants to subscribes to the
        // child topics as well. but we consider the topic here as the topic name just before any
        // special charactor.
        // eg. if topic name is myTopic/*/* then topic name is myTopic
        if (topicName.indexOf("*") > -1){
            topicName = topicName.substring(0, topicName.indexOf("*"));
        } else if (topicName.indexOf("#") > -1){
            topicName = topicName.substring(0, topicName.indexOf("#"));
        }

        resourcePath += topicName;

        if (!resourcePath.endsWith("/")) {
            resourcePath += "/";
        }

        resourcePath += EventBrokerConstants.EB_CONF_WS_SUBSCRIPTION_COLLECTION_NAME + "/" + subscriptionID;
        return resourcePath;
    }

    /**
     * Get all the subscriptions. it get the subscription ids from the topic index and get
     * relavent subscriptions.
     * @return
     * @throws org.wso2.carbon.event.core.exception.EventBrokerException
     */
    public List<Subscription> getAllSubscriptions() throws EventBrokerException {
        List<Subscription> subscriptions = new ArrayList<Subscription>();

        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            if (userRegistry.resourceExists(this.indexStoragePath)) {
                Resource topicIndexResource = userRegistry.get(this.indexStoragePath);
                Properties savedSubscriptions = topicIndexResource.getProperties();

                Resource subscriptionResource = null;
                Subscription subscription = null;
                String subscriptionID = null;
                String topicName = null;
                for (Enumeration e = savedSubscriptions.propertyNames(); e.hasMoreElements();) {
                    subscriptionID = (String) e.nextElement();
                    // when the registry is remotely mount to antoher registry. then registry automatically added
                    // some propertiest stary with registry we need to skip them.
                    if (!subscriptionID.startsWith("registry")) {
                        topicName = topicIndexResource.getProperty(subscriptionID);
                        subscriptionResource = userRegistry.get(getResourcePath(subscriptionID, topicName));
                        subscription = JavaUtil.getSubscription(subscriptionResource);
                        subscription.setId(subscriptionID);
                        subscription.setTopicName(topicName);
                        subscription.setTenantId(EventBrokerHolder.getInstance().getTenantId());
                        subscriptions.add(subscription);
                    }
                }
            }

        } catch (RegistryException e) {
            throw new EventBrokerException("Can not access the registry ", e);
        }
        return subscriptions;
    }

    public Subscription getSubscription(String id) throws EventBrokerException {

        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            Resource topicIndexResource = userRegistry.get(this.indexStoragePath);
            String subscriptionPath = getResourcePath(id, topicIndexResource.getProperty(id));
            if (subscriptionPath != null) {
                Resource subscriptionResource = userRegistry.get(subscriptionPath);
                Subscription subscription = JavaUtil.getSubscription(subscriptionResource);
                subscription.setTenantId(EventBrokerHolder.getInstance().getTenantId());
                return subscription;
            } else {
                return null;
            }
        } catch (RegistryException e) {
            throw new EventBrokerException("Can not access the registry ", e);
        }
    }

    public void renewSubscription(Subscription subscription) throws EventBrokerException {

         try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            Resource topicIndexResource = userRegistry.get(this.indexStoragePath);
            String topicName = topicIndexResource.getProperty(subscription.getId());
            String subscriptionPath = getResourcePath(subscription.getId(), topicName);
            if (subscriptionPath != null) {
                Resource subscriptionResource = userRegistry.get(subscriptionPath);
                // Set the expires property only if it has been set again.
                if (subscription.getExpires() != null) {
                    subscriptionResource.setProperty(EventBrokerConstants.EB_RES_EXPIRS,
                            ConverterUtil.convertToString(subscription.getExpires()));
                }
                // There might be updated subscription properties. Set them too.
                Subscription currentSubscription = JavaUtil.getSubscription(subscriptionResource);
                Map<String, String> properties = currentSubscription.getProperties();
                for (String key : properties.keySet()) {
                    subscriptionResource.removeProperty(key);
                }
                properties = subscription.getProperties();
                for (String key : properties.keySet()) {
                    subscriptionResource.setProperty(key, properties.get(key));
                }
                userRegistry.put(subscriptionPath, subscriptionResource);
            } else {
                throw new EventBrokerException("Can not find the resouce to the subscription with" +
                        " id " + subscription.getId());
            }
        } catch (RegistryException e) {
            throw new EventBrokerException("Can not access the registry ", e);
        }

    }

    public void unSubscribe(String subscriptionID) throws EventBrokerException {
        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            String fullPath = this.indexStoragePath;
            if (userRegistry.resourceExists(fullPath)) {
                Resource topicIndexResource = userRegistry.get(fullPath);

                String topicName = topicIndexResource.getProperty(subscriptionID);
                // delete the subscriptions resource
                // if the registry is read only there can be situations where the the subscriptions
                // is not saved to registry and hence the topic name
                if (topicName != null){
                    userRegistry.delete(getResourcePath(subscriptionID, topicName));
                }

                topicIndexResource.removeProperty(subscriptionID);

                userRegistry.put(fullPath, topicIndexResource);
            }

        } catch (RegistryException e) {
            throw new EventBrokerException("Can not access the registry ", e);
        }


    }
}
TOP

Related Classes of org.wso2.carbon.event.core.internal.subscription.registry.RegistrySubscriptionManager

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.