Package org.apache.stratos.manager.manager

Source Code of org.apache.stratos.manager.manager.CartridgeSubscriptionManager

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.cloud.controller.stub.CloudControllerServiceUnregisteredCartridgeExceptionException;
import org.apache.stratos.cloud.controller.stub.pojo.CartridgeInfo;
import org.apache.stratos.cloud.controller.stub.pojo.LoadbalancerConfig;
import org.apache.stratos.cloud.controller.stub.pojo.Properties;
import org.apache.stratos.cloud.controller.stub.pojo.Property;
import org.apache.stratos.manager.client.CloudControllerServiceClient;
import org.apache.stratos.manager.dao.CartridgeSubscriptionInfo;
import org.apache.stratos.manager.dto.SubscriptionInfo;
import org.apache.stratos.manager.exception.*;
import org.apache.stratos.manager.lb.category.*;
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.manager.subscription.CartridgeSubscription;
import org.apache.stratos.manager.subscription.PersistenceContext;
import org.apache.stratos.manager.subscription.SubscriptionData;
import org.apache.stratos.manager.subscription.factory.CartridgeSubscriptionFactory;
import org.apache.stratos.manager.subscription.tenancy.SubscriptionMultiTenantBehaviour;
import org.apache.stratos.manager.subscription.tenancy.SubscriptionSingleTenantBehaviour;
import org.apache.stratos.manager.subscription.tenancy.SubscriptionTenancyBehaviour;
import org.apache.stratos.manager.subscription.utils.CartridgeSubscriptionUtils;
import org.apache.stratos.manager.topology.model.TopologyClusterInformationModel;
import org.apache.stratos.manager.utils.ApplicationManagementUtil;
import org.apache.stratos.manager.utils.CartridgeConstants;
import org.apache.stratos.manager.utils.RepoPasswordMgtUtil;
import org.apache.stratos.messaging.domain.topology.Cluster;
import org.apache.stratos.messaging.domain.topology.Member;
import org.apache.stratos.messaging.util.Constants;
import org.wso2.carbon.context.CarbonContext;
import org.apache.stratos.manager.publisher.CartridgeSubscriptionDataPublisher;

import java.util.Collection;
import java.util.Random;

/**
* Manager class for the purpose of managing CartridgeSubscriptionInfo subscriptions, groupings, etc.
*/
public class CartridgeSubscriptionManager {

    private static Log log = LogFactory.getLog(CartridgeSubscriptionManager.class);
    //private static DataInsertionAndRetrievalManager dataInsertionAndRetrievalManager = new DataInsertionAndRetrievalManager();
   
