From 74b9b22e92d7761014cea05d60e91d85f8eda697 Mon Sep 17 00:00:00 2001 From: Shiro Date: Fri, 23 Jan 2015 17:14:49 +0530 Subject: [PATCH 1/4] Added functionality to do validation before cartridge and cartridgeGroup removal --- .../client/StratosManagerServiceClient.java | 111 ++++ .../context/StratosManagerContext.java | 328 ++++++++++- .../internal/ServiceReferenceHolder.java | 11 + .../StratosManagerServiceComponent.java | 22 +- .../services/StratosManagerService.java | 82 +++ .../impl/StratosManagerServiceImpl.java | 139 ++++- .../rest/endpoint/api/StratosApiV41Utils.java | 145 ++++- .../main/resources/StratosManagerService.wsdl | 517 +++++++++++++++--- 8 files changed, 1247 insertions(+), 108 deletions(-) diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java index 8aefa15b67..a62084338c 100644 --- a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java +++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java @@ -33,6 +33,7 @@ import org.apache.stratos.manager.service.stub.domain.application.signup.DomainMapping; import java.rmi.RemoteException; +import java.util.List; /** * Stratos manager service client. @@ -155,4 +156,114 @@ public void removeDomainMapping(String applicationId, int tenantId, String domai public DomainMapping[] getDomainMappings(String applicationId, int tenantId) throws RemoteException, StratosManagerServiceDomainMappingExceptionException { return stub.getDomainMappings(applicationId, tenantId); } + + /** + * Adds the used cartridges in cartridge groups to cache. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) throws RemoteException { + stub.addUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + } + + /** + * Removes the used cartridges in cartridge groups from cache. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) throws RemoteException { + stub.removeUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + } + + /** + * Adds the used cartridges in applications to cache. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) throws RemoteException { + stub.addUsedCartridgesInApplications(applicationName, cartridgeNames); + } + + /** + * Removes the used cartridges in applications from cache. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) throws RemoteException { + stub.removeUsedCartridgesInApplications(applicationName, cartridgeNames); + } + + /** + * Validates whether a cartridge can be removed. + * + * @param cartridgeName the cartridge name + * @return true, if successful + * @throws RemoteException the remote exception + */ + public boolean canCartridgeBeRemoved(String cartridgeName) throws RemoteException { + return stub.canCartridgeBeRemoved(cartridgeName); + } + + /** + * Adds the used cartridge groups in cartridge sub groups to cache. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) throws RemoteException { + stub.addUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + } + + /** + * Removes the used cartridge groups in cartridge sub groups from cache. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) throws RemoteException { + stub.removeUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + } + + /** + * Adds the used cartridge groups in applications to cache. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) throws RemoteException { + stub.addUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + } + + /** + * Removes the used cartridge groups in applications from cache. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) throws RemoteException { + stub.removeUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + } + + /** + * Validates whether a cartridge group can be removed. + * + * @param cartridgeGroupName the cartridge group name + * @return true, if successful + * @throws RemoteException the remote exception + */ + public boolean canCartirdgeGroupBeRemoved(String cartridgeGroupName) throws RemoteException { + return stub.canCartirdgeGroupBeRemoved(cartridgeGroupName); + } } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java index 55da89012f..7c6eac5a9c 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java @@ -19,16 +19,70 @@ package org.apache.stratos.manager.context; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.Lock; + import org.apache.axis2.engine.AxisConfiguration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.manager.registry.RegistryManager; +import org.apache.stratos.common.clustering.DistributedObjectProvider; import org.apache.stratos.manager.internal.ServiceReferenceHolder; +import org.wso2.carbon.registry.core.exceptions.RegistryException; /** * Stratos manager context. */ -public class StratosManagerContext { +public class StratosManagerContext implements Serializable { - private static volatile StratosManagerContext instance; + + private static volatile StratosManagerContext instance; + + private static final String SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP = "SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP"; + private static final String SM_CARTRIDGE_TYPE_TO_APPLICATIONS_MAP = "SM_CARTRIDGE_TYPE_TO_APPLICATIONS_MAP"; + private static final String SM_CARTRIDGE_GROUP_TO_CARTIDGE_GROUPS_MAP = "SM_CARTRIDGE_GROUP_TO_CARTIDGE_GROUPS_MAP"; + private static final String SM_CARTRIDGE_GROUP_TO_APPLICATIONS_MAP = "SM_CARTRIDGE_GROUP_TO_APPLICATIONS_MAP"; + + private static final String SM_CARTRIDGES_CARTRIDGEGROUPS_WRITE_LOCK = "SM_CARTRIDGES_CARTRIDGEGROUPS_WRITE_LOCK"; + private static final String SM_CARTRIDGES_APPLICATIONS_WRITE_LOCK = "SM_CARTRIDGES_APPLICATIONS_WRITE_LOCK"; + private static final String SM_CARTRIDGEGROUPS_CARTRIDGESUBGROUPS_WRITE_LOCK = "SM_CARTRIDGEGROUPS_CARTRIDGESUBGROUPS_WRITE_LOCK"; + private static final String SM_CARTRIDGEGROUPS_APPLICATIONS_WRITE_LOCK = "SM_CARTRIDGEGROUPS_APPLICATIONS_WRITE_LOCK"; + + public static final String DATA_RESOURCE = "/stratos.manager/data"; + + private final transient DistributedObjectProvider distributedObjectProvider; + private static final Log log = LogFactory.getLog(StratosManagerContext.class); + + /** + * Key - cartridge type + * Value - list of cartridgeGroupNames + */ + private Map> cartridgeTypeToCartridgeGroupsMap; + + /** + * Key - cartridge type + * Value - list of ApplicationNames + */ + private Map> cartridgeTypeToApplicationsMap; + + /** + * Key - cartridge group name + * Value - list of cartridgeGroupNames + */ + private Map> cartridgeGroupToCartridgeSubGroupsMap; + + /** + * Key - cartridge group name + * Value - list of ApplicationNames + */ + private Map> cartridgeGroupToApplicationsMap; + private boolean clustered; private boolean coordinator; @@ -49,6 +103,18 @@ private StratosManagerContext(){ if ((axisConfiguration != null) && (axisConfiguration.getClusteringAgent() != null)) { clustered = true; } + + // Initialize distributed object provider + distributedObjectProvider = ServiceReferenceHolder.getInstance().getDistributedObjectProvider(); + + // Get maps from distributed object provider + cartridgeTypeToCartridgeGroupsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP); + cartridgeTypeToApplicationsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_TYPE_TO_APPLICATIONS_MAP); + cartridgeGroupToCartridgeSubGroupsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_GROUP_TO_CARTIDGE_GROUPS_MAP); + cartridgeGroupToApplicationsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_GROUP_TO_APPLICATIONS_MAP); + + // Update context from the registry + updateContextFromRegistry(); } public void setCoordinator(boolean coordinator) { @@ -62,4 +128,262 @@ public boolean isCoordinator() { public boolean isClustered() { return clustered; } + + private Lock acquireWriteLock(String object) { + return distributedObjectProvider.acquireLock(object); + } + + public void releaseWriteLock(Lock lock) { + distributedObjectProvider.releaseLock(lock); + } + + public Lock acquireCartridgesCartridgeGroupsWriteLock() { + return acquireWriteLock(SM_CARTRIDGES_CARTRIDGEGROUPS_WRITE_LOCK); + } + + public Lock acquireCartridgesApplicationsWriteLock() { + return acquireWriteLock(SM_CARTRIDGES_APPLICATIONS_WRITE_LOCK); + } + + public Lock acquireCartridgeGroupsCartridgeSubGroupsWriteLock() { + return acquireWriteLock(SM_CARTRIDGEGROUPS_CARTRIDGESUBGROUPS_WRITE_LOCK); + } + + public Lock acquireCartridgeGroupsApplicationsWriteLock() { + return acquireWriteLock(SM_CARTRIDGEGROUPS_APPLICATIONS_WRITE_LOCK); + } + + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set cartridgeGroupNames = null; + if(cartridgeTypeToCartridgeGroupsMap.containsKey(cartridgeName)) { + cartridgeGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeName); + } else { + cartridgeGroupNames = new HashSet(); + cartridgeTypeToCartridgeGroupsMap.put(cartridgeName, cartridgeGroupNames); + } + cartridgeGroupNames.add(cartridgeGroupName); + } + } + + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set cartridgeGroupNames = null; + if(cartridgeTypeToCartridgeGroupsMap.containsKey(cartridgeName)) { + cartridgeGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeName); + // Remove current cartridge group name + cartridgeGroupNames.remove(cartridgeGroupName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (cartridgeGroupNames.isEmpty()) { + cartridgeGroupNames = null; + cartridgeTypeToCartridgeGroupsMap.remove(cartridgeName); + } + } + } + } + + public boolean isCartridgeIncludedInCartridgeGroups(String cartridgeName) { + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + if(!cartridgeTypeToApplicationsMap.get(cartridgeName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set applicationNames = null; + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + applicationNames = cartridgeTypeToApplicationsMap.get(cartridgeName); + } else { + applicationNames = new HashSet(); + cartridgeTypeToApplicationsMap.put(cartridgeName, applicationNames); + } + applicationNames.add(applicationName); + } + } + + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set applicationNames = null; + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + applicationNames = cartridgeTypeToApplicationsMap.get(cartridgeName); + // Remove current application name + applicationNames.remove(applicationName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (applicationNames.isEmpty()) { + applicationNames = null; + cartridgeTypeToApplicationsMap.remove(cartridgeName); + } + } + } + } + + public boolean isCartridgeIncludedInApplications(String cartridgeName) { + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + if(!cartridgeTypeToApplicationsMap.get(cartridgeName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set cartridgeSubGroupNames = null; + if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { + cartridgeSubGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeGroupName); + } else { + cartridgeSubGroupNames = new HashSet(); + cartridgeGroupToCartridgeSubGroupsMap.put(cartridgeSubGroupName, cartridgeSubGroupNames); + } + cartridgeSubGroupNames.add(cartridgeGroupName); + } + } + + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set cartridgeSubGroupNames = null; + if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { + cartridgeSubGroupNames = cartridgeGroupToCartridgeSubGroupsMap.get(cartridgeGroupName); + // Remove current cartridge group name + cartridgeSubGroupNames.remove(cartridgeGroupName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (cartridgeSubGroupNames.isEmpty()) { + cartridgeSubGroupNames = null; + cartridgeGroupToCartridgeSubGroupsMap.remove(cartridgeGroupName); + } + } + } + } + + public boolean isCartridgeGroupIncludedInCartridgeSubGroups(String cartridgeGroupName) { + if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { + if(!cartridgeGroupToCartridgeSubGroupsMap.get(cartridgeGroupName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set applicationNames = null; + if(cartridgeGroupToApplicationsMap.containsKey(cartridgeGroupName)) { + applicationNames = cartridgeGroupToApplicationsMap.get(cartridgeGroupName); + } else { + applicationNames = new HashSet(); + cartridgeGroupToApplicationsMap.put(cartridgeGroupName, applicationNames); + } + applicationNames.add(applicationName); + } + } + + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set applicationNames = null; + if(cartridgeGroupToApplicationsMap.containsKey(cartridgeGroupName)) { + applicationNames = cartridgeGroupToApplicationsMap.get(cartridgeGroupName); + // Remove current application name + applicationNames.remove(applicationName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (applicationNames.isEmpty()) { + applicationNames = null; + cartridgeGroupToApplicationsMap.remove(cartridgeGroupName); + } + } + } + } + + public boolean isCartridgeGroupIncludedInApplications(String cartridgeGroupName) { + if(cartridgeGroupToApplicationsMap.containsKey(cartridgeGroupName)) { + if(!cartridgeGroupToApplicationsMap.get(cartridgeGroupName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + private void updateContextFromRegistry() { + if ((!isClustered()) || (isCoordinator())) { + try { + Object dataObj = RegistryManager.getInstance().read(DATA_RESOURCE); + if (dataObj != null) { + if (dataObj instanceof StratosManagerContext) { + StratosManagerContext serializedObj = (StratosManagerContext) dataObj; + + copyMap(serializedObj.cartridgeTypeToCartridgeGroupsMap, cartridgeTypeToCartridgeGroupsMap); + copyMap(serializedObj.cartridgeTypeToApplicationsMap, cartridgeTypeToApplicationsMap); + copyMap(serializedObj.cartridgeGroupToCartridgeSubGroupsMap, cartridgeGroupToCartridgeSubGroupsMap); + copyMap(serializedObj.cartridgeGroupToApplicationsMap, cartridgeGroupToApplicationsMap); + + if (log.isDebugEnabled()) { + log.debug("Stratos Manager context is read from the registry"); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Stratos Manager context could not be found in the registry"); + } + } + } + } catch (Exception e) { + String msg = "Unable to read Stratos Manager context from the registry. " + + "Hence, any historical data will not be reflected"; + log.warn(msg, e); + } + } + } + + private void copyMap(Map sourceMap, Map destinationMap) { + for(Object key : sourceMap.keySet()) { + destinationMap.put(key, sourceMap.get(key)); + } + } + + public void persist() { + if ((!isClustered()) || (isCoordinator())) { + try { + RegistryManager.getInstance().persist(DATA_RESOURCE, this); + } catch (RegistryException e) { + log.error("Could not persist cloud controller context in registry", e); + } + } + } } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java index 85e9a0b43c..4c3d9a5c17 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java @@ -22,6 +22,7 @@ import com.hazelcast.core.HazelcastInstance; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.engine.AxisConfiguration; +import org.apache.stratos.common.clustering.DistributedObjectProvider; import org.wso2.carbon.ntask.core.service.TaskService; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; @@ -40,6 +41,7 @@ public class ServiceReferenceHolder { private TaskService taskService; private HazelcastInstance hazelcastInstance; private AxisConfiguration axisConfiguration; + private DistributedObjectProvider distributedObjectProvider; private ServiceReferenceHolder() { } @@ -111,4 +113,13 @@ public void setAxisConfiguration(AxisConfiguration axisConfiguration) { public AxisConfiguration getAxisConfiguration() { return axisConfiguration; } + + public void setDistributedObjectProvider(DistributedObjectProvider distributedObjectProvider) { + this.distributedObjectProvider = distributedObjectProvider; + } + + public DistributedObjectProvider getDistributedObjectProvider() { + return distributedObjectProvider; + } + } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java index 9eeded2046..e07f6f0837 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java @@ -18,19 +18,21 @@ */ package org.apache.stratos.manager.internal; -import com.hazelcast.core.HazelcastInstance; +import java.util.concurrent.ExecutorService; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.stratos.common.clustering.DistributedObjectProvider; import org.apache.stratos.common.threading.StratosThreadPool; import org.apache.stratos.manager.context.StratosManagerContext; +import org.apache.stratos.manager.messaging.publisher.TenantEventPublisher; import org.apache.stratos.manager.messaging.publisher.synchronizer.ApplicationSignUpSynchronizerTask; +import org.apache.stratos.manager.messaging.publisher.synchronizer.SynchronizerTaskScheduler; import org.apache.stratos.manager.messaging.publisher.synchronizer.TenantSynzhronizerTask; import org.apache.stratos.manager.messaging.receiver.StratosManagerApplicationEventReceiver; import org.apache.stratos.manager.messaging.receiver.StratosManagerInstanceStatusEventReceiver; -import org.apache.stratos.manager.user.management.TenantUserRoleManager; -import org.apache.stratos.manager.messaging.publisher.TenantEventPublisher; -import org.apache.stratos.manager.messaging.publisher.synchronizer.SynchronizerTaskScheduler; import org.apache.stratos.manager.messaging.receiver.StratosManagerTopologyEventReceiver; +import org.apache.stratos.manager.user.management.TenantUserRoleManager; import org.apache.stratos.manager.user.management.exception.UserManagerException; import org.apache.stratos.manager.utils.CartridgeConfigFileReader; import org.apache.stratos.manager.utils.StratosManagerConstants; @@ -46,7 +48,7 @@ import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.utils.ConfigurationContextService; -import java.util.concurrent.ExecutorService; +import com.hazelcast.core.HazelcastInstance; /** * @scr.component name="org.wso2.carbon.hosting.mgt.internal.StratosManagerServiceComponent" @@ -69,6 +71,8 @@ * @scr.reference name="ntask.component" interface="org.wso2.carbon.ntask.core.service.TaskService" * cardinality="1..1" policy="dynamic" bind="setTaskService" * unbind="unsetTaskService" + * @scr.reference name="distributedObjectProvider" interface="org.apache.stratos.common.clustering.DistributedObjectProvider" + * cardinality="1..1" policy="dynamic" bind="setDistributedObjectProvider" unbind="unsetDistributedObjectProvider" */ public class StratosManagerServiceComponent { @@ -277,6 +281,14 @@ protected void unsetTaskService(TaskService taskService) { } ServiceReferenceHolder.getInstance().setTaskService(null); } + + protected void setDistributedObjectProvider(DistributedObjectProvider distributedObjectProvider) { + ServiceReferenceHolder.getInstance().setDistributedObjectProvider(distributedObjectProvider); + } + + protected void unsetDistributedObjectProvider(DistributedObjectProvider distributedObjectProvider) { + ServiceReferenceHolder.getInstance().setDistributedObjectProvider(null); + } protected void deactivate(ComponentContext context) { // Close event publisher connections to message broker diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java index d9ba8667f7..f884a01d9d 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java @@ -19,6 +19,8 @@ package org.apache.stratos.manager.services; +import java.util.List; + import org.apache.stratos.messaging.domain.application.signup.ApplicationSignUp; import org.apache.stratos.manager.exception.ApplicationSignUpException; import org.apache.stratos.manager.exception.ArtifactDistributionCoordinatorException; @@ -98,4 +100,84 @@ public void notifyArtifactUpdatedEventForSignUp(String applicationId, int tenant * @throws DomainMappingException */ public void removeDomainMapping(String applicationId, int tenantId, String domainName) throws DomainMappingException; + + /** + * Adds the used cartridges in cartridge groups to cache structure. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + */ + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames); + + /** + * Removes the used cartridges in cartridge groups from cache structure. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + */ + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames); + + /** + * Adds the used cartridges in applications to cache structure. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + */ + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames); + + /** + * Removes the used cartridges in applications from cache structure. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + */ + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames); + + /** + * Verifies whether a cartridge can be removed. + * + * @param cartridgeName the cartridge name + * @return true, if successful + */ + public boolean canCartridgeBeRemoved(String cartridgeName); + + /** + * Adds the used cartridge groups in cartridge sub groups to cache structure. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + */ + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames); + + /** + * Removes the used cartridge groups in cartridge sub groups from cache structure. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + */ + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames); + + /** + * Adds the used cartridge groups in applications to cache structure. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + */ + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames); + + /** + * Removes the used cartridge groups in applications from cache structure. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + */ + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames); + + /** + * Verifies whether a cartridge group can be removed. + * + * @param cartridgeGroupName the cartridge group name + * @return true, if successful + */ + public boolean canCartirdgeGroupBeRemoved(String cartridgeGroupName); } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java index 45a8a0b9f0..d269f0ecc4 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java @@ -19,16 +19,17 @@ package org.apache.stratos.manager.services.impl; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import java.util.concurrent.locks.Lock; + import org.apache.stratos.manager.components.ApplicationSignUpHandler; import org.apache.stratos.manager.components.ArtifactDistributionCoordinator; import org.apache.stratos.manager.components.DomainMappingHandler; -import org.apache.stratos.messaging.domain.application.signup.ApplicationSignUp; +import org.apache.stratos.manager.context.StratosManagerContext; import org.apache.stratos.manager.exception.ApplicationSignUpException; import org.apache.stratos.manager.exception.ArtifactDistributionCoordinatorException; import org.apache.stratos.manager.exception.DomainMappingException; import org.apache.stratos.manager.services.StratosManagerService; +import org.apache.stratos.messaging.domain.application.signup.ApplicationSignUp; import org.apache.stratos.messaging.domain.application.signup.DomainMapping; /** @@ -36,8 +37,6 @@ */ public class StratosManagerServiceImpl implements StratosManagerService { - private static final Log log = LogFactory.getLog(StratosManagerServiceImpl.class); - private ApplicationSignUpHandler signUpHandler; private ArtifactDistributionCoordinator artifactDistributionCoordinator; private DomainMappingHandler domainMappingHandler; @@ -92,4 +91,134 @@ public DomainMapping[] getDomainMappings(String applicationId, int tenantId) thr public void removeDomainMapping(String applicationId, int tenantId, String domainName) throws DomainMappingException { domainMappingHandler.removeDomainMapping(applicationId, tenantId, domainName); } + + @Override + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesCartridgeGroupsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesCartridgeGroupsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesApplicationsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgesInApplications(applicationName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesApplicationsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgesInApplications(applicationName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public boolean canCartridgeBeRemoved(String cartridgeName) { + if (StratosManagerContext.getInstance().isCartridgeIncludedInCartridgeGroups(cartridgeName) || + StratosManagerContext.getInstance().isCartridgeIncludedInApplications(cartridgeName)) { + return false; + } + return true; + } + + @Override + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsCartridgeSubGroupsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsCartridgeSubGroupsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsApplicationsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsApplicationsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public boolean canCartirdgeGroupBeRemoved(String cartridgeGroupName) { + if(StratosManagerContext.getInstance().isCartridgeGroupIncludedInCartridgeSubGroups(cartridgeGroupName) || + StratosManagerContext.getInstance().isCartridgeGroupIncludedInApplications(cartridgeGroupName)) { + return false; + } + return true; + } } diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java index abcddacac2..24b961d1f0 100644 --- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java +++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java @@ -37,11 +37,13 @@ import org.apache.stratos.common.beans.PropertyBean; import org.apache.stratos.common.beans.application.ApplicationBean; import org.apache.stratos.common.beans.application.GroupBean; +import org.apache.stratos.common.beans.application.GroupReferenceBean; import org.apache.stratos.common.beans.application.domain.mapping.ApplicationDomainMappingsBean; import org.apache.stratos.common.beans.application.domain.mapping.DomainMappingBean; import org.apache.stratos.common.beans.application.signup.ApplicationSignUpBean; import org.apache.stratos.common.beans.artifact.repository.GitNotificationPayloadBean; import org.apache.stratos.common.beans.cartridge.CartridgeBean; +import org.apache.stratos.common.beans.cartridge.CartridgeReferenceBean; import org.apache.stratos.common.beans.cartridge.PersistenceBean; import org.apache.stratos.common.beans.cartridge.VolumeBean; import org.apache.stratos.common.beans.kubernetes.KubernetesClusterBean; @@ -123,10 +125,19 @@ public static void removeCartridge(String cartridgeType) throws RestAPIException log.debug(String.format("Removing cartridge: [cartridge-type] %s ", cartridgeType)); } - CloudControllerServiceClient cloudControllerServiceClient = CloudControllerServiceClient.getInstance(); + CloudControllerServiceClient cloudControllerServiceClient = getCloudControllerServiceClient(); if(cloudControllerServiceClient.getCartridgeInfo(cartridgeType) == null) { throw new RuntimeException("Cartridge not found: [cartridge-type] " + cartridgeType); } + + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + // Validate whether cartridge can be removed + if(!smServiceClient.canCartridgeBeRemoved(cartridgeType)) { + String message = "Cannot remove cartridge : [cartridge-type] " + cartridgeType + " since it is used in another cartridge group or an application"; + log.error(message); + throw new RestAPIException(message); + } cloudControllerServiceClient.removeCartridge(cartridgeType); if(log.isInfoEnabled()) { @@ -456,6 +467,17 @@ private static AutoscalerServiceClient getAutoscalerServiceClient() throws RestA throw new RestAPIException(errorMsg, axisFault); } } + + private static StratosManagerServiceClient getStratosManagerServiceClient() throws RestAPIException { + try { + return StratosManagerServiceClient.getInstance(); + } catch (AxisFault axisFault) { + String errorMsg = "Error while getting StratosManagerServiceClient instance to connect to the " + + "Stratos Manager. Cause: " + axisFault.getMessage(); + log.error(errorMsg, axisFault); + throw new RestAPIException(errorMsg, axisFault); + } + } // Util methods for Autoscaling policies @@ -596,15 +618,18 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest if (serviceGroupDefinition == null) { throw new RuntimeException("Service Group definition is null"); } + + List cartridgeTypes = null; + List groupNames = null; // if any cartridges are specified in the group, they should be already deployed if (serviceGroupDefinition.getCartridges() != null) { - + if (log.isDebugEnabled()) { log.debug("checking cartridges in cartridge group " + serviceGroupDefinition.getName()); } - List cartridgeTypes = serviceGroupDefinition.getCartridges(); + cartridgeTypes = serviceGroupDefinition.getCartridges(); Set duplicates = findDuplicates(cartridgeTypes); if (duplicates.size() > 0) { @@ -618,13 +643,7 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest throw new RestAPIException("Invalid Service Group definition, duplicate cartridges defined:" + buf.toString()); } - CloudControllerServiceClient ccServiceClient = null; - - try { - ccServiceClient = CloudControllerServiceClient.getInstance(); - } catch (AxisFault axisFault) { - throw new RestAPIException(axisFault); - } + CloudControllerServiceClient ccServiceClient = getCloudControllerServiceClient(); for (String cartridgeType : cartridgeTypes) { try { @@ -648,7 +667,7 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest } List groupDefinitions = serviceGroupDefinition.getGroups(); - List groupNames = new ArrayList(); + groupNames = new ArrayList(); for (GroupBean groupList : groupDefinitions) { groupNames.add(groupList.getName()); } @@ -664,13 +683,23 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest log.debug("duplicate subGroups defined: " + buf.toString()); } throw new RestAPIException("Invalid Service Group definition, duplicate subGroups defined:" + buf.toString()); - } + } } ServiceGroup serviceGroup = ObjectConverter.convertServiceGroupDefinitionToASStubServiceGroup(serviceGroupDefinition); - AutoscalerServiceClient asServiceClient = AutoscalerServiceClient.getInstance(); + AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); asServiceClient.addServiceGroup(serviceGroup); + + // Add cartridge group elements to SM cache - done after service group has been added + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + if(cartridgeTypes != null) { + smServiceClient.addUsedCartridgesInCartridgeGroups(serviceGroupDefinition.getName(), (String[]) cartridgeTypes.toArray()); + } + if(groupNames != null) { + smServiceClient.addUsedCartridgeGroupsInCartridgeSubGroups(serviceGroupDefinition.getName(), (String[]) groupNames.toArray()); + } + } catch (Exception e) { String message = "Could not add cartridge group"; log.error(message, e); @@ -750,9 +779,35 @@ public static void removeServiceGroup(String name) throws RestAPIException { if (log.isDebugEnabled()) { log.debug("Removing cartridge group: [name] " + name); } - - AutoscalerServiceClient autoscalerServiceClient = AutoscalerServiceClient.getInstance(); - autoscalerServiceClient.undeployServiceGroupDefinition(name); + + AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + // Validate whether cartridge group can be removed + if(!smServiceClient.canCartirdgeGroupBeRemoved(name)) { + String message = "Cannot remove cartridge group: [group-name] " + name + " since it is used in another cartridge group or an application"; + log.error(message); + throw new RestAPIException(message); + } + + ServiceGroup serviceGroup = asServiceClient.getServiceGroup(name); + + asServiceClient.undeployServiceGroupDefinition(name); + + // Remove the dependent cartridges and cartridge groups from Stratos Manager cache - done after service group has been removed + if (serviceGroup.getCartridges() != null) { + String[] cartridgeNames = serviceGroup.getCartridges(); + smServiceClient.removeUsedCartridgesInCartridgeGroups(name, cartridgeNames); + } + + if (serviceGroup.getGroups() != null) { + ServiceGroup[] cartridgeGroups = serviceGroup.getGroups(); + Set cartridgeGroupNames = new HashSet(); + for(ServiceGroup cartridgeGroup : cartridgeGroups) { + cartridgeGroupNames.add(cartridgeGroup.getName()); + } + smServiceClient.removeUsedCartridgeGroupsInCartridgeSubGroups(name, (String[]) cartridgeGroupNames.toArray()); + } } catch (Exception e) { throw new RestAPIException(e); @@ -803,6 +858,33 @@ public static void addApplication(ApplicationBean appDefinition, ConfigurationCo try { AutoscalerServiceClient.getInstance().addApplication(applicationContext); + + // Add application elements to SM cache - done after application has been added + Set cartridgeNames; + Set cartridgeGroupNames; + + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + List cartridges = appDefinition.getComponents().getCartridges(); + if(cartridges != null) { + cartridgeNames = new HashSet(); + for(CartridgeReferenceBean cartridge : cartridges) { + cartridgeNames.add(cartridge.getType()); + } + + smServiceClient.addUsedCartridgesInApplications(appDefinition.getApplicationId(), (String[]) cartridgeNames.toArray()); + } + + List cartridgeGroups = appDefinition.getComponents().getGroups(); + if(cartridgeGroups != null) { + cartridgeGroupNames = new HashSet(); + for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { + cartridgeGroupNames.add(cartridgeGroup.getName()); + } + + smServiceClient.addUsedCartridgeGroupsInApplications(appDefinition.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + } + } catch (AutoScalerServiceApplicationDefinitionExceptionException e) { throw new RestAPIException(e); } catch (RemoteException e) { @@ -861,7 +943,36 @@ public static void deployApplication(String applicationId, DeploymentPolicyBean public static void removeApplication(String applicationId) throws RestAPIException { try { - AutoscalerServiceClient.getInstance().deleteApplication(applicationId); + AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); + + ApplicationBean application = ObjectConverter.convertStubApplicationContextToApplicationDefinition(asServiceClient.getApplication(applicationId)); + asServiceClient.deleteApplication(applicationId); + + // Remove application elements in SM cache - done after deleting + Set cartridgeNames; + Set cartridgeGroupNames; + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + List cartridges = application.getComponents().getCartridges(); + if(cartridges != null) { + cartridgeNames = new HashSet(); + for(CartridgeReferenceBean cartridge : cartridges) { + cartridgeNames.add(cartridge.getType()); + } + + smServiceClient.removeUsedCartridgesInApplications(application.getApplicationId(), (String[]) cartridgeNames.toArray()); + } + + List cartridgeGroups = application.getComponents().getGroups(); + if(cartridgeGroups != null) { + cartridgeGroupNames = new HashSet(); + for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { + cartridgeGroupNames.add(cartridgeGroup.getName()); + } + + smServiceClient.removeUsedCartridgeGroupsInApplications(application.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + } + } catch (RemoteException e) { String message = "Could not delete application: [application-id] " + applicationId; log.error(message, e); diff --git a/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl b/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl index c621b78c06..571260ddfd 100644 --- a/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl +++ b/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl @@ -1,6 +1,17 @@ - + + + + + + + + + + + + @@ -20,75 +31,92 @@ - - - - - - - - - - - + - + + - + - + + - + - - + + - + + + + + + + + + + + + + + + + + - + - + - + + - + - + - + - + + + + + + + + + @@ -107,50 +135,115 @@ - + + + + + + + + + + + + + + + - - + - + - + - + - + - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -158,14 +251,14 @@ - - + + - - + + - - + + @@ -176,15 +269,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -194,6 +317,12 @@ + + + + + + @@ -204,24 +333,52 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -234,6 +391,10 @@ + + + + @@ -258,6 +419,21 @@ + + + + + + + + + + + + + + + @@ -279,6 +455,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -288,6 +500,12 @@ + + + + + + @@ -297,41 +515,50 @@ - - + + - - + + - - + + - - + + - - + + + + + + + + - - + + + + + @@ -351,6 +578,21 @@ + + + + + + + + + + + + + + + @@ -372,6 +614,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -381,6 +659,12 @@ + + + + + + @@ -390,41 +674,50 @@ - - + + - - + + - - + + - - + + - - + + + + + + + + - - + + + + + @@ -441,6 +734,21 @@ + + + + + + + + + + + + + + + @@ -456,20 +764,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + @@ -480,8 +824,14 @@ - - + + + + + + + + @@ -495,6 +845,15 @@ + + + + + + + + + From b5075fb64b68d94f9b8d634750208b2435a8e7cb Mon Sep 17 00:00:00 2001 From: Shiro Date: Fri, 23 Jan 2015 20:48:01 +0530 Subject: [PATCH 2/4] Fixed a few issues in validation proceedures --- .../context/StratosManagerContext.java | 8 +- .../rest/endpoint/api/StratosApiV41Utils.java | 76 +++++++++++++------ 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java index 7c6eac5a9c..8841b46d04 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java @@ -40,8 +40,6 @@ */ public class StratosManagerContext implements Serializable { - - private static volatile StratosManagerContext instance; private static final String SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP = "SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP"; @@ -191,8 +189,8 @@ public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, Str } public boolean isCartridgeIncludedInCartridgeGroups(String cartridgeName) { - if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { - if(!cartridgeTypeToApplicationsMap.get(cartridgeName).isEmpty()) { + if(cartridgeTypeToCartridgeGroupsMap.containsKey(cartridgeName)) { + if(!cartridgeTypeToCartridgeGroupsMap.get(cartridgeName).isEmpty()) { return true; } return false; @@ -255,7 +253,7 @@ public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupN for(String cartridgeGroupName : cartridgeGroupNames) { Set cartridgeSubGroupNames = null; if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { - cartridgeSubGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeGroupName); + cartridgeSubGroupNames = cartridgeGroupToCartridgeSubGroupsMap.get(cartridgeGroupName); } else { cartridgeSubGroupNames = new HashSet(); cartridgeGroupToCartridgeSubGroupsMap.put(cartridgeSubGroupName, cartridgeSubGroupNames); diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java index 24b961d1f0..0281e9b8bc 100644 --- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java +++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java @@ -620,7 +620,9 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest } List cartridgeTypes = null; + String[] cartridgeNames = null; List groupNames = null; + String[] cartridgeGroupNames = null; // if any cartridges are specified in the group, they should be already deployed if (serviceGroupDefinition.getCartridges() != null) { @@ -644,13 +646,18 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest } CloudControllerServiceClient ccServiceClient = getCloudControllerServiceClient(); - + + cartridgeNames = new String[cartridgeTypes.size()]; + int i=0; for (String cartridgeType : cartridgeTypes) { try { if (ccServiceClient.getCartridgeInfo(cartridgeType) == null) { // cartridge is not deployed, can't continue log.error("invalid cartridge found in cartridge group " + cartridgeType); throw new RestAPIException("No Cartridge Definition found with type " + cartridgeType); + } else { + cartridgeNames[i] = cartridgeType; + i++; } } catch (RemoteException e) { throw new RestAPIException(e); @@ -668,8 +675,12 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest List groupDefinitions = serviceGroupDefinition.getGroups(); groupNames = new ArrayList(); + cartridgeGroupNames = new String[groupNames.size()]; + int i=0; for (GroupBean groupList : groupDefinitions) { groupNames.add(groupList.getName()); + cartridgeGroupNames[i] = groupList.getName(); + i++; } Set duplicates = findDuplicates(groupNames); @@ -694,10 +705,10 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest // Add cartridge group elements to SM cache - done after service group has been added StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); if(cartridgeTypes != null) { - smServiceClient.addUsedCartridgesInCartridgeGroups(serviceGroupDefinition.getName(), (String[]) cartridgeTypes.toArray()); + smServiceClient.addUsedCartridgesInCartridgeGroups(serviceGroupDefinition.getName(), cartridgeNames); } if(groupNames != null) { - smServiceClient.addUsedCartridgeGroupsInCartridgeSubGroups(serviceGroupDefinition.getName(), (String[]) groupNames.toArray()); + smServiceClient.addUsedCartridgeGroupsInCartridgeSubGroups(serviceGroupDefinition.getName(), cartridgeGroupNames); } } catch (Exception e) { @@ -783,6 +794,13 @@ public static void removeServiceGroup(String name) throws RestAPIException { AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + // Check whether cartridge group exists + if(asServiceClient.getServiceGroup(name) == null) { + String message = "Cartridge group: [group-name] " + name + " cannot be removed since it does not exist"; + log.error(message); + throw new RestAPIException(message); + } + // Validate whether cartridge group can be removed if(!smServiceClient.canCartirdgeGroupBeRemoved(name)) { String message = "Cannot remove cartridge group: [group-name] " + name + " since it is used in another cartridge group or an application"; @@ -802,11 +820,17 @@ public static void removeServiceGroup(String name) throws RestAPIException { if (serviceGroup.getGroups() != null) { ServiceGroup[] cartridgeGroups = serviceGroup.getGroups(); - Set cartridgeGroupNames = new HashSet(); + String[] cartridgeGroupNames = new String[cartridgeGroups.length]; + int i = 0; for(ServiceGroup cartridgeGroup : cartridgeGroups) { - cartridgeGroupNames.add(cartridgeGroup.getName()); + if(cartridgeGroup != null) { + cartridgeGroupNames[i] = cartridgeGroup.getName(); + i++; + } else { + break; + } } - smServiceClient.removeUsedCartridgeGroupsInCartridgeSubGroups(name, (String[]) cartridgeGroupNames.toArray()); + smServiceClient.removeUsedCartridgeGroupsInCartridgeSubGroups(name, cartridgeGroupNames); } } catch (Exception e) { @@ -860,29 +884,33 @@ public static void addApplication(ApplicationBean appDefinition, ConfigurationCo AutoscalerServiceClient.getInstance().addApplication(applicationContext); // Add application elements to SM cache - done after application has been added - Set cartridgeNames; - Set cartridgeGroupNames; + String[] cartridgeNames; + String[] cartridgeGroupNames; StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); List cartridges = appDefinition.getComponents().getCartridges(); if(cartridges != null) { - cartridgeNames = new HashSet(); + cartridgeNames = new String[cartridges.size()]; + int i=0; for(CartridgeReferenceBean cartridge : cartridges) { - cartridgeNames.add(cartridge.getType()); + cartridgeNames[i] = cartridge.getType(); + i++; } - smServiceClient.addUsedCartridgesInApplications(appDefinition.getApplicationId(), (String[]) cartridgeNames.toArray()); + smServiceClient.addUsedCartridgesInApplications(appDefinition.getApplicationId(), cartridgeNames); } List cartridgeGroups = appDefinition.getComponents().getGroups(); if(cartridgeGroups != null) { - cartridgeGroupNames = new HashSet(); + cartridgeGroupNames = new String[cartridgeGroups.size()]; + int i=0; for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { - cartridgeGroupNames.add(cartridgeGroup.getName()); + cartridgeGroupNames[i] = cartridgeGroup.getName(); + i++; } - smServiceClient.addUsedCartridgeGroupsInApplications(appDefinition.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + smServiceClient.addUsedCartridgeGroupsInApplications(appDefinition.getApplicationId(), cartridgeGroupNames); } } catch (AutoScalerServiceApplicationDefinitionExceptionException e) { @@ -949,28 +977,32 @@ public static void removeApplication(String applicationId) throws RestAPIExcepti asServiceClient.deleteApplication(applicationId); // Remove application elements in SM cache - done after deleting - Set cartridgeNames; - Set cartridgeGroupNames; + String[] cartridgeNames; + String[] cartridgeGroupNames; StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); List cartridges = application.getComponents().getCartridges(); if(cartridges != null) { - cartridgeNames = new HashSet(); + cartridgeNames = new String[cartridges.size()]; + int i=0; for(CartridgeReferenceBean cartridge : cartridges) { - cartridgeNames.add(cartridge.getType()); + cartridgeNames[i] = cartridge.getType(); + i++; } - smServiceClient.removeUsedCartridgesInApplications(application.getApplicationId(), (String[]) cartridgeNames.toArray()); + smServiceClient.removeUsedCartridgesInApplications(application.getApplicationId(), cartridgeNames); } List cartridgeGroups = application.getComponents().getGroups(); if(cartridgeGroups != null) { - cartridgeGroupNames = new HashSet(); + cartridgeGroupNames = new String[cartridgeGroups.size()]; + int i=0; for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { - cartridgeGroupNames.add(cartridgeGroup.getName()); + cartridgeGroupNames[i] = cartridgeGroup.getName(); + i++; } - smServiceClient.removeUsedCartridgeGroupsInApplications(application.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + smServiceClient.removeUsedCartridgeGroupsInApplications(application.getApplicationId(), cartridgeGroupNames); } } catch (RemoteException e) { From cae97c3860dde90cb88014ea22c695210b60799f Mon Sep 17 00:00:00 2001 From: Shiro Date: Fri, 23 Jan 2015 17:14:49 +0530 Subject: [PATCH 3/4] Added functionality to do validation before cartridge and cartridgeGroup removal --- .../client/StratosManagerServiceClient.java | 111 ++++ .../context/StratosManagerContext.java | 328 ++++++++++- .../internal/ServiceReferenceHolder.java | 11 + .../StratosManagerServiceComponent.java | 22 +- .../services/StratosManagerService.java | 82 +++ .../impl/StratosManagerServiceImpl.java | 139 ++++- .../rest/endpoint/api/StratosApiV41Utils.java | 145 ++++- .../main/resources/StratosManagerService.wsdl | 517 +++++++++++++++--- 8 files changed, 1247 insertions(+), 108 deletions(-) diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java index 8aefa15b67..a62084338c 100644 --- a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java +++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/StratosManagerServiceClient.java @@ -33,6 +33,7 @@ import org.apache.stratos.manager.service.stub.domain.application.signup.DomainMapping; import java.rmi.RemoteException; +import java.util.List; /** * Stratos manager service client. @@ -155,4 +156,114 @@ public void removeDomainMapping(String applicationId, int tenantId, String domai public DomainMapping[] getDomainMappings(String applicationId, int tenantId) throws RemoteException, StratosManagerServiceDomainMappingExceptionException { return stub.getDomainMappings(applicationId, tenantId); } + + /** + * Adds the used cartridges in cartridge groups to cache. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) throws RemoteException { + stub.addUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + } + + /** + * Removes the used cartridges in cartridge groups from cache. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) throws RemoteException { + stub.removeUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + } + + /** + * Adds the used cartridges in applications to cache. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) throws RemoteException { + stub.addUsedCartridgesInApplications(applicationName, cartridgeNames); + } + + /** + * Removes the used cartridges in applications from cache. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) throws RemoteException { + stub.removeUsedCartridgesInApplications(applicationName, cartridgeNames); + } + + /** + * Validates whether a cartridge can be removed. + * + * @param cartridgeName the cartridge name + * @return true, if successful + * @throws RemoteException the remote exception + */ + public boolean canCartridgeBeRemoved(String cartridgeName) throws RemoteException { + return stub.canCartridgeBeRemoved(cartridgeName); + } + + /** + * Adds the used cartridge groups in cartridge sub groups to cache. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) throws RemoteException { + stub.addUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + } + + /** + * Removes the used cartridge groups in cartridge sub groups from cache. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) throws RemoteException { + stub.removeUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + } + + /** + * Adds the used cartridge groups in applications to cache. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) throws RemoteException { + stub.addUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + } + + /** + * Removes the used cartridge groups in applications from cache. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + * @throws RemoteException the remote exception + */ + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) throws RemoteException { + stub.removeUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + } + + /** + * Validates whether a cartridge group can be removed. + * + * @param cartridgeGroupName the cartridge group name + * @return true, if successful + * @throws RemoteException the remote exception + */ + public boolean canCartirdgeGroupBeRemoved(String cartridgeGroupName) throws RemoteException { + return stub.canCartirdgeGroupBeRemoved(cartridgeGroupName); + } } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java index 55da89012f..7c6eac5a9c 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java @@ -19,16 +19,70 @@ package org.apache.stratos.manager.context; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.Lock; + import org.apache.axis2.engine.AxisConfiguration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.manager.registry.RegistryManager; +import org.apache.stratos.common.clustering.DistributedObjectProvider; import org.apache.stratos.manager.internal.ServiceReferenceHolder; +import org.wso2.carbon.registry.core.exceptions.RegistryException; /** * Stratos manager context. */ -public class StratosManagerContext { +public class StratosManagerContext implements Serializable { - private static volatile StratosManagerContext instance; + + private static volatile StratosManagerContext instance; + + private static final String SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP = "SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP"; + private static final String SM_CARTRIDGE_TYPE_TO_APPLICATIONS_MAP = "SM_CARTRIDGE_TYPE_TO_APPLICATIONS_MAP"; + private static final String SM_CARTRIDGE_GROUP_TO_CARTIDGE_GROUPS_MAP = "SM_CARTRIDGE_GROUP_TO_CARTIDGE_GROUPS_MAP"; + private static final String SM_CARTRIDGE_GROUP_TO_APPLICATIONS_MAP = "SM_CARTRIDGE_GROUP_TO_APPLICATIONS_MAP"; + + private static final String SM_CARTRIDGES_CARTRIDGEGROUPS_WRITE_LOCK = "SM_CARTRIDGES_CARTRIDGEGROUPS_WRITE_LOCK"; + private static final String SM_CARTRIDGES_APPLICATIONS_WRITE_LOCK = "SM_CARTRIDGES_APPLICATIONS_WRITE_LOCK"; + private static final String SM_CARTRIDGEGROUPS_CARTRIDGESUBGROUPS_WRITE_LOCK = "SM_CARTRIDGEGROUPS_CARTRIDGESUBGROUPS_WRITE_LOCK"; + private static final String SM_CARTRIDGEGROUPS_APPLICATIONS_WRITE_LOCK = "SM_CARTRIDGEGROUPS_APPLICATIONS_WRITE_LOCK"; + + public static final String DATA_RESOURCE = "/stratos.manager/data"; + + private final transient DistributedObjectProvider distributedObjectProvider; + private static final Log log = LogFactory.getLog(StratosManagerContext.class); + + /** + * Key - cartridge type + * Value - list of cartridgeGroupNames + */ + private Map> cartridgeTypeToCartridgeGroupsMap; + + /** + * Key - cartridge type + * Value - list of ApplicationNames + */ + private Map> cartridgeTypeToApplicationsMap; + + /** + * Key - cartridge group name + * Value - list of cartridgeGroupNames + */ + private Map> cartridgeGroupToCartridgeSubGroupsMap; + + /** + * Key - cartridge group name + * Value - list of ApplicationNames + */ + private Map> cartridgeGroupToApplicationsMap; + private boolean clustered; private boolean coordinator; @@ -49,6 +103,18 @@ private StratosManagerContext(){ if ((axisConfiguration != null) && (axisConfiguration.getClusteringAgent() != null)) { clustered = true; } + + // Initialize distributed object provider + distributedObjectProvider = ServiceReferenceHolder.getInstance().getDistributedObjectProvider(); + + // Get maps from distributed object provider + cartridgeTypeToCartridgeGroupsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP); + cartridgeTypeToApplicationsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_TYPE_TO_APPLICATIONS_MAP); + cartridgeGroupToCartridgeSubGroupsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_GROUP_TO_CARTIDGE_GROUPS_MAP); + cartridgeGroupToApplicationsMap = distributedObjectProvider.getMap(SM_CARTRIDGE_GROUP_TO_APPLICATIONS_MAP); + + // Update context from the registry + updateContextFromRegistry(); } public void setCoordinator(boolean coordinator) { @@ -62,4 +128,262 @@ public boolean isCoordinator() { public boolean isClustered() { return clustered; } + + private Lock acquireWriteLock(String object) { + return distributedObjectProvider.acquireLock(object); + } + + public void releaseWriteLock(Lock lock) { + distributedObjectProvider.releaseLock(lock); + } + + public Lock acquireCartridgesCartridgeGroupsWriteLock() { + return acquireWriteLock(SM_CARTRIDGES_CARTRIDGEGROUPS_WRITE_LOCK); + } + + public Lock acquireCartridgesApplicationsWriteLock() { + return acquireWriteLock(SM_CARTRIDGES_APPLICATIONS_WRITE_LOCK); + } + + public Lock acquireCartridgeGroupsCartridgeSubGroupsWriteLock() { + return acquireWriteLock(SM_CARTRIDGEGROUPS_CARTRIDGESUBGROUPS_WRITE_LOCK); + } + + public Lock acquireCartridgeGroupsApplicationsWriteLock() { + return acquireWriteLock(SM_CARTRIDGEGROUPS_APPLICATIONS_WRITE_LOCK); + } + + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set cartridgeGroupNames = null; + if(cartridgeTypeToCartridgeGroupsMap.containsKey(cartridgeName)) { + cartridgeGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeName); + } else { + cartridgeGroupNames = new HashSet(); + cartridgeTypeToCartridgeGroupsMap.put(cartridgeName, cartridgeGroupNames); + } + cartridgeGroupNames.add(cartridgeGroupName); + } + } + + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set cartridgeGroupNames = null; + if(cartridgeTypeToCartridgeGroupsMap.containsKey(cartridgeName)) { + cartridgeGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeName); + // Remove current cartridge group name + cartridgeGroupNames.remove(cartridgeGroupName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (cartridgeGroupNames.isEmpty()) { + cartridgeGroupNames = null; + cartridgeTypeToCartridgeGroupsMap.remove(cartridgeName); + } + } + } + } + + public boolean isCartridgeIncludedInCartridgeGroups(String cartridgeName) { + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + if(!cartridgeTypeToApplicationsMap.get(cartridgeName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set applicationNames = null; + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + applicationNames = cartridgeTypeToApplicationsMap.get(cartridgeName); + } else { + applicationNames = new HashSet(); + cartridgeTypeToApplicationsMap.put(cartridgeName, applicationNames); + } + applicationNames.add(applicationName); + } + } + + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + if(cartridgeNames == null) { + return; + } + + for(String cartridgeName : cartridgeNames) { + Set applicationNames = null; + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + applicationNames = cartridgeTypeToApplicationsMap.get(cartridgeName); + // Remove current application name + applicationNames.remove(applicationName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (applicationNames.isEmpty()) { + applicationNames = null; + cartridgeTypeToApplicationsMap.remove(cartridgeName); + } + } + } + } + + public boolean isCartridgeIncludedInApplications(String cartridgeName) { + if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { + if(!cartridgeTypeToApplicationsMap.get(cartridgeName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set cartridgeSubGroupNames = null; + if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { + cartridgeSubGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeGroupName); + } else { + cartridgeSubGroupNames = new HashSet(); + cartridgeGroupToCartridgeSubGroupsMap.put(cartridgeSubGroupName, cartridgeSubGroupNames); + } + cartridgeSubGroupNames.add(cartridgeGroupName); + } + } + + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set cartridgeSubGroupNames = null; + if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { + cartridgeSubGroupNames = cartridgeGroupToCartridgeSubGroupsMap.get(cartridgeGroupName); + // Remove current cartridge group name + cartridgeSubGroupNames.remove(cartridgeGroupName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (cartridgeSubGroupNames.isEmpty()) { + cartridgeSubGroupNames = null; + cartridgeGroupToCartridgeSubGroupsMap.remove(cartridgeGroupName); + } + } + } + } + + public boolean isCartridgeGroupIncludedInCartridgeSubGroups(String cartridgeGroupName) { + if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { + if(!cartridgeGroupToCartridgeSubGroupsMap.get(cartridgeGroupName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set applicationNames = null; + if(cartridgeGroupToApplicationsMap.containsKey(cartridgeGroupName)) { + applicationNames = cartridgeGroupToApplicationsMap.get(cartridgeGroupName); + } else { + applicationNames = new HashSet(); + cartridgeGroupToApplicationsMap.put(cartridgeGroupName, applicationNames); + } + applicationNames.add(applicationName); + } + } + + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + if(cartridgeGroupNames == null) { + return; + } + + for(String cartridgeGroupName : cartridgeGroupNames) { + Set applicationNames = null; + if(cartridgeGroupToApplicationsMap.containsKey(cartridgeGroupName)) { + applicationNames = cartridgeGroupToApplicationsMap.get(cartridgeGroupName); + // Remove current application name + applicationNames.remove(applicationName); + // Remove entry if there are no more cartridge group names for that cartridge type + if (applicationNames.isEmpty()) { + applicationNames = null; + cartridgeGroupToApplicationsMap.remove(cartridgeGroupName); + } + } + } + } + + public boolean isCartridgeGroupIncludedInApplications(String cartridgeGroupName) { + if(cartridgeGroupToApplicationsMap.containsKey(cartridgeGroupName)) { + if(!cartridgeGroupToApplicationsMap.get(cartridgeGroupName).isEmpty()) { + return true; + } + return false; + } + return false; + } + + private void updateContextFromRegistry() { + if ((!isClustered()) || (isCoordinator())) { + try { + Object dataObj = RegistryManager.getInstance().read(DATA_RESOURCE); + if (dataObj != null) { + if (dataObj instanceof StratosManagerContext) { + StratosManagerContext serializedObj = (StratosManagerContext) dataObj; + + copyMap(serializedObj.cartridgeTypeToCartridgeGroupsMap, cartridgeTypeToCartridgeGroupsMap); + copyMap(serializedObj.cartridgeTypeToApplicationsMap, cartridgeTypeToApplicationsMap); + copyMap(serializedObj.cartridgeGroupToCartridgeSubGroupsMap, cartridgeGroupToCartridgeSubGroupsMap); + copyMap(serializedObj.cartridgeGroupToApplicationsMap, cartridgeGroupToApplicationsMap); + + if (log.isDebugEnabled()) { + log.debug("Stratos Manager context is read from the registry"); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Stratos Manager context could not be found in the registry"); + } + } + } + } catch (Exception e) { + String msg = "Unable to read Stratos Manager context from the registry. " + + "Hence, any historical data will not be reflected"; + log.warn(msg, e); + } + } + } + + private void copyMap(Map sourceMap, Map destinationMap) { + for(Object key : sourceMap.keySet()) { + destinationMap.put(key, sourceMap.get(key)); + } + } + + public void persist() { + if ((!isClustered()) || (isCoordinator())) { + try { + RegistryManager.getInstance().persist(DATA_RESOURCE, this); + } catch (RegistryException e) { + log.error("Could not persist cloud controller context in registry", e); + } + } + } } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java index 85e9a0b43c..4c3d9a5c17 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/ServiceReferenceHolder.java @@ -22,6 +22,7 @@ import com.hazelcast.core.HazelcastInstance; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.engine.AxisConfiguration; +import org.apache.stratos.common.clustering.DistributedObjectProvider; import org.wso2.carbon.ntask.core.service.TaskService; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; @@ -40,6 +41,7 @@ public class ServiceReferenceHolder { private TaskService taskService; private HazelcastInstance hazelcastInstance; private AxisConfiguration axisConfiguration; + private DistributedObjectProvider distributedObjectProvider; private ServiceReferenceHolder() { } @@ -111,4 +113,13 @@ public void setAxisConfiguration(AxisConfiguration axisConfiguration) { public AxisConfiguration getAxisConfiguration() { return axisConfiguration; } + + public void setDistributedObjectProvider(DistributedObjectProvider distributedObjectProvider) { + this.distributedObjectProvider = distributedObjectProvider; + } + + public DistributedObjectProvider getDistributedObjectProvider() { + return distributedObjectProvider; + } + } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java index 9eeded2046..e07f6f0837 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/internal/StratosManagerServiceComponent.java @@ -18,19 +18,21 @@ */ package org.apache.stratos.manager.internal; -import com.hazelcast.core.HazelcastInstance; +import java.util.concurrent.ExecutorService; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.stratos.common.clustering.DistributedObjectProvider; import org.apache.stratos.common.threading.StratosThreadPool; import org.apache.stratos.manager.context.StratosManagerContext; +import org.apache.stratos.manager.messaging.publisher.TenantEventPublisher; import org.apache.stratos.manager.messaging.publisher.synchronizer.ApplicationSignUpSynchronizerTask; +import org.apache.stratos.manager.messaging.publisher.synchronizer.SynchronizerTaskScheduler; import org.apache.stratos.manager.messaging.publisher.synchronizer.TenantSynzhronizerTask; import org.apache.stratos.manager.messaging.receiver.StratosManagerApplicationEventReceiver; import org.apache.stratos.manager.messaging.receiver.StratosManagerInstanceStatusEventReceiver; -import org.apache.stratos.manager.user.management.TenantUserRoleManager; -import org.apache.stratos.manager.messaging.publisher.TenantEventPublisher; -import org.apache.stratos.manager.messaging.publisher.synchronizer.SynchronizerTaskScheduler; import org.apache.stratos.manager.messaging.receiver.StratosManagerTopologyEventReceiver; +import org.apache.stratos.manager.user.management.TenantUserRoleManager; import org.apache.stratos.manager.user.management.exception.UserManagerException; import org.apache.stratos.manager.utils.CartridgeConfigFileReader; import org.apache.stratos.manager.utils.StratosManagerConstants; @@ -46,7 +48,7 @@ import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.utils.ConfigurationContextService; -import java.util.concurrent.ExecutorService; +import com.hazelcast.core.HazelcastInstance; /** * @scr.component name="org.wso2.carbon.hosting.mgt.internal.StratosManagerServiceComponent" @@ -69,6 +71,8 @@ * @scr.reference name="ntask.component" interface="org.wso2.carbon.ntask.core.service.TaskService" * cardinality="1..1" policy="dynamic" bind="setTaskService" * unbind="unsetTaskService" + * @scr.reference name="distributedObjectProvider" interface="org.apache.stratos.common.clustering.DistributedObjectProvider" + * cardinality="1..1" policy="dynamic" bind="setDistributedObjectProvider" unbind="unsetDistributedObjectProvider" */ public class StratosManagerServiceComponent { @@ -277,6 +281,14 @@ protected void unsetTaskService(TaskService taskService) { } ServiceReferenceHolder.getInstance().setTaskService(null); } + + protected void setDistributedObjectProvider(DistributedObjectProvider distributedObjectProvider) { + ServiceReferenceHolder.getInstance().setDistributedObjectProvider(distributedObjectProvider); + } + + protected void unsetDistributedObjectProvider(DistributedObjectProvider distributedObjectProvider) { + ServiceReferenceHolder.getInstance().setDistributedObjectProvider(null); + } protected void deactivate(ComponentContext context) { // Close event publisher connections to message broker diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java index d9ba8667f7..f884a01d9d 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/StratosManagerService.java @@ -19,6 +19,8 @@ package org.apache.stratos.manager.services; +import java.util.List; + import org.apache.stratos.messaging.domain.application.signup.ApplicationSignUp; import org.apache.stratos.manager.exception.ApplicationSignUpException; import org.apache.stratos.manager.exception.ArtifactDistributionCoordinatorException; @@ -98,4 +100,84 @@ public void notifyArtifactUpdatedEventForSignUp(String applicationId, int tenant * @throws DomainMappingException */ public void removeDomainMapping(String applicationId, int tenantId, String domainName) throws DomainMappingException; + + /** + * Adds the used cartridges in cartridge groups to cache structure. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + */ + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames); + + /** + * Removes the used cartridges in cartridge groups from cache structure. + * + * @param cartridgeGroupName the cartridge group name + * @param cartridgeNames the cartridge names + */ + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames); + + /** + * Adds the used cartridges in applications to cache structure. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + */ + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames); + + /** + * Removes the used cartridges in applications from cache structure. + * + * @param applicationName the application name + * @param cartridgeNames the cartridge names + */ + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames); + + /** + * Verifies whether a cartridge can be removed. + * + * @param cartridgeName the cartridge name + * @return true, if successful + */ + public boolean canCartridgeBeRemoved(String cartridgeName); + + /** + * Adds the used cartridge groups in cartridge sub groups to cache structure. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + */ + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames); + + /** + * Removes the used cartridge groups in cartridge sub groups from cache structure. + * + * @param cartridgeSubGroupName the cartridge sub group name + * @param cartridgeGroupNames the cartridge group names + */ + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames); + + /** + * Adds the used cartridge groups in applications to cache structure. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + */ + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames); + + /** + * Removes the used cartridge groups in applications from cache structure. + * + * @param applicationName the application name + * @param cartridgeGroupNames the cartridge group names + */ + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames); + + /** + * Verifies whether a cartridge group can be removed. + * + * @param cartridgeGroupName the cartridge group name + * @return true, if successful + */ + public boolean canCartirdgeGroupBeRemoved(String cartridgeGroupName); } diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java index 45a8a0b9f0..d269f0ecc4 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/services/impl/StratosManagerServiceImpl.java @@ -19,16 +19,17 @@ package org.apache.stratos.manager.services.impl; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import java.util.concurrent.locks.Lock; + import org.apache.stratos.manager.components.ApplicationSignUpHandler; import org.apache.stratos.manager.components.ArtifactDistributionCoordinator; import org.apache.stratos.manager.components.DomainMappingHandler; -import org.apache.stratos.messaging.domain.application.signup.ApplicationSignUp; +import org.apache.stratos.manager.context.StratosManagerContext; import org.apache.stratos.manager.exception.ApplicationSignUpException; import org.apache.stratos.manager.exception.ArtifactDistributionCoordinatorException; import org.apache.stratos.manager.exception.DomainMappingException; import org.apache.stratos.manager.services.StratosManagerService; +import org.apache.stratos.messaging.domain.application.signup.ApplicationSignUp; import org.apache.stratos.messaging.domain.application.signup.DomainMapping; /** @@ -36,8 +37,6 @@ */ public class StratosManagerServiceImpl implements StratosManagerService { - private static final Log log = LogFactory.getLog(StratosManagerServiceImpl.class); - private ApplicationSignUpHandler signUpHandler; private ArtifactDistributionCoordinator artifactDistributionCoordinator; private DomainMappingHandler domainMappingHandler; @@ -92,4 +91,134 @@ public DomainMapping[] getDomainMappings(String applicationId, int tenantId) thr public void removeDomainMapping(String applicationId, int tenantId, String domainName) throws DomainMappingException { domainMappingHandler.removeDomainMapping(applicationId, tenantId, domainName); } + + @Override + public void addUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesCartridgeGroupsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesCartridgeGroupsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgesInCartridgeGroups(cartridgeGroupName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void addUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesApplicationsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgesInApplications(applicationName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgesInApplications(String applicationName, String[] cartridgeNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgesApplicationsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgesInApplications(applicationName, cartridgeNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public boolean canCartridgeBeRemoved(String cartridgeName) { + if (StratosManagerContext.getInstance().isCartridgeIncludedInCartridgeGroups(cartridgeName) || + StratosManagerContext.getInstance().isCartridgeIncludedInApplications(cartridgeName)) { + return false; + } + return true; + } + + @Override + public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsCartridgeSubGroupsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsCartridgeSubGroupsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgeGroupsInCartridgeSubGroups(cartridgeSubGroupName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void addUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsApplicationsWriteLock(); + StratosManagerContext.getInstance().addUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public void removeUsedCartridgeGroupsInApplications(String applicationName, String[] cartridgeGroupNames) { + Lock lock = null; + try { + lock = StratosManagerContext.getInstance().acquireCartridgeGroupsApplicationsWriteLock(); + StratosManagerContext.getInstance().removeUsedCartridgeGroupsInApplications(applicationName, cartridgeGroupNames); + StratosManagerContext.getInstance().persist(); + } finally { + if (lock != null) { + StratosManagerContext.getInstance().releaseWriteLock(lock); + } + } + } + + @Override + public boolean canCartirdgeGroupBeRemoved(String cartridgeGroupName) { + if(StratosManagerContext.getInstance().isCartridgeGroupIncludedInCartridgeSubGroups(cartridgeGroupName) || + StratosManagerContext.getInstance().isCartridgeGroupIncludedInApplications(cartridgeGroupName)) { + return false; + } + return true; + } } diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java index 95baf3aece..19d8136ae4 100644 --- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java +++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java @@ -37,11 +37,13 @@ import org.apache.stratos.common.beans.PropertyBean; import org.apache.stratos.common.beans.application.ApplicationBean; import org.apache.stratos.common.beans.application.GroupBean; +import org.apache.stratos.common.beans.application.GroupReferenceBean; import org.apache.stratos.common.beans.application.domain.mapping.ApplicationDomainMappingsBean; import org.apache.stratos.common.beans.application.domain.mapping.DomainMappingBean; import org.apache.stratos.common.beans.application.signup.ApplicationSignUpBean; import org.apache.stratos.common.beans.artifact.repository.GitNotificationPayloadBean; import org.apache.stratos.common.beans.cartridge.CartridgeBean; +import org.apache.stratos.common.beans.cartridge.CartridgeReferenceBean; import org.apache.stratos.common.beans.cartridge.PersistenceBean; import org.apache.stratos.common.beans.cartridge.VolumeBean; import org.apache.stratos.common.beans.kubernetes.KubernetesClusterBean; @@ -158,10 +160,19 @@ public static void removeCartridge(String cartridgeType) throws RestAPIException log.debug(String.format("Removing cartridge: [cartridge-type] %s ", cartridgeType)); } - CloudControllerServiceClient cloudControllerServiceClient = CloudControllerServiceClient.getInstance(); + CloudControllerServiceClient cloudControllerServiceClient = getCloudControllerServiceClient(); if(cloudControllerServiceClient.getCartridgeInfo(cartridgeType) == null) { throw new RuntimeException("Cartridge not found: [cartridge-type] " + cartridgeType); } + + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + // Validate whether cartridge can be removed + if(!smServiceClient.canCartridgeBeRemoved(cartridgeType)) { + String message = "Cannot remove cartridge : [cartridge-type] " + cartridgeType + " since it is used in another cartridge group or an application"; + log.error(message); + throw new RestAPIException(message); + } cloudControllerServiceClient.removeCartridge(cartridgeType); if(log.isInfoEnabled()) { @@ -510,6 +521,17 @@ private static AutoscalerServiceClient getAutoscalerServiceClient() throws RestA throw new RestAPIException(errorMsg, axisFault); } } + + private static StratosManagerServiceClient getStratosManagerServiceClient() throws RestAPIException { + try { + return StratosManagerServiceClient.getInstance(); + } catch (AxisFault axisFault) { + String errorMsg = "Error while getting StratosManagerServiceClient instance to connect to the " + + "Stratos Manager. Cause: " + axisFault.getMessage(); + log.error(errorMsg, axisFault); + throw new RestAPIException(errorMsg, axisFault); + } + } // Util methods for Autoscaling policies @@ -650,15 +672,18 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest if (serviceGroupDefinition == null) { throw new RuntimeException("Service Group definition is null"); } + + List cartridgeTypes = null; + List groupNames = null; // if any cartridges are specified in the group, they should be already deployed if (serviceGroupDefinition.getCartridges() != null) { - + if (log.isDebugEnabled()) { log.debug("checking cartridges in cartridge group " + serviceGroupDefinition.getName()); } - List cartridgeTypes = serviceGroupDefinition.getCartridges(); + cartridgeTypes = serviceGroupDefinition.getCartridges(); Set duplicates = findDuplicates(cartridgeTypes); if (duplicates.size() > 0) { @@ -672,13 +697,7 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest throw new RestAPIException("Invalid Service Group definition, duplicate cartridges defined:" + buf.toString()); } - CloudControllerServiceClient ccServiceClient = null; - - try { - ccServiceClient = CloudControllerServiceClient.getInstance(); - } catch (AxisFault axisFault) { - throw new RestAPIException(axisFault); - } + CloudControllerServiceClient ccServiceClient = getCloudControllerServiceClient(); for (String cartridgeType : cartridgeTypes) { try { @@ -702,7 +721,7 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest } List groupDefinitions = serviceGroupDefinition.getGroups(); - List groupNames = new ArrayList(); + groupNames = new ArrayList(); for (GroupBean groupList : groupDefinitions) { groupNames.add(groupList.getName()); } @@ -718,13 +737,23 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest log.debug("duplicate subGroups defined: " + buf.toString()); } throw new RestAPIException("Invalid Service Group definition, duplicate subGroups defined:" + buf.toString()); - } + } } ServiceGroup serviceGroup = ObjectConverter.convertServiceGroupDefinitionToASStubServiceGroup(serviceGroupDefinition); - AutoscalerServiceClient asServiceClient = AutoscalerServiceClient.getInstance(); + AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); asServiceClient.addServiceGroup(serviceGroup); + + // Add cartridge group elements to SM cache - done after service group has been added + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + if(cartridgeTypes != null) { + smServiceClient.addUsedCartridgesInCartridgeGroups(serviceGroupDefinition.getName(), (String[]) cartridgeTypes.toArray()); + } + if(groupNames != null) { + smServiceClient.addUsedCartridgeGroupsInCartridgeSubGroups(serviceGroupDefinition.getName(), (String[]) groupNames.toArray()); + } + } catch (Exception e) { String message = "Could not add cartridge group"; log.error(message, e); @@ -804,9 +833,35 @@ public static void removeServiceGroup(String name) throws RestAPIException { if (log.isDebugEnabled()) { log.debug("Removing cartridge group: [name] " + name); } - - AutoscalerServiceClient autoscalerServiceClient = AutoscalerServiceClient.getInstance(); - autoscalerServiceClient.undeployServiceGroupDefinition(name); + + AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + // Validate whether cartridge group can be removed + if(!smServiceClient.canCartirdgeGroupBeRemoved(name)) { + String message = "Cannot remove cartridge group: [group-name] " + name + " since it is used in another cartridge group or an application"; + log.error(message); + throw new RestAPIException(message); + } + + ServiceGroup serviceGroup = asServiceClient.getServiceGroup(name); + + asServiceClient.undeployServiceGroupDefinition(name); + + // Remove the dependent cartridges and cartridge groups from Stratos Manager cache - done after service group has been removed + if (serviceGroup.getCartridges() != null) { + String[] cartridgeNames = serviceGroup.getCartridges(); + smServiceClient.removeUsedCartridgesInCartridgeGroups(name, cartridgeNames); + } + + if (serviceGroup.getGroups() != null) { + ServiceGroup[] cartridgeGroups = serviceGroup.getGroups(); + Set cartridgeGroupNames = new HashSet(); + for(ServiceGroup cartridgeGroup : cartridgeGroups) { + cartridgeGroupNames.add(cartridgeGroup.getName()); + } + smServiceClient.removeUsedCartridgeGroupsInCartridgeSubGroups(name, (String[]) cartridgeGroupNames.toArray()); + } } catch (Exception e) { throw new RestAPIException(e); @@ -857,6 +912,33 @@ public static void addApplication(ApplicationBean appDefinition, ConfigurationCo try { AutoscalerServiceClient.getInstance().addApplication(applicationContext); + + // Add application elements to SM cache - done after application has been added + Set cartridgeNames; + Set cartridgeGroupNames; + + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + List cartridges = appDefinition.getComponents().getCartridges(); + if(cartridges != null) { + cartridgeNames = new HashSet(); + for(CartridgeReferenceBean cartridge : cartridges) { + cartridgeNames.add(cartridge.getType()); + } + + smServiceClient.addUsedCartridgesInApplications(appDefinition.getApplicationId(), (String[]) cartridgeNames.toArray()); + } + + List cartridgeGroups = appDefinition.getComponents().getGroups(); + if(cartridgeGroups != null) { + cartridgeGroupNames = new HashSet(); + for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { + cartridgeGroupNames.add(cartridgeGroup.getName()); + } + + smServiceClient.addUsedCartridgeGroupsInApplications(appDefinition.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + } + } catch (AutoscalerServiceApplicationDefinitionExceptionException e) { throw new RestAPIException(e); } catch (RemoteException e) { @@ -915,7 +997,36 @@ public static void deployApplication(String applicationId, DeploymentPolicyBean public static void removeApplication(String applicationId) throws RestAPIException { try { - AutoscalerServiceClient.getInstance().deleteApplication(applicationId); + AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); + + ApplicationBean application = ObjectConverter.convertStubApplicationContextToApplicationDefinition(asServiceClient.getApplication(applicationId)); + asServiceClient.deleteApplication(applicationId); + + // Remove application elements in SM cache - done after deleting + Set cartridgeNames; + Set cartridgeGroupNames; + StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + + List cartridges = application.getComponents().getCartridges(); + if(cartridges != null) { + cartridgeNames = new HashSet(); + for(CartridgeReferenceBean cartridge : cartridges) { + cartridgeNames.add(cartridge.getType()); + } + + smServiceClient.removeUsedCartridgesInApplications(application.getApplicationId(), (String[]) cartridgeNames.toArray()); + } + + List cartridgeGroups = application.getComponents().getGroups(); + if(cartridgeGroups != null) { + cartridgeGroupNames = new HashSet(); + for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { + cartridgeGroupNames.add(cartridgeGroup.getName()); + } + + smServiceClient.removeUsedCartridgeGroupsInApplications(application.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + } + } catch (RemoteException e) { String message = "Could not delete application: [application-id] " + applicationId; log.error(message, e); diff --git a/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl b/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl index c621b78c06..571260ddfd 100644 --- a/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl +++ b/service-stubs/org.apache.stratos.manager.service.stub/src/main/resources/StratosManagerService.wsdl @@ -1,6 +1,17 @@ - + + + + + + + + + + + + @@ -20,75 +31,92 @@ - - - - - - - - - - - + - + + - + - + + - + - - + + - + + + + + + + + + + + + + + + + + - + - + - + + - + - + - + - + + + + + + + + + @@ -107,50 +135,115 @@ - + + + + + + + + + + + + + + + - - + - + - + - + - + - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -158,14 +251,14 @@ - - + + - - + + - - + + @@ -176,15 +269,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -194,6 +317,12 @@ + + + + + + @@ -204,24 +333,52 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -234,6 +391,10 @@ + + + + @@ -258,6 +419,21 @@ + + + + + + + + + + + + + + + @@ -279,6 +455,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -288,6 +500,12 @@ + + + + + + @@ -297,41 +515,50 @@ - - + + - - + + - - + + - - + + - - + + + + + + + + - - + + + + + @@ -351,6 +578,21 @@ + + + + + + + + + + + + + + + @@ -372,6 +614,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -381,6 +659,12 @@ + + + + + + @@ -390,41 +674,50 @@ - - + + - - + + - - + + - - + + - - + + + + + + + + - - + + + + + @@ -441,6 +734,21 @@ + + + + + + + + + + + + + + + @@ -456,20 +764,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + @@ -480,8 +824,14 @@ - - + + + + + + + + @@ -495,6 +845,15 @@ + + + + + + + + + From fa0292b3d4b5ad02eb36834c59e5ef62c0e14144 Mon Sep 17 00:00:00 2001 From: Shiro Date: Fri, 23 Jan 2015 20:48:01 +0530 Subject: [PATCH 4/4] Fixed a few issues in validation proceedures --- .../context/StratosManagerContext.java | 8 +- .../rest/endpoint/api/StratosApiV41Utils.java | 76 +++++++++++++------ 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java index 7c6eac5a9c..8841b46d04 100644 --- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java +++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/context/StratosManagerContext.java @@ -40,8 +40,6 @@ */ public class StratosManagerContext implements Serializable { - - private static volatile StratosManagerContext instance; private static final String SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP = "SM_CARTRIDGE_TYPE_TO_CARTIDGE_GROUPS_MAP"; @@ -191,8 +189,8 @@ public void removeUsedCartridgesInCartridgeGroups(String cartridgeGroupName, Str } public boolean isCartridgeIncludedInCartridgeGroups(String cartridgeName) { - if(cartridgeTypeToApplicationsMap.containsKey(cartridgeName)) { - if(!cartridgeTypeToApplicationsMap.get(cartridgeName).isEmpty()) { + if(cartridgeTypeToCartridgeGroupsMap.containsKey(cartridgeName)) { + if(!cartridgeTypeToCartridgeGroupsMap.get(cartridgeName).isEmpty()) { return true; } return false; @@ -255,7 +253,7 @@ public void addUsedCartridgeGroupsInCartridgeSubGroups(String cartridgeSubGroupN for(String cartridgeGroupName : cartridgeGroupNames) { Set cartridgeSubGroupNames = null; if(cartridgeGroupToCartridgeSubGroupsMap.containsKey(cartridgeGroupName)) { - cartridgeSubGroupNames = cartridgeTypeToCartridgeGroupsMap.get(cartridgeGroupName); + cartridgeSubGroupNames = cartridgeGroupToCartridgeSubGroupsMap.get(cartridgeGroupName); } else { cartridgeSubGroupNames = new HashSet(); cartridgeGroupToCartridgeSubGroupsMap.put(cartridgeSubGroupName, cartridgeSubGroupNames); diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java index 19d8136ae4..6dfc8dd149 100644 --- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java +++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java @@ -674,7 +674,9 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest } List cartridgeTypes = null; + String[] cartridgeNames = null; List groupNames = null; + String[] cartridgeGroupNames = null; // if any cartridges are specified in the group, they should be already deployed if (serviceGroupDefinition.getCartridges() != null) { @@ -698,13 +700,18 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest } CloudControllerServiceClient ccServiceClient = getCloudControllerServiceClient(); - + + cartridgeNames = new String[cartridgeTypes.size()]; + int i=0; for (String cartridgeType : cartridgeTypes) { try { if (ccServiceClient.getCartridgeInfo(cartridgeType) == null) { // cartridge is not deployed, can't continue log.error("invalid cartridge found in cartridge group " + cartridgeType); throw new RestAPIException("No Cartridge Definition found with type " + cartridgeType); + } else { + cartridgeNames[i] = cartridgeType; + i++; } } catch (RemoteException e) { throw new RestAPIException(e); @@ -722,8 +729,12 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest List groupDefinitions = serviceGroupDefinition.getGroups(); groupNames = new ArrayList(); + cartridgeGroupNames = new String[groupNames.size()]; + int i=0; for (GroupBean groupList : groupDefinitions) { groupNames.add(groupList.getName()); + cartridgeGroupNames[i] = groupList.getName(); + i++; } Set duplicates = findDuplicates(groupNames); @@ -748,10 +759,10 @@ public static void addServiceGroup(GroupBean serviceGroupDefinition) throws Rest // Add cartridge group elements to SM cache - done after service group has been added StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); if(cartridgeTypes != null) { - smServiceClient.addUsedCartridgesInCartridgeGroups(serviceGroupDefinition.getName(), (String[]) cartridgeTypes.toArray()); + smServiceClient.addUsedCartridgesInCartridgeGroups(serviceGroupDefinition.getName(), cartridgeNames); } if(groupNames != null) { - smServiceClient.addUsedCartridgeGroupsInCartridgeSubGroups(serviceGroupDefinition.getName(), (String[]) groupNames.toArray()); + smServiceClient.addUsedCartridgeGroupsInCartridgeSubGroups(serviceGroupDefinition.getName(), cartridgeGroupNames); } } catch (Exception e) { @@ -837,6 +848,13 @@ public static void removeServiceGroup(String name) throws RestAPIException { AutoscalerServiceClient asServiceClient = getAutoscalerServiceClient(); StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); + // Check whether cartridge group exists + if(asServiceClient.getServiceGroup(name) == null) { + String message = "Cartridge group: [group-name] " + name + " cannot be removed since it does not exist"; + log.error(message); + throw new RestAPIException(message); + } + // Validate whether cartridge group can be removed if(!smServiceClient.canCartirdgeGroupBeRemoved(name)) { String message = "Cannot remove cartridge group: [group-name] " + name + " since it is used in another cartridge group or an application"; @@ -856,11 +874,17 @@ public static void removeServiceGroup(String name) throws RestAPIException { if (serviceGroup.getGroups() != null) { ServiceGroup[] cartridgeGroups = serviceGroup.getGroups(); - Set cartridgeGroupNames = new HashSet(); + String[] cartridgeGroupNames = new String[cartridgeGroups.length]; + int i = 0; for(ServiceGroup cartridgeGroup : cartridgeGroups) { - cartridgeGroupNames.add(cartridgeGroup.getName()); + if(cartridgeGroup != null) { + cartridgeGroupNames[i] = cartridgeGroup.getName(); + i++; + } else { + break; + } } - smServiceClient.removeUsedCartridgeGroupsInCartridgeSubGroups(name, (String[]) cartridgeGroupNames.toArray()); + smServiceClient.removeUsedCartridgeGroupsInCartridgeSubGroups(name, cartridgeGroupNames); } } catch (Exception e) { @@ -914,29 +938,33 @@ public static void addApplication(ApplicationBean appDefinition, ConfigurationCo AutoscalerServiceClient.getInstance().addApplication(applicationContext); // Add application elements to SM cache - done after application has been added - Set cartridgeNames; - Set cartridgeGroupNames; + String[] cartridgeNames; + String[] cartridgeGroupNames; StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); List cartridges = appDefinition.getComponents().getCartridges(); if(cartridges != null) { - cartridgeNames = new HashSet(); + cartridgeNames = new String[cartridges.size()]; + int i=0; for(CartridgeReferenceBean cartridge : cartridges) { - cartridgeNames.add(cartridge.getType()); + cartridgeNames[i] = cartridge.getType(); + i++; } - smServiceClient.addUsedCartridgesInApplications(appDefinition.getApplicationId(), (String[]) cartridgeNames.toArray()); + smServiceClient.addUsedCartridgesInApplications(appDefinition.getApplicationId(), cartridgeNames); } List cartridgeGroups = appDefinition.getComponents().getGroups(); if(cartridgeGroups != null) { - cartridgeGroupNames = new HashSet(); + cartridgeGroupNames = new String[cartridgeGroups.size()]; + int i=0; for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { - cartridgeGroupNames.add(cartridgeGroup.getName()); + cartridgeGroupNames[i] = cartridgeGroup.getName(); + i++; } - smServiceClient.addUsedCartridgeGroupsInApplications(appDefinition.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + smServiceClient.addUsedCartridgeGroupsInApplications(appDefinition.getApplicationId(), cartridgeGroupNames); } } catch (AutoscalerServiceApplicationDefinitionExceptionException e) { @@ -1003,28 +1031,32 @@ public static void removeApplication(String applicationId) throws RestAPIExcepti asServiceClient.deleteApplication(applicationId); // Remove application elements in SM cache - done after deleting - Set cartridgeNames; - Set cartridgeGroupNames; + String[] cartridgeNames; + String[] cartridgeGroupNames; StratosManagerServiceClient smServiceClient = getStratosManagerServiceClient(); List cartridges = application.getComponents().getCartridges(); if(cartridges != null) { - cartridgeNames = new HashSet(); + cartridgeNames = new String[cartridges.size()]; + int i=0; for(CartridgeReferenceBean cartridge : cartridges) { - cartridgeNames.add(cartridge.getType()); + cartridgeNames[i] = cartridge.getType(); + i++; } - smServiceClient.removeUsedCartridgesInApplications(application.getApplicationId(), (String[]) cartridgeNames.toArray()); + smServiceClient.removeUsedCartridgesInApplications(application.getApplicationId(), cartridgeNames); } List cartridgeGroups = application.getComponents().getGroups(); if(cartridgeGroups != null) { - cartridgeGroupNames = new HashSet(); + cartridgeGroupNames = new String[cartridgeGroups.size()]; + int i=0; for(GroupReferenceBean cartridgeGroup : cartridgeGroups) { - cartridgeGroupNames.add(cartridgeGroup.getName()); + cartridgeGroupNames[i] = cartridgeGroup.getName(); + i++; } - smServiceClient.removeUsedCartridgeGroupsInApplications(application.getApplicationId(), (String[]) cartridgeGroupNames.toArray()); + smServiceClient.removeUsedCartridgeGroupsInApplications(application.getApplicationId(), cartridgeGroupNames); } } catch (RemoteException e) {