org.apache.stratos.manager.subscription.utils.CartridgeSubscriptionUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.stratos.manager.subscription.utils.CartridgeSubscriptionUtils.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.apache.stratos.manager.subscription.utils;

import org.apache.axis2.AxisFault;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.autoscaler.deployment.policy.DeploymentPolicy;
import org.apache.stratos.cloud.controller.stub.pojo.*;
import org.apache.stratos.manager.client.AutoscalerServiceClient;
import org.apache.stratos.manager.client.CloudControllerServiceClient;
import org.apache.stratos.manager.dao.Cluster;
import org.apache.stratos.manager.deploy.service.Service;
import org.apache.stratos.manager.exception.ADCException;
import org.apache.stratos.manager.exception.DuplicateCartridgeAliasException;
import org.apache.stratos.manager.exception.InvalidCartridgeAliasException;
import org.apache.stratos.manager.exception.UnregisteredCartridgeException;
import org.apache.stratos.manager.lb.category.LBDataContext;
import org.apache.stratos.manager.payload.BasicPayloadData;
import org.apache.stratos.manager.repository.Repository;
import org.apache.stratos.manager.retriever.DataInsertionAndRetrievalManager;
import org.apache.stratos.manager.subscriber.Subscriber;
import org.apache.stratos.messaging.broker.publish.EventPublisher;
import org.apache.stratos.messaging.broker.publish.EventPublisherPool;
import org.apache.stratos.messaging.event.tenant.TenantSubscribedEvent;
import org.apache.stratos.messaging.event.tenant.TenantUnSubscribedEvent;
import org.apache.stratos.messaging.util.Constants;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.regex.Pattern;

public class CartridgeSubscriptionUtils {

    private static Log log = LogFactory.getLog(CartridgeSubscriptionUtils.class);

    public static BasicPayloadData createBasicPayload(CartridgeInfo cartridgeInfo, String subscriptionKey,
            Cluster cluster, Repository repository, String alias, Subscriber subscriber) {

        BasicPayloadData basicPayloadData = new BasicPayloadData();
        basicPayloadData.setApplicationPath(cartridgeInfo.getBaseDir());
        basicPayloadData.setSubscriptionKey(subscriptionKey);
        //basicPayloadData.setDeployment("default");//currently hard coded to default
        basicPayloadData.setMultitenant(String.valueOf(cartridgeInfo.getMultiTenant()));
        basicPayloadData.setPortMappings(createPortMappingPayloadString(cartridgeInfo));
        basicPayloadData.setServiceName(cartridgeInfo.getType());
        basicPayloadData.setProvider(cartridgeInfo.getProvider());

        if (repository != null) {
            basicPayloadData.setGitRepositoryUrl(repository.getUrl());
        }

        if (cluster != null) {
            basicPayloadData.setClusterId(cluster.getClusterDomain());
            basicPayloadData.setHostName(cluster.getHostName());
        }

        if (alias != null) {
            basicPayloadData.setSubscriptionAlias(alias);
        }

        if (subscriber != null) {
            basicPayloadData.setTenantId(subscriber.getTenantId());
        }

        //TODO:remove. we do not want to know about the tenant rance in subscription!
        if (cartridgeInfo.getMultiTenant()) { //TODO: fix properly
            basicPayloadData.setTenantRange("*");
        } else if (subscriber != null) {
            basicPayloadData.setTenantRange(String.valueOf(subscriber.getTenantId()));
        }

        return basicPayloadData;
    }

    public static BasicPayloadData createBasicPayload(Service service) {

        BasicPayloadData basicPayloadData = new BasicPayloadData();
        basicPayloadData.setApplicationPath(service.getCartridgeInfo().getBaseDir());
        basicPayloadData.setSubscriptionKey(service.getSubscriptionKey());
        basicPayloadData.setClusterId(service.getClusterId());
        //basicPayloadData.setDeployment("default");//currently hard coded to default
        basicPayloadData.setHostName(service.getHostName());
        basicPayloadData.setMultitenant(String.valueOf(service.getCartridgeInfo().getMultiTenant()));
        basicPayloadData.setPortMappings(createPortMappingPayloadString(service.getCartridgeInfo()));
        basicPayloadData.setServiceName(service.getType());
        basicPayloadData.setTenantId(service.getTenantId());
        basicPayloadData.setTenantRange(service.getTenantRange());

        return basicPayloadData;
    }

