org.wso2.carbon.andes.admin.mqtt.AndesMQTTAdminService.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.andes.admin.mqtt.AndesMQTTAdminService.java

Source

/*
 * Copyright (c) 2005-2014, 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.
 */
package org.wso2.carbon.andes.admin.mqtt;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.andes.admin.mqtt.util.AndesBrokerManagerMQTTAdminServiceDSHolder;
import org.wso2.carbon.andes.admin.mqtt.internal.Exception.BrokerManagerAdminException;
import org.wso2.carbon.andes.admin.mqtt.internal.Subscription;
import org.wso2.carbon.andes.core.QueueManagerException;
import org.wso2.carbon.andes.core.QueueManagerService;
import org.wso2.carbon.andes.core.SubscriptionManagerException;
import org.wso2.carbon.andes.core.SubscriptionManagerService;
import org.wso2.carbon.andes.core.internal.util.Utils;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.core.AbstractAdmin;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Provides all the andes MQTT admin services.
 */
public class AndesMQTTAdminService extends AbstractAdmin {
    private static Log log = LogFactory.getLog(org.wso2.carbon.andes.admin.mqtt.AndesMQTTAdminService.class);
    /**
     * Permission value for changing permissions through UI.
     */
    private static final String UI_EXECUTE = "ui.execute";

    /**
     * Permission path for restore message in dlc
     */
    private static final String PERMISSION_ADMIN_MANAGE_DLC_RESTORE_MESSAGE = "/permission/admin/manage/dlc/restore";

    /**
     * Permission path for forcibly close subscriptions for topics
     */
    private static final String PERMISSION_ADMIN_MANAGE_TOPIC_SUBSCRIPTION_CLOSE = "/permission/admin/manage/subscriptions/topic-close";

    @SuppressWarnings("UnusedDeclaration")
    public long getMessageCount(String destinationName, String msgPattern) throws BrokerManagerAdminException {
        long messageCount;
        try {
            QueueManagerService queueManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder.getInstance()
                    .getQueueManagerService();
            messageCount = queueManagerService.getMessageCount(destinationName, msgPattern);
            return messageCount;
        } catch (Exception e) {
            log.error("Error while retrieving message count by queue manager service", e);
            throw new BrokerManagerAdminException(
                    "Error while retrieving message count " + "by queue manager service", e);
        }
    }

