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

Source Code of org.wso2.carbon.event.core.internal.topic.registry.RegistryTopicManager

/*
* 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.topic.registry;

import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.event.core.exception.EventBrokerException;
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.topic.TopicManager;
import org.wso2.carbon.event.core.topic.TopicNode;
import org.wso2.carbon.event.core.topic.TopicRolePermission;
import org.wso2.carbon.event.core.util.EventBrokerConstants;
import org.wso2.carbon.registry.core.Collection;
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.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.regex.Pattern;

public class RegistryTopicManager implements TopicManager {

    private String topicStoragePath;
    private RegistryService registryService;


    public RegistryTopicManager(String topicStoragePath) {
        this.topicStoragePath = topicStoragePath;
        this.registryService = EventBrokerHolder.getInstance().getRegistryService();
    }

    public TopicNode getTopicTree() throws EventBrokerException {
        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            if (!userRegistry.resourceExists(topicStoragePath)) {
                userRegistry.put(topicStoragePath,
                                 userRegistry.newCollection());
            }
            Resource root = userRegistry.get(this.topicStoragePath);
            TopicNode rootTopic = new TopicNode("/", "/");
            buildTopicTree(rootTopic, (Collection) root, userRegistry);
            return rootTopic;
        } catch (RegistryException e) {
            throw new EventBrokerException(e.getMessage(), e);
        }
    }

    private void buildTopicTree(TopicNode topicNode, Collection resource, UserRegistry userRegistry)
            throws EventBrokerException {
        try {
            String[] children = resource.getChildren();
            if (children != null) {
                List<TopicNode> nodes = new ArrayList<TopicNode>();
                for (String childTopic : children) {
                    Resource childResource = userRegistry.get(childTopic);
                    if (childResource instanceof Collection) {
                        if (childTopic.endsWith("/")) {
                            childTopic = childTopic.substring(0, childTopic.length() - 2);
                        }
                        String nodeName = childTopic.substring(childTopic.lastIndexOf("/") + 1);
                        if (!nodeName.equals(EventBrokerConstants.EB_CONF_WS_SUBSCRIPTION_COLLECTION_NAME) &&
                            !nodeName.equals(EventBrokerConstants.EB_CONF_JMS_SUBSCRIPTION_COLLECTION_NAME)) {
                            childTopic =
                                    childTopic.substring(childTopic.indexOf(this.topicStoragePath)
                                                         + this.topicStoragePath.length() + 1);
                            TopicNode childNode = new TopicNode(nodeName, childTopic);
                            nodes.add(childNode);
                            buildTopicTree(childNode, (Collection) childResource, userRegistry);
                        }
                    }
                }
                topicNode.setChildren(nodes.toArray(new TopicNode[nodes.size()]));
            }
        } catch (RegistryException e) {
            throw new EventBrokerException(e.getMessage(), e);
        }
    }

    public void addTopic(String topicName) throws EventBrokerException {
        if (!validateTopicName(topicName)) {
            throw new EventBrokerException("Topic name " + topicName + " is not a valid topic name. " +
                                           "Only alphanumeric characters, hyphens (-), stars(*)," +
                                           " hash(#) ,dot(.),question mark(?)" +
                                           " and underscores (_) are allowed.");
        }

        String loggedInUser = CarbonContext.getCurrentContext().getUsername();

        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            String resourcePath = getResourcePath(topicName);

            //we add the topic only if it does not exits. if the topic exists then
            //we don't do any thing.
            if (!userRegistry.resourceExists(resourcePath)) {
                Collection collection = userRegistry.newCollection();
                userRegistry.put(resourcePath, collection);

                // Grant this user (owner) rights to update permission on newly created topic
                UserRealm userRealm = CarbonContext.getCurrentContext().getUserRealm();

                userRealm.getAuthorizationManager().authorizeUser(
                        loggedInUser, resourcePath, EventBrokerConstants.EB_PERMISSION_CHANGE_PERMISSION);
            }
        } catch (RegistryException e) {
            throw new EventBrokerException("Can not access the config registry");
        } catch (UserStoreException e) {
            throw new EventBrokerException("Error while granting user " + loggedInUser +
                                           ", permission " + EventBrokerConstants.EB_PERMISSION_CHANGE_PERMISSION +
                                           ", on topic " + topicName);
        }
    }

    private String removeResourcePath(String topic) {
        String resourcePath = this.topicStoragePath;
        if (topic.indexOf(resourcePath) > -1) {
            topic = topic.substring(topic.indexOf(resourcePath) + resourcePath.length());
        }
        return topic;
    }

    private String getResourcePath(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;
        return resourcePath;
    }


    public TopicRolePermission[] getTopicRolePermission(String topicName)
            throws EventBrokerException {
        String topicResoucePath = getResourcePath(topicName);
        List<TopicRolePermission> topicRolePermissions = new ArrayList<TopicRolePermission>();
        UserRealm userRealm = CarbonContext.getCurrentContext().getUserRealm();
        String adminRole =
                EventBrokerHolder.getInstance().getRealmService().
                        getBootstrapRealmConfiguration().getAdminRoleName();
        TopicRolePermission topicRolePermission;
        try {
            for (String role : userRealm.getUserStoreManager().getRoleNames()) {
                // remove admin role and anonymous role related permissions
                if (!(role.equals(adminRole) ||
                      CarbonConstants.REGISTRY_ANONNYMOUS_ROLE_NAME.equals(adminRole))) {
                    topicRolePermission = new TopicRolePermission();
                    topicRolePermission.setRoleName(role);
                    topicRolePermission.setAllowedToSubscribe(
                            userRealm.getAuthorizationManager().isRoleAuthorized(
                                    role, topicResoucePath, EventBrokerConstants.EB_PERMISSION_SUBSCRIBE));
                    topicRolePermission.setAllowedToPublish(
                            userRealm.getAuthorizationManager().isRoleAuthorized(
                                    role, topicResoucePath, EventBrokerConstants.EB_PERMISSION_PUBLISH));
                    topicRolePermissions.add(topicRolePermission);
                }
            }
            return topicRolePermissions.toArray(
                    new TopicRolePermission[topicRolePermissions.size()]);
        } catch (UserStoreException e) {
            throw new EventBrokerException("Can not access the Userstore manager ", e);
        }
    }

    public void updatePermissions(String topicName, TopicRolePermission[] topicRolePermissions)
            throws EventBrokerException {
        String topicResourcePath = getResourcePath(topicName);
        UserRealm userRealm = CarbonContext.getCurrentContext().getUserRealm();
        String role;
        String loggedInUser = CarbonContext.getCurrentContext().getUsername();
        try {
            if (!userRealm.getAuthorizationManager().isUserAuthorized(
                    loggedInUser, topicResourcePath,
                    EventBrokerConstants.EB_PERMISSION_CHANGE_PERMISSION)) {
                if (!JavaUtil.isAdmin(loggedInUser)) {
                    throw new EventBrokerException(" User " + loggedInUser + " can not change" +
                                                   " the permissions of " + topicName);
                }
            }
            for (TopicRolePermission topicRolePermission : topicRolePermissions) {
                role = topicRolePermission.getRoleName();
                if (topicRolePermission.isAllowedToSubscribe()) {
                    if (!userRealm.getAuthorizationManager().isRoleAuthorized(
                            role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_SUBSCRIBE)) {
                        userRealm.getAuthorizationManager().authorizeRole(
                                role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_SUBSCRIBE);
                    }
                } else {
                    if (userRealm.getAuthorizationManager().isRoleAuthorized(
                            role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_SUBSCRIBE)) {
                        userRealm.getAuthorizationManager().denyRole(
                                role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_SUBSCRIBE);
                    }
                }

                if (topicRolePermission.isAllowedToPublish()) {
                    if (!userRealm.getAuthorizationManager().isRoleAuthorized(
                            role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_PUBLISH)) {
                        userRealm.getAuthorizationManager().authorizeRole(
                                role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_PUBLISH);
                    }
                } else {
                    if (userRealm.getAuthorizationManager().isRoleAuthorized(
                            role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_PUBLISH)) {
                        userRealm.getAuthorizationManager().denyRole(
                                role, topicResourcePath, EventBrokerConstants.EB_PERMISSION_PUBLISH);
                    }
                }
            }
        } catch (UserStoreException e) {
            throw new EventBrokerException("Can not access the user store manager", e);
        }
    }

    public String getTopicStoragePath() {
        return topicStoragePath;
    }

    public void setTopicStoragePath(String topicStoragePath) {
        this.topicStoragePath = topicStoragePath;
    }


    public Subscription[] getSubscriptions(String topicName,
                                           boolean withChildren) throws EventBrokerException {

        List<Subscription> subscriptions = new ArrayList<Subscription>();
        Queue<String> pathsQueue = new LinkedList<String>();
        String resourcePath = getResourcePath(topicName);

        pathsQueue.add(resourcePath);
        while (!pathsQueue.isEmpty()) {
            addSubscriptions(pathsQueue.remove(), subscriptions, pathsQueue, withChildren);
        }

        return subscriptions.toArray(new Subscription[subscriptions.size()]);

    }

    private void addSubscriptions(String resourcePath,
                                  List<Subscription> subscriptions,
                                  Queue<String> pathsQueue,
                                  boolean withChildren) throws EventBrokerException {

        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            String subscriptionsPath = getSubscriptionsPath(resourcePath);

            //first if there are subscriptions for this topic add them. else go to the other folders.

            if (userRegistry.resourceExists(subscriptionsPath)) {
                Collection collection = (Collection) userRegistry.get(subscriptionsPath);
                for (String subscriptionPath : collection.getChildren()) {
                    Resource subscriptionResource = userRegistry.get(subscriptionPath);
                    Subscription subscription = JavaUtil.getSubscription(subscriptionResource);
                    subscription.setTopicName(removeResourcePath(resourcePath));

                    if (subscriptionPath.endsWith("/")) {
                        subscriptionPath = subscriptionsPath.substring(0, subscriptionPath.lastIndexOf("/"));
                    }
                    subscription.setId(subscriptionPath.substring(subscriptionPath.lastIndexOf("/") + 1));
                    subscriptions.add(subscription);
                }
            }

            // add child subscriptions
            if (withChildren) {
                Collection childResouces = (Collection) userRegistry.get(resourcePath);
                for (String childResoucePath : childResouces.getChildren()) {
                    if ((childResoucePath.indexOf(EventBrokerConstants.EB_CONF_WS_SUBSCRIPTION_COLLECTION_NAME) < 0) &&
                        (childResoucePath.indexOf(EventBrokerConstants.EB_CONF_JMS_SUBSCRIPTION_COLLECTION_NAME) < 0)) {
                        // i.e. this folder is a topic folder
                        pathsQueue.add(childResoucePath);
                    }
                }
            }

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

    private String getSubscriptionsPath(String topicName) {

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

        topicName += EventBrokerConstants.EB_CONF_WS_SUBSCRIPTION_COLLECTION_NAME;
        return topicName;
    }

    private boolean validateTopicName(String topicName) {
        String topicNameRegex = "([a-zA-Z0-9_\\-/#*.?])+";
        return Pattern.matches(topicNameRegex, topicName);
    }

    /**
     * Get array of backend roles excluding admin and wso2.anonymous.role roles
     *
     * @return array of roles
     * @throws EventBrokerException if fails to get roles
     */
    public String[] getBackendRoles() throws EventBrokerException {
        UserRealm userRealm = CarbonContext.getCurrentContext().getUserRealm();
        try {
            String adminRole =
                    EventBrokerHolder.getInstance().getRealmService().
                            getBootstrapRealmConfiguration().getAdminRoleName();
            String[] allRoles = userRealm.getUserStoreManager().getRoleNames();
            // check if more roles available than admin role and anonymous role
            if (allRoles!=null && allRoles.length > 2) {
                String[] rolesExceptAdminRole = new String[allRoles.length - 2];
                int index = 0;
                for (String role : allRoles) {
                    if (!(role.equals(adminRole) ||
                          CarbonConstants.REGISTRY_ANONNYMOUS_ROLE_NAME.equals(role))) {
                        rolesExceptAdminRole[index] = role;
                        index++;
                    }
                }
                return rolesExceptAdminRole;
            } else {
                return new String[0];
            }

        } catch (UserStoreException e) {
            throw new EventBrokerException("Unable to getRoles from user store", e);
        }
    }

    public boolean removeTopic(String topicName) throws EventBrokerException {

        try {
            UserRegistry userRegistry =
                    this.registryService.getGovernanceSystemRegistry(EventBrokerHolder.getInstance().getTenantId());
            String resourcePath = getResourcePath(topicName);

            if (userRegistry.resourceExists(resourcePath)) {
                userRegistry.delete(resourcePath);
                return true;
            } else {
                return false;
            }
        } catch (RegistryException e) {
            throw new EventBrokerException("Can not access the config registry");
        }
    }
}
TOP

Related Classes of org.wso2.carbon.event.core.internal.topic.registry.RegistryTopicManager

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.