    //    public static BasicPayloadData createBasicPayload (LBCategoryContext lbCategoryContext) {
    //
    //        BasicPayloadData basicPayloadData = new BasicPayloadData();
    //        basicPayloadData.setApplicationPath(lbCategoryContext.getCartridgeInfo().getBaseDir());
    //        basicPayloadData.setSubscriptionKey(lbCategoryContext.getKey());
    //        basicPayloadData.setClusterId(lbCategoryContext.getCluster().getClusterDomain());
    //        basicPayloadData.setDeployment("default");//currently hard coded to default
    //        basicPayloadData.setHostName(lbCategoryContext.getCluster().getHostName());
    //        basicPayloadData.setMultitenant(String.valueOf(lbCategoryContext.getCartridgeInfo().getMultiTenant()));
    //        basicPayloadData.setPortMappings(createPortMappingPayloadString(lbCategoryContext.getCartridgeInfo()));
    //        basicPayloadData.setServiceName(lbCategoryContext.getLbType());
    //
    //        if (lbCategoryContext.getSubscriptionAlias() != null && !lbCategoryContext.getSubscriptionAlias().isEmpty()) {
    //            basicPayloadData.setSubscriptionAlias(lbCategoryContext.getSubscriptionAlias());
    //        }
    //
    //        if (lbCategoryContext.getSubscriber() != null) {
    //            basicPayloadData.setTenantId(lbCategoryContext.getSubscriber().getTenantId());
    //        }
    //
    //        return basicPayloadData;
    //    }

    private static String createPortMappingPayloadString(CartridgeInfo cartridgeInfo) {

        // port mappings
        StringBuilder portMapBuilder = new StringBuilder();
        PortMapping[] portMappings = cartridgeInfo.getPortMappings();
        for (PortMapping portMapping : portMappings) {
            String port = portMapping.getPort();
            portMapBuilder.append(port).append("|");
        }

        // remove last "|" character
        String portMappingString = portMapBuilder.toString().replaceAll("\\|$", "");

        return portMappingString;
    }

    public static String generateSubscriptionKey() {
        return RandomStringUtils.randomAlphanumeric(16);
    }

    static class TenantSubscribedEventPublisher implements Runnable {

        private int tenantId;
        private String serviceName;
        private Set<String> clusterIds;

        public TenantSubscribedEventPublisher(int tenantId, String service, Set<String> clusterIds) {
            this.tenantId = tenantId;
            this.serviceName = service;
            this.clusterIds = clusterIds;
        }

        @Override
        public void run() {
            try {
                if (log.isInfoEnabled()) {
                    log.info(String.format("Publishing tenant subscribed event: [tenant-id] %d [service] %s",
                            tenantId, serviceName));
                }
                TenantSubscribedEvent subscribedEvent = new TenantSubscribedEvent(tenantId, serviceName,
                        clusterIds);
                EventPublisher eventPublisher = EventPublisherPool.getPublisher(Constants.TENANT_TOPIC);
                eventPublisher.publish(subscribedEvent);
            } catch (Exception e) {
                if (log.isErrorEnabled()) {
                    log.error(
                            String.format("Could not publish tenant subscribed event: [tenant-id] %d [service] %s",
                                    tenantId, serviceName),
                            e);
                }
            }

        }

    }

    public static void publishTenantSubscribedEvent(int tenantId, String serviceName, Set<String> clusterIds) {

        Executor exec = new Executor() {
            @Override
            public void execute(Runnable command) {
                command.run();
            }
        };

        exec.execute(new TenantSubscribedEventPublisher(tenantId, serviceName, clusterIds));
    }