    public SubscriptionInfo subscribeToCartridgeWithProperties(SubscriptionData subscriptionDatathrows ADCException,
                                                                                            InvalidCartridgeAliasException,
                                                                                            DuplicateCartridgeAliasException,
                                                                                            PolicyException,
                                                                                            UnregisteredCartridgeException,
                                                                                            RepositoryRequiredException,
                                                                                            RepositoryCredentialsRequiredException,
                                                                                            RepositoryTransportException,
                                                                                            AlreadySubscribedException,
                                                                                            InvalidRepositoryException {

        // validate cartridge alias
        CartridgeSubscriptionUtils.validateCartridgeAlias(subscriptionData.getTenantId(), subscriptionData.getCartridgeType(), subscriptionData.getCartridgeAlias());

        CartridgeInfo cartridgeInfo;
        try {
            cartridgeInfo = CloudControllerServiceClient.getServiceClient().getCartridgeInfo(subscriptionData.getCartridgeType());

        } catch (CloudControllerServiceUnregisteredCartridgeExceptionException e) {
            String message = subscriptionData.getCartridgeType() + " is not a valid cartridgeSubscription type. Please try again with a valid cartridgeSubscription type.";
            log.error(message);
            throw new ADCException(message, e);

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

        // For MT subscriptions check whether there are active instances
        if(cartridgeInfo.getMultiTenant() && !activeInstancesAvailable(subscriptionData)) {
          String msg = "No active instances are found for cartridge [" + subscriptionData.getCartridgeType() + "]";
          log.error(msg);
          throw new ADCException(msg);
        }
       
        // check if this subscription requires Persistence Mapping, and its supported by the cartridge definition
        Properties persistenceMappingProperties = null;
        if (subscriptionData.getPersistanceContext() != null) {
            persistenceMappingProperties = getPersistenceMappingProperties(subscriptionData.getPersistanceContext(), cartridgeInfo);
        }

        Properties serviceCartridgeSubscriptionProperties = null;
        LBDataContext lbDataCtxt = null;
        CartridgeSubscription lbCartridgeSubscription = null;
        Properties lbCartridgeSubscriptionProperties = null;
        String lbClusterId = null;

        // get lb config reference
        LoadbalancerConfig lbConfig = cartridgeInfo.getLbConfig();
        if (lbConfig == null || lbConfig.getProperties() == null) {
            // no LB ref
            if (log.isDebugEnabled()) {
                log.debug("This Service does not require a load balancer. " + "[Service Name] " +
                        subscriptionData.getCartridgeType());
            }

        } else {

            // LB ref found, get relevant LB Context data
            lbDataCtxt = CartridgeSubscriptionUtils.getLoadBalancerDataContext(subscriptionData.getTenantId(), subscriptionData.getCartridgeType(),
                    subscriptionData.getDeploymentPolicyName(), lbConfig);

            // subscribe to LB
            lbCartridgeSubscription = subscribeToLB (subscriptionData, lbDataCtxt, cartridgeInfo);

            // determine the LB cluster id, if available
            if (lbCartridgeSubscription != null) {
                lbClusterId = lbCartridgeSubscription.getClusterDomain();
            }

            lbCartridgeSubscriptionProperties =  new Properties();
            if (lbDataCtxt.getLbProperperties() != null && !lbDataCtxt.getLbProperperties().isEmpty()) {
                lbCartridgeSubscriptionProperties.setProperties(lbDataCtxt.getLbProperperties().toArray(new Property[0]));
            }
        }

        // subscribe to relevant service cartridge
        CartridgeSubscription serviceCartridgeSubscription = subscribe (subscriptionData, cartridgeInfo, lbClusterId);
        serviceCartridgeSubscriptionProperties = new Properties();

        // lb related properties
        if ((lbDataCtxt != null && lbDataCtxt.getLoadBalancedServiceProperties() != null) && !lbDataCtxt.getLoadBalancedServiceProperties().isEmpty()) {
            serviceCartridgeSubscriptionProperties.setProperties(lbDataCtxt.getLoadBalancedServiceProperties().toArray(new Property[0]));
        }

        // Persistence Mapping related properties
        if (persistenceMappingProperties != null && persistenceMappingProperties.getProperties().length > 0) {
            // add the properties to send to CC via register method
            for (Property persistenceMappingProperty : persistenceMappingProperties.getProperties()) {
                serviceCartridgeSubscriptionProperties.addProperties(persistenceMappingProperty);
            }
        }

        if (lbCartridgeSubscription != null) {
            // register LB cartridge subscription
          if(log.isDebugEnabled()) {
            log.debug(" Registering LB Cartridge subscription ");
          }
            registerCartridgeSubscription(lbCartridgeSubscription, lbCartridgeSubscriptionProperties);
        }

        // register service cartridge subscription
        return registerCartridgeSubscription(serviceCartridgeSubscription, serviceCartridgeSubscriptionProperties);
    }

    private boolean activeInstancesAvailable(SubscriptionData subscriptionData) {
      Cluster cluster = TopologyClusterInformationModel.getInstance().getCluster(subscriptionData.getCartridgeType());
      int activeMemberCount = 0;
      if(cluster != null) {
          Collection<Member> members = cluster.getMembers();
          for (Member member : members) {
        if(member.isActive()) {
          activeMemberCount++;
        }
      }
      }
      if(log.isDebugEnabled()) {
        log.debug("Active member count for cluster  [" + cluster +"] is : "+ activeMemberCount);
      }
    return activeMemberCount > 0;  
  }

  private CartridgeSubscription subscribeToLB (SubscriptionData subscriptionData, LBDataContext lbDataContext,
            CartridgeInfo serviceCartridgeInfo)

            throws ADCException, InvalidCartridgeAliasException,
            DuplicateCartridgeAliasException, PolicyException, UnregisteredCartridgeException, RepositoryRequiredException, RepositoryCredentialsRequiredException,
            RepositoryTransportException, AlreadySubscribedException, InvalidRepositoryException {

       
        if (lbDataContext.getLbCategory() == null || lbDataContext.getLbCategory().equals(Constants.NO_LOAD_BALANCER)) {
            // no load balancer subscription requiredgenerateSubscriptionKey
            log.info("No LB subscription required for the Subscription with alias: " + subscriptionData.getCartridgeAlias() + ", type: " +
                    subscriptionData.getCartridgeType());
            return null;
        }

        LoadBalancerCategory loadBalancerCategory = null;

        String lbAlias = "lb" + lbDataContext.getLbCartridgeInfo().getType() + new Random().nextInt();

        if (lbDataContext.getLbCategory().equals(Constants.EXISTING_LOAD_BALANCERS)) {
            loadBalancerCategory = new ExistingLoadBalancerCategory();

        } else if (lbDataContext.getLbCategory().equals(Constants.DEFAULT_LOAD_BALANCER)) {
            loadBalancerCategory = new DefaultLoadBalancerCategory();

        } else if (lbDataContext.getLbCategory().equals(Constants.SERVICE_AWARE_LOAD_BALANCER)) {
            loadBalancerCategory = new ServiceLevelLoadBalancerCategory();
        }

        if (loadBalancerCategory == null) {
            throw new ADCException("The given Load Balancer category " + lbDataContext.getLbCategory() + " not found");
        }

        if(lbDataContext.getLbCartridgeInfo().getMultiTenant()) {
            throw new ADCException("LB Cartridge must be single tenant");
        }
        // Set the load balanced service type
        loadBalancerCategory.setLoadBalancedServiceType(subscriptionData.getCartridgeType());
       
    // Set if the load balanced service is multi tenant or not
        loadBalancerCategory.setLoadBalancedServiceMultiTenant(serviceCartridgeInfo.getMultiTenant());

        // set the relevant deployment policy
        loadBalancerCategory.setDeploymentPolicyName(lbDataContext.getDeploymentPolicy());

        // Create the CartridgeSubscription instance
        CartridgeSubscription cartridgeSubscription = CartridgeSubscriptionFactory.getLBCartridgeSubscriptionInstance(lbDataContext, loadBalancerCategory);

        // Generate and set the key
        String subscriptionKey = CartridgeSubscriptionUtils.generateSubscriptionKey();
        cartridgeSubscription.setSubscriptionKey(subscriptionKey);

        // Create repository
        Repository repository = cartridgeSubscription.manageRepository(null, """", false);

        // Create subscriber
        Subscriber subscriber = new Subscriber(subscriptionData.getTenantAdminUsername(), subscriptionData.getTenantId(), subscriptionData.getTenantDomain());

        // create subscription
        cartridgeSubscription.createSubscription(subscriber, lbAlias, lbDataContext.getAutoscalePolicy(),
                lbDataContext.getDeploymentPolicy(), repository);

        // add LB category to the payload
        if (cartridgeSubscription.getPayloadData() != null) {
            cartridgeSubscription.getPayloadData().add(CartridgeConstants.LB_CATEGORY, lbDataContext.getLbCategory());
        }

                // publishing to bam
               CartridgeSubscriptionDataPublisher.publish(subscriptionData.getTenantId(),
                     subscriptionData.getTenantAdminUsername(), lbAlias,
                     lbDataContext.getLbCartridgeInfo().getType(),
                     subscriptionData.getRepositoryURL(),
                     serviceCartridgeInfo.getMultiTenant(),
                     lbDataContext.getDeploymentPolicy(),
                     lbDataContext.getAutoscalePolicy(),
                     cartridgeSubscription.getCluster().getClusterDomain(),
                     cartridgeSubscription.getHostName(),
                     cartridgeSubscription.getMappedDomain(), "Subscribed");
       
        log.info("Tenant [" + subscriptionData.getTenantId() + "] with username [" + subscriptionData.getTenantAdminUsername() +
                " subscribed to " + "] Cartridge with Alias " + lbAlias + ", Cartridge Type: " + lbDataContext.getLbCartridgeInfo().getType() +
                ", Autoscale Policy: " + lbDataContext.getAutoscalePolicy() + ", Deployment Policy: " + lbDataContext.getDeploymentPolicy());

        return cartridgeSubscription;
    }

    private CartridgeSubscription subscribe (SubscriptionData subscriptionData, CartridgeInfo cartridgeInfo, String lbClusterId)

            throws ADCException, InvalidCartridgeAliasException,
            DuplicateCartridgeAliasException, PolicyException, UnregisteredCartridgeException, RepositoryRequiredException, RepositoryCredentialsRequiredException,
            RepositoryTransportException, AlreadySubscribedException, InvalidRepositoryException {


        // Decide tenancy behaviour
        SubscriptionTenancyBehaviour tenancyBehaviour;
        if(cartridgeInfo.getMultiTenant()) {
            tenancyBehaviour = new SubscriptionMultiTenantBehaviour();
        } else {
            tenancyBehaviour = new SubscriptionSingleTenantBehaviour();
        }

        // Create the CartridgeSubscription instance
        CartridgeSubscription cartridgeSubscription = CartridgeSubscriptionFactory.getCartridgeSubscriptionInstance(cartridgeInfo, tenancyBehaviour);

        // Generate and set the key
        String subscriptionKey = CartridgeSubscriptionUtils.generateSubscriptionKey();
        cartridgeSubscription.setSubscriptionKey(subscriptionKey);
       
        String encryptedRepoPassword;
        String repositoryPassword = subscriptionData.getRepositoryPassword();
        if(repositoryPassword != null && !repositoryPassword.isEmpty()) {
          encryptedRepoPassword = RepoPasswordMgtUtil.encryptPassword(repositoryPassword, subscriptionKey);
        } else {
          encryptedRepoPassword = "";
        }

        // Create repository
        Repository repository = cartridgeSubscription.manageRepository(subscriptionData.getRepositoryURL(), subscriptionData.getRepositoryUsername(),
                encryptedRepoPassword,
                subscriptionData.isPrivateRepository());

        // Create subscriber
        Subscriber subscriber = new Subscriber(subscriptionData.getTenantAdminUsername(), subscriptionData.getTenantId(), subscriptionData.getTenantDomain());

        // set the LB cluster id relevant to this service cluster
        cartridgeSubscription.setLbClusterId(lbClusterId);

        //create subscription
        cartridgeSubscription.createSubscription(subscriber, subscriptionData.getCartridgeAlias(), subscriptionData.getAutoscalingPolicyName(),
                                                subscriptionData.getDeploymentPolicyName(), repository);

    // publishing to bam
    CartridgeSubscriptionDataPublisher.publish(
        subscriptionData.getTenantId(),
        subscriptionData.getTenantAdminUsername(),
        subscriptionData.getCartridgeAlias(),
        subscriptionData.getCartridgeType(),
        subscriptionData.getRepositoryURL(),
        cartridgeInfo.getMultiTenant(),
        subscriptionData.getAutoscalingPolicyName(),
        subscriptionData.getDeploymentPolicyName(),
        cartridgeSubscription.getCluster().getClusterDomain(),
        cartridgeSubscription.getHostName(),
        cartridgeSubscription.getMappedDomain(), "Subscribed");
       
        // Add whether the subscription is enabled upstream git commits
        if(cartridgeSubscription.getPayloadData() != null) {
            cartridgeSubscription.getPayloadData().add(CartridgeConstants.COMMIT_ENABLED, String.valueOf(subscriptionData.isCommitsEnabled()));
        }
       

        log.info("Tenant [" + subscriptionData.getTenantId() + "] with username [" + subscriptionData.getTenantAdminUsername() +
                " subscribed to " + "] Cartridge with Alias " + subscriptionData.getCartridgeAlias() + ", Cartridge Type: " +
                subscriptionData.getCartridgeType() + ", Repo URL: " + subscriptionData.getRepositoryURL() + ", Autoscale Policy: " +
                subscriptionData.getAutoscalingPolicyName() + ", Deployment Policy: " + subscriptionData.getDeploymentPolicyName());

        return cartridgeSubscription;
    }

    /**
     * Registers the cartridge subscription for the given CartridgeSubscriptionInfo object
     *
     * @param cartridgeSubscription CartridgeSubscription subscription
     *
     * @return SubscriptionInfo object populated with relevant information
     * @throws ADCException
     * @throws UnregisteredCartridgeException
     */
    private SubscriptionInfo registerCartridgeSubscription(CartridgeSubscription cartridgeSubscription, Properties properties)
            throws ADCException, UnregisteredCartridgeException {

        CartridgeSubscriptionInfo cartridgeSubscriptionInfo = cartridgeSubscription.registerSubscription(properties);

        //set status as 'SUBSCRIBED'
        cartridgeSubscription.setSubscriptionStatus(CartridgeConstants.SUBSCRIBED);

        try {
            new DataInsertionAndRetrievalManager().cacheAndPersistSubcription(cartridgeSubscription);

        } catch (PersistenceManagerException e) {
            String errorMsg = "Error saving subscription for tenant " +
                    cartridgeSubscription.getSubscriber().getTenantDomain() + ", alias " + cartridgeSubscription.getType();
            log.error(errorMsg);
            throw new ADCException(errorMsg, e);
        }

        log.info("Successful Subscription: " + cartridgeSubscription.toString());

        // Publish tenant subscribed event to message broker
        CartridgeSubscriptionUtils.publishTenantSubscribedEvent(cartridgeSubscription.getSubscriber().getTenantId(),
                cartridgeSubscription.getCartridgeInfo().getType());

        return ApplicationManagementUtil.
                createSubscriptionResponse(cartridgeSubscriptionInfo, cartridgeSubscription.getRepository());
    }

    public Collection<CartridgeSubscription> getCartridgeSubscriptions (int tenantId, String type) throws ADCException {

        if (type == null || type.isEmpty()) {
            return new DataInsertionAndRetrievalManager().getCartridgeSubscriptions(tenantId);

        } else {
            return new DataInsertionAndRetrievalManager().getCartridgeSubscriptions(tenantId, type);
        }
    }

    public CartridgeSubscription getCartridgeSubscription (int tenantId, String subscriptionAlias) {

        return new DataInsertionAndRetrievalManager().getCartridgeSubscription(tenantId, subscriptionAlias);
    }

    /**
     * Unsubscribe from a Cartridge
     *
     * @param tenantDomain Tenant's domain
     * @param alias Alias given at subscription time
     * @throws ADCException
     * @throws NotSubscribedException
     */
    public void unsubscribeFromCartridge (String tenantDomain, String alias)
            throws ADCException, NotSubscribedException {

        DataInsertionAndRetrievalManager dataInsertionAndRetrievalManager = new DataInsertionAndRetrievalManager();

        CartridgeSubscription cartridgeSubscription = dataInsertionAndRetrievalManager.getCartridgeSubscription(CarbonContext.getThreadLocalCarbonContext().getTenantId(), alias);
        if(cartridgeSubscription != null) {
            cartridgeSubscription.removeSubscription();

            // Remove the information from Topology Model
            // Not needed now. TopologyModel is now changed so that information is taken from subscriptions
            //TopologyClusterInformationModel.getInstance().removeCluster(cartridgeSubscription.getSubscriber().getTenantId(),
            //        cartridgeSubscription.getType(), cartridgeSubscription.getAlias());

            // remove subscription
            try {
                dataInsertionAndRetrievalManager.removeSubscription(cartridgeSubscription.getSubscriber().getTenantId(), alias);

            } catch (PersistenceManagerException e) {
                String errorMsg = "Error removing subscription for tenant " + tenantDomain + ", alias " + cartridgeSubscription.getAlias();
                log.error(errorMsg);
                throw new ADCException(errorMsg, e);
            }

            // Publish tenant un-subscribed event to message broker
            CartridgeSubscriptionUtils.publishTenantUnSubscribedEvent(cartridgeSubscription.getSubscriber().getTenantId(),
                    cartridgeSubscription.getCartridgeInfo().getType());
           
      // publishing to the unsubscribed event details to bam
      CartridgeSubscriptionDataPublisher.publish(cartridgeSubscription
          .getSubscriber().getTenantId(), cartridgeSubscription
          .getSubscriber().getAdminUserName(), cartridgeSubscription
          .getAlias(), cartridgeSubscription.getType(),
          "",
          cartridgeSubscription.getCartridgeInfo().getMultiTenant(),
          cartridgeSubscription.getAutoscalingPolicyName(),
          cartridgeSubscription.getDeploymentPolicyName(),
          cartridgeSubscription.getCluster().getClusterDomain(),
          cartridgeSubscription.getHostName(), cartridgeSubscription
              .getMappedDomain(), "unsubscribed");
        }
        else {
            String errorMsg = "No cartridge subscription found with [alias] " + alias + " for [tenant] " + tenantDomain;
            log.error(errorMsg);
            throw new NotSubscribedException(errorMsg, alias);
        }
    }

    private Properties getPersistenceMappingProperties (PersistenceContext persistenceCtxt, CartridgeInfo cartridgeInfo) throws ADCException {

        if (!cartridgeInfo.isPersistenceSpecified()) {
            // Persistence Mapping not supported in the cartridge definition - error
            String errorMsg = "Persistence Mapping not supported by the cartridge type " + cartridgeInfo.getType();
            log.error(errorMsg);
            throw new ADCException(errorMsg);
        }

        Properties persistenceMappingProperties = new Properties();
        persistenceMappingProperties.setProperties(new Property[]{persistenceCtxt.getPersistanceRequiredProperty(), persistenceCtxt.getSizeProperty(),
                persistenceCtxt.getDeleteOnTerminationProperty()});

        return persistenceMappingProperties;
    }
   
    /**
     *
     * Returns a collection of Cartridge subscriptions for a particular tenant and a cartridge type
     *
     * @param tenantId
     * @param cartridgeType
     * @return
     */
    public Collection<CartridgeSubscription> isCartridgeSubscribed(int tenantId, String cartridgeType) {
     
      DataInsertionAndRetrievalManager dataInsertionAndRetrievalManager = new DataInsertionAndRetrievalManager();
        return dataInsertionAndRetrievalManager.getCartridgeSubscriptions(tenantId, cartridgeType);
    }
}
TOP

Related Classes of org.apache.stratos.manager.manager.CartridgeSubscriptionManager

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.