    /**
     * Delete topic related resources from registry
     * @param topicName Topic Name
     * @param subscriptionId Subscription ID
     * @throws BrokerManagerAdminException
     */
    public void deleteTopicFromRegistry(String topicName, String subscriptionId)
            throws BrokerManagerAdminException {
        try {
            QueueManagerService queueManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder.getInstance()
                    .getQueueManagerService();
            queueManagerService.deleteTopicFromRegistry(topicName, subscriptionId);
        } catch (QueueManagerException e) {
            String errorMessage = e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
    }

    /**
     * Close subscription defined by subscription ID forcibly
     * @param subscriptionID ID of the subscription
     * @param destination queue / topic name of the subscribed destination
     * @param protocolType The protocol type of the subscriptions to close
     * @param destinationType The destination type of the subscriptions to close
     * @throws BrokerManagerAdminException
     */
    public void closeSubscription(String subscriptionID, String destination, String protocolType,
            String destinationType) throws BrokerManagerAdminException {
        try {
            SubscriptionManagerService subscriptionManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder
                    .getInstance().getSubscriptionManagerService();
            subscriptionManagerService.closeSubscription(subscriptionID, destination, protocolType,
                    destinationType);
        } catch (SubscriptionManagerException e) {
            String errorMessage = e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
    }

    /**
     * Gets all subscriptions.
     * Suppressing 'MismatchedQueryAndUpdateOfCollection' as 'allSubscriptions' is used to convert
     * to an array.
     *
     * @return An array of {@link Subscription}.
     * @throws BrokerManagerAdminException
     */
    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
    public Subscription[] getAllSubscriptions() throws BrokerManagerAdminException {
        List<Subscription> allSubscriptions = new ArrayList<Subscription>();
        Subscription[] subscriptionsDTO;
        try {
            SubscriptionManagerService subscriptionManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder
                    .getInstance().getSubscriptionManagerService();
            List<org.wso2.carbon.andes.core.types.Subscription> subscriptions = subscriptionManagerService
                    .getAllSubscriptions();
            subscriptionsDTO = new Subscription[subscriptions.size()];
            for (org.wso2.carbon.andes.core.types.Subscription sub : subscriptions) {
                Subscription subscriptionDTO = new Subscription();
                subscriptionDTO.setSubscriptionIdentifier(sub.getSubscriptionIdentifier());
                subscriptionDTO.setSubscribedQueueOrTopicName(sub.getSubscribedQueueOrTopicName());
                subscriptionDTO.setSubscriberQueueBoundExchange(sub.getSubscriberQueueBoundExchange());
                subscriptionDTO.setSubscriberQueueName(sub.getSubscriberQueueName());
                subscriptionDTO.setDurable(sub.isDurable());
                subscriptionDTO.setActive(sub.isActive());
                subscriptionDTO
                        .setNumberOfMessagesRemainingForSubscriber(sub.getNumberOfMessagesRemainingForSubscriber());
                subscriptionDTO.setConnectedNodeAddress(sub.getConnectedNodeAddress());
                subscriptionDTO.setProtocolType(sub.getProtocolType());
                subscriptionDTO.setDestinationType(sub.getDestinationType());
                subscriptionDTO.setOriginHostAddress(sub.getOriginHostAddress());

                allSubscriptions.add(subscriptionDTO);
            }
            CustomSubscriptionComparator comparator = new CustomSubscriptionComparator();
            Collections.sort(allSubscriptions, Collections.reverseOrder(comparator));
            allSubscriptions.toArray(subscriptionsDTO);
        } catch (SubscriptionManagerException e) {
            String errorMessage = e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
        return subscriptionsDTO;
    }

    /**
     * Retrieve subscriptions matching the given criteria.
     *
     * @param isDurable Are the subscriptions to be retrieved durable (true/false)
     * @param isActive Are the subscriptions to be retrieved active (true/false/*, * meaning any)
     * @param protocolType The protocol type of the subscriptions to be retrieved
     * @param destinationType The destination type of the subscriptions to be retrieved
     *
     * @return The list of subscriptions matching the given criteria
     * @throws BrokerManagerAdminException
     */
    public Subscription[] getSubscriptions(String isDurable, String isActive, String protocolType,
            String destinationType) throws BrokerManagerAdminException {

        List<Subscription> allSubscriptions = new ArrayList<Subscription>();
        Subscription[] subscriptionsDTO;
        try {
            SubscriptionManagerService subscriptionManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder
                    .getInstance().getSubscriptionManagerService();
            List<org.wso2.carbon.andes.core.types.Subscription> subscriptions = subscriptionManagerService
                    .getSubscriptions(isDurable, isActive, protocolType, destinationType);
            subscriptionsDTO = new Subscription[subscriptions.size()];
            for (org.wso2.carbon.andes.core.types.Subscription sub : subscriptions) {
                Subscription subscriptionDTO = new Subscription();
                subscriptionDTO.setSubscriptionIdentifier(sub.getSubscriptionIdentifier());
                subscriptionDTO.setSubscribedQueueOrTopicName(sub.getSubscribedQueueOrTopicName());
                subscriptionDTO.setSubscriberQueueBoundExchange(sub.getSubscriberQueueBoundExchange());
                subscriptionDTO.setSubscriberQueueName(sub.getSubscriberQueueName());
                subscriptionDTO.setDurable(sub.isDurable());
                subscriptionDTO.setActive(sub.isActive());
                subscriptionDTO
                        .setNumberOfMessagesRemainingForSubscriber(sub.getNumberOfMessagesRemainingForSubscriber());
                subscriptionDTO.setConnectedNodeAddress(sub.getConnectedNodeAddress());
                subscriptionDTO.setProtocolType(sub.getProtocolType());
                subscriptionDTO.setDestinationType(sub.getDestinationType());
                subscriptionDTO.setOriginHostAddress(sub.getOriginHostAddress());

                allSubscriptions.add(subscriptionDTO);
            }
            CustomSubscriptionComparator comparator = new CustomSubscriptionComparator();
            Collections.sort(allSubscriptions, Collections.reverseOrder(comparator));
            allSubscriptions.toArray(subscriptionsDTO);
        } catch (SubscriptionManagerException e) {
            String errorMessage = e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
        return subscriptionsDTO;
    }

    /**
     * Retrieve subscriptions matching to the given search criteria.
     *
     * @param isDurable  are the subscriptions to be retrieve durable (true/ false)
     * @param isActive   are the subscriptions to be retrieved active (true/false)
     * @param protocolType  the protocol type of the subscriptions to be retrieved
     * @param destinationType the destination type of the subscriptions to be retrieved
     * @param filteredNamePattern queue or topic name pattern to search the subscriptions ("" for all)
     * @param isFilteredNameByExactMatch exactly match the name or not
     * @param identifierPattern  identifier pattern to search the subscriptions ("" for all)
     * @param isIdentifierPatternByExactMatch  exactly match the identifier or not
     * @param ownNodeId node Id of the node which own the subscriptions
     * @param pageNumber  page number in the pagination table
     * @param subscriptionCountPerPage  number of subscriptions to be shown in the UI per page
     * @return a list of subscriptions which match to the search criteria
     * @throws BrokerManagerAdminException throws when an error occurs
     */
    public Subscription[] getFilteredSubscriptions(boolean isDurable, boolean isActive, String protocolType,
            String destinationType, String filteredNamePattern, boolean isFilteredNameByExactMatch,
            String identifierPattern, boolean isIdentifierPatternByExactMatch, String ownNodeId, int pageNumber,
            int subscriptionCountPerPage) throws BrokerManagerAdminException {
        List<Subscription> allSubscriptions = new ArrayList<>();
        Subscription[] subscriptionsDTO;

        try {
            SubscriptionManagerService subscriptionManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder
                    .getInstance().getSubscriptionManagerService();
            List<org.wso2.carbon.andes.core.types.Subscription> subscriptions = subscriptionManagerService
                    .getFilteredSubscriptions(isDurable, isActive, protocolType, destinationType,
                            filteredNamePattern, isFilteredNameByExactMatch, identifierPattern,
                            isIdentifierPatternByExactMatch, ownNodeId, pageNumber, subscriptionCountPerPage);
            subscriptionsDTO = new Subscription[subscriptions.size()];
            for (org.wso2.carbon.andes.core.types.Subscription sub : subscriptions) {
                Subscription subscriptionDTO = new Subscription();
                subscriptionDTO.setSubscriptionIdentifier(sub.getSubscriptionIdentifier());
                subscriptionDTO.setSubscribedQueueOrTopicName(sub.getSubscribedQueueOrTopicName());
                subscriptionDTO.setSubscriberQueueBoundExchange(sub.getSubscriberQueueBoundExchange());
                subscriptionDTO.setSubscriberQueueName(sub.getSubscriberQueueName());
                subscriptionDTO.setDurable(sub.isDurable());
                subscriptionDTO.setActive(sub.isActive());
                subscriptionDTO
                        .setNumberOfMessagesRemainingForSubscriber(sub.getNumberOfMessagesRemainingForSubscriber());
                subscriptionDTO.setConnectedNodeAddress(sub.getConnectedNodeAddress());
                subscriptionDTO.setProtocolType(sub.getProtocolType());
                subscriptionDTO.setDestinationType(sub.getDestinationType());
                subscriptionDTO.setOriginHostAddress(sub.getOriginHostAddress());

                allSubscriptions.add(subscriptionDTO);
            }
            CustomSubscriptionComparator comparator = new CustomSubscriptionComparator();
            Collections.sort(allSubscriptions, Collections.reverseOrder(comparator));
            allSubscriptions.toArray(subscriptionsDTO);
        } catch (SubscriptionManagerException e) {
            String errorMessage = "An error occurred while retrieving subscriptions from backend " + e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
        return subscriptionsDTO;
    }

    /**
     * Returns the total subscription count relevant to a particular search criteria.
     *
     * @param isDurable are the subscriptions to be retrieve durable (true/ false)
     * @param isActive are the subscriptions to be retrieved active (true/false)
     * @param protocolType the protocol type of the subscriptions to be retrieved
     * @param destinationType the destination type of the subscriptions to be retrieved
     * @param filteredNamePattern queue or topic name pattern to search the subscriptions ("" for all)
     * @param isFilteredNameByExactMatch exactly match the name or not
     * @param identifierPattern identifier pattern to search the subscriptions ("" for all)
     * @param isIdentifierPatternByExactMatch exactly match the identifier or not
     * @param ownNodeId node Id of the node which own the subscriptions
     * @return total subscription count matching to the given criteria
     * @throws BrokerManagerAdminException hrows when an error occurs
     */
    public int getTotalSubscriptionCountForSearchResult(boolean isDurable, boolean isActive, String protocolType,
            String destinationType, String filteredNamePattern, boolean isFilteredNameByExactMatch,
            String identifierPattern, boolean isIdentifierPatternByExactMatch, String ownNodeId)
            throws BrokerManagerAdminException {
        int subscriptionCountForSearchResult = 0;
        try {
            SubscriptionManagerService subscriptionManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder
                    .getInstance().getSubscriptionManagerService();
            subscriptionCountForSearchResult = subscriptionManagerService.getTotalSubscriptionCountForSearchResult(
                    isDurable, isActive, protocolType, destinationType, filteredNamePattern,
                    isFilteredNameByExactMatch, identifierPattern, isIdentifierPatternByExactMatch, ownNodeId);

        } catch (SubscriptionManagerException e) {
            String errorMessage = "An error occurred while getting subscription count from backend "
                    + e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
        return subscriptionCountForSearchResult;
    }

    /**
     * Get roles of the current logged user
     * If user has admin role, then all available roles will be return
     *
     * @return Array of user roles.
     * @throws BrokerManagerAdminException
     */
    public String[] getUserRoles() throws BrokerManagerAdminException {
        String[] roles;
        QueueManagerService queueManagerService = AndesBrokerManagerMQTTAdminServiceDSHolder.getInstance()
                .getQueueManagerService();
        try {
            roles = queueManagerService.getBackendRoles();
        } catch (QueueManagerException e) {
            String errorMessage = e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
        return roles;
    }

    /**
     * Check if current user has restore messages in dlc permission. This is global level permission. Usage of service
     * is to control UI action.
     *
     * @return true/false based on permission
     * @throws BrokerManagerAdminException
     */
    public boolean checkCurrentUserHasRestoreMessagesInDLCPermission() throws BrokerManagerAdminException {
        return checkUserHasRestoreMessagesInDLCPermission(
                CarbonContext.getThreadLocalCarbonContext().getUsername());
    }

    /**
     * Check if given user has restore messages in dlc permission. This is global level permission. Usage of service
     * is to control UI action.
     *
     * @param username username
     * @return true/false based on permission
     * @throws BrokerManagerAdminException
     */
    public boolean checkUserHasRestoreMessagesInDLCPermission(String username) throws BrokerManagerAdminException {
        boolean hasPermission = false;
        try {
            if (Utils.isAdmin(username)) {
                hasPermission = true;
            } else if (CarbonContext.getThreadLocalCarbonContext().getUserRealm().getAuthorizationManager()
                    .isUserAuthorized(username, PERMISSION_ADMIN_MANAGE_DLC_RESTORE_MESSAGE, UI_EXECUTE)) {
                hasPermission = true;
            }
        } catch (UserStoreException | QueueManagerException e) {
            String errorMessage = e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
        return hasPermission;
    }

    /**
     * Evaluate current logged in user has close subscription permission for topic subscriptions. This service mainly
     * used to restrict UI
     * control for un-authorize users
     * @return true/false based on permission
     * @throws BrokerManagerAdminException
     */
    public boolean checkCurrentUserHasTopicSubscriptionClosePermission() throws BrokerManagerAdminException {
        boolean hasPermission = false;
        String username = getCurrentUser();
        try {
            if (Utils.isAdmin(username)) {
                hasPermission = true;
            } else if (CarbonContext.getThreadLocalCarbonContext().getUserRealm().getAuthorizationManager()
                    .isUserAuthorized(username, PERMISSION_ADMIN_MANAGE_TOPIC_SUBSCRIPTION_CLOSE, UI_EXECUTE)) {
                hasPermission = true;
            }
        } catch (UserStoreException | QueueManagerException e) {
            String errorMessage = e.getMessage();
            log.error(errorMessage, e);
            throw new BrokerManagerAdminException(errorMessage, e);
        }
        return hasPermission;
    }

    /**
     * Get current user's username.
     * @return The user name.
     */
    private String getCurrentUser() {
        String userName;
        if (CarbonContext.getThreadLocalCarbonContext().getTenantId() > MultitenantConstants.INVALID_TENANT_ID) {
            userName = CarbonContext.getThreadLocalCarbonContext().getUsername() + "!"
                    + CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
        } else {
            userName = CarbonContext.getThreadLocalCarbonContext().getUsername();
        }
        return userName.trim();
    }

    /**
     * A comparator class to order subscriptions.
     */
    public class CustomSubscriptionComparator implements Comparator<Subscription> {

        /**
         * {@inheritDoc}
         */
        @Override
        public int compare(Subscription sub1, Subscription sub2) {
            return sub1.getNumberOfMessagesRemainingForSubscriber()
                    - sub2.getNumberOfMessagesRemainingForSubscriber();
        }
    }
}