    public static void publishTenantUnSubscribedEvent(int tenantId, String serviceName, Set<String> clusterIds) {
        try {
            if (log.isInfoEnabled()) {
                log.info(String.format("Publishing tenant un-subscribed event: [tenant-id] %d [service] %s",
                        tenantId, serviceName));
            }
            TenantUnSubscribedEvent event = new TenantUnSubscribedEvent(tenantId, serviceName, clusterIds);
            EventPublisher eventPublisher = EventPublisherPool.getPublisher(Constants.TENANT_TOPIC);
            eventPublisher.publish(event);
        } catch (Exception e) {
            if (log.isErrorEnabled()) {
                log.error(String.format("Could not publish tenant un-subscribed event: [tenant-id] %d [service] %s",
                        tenantId, serviceName), e);
            }
        }
    }

    public static void validateCartridgeAlias(int tenantId, String cartridgeType, String alias)
            throws InvalidCartridgeAliasException, DuplicateCartridgeAliasException, ADCException {

        String patternString = "([a-z0-9]+([-][a-z0-9])*)+";
        Pattern pattern = Pattern.compile(patternString);

        if (!pattern.matcher(alias).matches()) {
            String msg = "The alias " + alias
                    + " can contain only alpha-numeric lowercase characters. Please enter a valid alias.";
            log.error(msg);
            throw new InvalidCartridgeAliasException(msg, tenantId, cartridgeType, alias);
        }

        boolean isAliasTaken = false;
        try {
            isAliasTaken = isAliasTaken(tenantId, alias);
        } catch (Exception e) {
            String msg = "Exception : " + e.getMessage();
            log.error(msg, e);
            throw new ADCException("Error when checking alias is already taken", e);
        }

        if (isAliasTaken) {
            String msg = "The alias " + alias + " is already taken. Please try again with a different alias.";
            log.error(msg);
            throw new DuplicateCartridgeAliasException(msg, cartridgeType, alias);
        }
    }

    public static boolean isAliasTaken(int tenantId, String alias) {

        DataInsertionAndRetrievalManager dataInsertionAndRetrievalManager = new DataInsertionAndRetrievalManager();
        // return (dataInsertionAndRetrievalManager.getCartridgeSubscription(tenantId, alias) == null) ? false : true;
        // fixing STRATOS-427, making the alias globally unique
        return (dataInsertionAndRetrievalManager.getCartridgeSubscriptionForAlias(alias) == null) ? false : true;
    }

    public static String limitLengthOfString(String source, int length) {

        return source.substring(0, length);
    }

    public static LBDataContext getLoadBalancerDataContext(int tenantId, String serviceType,
            String deploymentPolicyName, LoadbalancerConfig lbConfig)
            throws UnregisteredCartridgeException, ADCException {

        String lbCartridgeType = lbConfig.getType();

        LBDataContext lbDataCtxt = new LBDataContext();
        // set tenant Id
        lbDataCtxt.setTenantId(tenantId);

        Properties lbReferenceProperties = lbConfig.getProperties();

        Property lbRefProperty = new Property();
        lbRefProperty.setName(org.apache.stratos.messaging.util.Constants.LOAD_BALANCER_REF);

        for (Property prop : lbReferenceProperties.getProperties()) {

            String name = prop.getName();
            String value = prop.getValue();

            // TODO make following a chain of responsibility pattern
            if (Constants.NO_LOAD_BALANCER.equals(name)) {

                if ("true".equals(value)) {
                    lbDataCtxt.setLbCategory(Constants.NO_LOAD_BALANCER);

                    if (log.isDebugEnabled()) {
                        log.debug("This cartridge does not require a load balancer. " + "[Type] " + serviceType);
                    }
                    lbRefProperty.setValue(name);
                    lbDataCtxt.addLoadBalancedServiceProperty(lbRefProperty);
                    break;
                }
            } else if (Constants.EXISTING_LOAD_BALANCERS.equals(name)) {

                lbDataCtxt.setLbCategory(Constants.EXISTING_LOAD_BALANCERS);

                String clusterIdsVal = value;
                if (log.isDebugEnabled()) {
                    log.debug("This cartridge refers to existing load balancers. " + "[Type] " + serviceType
                            + "[Referenced Cluster Ids] " + clusterIdsVal);
                }

                String[] clusterIds = clusterIdsVal.split(",");

                for (String clusterId : clusterIds) {
                    try {
                        AutoscalerServiceClient.getServiceClient().checkLBExistenceAgainstPolicy(clusterId,
                                deploymentPolicyName);
                    } catch (Exception ex) {
                        // we don't need to throw the error here.
                        log.error(ex.getMessage(), ex);
                    }
                }

                lbRefProperty.setValue(name);
                lbDataCtxt.addLoadBalancedServiceProperty(lbRefProperty);
                break;

            } else if (Constants.DEFAULT_LOAD_BALANCER.equals(name)) {

                if ("true".equals(value)) {

                    lbDataCtxt.setLbCategory(Constants.DEFAULT_LOAD_BALANCER);

                    lbRefProperty.setValue(name);

                    CartridgeInfo lbCartridgeInfo;

                    try {
                        lbCartridgeInfo = CloudControllerServiceClient.getServiceClient()
                                .getCartridgeInfo(lbCartridgeType);

                    } catch (Exception e) {
                        String message = "Error getting info for " + lbCartridgeType;
                        log.error(message, e);
                        throw new ADCException(message, e);
                    }

                    if (lbCartridgeInfo == null) {
                        String msg = "Please specify a LB cartridge type for the cartridge: " + serviceType
                                + " as category: " + Constants.DEFAULT_LOAD_BALANCER;
                        log.error(msg);
                        throw new ADCException(msg);
                    }

                    lbDataCtxt.setLbCartridgeInfo(lbCartridgeInfo);

                    if (log.isDebugEnabled()) {
                        log.debug("This cartridge uses default load balancer. " + "[Type] " + serviceType);
                    }

                    try {
                        // get the valid policies for lb cartridge
                        DeploymentPolicy[] lbCartridgeDepPolicies = getAutoscalerServiceClient()
                                .getDeploymentPolicies(lbCartridgeType);
                        // traverse deployment policies of lb cartridge
                        for (DeploymentPolicy policy : lbCartridgeDepPolicies) {

                            // check existence of the subscribed policy
                            if (deploymentPolicyName.equals(policy.getId())) {

                                if (!getAutoscalerServiceClient()
                                        .checkDefaultLBExistenceAgainstPolicy(deploymentPolicyName)) {
                                    if (log.isDebugEnabled()) {
                                        log.debug(" Default LB doesn't exist for deployment policy ["
                                                + deploymentPolicyName + "] ");
                                    }

                                    Properties lbProperties = new Properties();

                                    // if LB cartridge definition has properties as well, combine
                                    if (lbCartridgeInfo.getProperties() != null
                                            && lbCartridgeInfo.getProperties().length > 0) {
                                        if (log.isDebugEnabled()) {
                                            log.debug(" Combining LB properties ");
                                        }
                                        lbProperties.setProperties(combine(lbCartridgeInfo.getProperties(),
                                                new Property[] { lbRefProperty }));
                                    } else {
                                        lbProperties.setProperties(new Property[] { lbRefProperty });
                                    }

                                    lbDataCtxt.addLBProperties(lbProperties);
                                }
                            }
                        }

                    } catch (Exception ex) {
                        // we don't need to throw the error here.
                        log.error(ex.getMessage(), ex);
                    }

                    // set deployment and autoscaling policies
                    lbDataCtxt.setDeploymentPolicy(deploymentPolicyName);
                    lbDataCtxt.setAutoscalePolicy(lbCartridgeInfo.getDefaultAutoscalingPolicy());

                    lbDataCtxt.addLoadBalancedServiceProperty(lbRefProperty);
                    break;
                }

            } else if (Constants.SERVICE_AWARE_LOAD_BALANCER.equals(name)) {

                if ("true".equals(value)) {

                    lbDataCtxt.setLbCategory(Constants.SERVICE_AWARE_LOAD_BALANCER);

                    lbRefProperty.setValue(name);

                    CartridgeInfo lbCartridgeInfo;

                    try {
                        lbCartridgeInfo = CloudControllerServiceClient.getServiceClient()
                                .getCartridgeInfo(lbCartridgeType);

                    } catch (Exception e) {
                        String message = "Error getting info for " + lbCartridgeType;
                        log.error(message, e);
                        throw new ADCException(message, e);
                    }

                    if (lbCartridgeInfo == null) {
                        String msg = "Please specify a LB cartridge type for the cartridge: " + serviceType
                                + " as category: " + Constants.SERVICE_AWARE_LOAD_BALANCER;
                        log.error(msg);
                        throw new ADCException(msg);
                    }

                    lbDataCtxt.setLbCartridgeInfo(lbCartridgeInfo);

                    // add a property for the service type
                    Property loadBalancedServiceTypeProperty = new Property();
                    loadBalancedServiceTypeProperty.setName(Constants.LOAD_BALANCED_SERVICE_TYPE);
                    // set the load balanced service type
                    loadBalancedServiceTypeProperty.setValue(serviceType);

                    if (log.isDebugEnabled()) {
                        log.debug("This cartridge uses a service aware load balancer. [Type] " + serviceType);
                    }

                    try {

                        // get the valid policies for lb cartridge
                        DeploymentPolicy[] lbCartridgeDepPolicies = getAutoscalerServiceClient()
                                .getDeploymentPolicies(lbCartridgeType);
                        // traverse deployment policies of lb cartridge
                        for (DeploymentPolicy policy : lbCartridgeDepPolicies) {
                            // check existence of the subscribed policy
                            if (deploymentPolicyName.equals(policy.getId())) {

                                if (!getAutoscalerServiceClient().checkServiceLBExistenceAgainstPolicy(serviceType,
                                        deploymentPolicyName)) {

                                    Properties lbProperties = new Properties();

                                    // if LB cartridge definition has properties as well, combine
                                    if (lbCartridgeInfo.getProperties() != null
                                            && lbCartridgeInfo.getProperties().length > 0) {
                                        lbProperties.setProperties(combine(lbCartridgeInfo.getProperties(),
                                                new Property[] { lbRefProperty, loadBalancedServiceTypeProperty }));

                                    } else {
                                        lbProperties.setProperties(
                                                new Property[] { lbRefProperty, loadBalancedServiceTypeProperty });
                                    }

                                    // set a payload property for load balanced service type
                                    Property payloadProperty = new Property();
                                    payloadProperty.setName("LOAD_BALANCED_SERVICE_TYPE"); //TODO: refactor hardcoded name
                                    payloadProperty.setValue(serviceType);

                                    lbDataCtxt.addLBProperties(lbProperties);
                                }
                            }
                        }

                    } catch (Exception ex) {
                        // we don't need to throw the error here.
                        log.error(ex.getMessage(), ex);
                    }

                    // set deployment and autoscaling policies
                    lbDataCtxt.setDeploymentPolicy(deploymentPolicyName);
                    lbDataCtxt.setAutoscalePolicy(lbCartridgeInfo.getDefaultAutoscalingPolicy());

                    lbDataCtxt.addLoadBalancedServiceProperty(lbRefProperty);
                    break;
                }
            }
        }

        return lbDataCtxt;
    }

    private static AutoscalerServiceClient getAutoscalerServiceClient() throws ADCException {

        try {
            return AutoscalerServiceClient.getServiceClient();

        } catch (AxisFault axisFault) {
            String errorMsg = "Error in getting AutoscalerServiceClient instance";
            log.error(errorMsg, axisFault);
            throw new ADCException(errorMsg, axisFault);
        }
    }

    private static Property[] combine(Property[] propertyArray1, Property[] propertyArray2) {

        int length = propertyArray1.length + propertyArray2.length;
        Property[] combinedProperties = new Property[length];
        System.arraycopy(propertyArray1, 0, combinedProperties, 0, propertyArray1.length);
        System.arraycopy(propertyArray2, 0, combinedProperties, propertyArray1.length, propertyArray2.length);

        return combinedProperties;
    }
}