adding application builder
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/686d0e06 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/686d0e06 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/686d0e06 Branch: refs/heads/docker-grouping-merge Commit: 686d0e063be8926447a7eef7e636622c2be55863 Parents: 4de85b5 Author: reka <[email protected]> Authored: Fri Oct 31 15:55:14 2014 +0530 Committer: reka <[email protected]> Committed: Fri Oct 31 15:55:14 2014 +0530 ---------------------------------------------------------------------- .../dependency/DependencyBuilder.java | 156 ++++++ .../applications/dependency/DependencyTree.java | 290 +++++++++++ .../dependency/context/ApplicationContext.java | 113 +++++ .../context/ApplicationContextFactory.java | 101 ++++ .../dependency/context/ClusterContext.java | 38 ++ .../dependency/context/GroupContext.java | 25 + .../applications/topic/ApplicationBuilder.java | 478 +++++++++++++++++++ .../topic/ApplicationsEventPublisher.java | 236 +++++++++ .../grouping/dependency/DependencyBuilder.java | 156 ------ .../grouping/dependency/DependencyTree.java | 290 ----------- .../dependency/context/ApplicationContext.java | 113 ----- .../context/ApplicationContextFactory.java | 101 ---- .../dependency/context/ClusterContext.java | 38 -- .../dependency/context/GroupContext.java | 25 - .../topic/ApplicationsEventPublisher.java | 238 --------- .../AutoscalerTopologyEventReceiver.java | 4 +- .../monitor/ApplicationMonitorFactory.java | 6 +- .../monitor/ParentComponentMonitor.java | 8 +- .../monitor/cluster/ClusterMonitor.java | 1 - .../autoscaler/monitor/group/GroupMonitor.java | 5 +- .../status/checker/StatusChecker.java | 78 ++- .../impl/CloudControllerServiceImpl.java | 6 +- .../controller/topology/TopologyBuilder.java | 421 +--------------- 23 files changed, 1502 insertions(+), 1425 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyBuilder.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyBuilder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyBuilder.java new file mode 100644 index 0000000..48c22fd --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyBuilder.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.applications.dependency; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.*; +import org.apache.stratos.autoscaler.exception.DependencyBuilderException; +import org.apache.stratos.autoscaler.applications.dependency.context.ApplicationContext; +import org.apache.stratos.autoscaler.applications.dependency.context.ApplicationContextFactory; +import org.apache.stratos.messaging.domain.applications.*; + +import java.util.Set; + +/** + * This is to build the startup/termination dependencies + * across immediate children according to the start order defined. + */ +public class DependencyBuilder { + private static final Log log = LogFactory.getLog(DependencyBuilder.class); + + private DependencyBuilder() { + + } + + private static class Holder { + private static final DependencyBuilder INSTANCE = new DependencyBuilder(); + } + + public static DependencyBuilder getInstance() { + return Holder.INSTANCE; + } + + /** + * This will build the dependency tree based on the given dependency order + * @param component it will give the necessary information to build the tree + * @return the dependency tree out of the dependency orders + */ + public DependencyTree buildDependency(ParentComponent component) throws DependencyBuilderException{ + + String identifier = component.getUniqueIdentifier(); + DependencyTree dependencyTree = new DependencyTree(identifier); + DependencyOrder dependencyOrder = component.getDependencyOrder(); + + if (dependencyOrder != null) { + log.info("Building dependency for the Application/Group " + identifier); + + //Parsing the kill behaviour + String terminationBehaviour = dependencyOrder.getTerminationBehaviour(); + + if (Constants.TERMINATE_NONE.equals(terminationBehaviour)) { + dependencyTree.setKillNone(true); + } else if (Constants.TERMINATE_ALL.equals(terminationBehaviour)) { + dependencyTree.setKillAll(true); + } else if (Constants.TERMINATE_DEPENDENTS.equals(terminationBehaviour)) { + dependencyTree.setKillDependent(true); + } + + log.info("Setting the [terminationBehaviour] " + terminationBehaviour + " to the " + + "[dependency-tree] " + dependencyTree.getId()); + + + //Parsing the start up order + Set<StartupOrder> startupOrders = dependencyOrder.getStartupOrders(); + ApplicationContext foundContext; + ApplicationContext parentContext; + + if (startupOrders != null) { + for (StartupOrder startupOrder : startupOrders) { + foundContext = null; + parentContext = null; + for (String start : startupOrder.getStartList()) { + + if (start != null) { + ApplicationContext applicationContext = ApplicationContextFactory. + getApplicationContext(start, component, dependencyTree); + String id = applicationContext.getId(); + + ApplicationContext existingApplicationContext = + dependencyTree.findApplicationContextWithId(id); + if (existingApplicationContext == null) { + if (parentContext != null) { + //appending the start up order to already added parent group/cluster + parentContext.addApplicationContext(applicationContext); + parentContext = applicationContext; + if (log.isDebugEnabled()) { + log.debug("Found an existing [dependency] " + parentContext.getId() + + " and adding the [dependency] " + id + " as the child"); + } + } else { + //adding list of startup order to the dependency tree + dependencyTree.addApplicationContext(applicationContext); + parentContext = applicationContext; + } + } else { + if (foundContext == null) { + //if existing context found, add it to child of existing context and + //set the existing context as the next parent + existingApplicationContext.addApplicationContext(applicationContext); + parentContext = existingApplicationContext; + if (log.isDebugEnabled()) { + log.debug("Found an existing [dependency] " + id + " and setting it " + + "for the next dependency to follow"); + } + } else { + String msg = "Startup order is not consistent. It contains the group/cluster " + + "which has been used more than one in another startup order"; + throw new DependencyBuilderException(msg); + } + + } + } + } + + } + } + //TODO need to parser the scalable dependencies + } + + + //adding the rest of the children who are independent to the top level + // as they can start in parallel. + for (Group group1 : component.getAliasToGroupMap().values()) { + if (dependencyTree.findApplicationContextWithId(group1.getAlias()) == null) { + ApplicationContext context = ApplicationContextFactory. + getGroupContext(group1.getAlias(), dependencyTree.isKillDependent()); + dependencyTree.addApplicationContext(context); + } + } + for (ClusterDataHolder dataHolder : component.getClusterDataMap().values()) { + if (dependencyTree.findApplicationContextWithId(dataHolder.getClusterId()) == null) { + ApplicationContext context = ApplicationContextFactory.getClusterContext(dataHolder, + dependencyTree.isKillDependent()); + dependencyTree.addApplicationContext(context); + + } + } + return dependencyTree; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyTree.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyTree.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyTree.java new file mode 100644 index 0000000..0cb9aa4 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/DependencyTree.java @@ -0,0 +1,290 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.applications.dependency; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.applications.dependency.context.ApplicationContext; + +import java.util.ArrayList; +import java.util.List; + +/** + * This is to contain the dependency tree of an application/group + */ +public class DependencyTree { + private static final Log log = LogFactory.getLog(DependencyTree.class); + + private List<ApplicationContext> applicationContextList; + + private boolean started; + + private boolean terminated; + + private boolean killAll; + + private boolean killNone; + + private boolean killDependent; + + private boolean startupOder; + + private boolean reverseStartupOrder; + + private String id; + + public DependencyTree(String id) { + applicationContextList = new ArrayList<ApplicationContext>(); + this.setId(id); + if (log.isDebugEnabled()) { + log.debug("Starting a dependency tree for the [group/application] " + id); + } + } + + public List<ApplicationContext> getApplicationContextList() { + return applicationContextList; + } + + public void setApplicationContextList(List<ApplicationContext> applicationContextList) { + this.applicationContextList = applicationContextList; + } + + public void addApplicationContext(ApplicationContext applicationContext) { + applicationContextList.add(applicationContext); + + } + + /** + * Find an ApplicationContext from dependency tree with the given id + * + * @param id the alias/id of group/cluster + * @return ApplicationContext of the given id + */ + public ApplicationContext findApplicationContextWithId(String id) { + return findApplicationContextWithId(id, applicationContextList); + } + + /** + * Find the ApplicationContext using Breadth first search. + * + * @param id the alias/id of group/cluster + * @param contexts the list of contexts in the same level of the tree + * @return ApplicationContext of the given id + */ + private ApplicationContext findApplicationContextWithId(String id, List<ApplicationContext> contexts) { + for (ApplicationContext context : contexts) { + //TODO check for the status + if (context.getId().equals(id)) { + return context; + } + } + //if not found in the top level search recursively + for (ApplicationContext context : contexts) { + return findApplicationContextWithId(id, context.getApplicationContextList()); + } + return null; + } + + public ApplicationContext findParentContextWithId(String id) { + return findParentContextWithId(null, id, this.applicationContextList); + } + + public List<ApplicationContext> findAllParentContextWithId(String id) { + List<ApplicationContext> applicationContexts = new ArrayList<ApplicationContext>(); + return findAllParent(applicationContexts, id); + } + + private List<ApplicationContext> findAllParent(List<ApplicationContext> parentContexts, String id) { + ApplicationContext context = findParentContextWithId(null, id, this.applicationContextList); + if (context != null) { + parentContexts.add(context); + findAllParent(parentContexts, context.getId()); + } + return parentContexts; + } + + + private ApplicationContext findParentContextWithId(ApplicationContext parent, String id, + List<ApplicationContext> contexts) { + for (ApplicationContext context : contexts) { + //TODO check for the status + if (context.getId().equals(id)) { + return parent; + } + } + //if not found in the top level search recursively + for (ApplicationContext context : this.applicationContextList) { + return findParentContextWithId(context, id, context.getApplicationContextList()); + } + return null; + } + + /** + * Getting the next start able dependencies upon the activate event + * received for a group/cluster which is part of this tree. + * + * @param id the alias/id of group/cluster which received the activated event. + * @return list of dependencies + */ + public List<ApplicationContext> getStarAbleDependencies(String id) { + //finding the application context which received the activated event and + // returning it's immediate children as the dependencies. + ApplicationContext context = findApplicationContextWithId(id); + return context.getApplicationContextList(); + } + + /** + * Getting the next start able dependencies upon the monitor initialization. + * + * @return list of dependencies + */ + public List<ApplicationContext> getStarAbleDependencies() { + //returning the top level as the monitor is in initializing state + return this.applicationContextList; + } + + public List<ApplicationContext> getStarAbleDependenciesByTermination() { + //Breadth First search over the graph to find out which level has the terminated contexts + return traverseGraphByLevel(this.applicationContextList); + } + + + private List<ApplicationContext> traverseGraphByLevel(List<ApplicationContext> contexts) { + for(ApplicationContext context : contexts) { + if(context.isTerminated()) { + return contexts; + } + } + + for(ApplicationContext context : contexts) { + return traverseGraphByLevel(context.getApplicationContextList()); + } + return null; + } + + + + /** + * When one group/cluster terminates/in_maintenance, need to consider about other + * dependencies + * + * @param id the alias/id of group/cluster in which terminated event received + * @return all the kill able children dependencies + */ + public List<ApplicationContext> getTerminationDependencies(String id) { + List<ApplicationContext> allChildrenOfAppContext = new ArrayList<ApplicationContext>(); + ApplicationContext applicationContext = findApplicationContextWithId(id); + + if (this.killDependent) { + //finding the ApplicationContext of the given id + //finding all the children of the found application context + allChildrenOfAppContext.add(applicationContext); + findAllChildrenOfAppContext(applicationContext.getApplicationContextList(), + allChildrenOfAppContext); + return allChildrenOfAppContext; + } else if (this.killAll) { + //killall will be killed by the monitor from it's list. + findAllChildrenOfAppContext(this.applicationContextList, + allChildrenOfAppContext); + + } + //return empty for the kill-none case, what ever returns here will be killed in + return allChildrenOfAppContext; + } + + /** + * This will help to find out all the children of a particular node + * + * @param applicationContexts app contexts of the particular node + * @param childContexts contains the children of the node + * @return all the children of the given node + */ + public List<ApplicationContext> findAllChildrenOfAppContext(List<ApplicationContext> applicationContexts, + List<ApplicationContext> childContexts) { + for (ApplicationContext context : applicationContexts) { + childContexts.add(context); + findAllChildrenOfAppContext(context.getApplicationContextList(), childContexts); + } + return childContexts; + } + + public boolean isKillAll() { + return killAll; + } + + public void setKillAll(boolean killAll) { + this.killAll = killAll; + } + + public boolean isKillNone() { + return killNone; + } + + public void setKillNone(boolean killNone) { + this.killNone = killNone; + } + + public boolean isStarted() { + return started; + } + + public void setStarted(boolean started) { + this.started = started; + } + + public boolean isTerminated() { + return terminated; + } + + public void setTerminated(boolean terminated) { + this.terminated = terminated; + } + + public boolean isKillDependent() { + return killDependent; + } + + public void setKillDependent(boolean killDependent) { + this.killDependent = killDependent; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public boolean isStartupOder() { + return startupOder; + } + + public void setStartupOder(boolean startupOder) { + this.startupOder = startupOder; + } + + public boolean isReverseStartupOrder() { + return reverseStartupOrder; + } + + public void setReverseStartupOrder(boolean reverseStartupOrder) { + this.reverseStartupOrder = reverseStartupOrder; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContext.java new file mode 100644 index 0000000..45d1544 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContext.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.applications.dependency.context; + +import org.apache.stratos.messaging.domain.topology.ClusterStatus; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * This is to keep track of the + */ +public abstract class ApplicationContext { + private List<ApplicationContext> applicationContextList; + + private String id; + protected boolean started; + private boolean terminated; + + private ClusterStatus status; + + private Stack<ClusterStatus> statusLifeCycle; + + protected boolean isDependent; + + public ApplicationContext(String id, boolean killDependent) { + applicationContextList = new ArrayList<ApplicationContext>(); + statusLifeCycle = new Stack<ClusterStatus>(); + this.setDependent(killDependent); + this.id = id; + } + + public List<ApplicationContext> getApplicationContextList() { + return applicationContextList; + } + + public void setApplicationContextList(List<ApplicationContext> applicationContextList) { + this.applicationContextList = applicationContextList; + } + + public void addApplicationContext(ApplicationContext applicationContext) { + applicationContextList.add(applicationContext); + + } + + public void addStatusToLIfeCycle(ClusterStatus status) { + this.statusLifeCycle.push(status); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public ClusterStatus getCurrentStatus() { + return status; + } + + public void setCurrentStatus(ClusterStatus status) { + this.status = status; + } + + public List<ClusterStatus> getStatusLifeCycle() { + return statusLifeCycle; + } + + public boolean hasChild() { + boolean hasChild; + if(this.applicationContextList.isEmpty()) { + hasChild = false; + } else { + hasChild = true; + } + return hasChild; + } + + + public boolean isTerminated() { + return terminated; + } + + public void setTerminated(boolean terminated) { + this.terminated = terminated; + } + + public boolean isDependent() { + return isDependent; + } + + public void setDependent(boolean isDependent) { + this.isDependent = isDependent; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContextFactory.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContextFactory.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContextFactory.java new file mode 100644 index 0000000..b4d7740 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ApplicationContextFactory.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.applications.dependency.context; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.Constants; +import org.apache.stratos.autoscaler.applications.dependency.DependencyTree; +import org.apache.stratos.messaging.domain.applications.ClusterDataHolder; +import org.apache.stratos.messaging.domain.applications.ParentComponent; + +/** + * Factory to create new GroupContext or ClusterContext + */ +public class ApplicationContextFactory { + private static final Log log = LogFactory.getLog(ApplicationContextFactory.class); + + /** + * Will return the GroupContext/ClusterContext based on the type in start order + * + * @param startOrder reference of group/cluster in the start order + * @param component The component which used to build the dependency + * @param tree kill dependent behaviour of this component + * @return Context + */ + public static ApplicationContext getApplicationContext(String startOrder, + ParentComponent component, + DependencyTree tree) { + String id; + ApplicationContext applicationContext = null; + boolean isDependent = tree.isKillDependent() || tree.isKillAll(); + if (startOrder.startsWith(Constants.GROUP + ".")) { + //getting the group alias + id = getGroupFromStartupOrder(startOrder); + applicationContext = getGroupContext(id, isDependent); + } else if (startOrder.startsWith(Constants.CARTRIDGE + ".")) { + //getting the cluster alias + id = getClusterFromStartupOrder(startOrder); + //getting the cluster-id from cluster alias + ClusterDataHolder clusterDataHolder = component.getClusterDataMap().get(id); + applicationContext = getClusterContext(clusterDataHolder, isDependent); + + } else { + log.warn("[Startup Order]: " + startOrder + " contains unknown reference"); + } + return applicationContext; + + } + + /** + * Utility method to get the group alias from the startup order Eg: group.mygroup + * + * @param startupOrder startup order + * @return group alias + */ + public static String getGroupFromStartupOrder(String startupOrder) { + return startupOrder.substring(Constants.GROUP.length() + 1); + } + + /** + * Utility method to get the cluster alias from startup order Eg: cartridge.myphp + * + * @param startupOrder startup order + * @return cluster alias + */ + public static String getClusterFromStartupOrder(String startupOrder) { + return startupOrder.substring(Constants.CARTRIDGE.length() + 1); + } + + public static ApplicationContext getClusterContext(ClusterDataHolder dataHolder, + boolean isKillDependent) { + ApplicationContext applicationContext; + applicationContext = new ClusterContext(dataHolder.getClusterId(), + isKillDependent); + ((ClusterContext) applicationContext).setServiceName(dataHolder.getServiceType()); + return applicationContext; + } + + public static ApplicationContext getGroupContext(String id, boolean isDependent) { + ApplicationContext applicationContext; + applicationContext = new GroupContext(id, + isDependent); + return applicationContext; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ClusterContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ClusterContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ClusterContext.java new file mode 100644 index 0000000..6de38d4 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/ClusterContext.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.applications.dependency.context; + +/** + * ClusterContext to keep cluster level context information + */ +public class ClusterContext extends ApplicationContext { + private String serviceName; + + public ClusterContext(String id, boolean killDependent) { + super(id ,killDependent); + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/GroupContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/GroupContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/GroupContext.java new file mode 100644 index 0000000..3f546c5 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/dependency/context/GroupContext.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.applications.dependency.context; + +public class GroupContext extends ApplicationContext { + public GroupContext(String id, boolean killDependent) { + super(id ,killDependent); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java new file mode 100644 index 0000000..5aa05a2 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java @@ -0,0 +1,478 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.applications.topic; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.applications.ApplicationHolder; +import org.apache.stratos.messaging.domain.applications.*; +import org.apache.stratos.messaging.event.applications.*; +import org.apache.stratos.messaging.event.applications.ApplicationActivatedEvent; +import org.apache.stratos.messaging.event.applications.ApplicationInactivatedEvent; +import org.apache.stratos.messaging.event.applications.GroupActivatedEvent; +import org.apache.stratos.messaging.event.applications.GroupCreatedEvent; +import org.apache.stratos.messaging.event.applications.GroupTerminatingEvent; +import org.apache.stratos.messaging.event.topology.*; + +import java.util.Collection; +import java.util.Set; + +/** + * This will build the application. + */ +public class ApplicationBuilder { + private static final Log log = LogFactory.getLog(ApplicationBuilder.class); + + + /*public static synchronized void handleApplicationDeployed(Application application, + Set<ApplicationClusterContext> applicationClusterContexts, + Set<MetaDataHolder> metaDataHolders) { + + + Applications applications = Appcation.getApplications(); + try { + ApplicationHolder.acquireWriteLock(); + + if (applications.applicationExists(application.getUniqueIdentifier())) { + log.warn("Application with id [ " + application.getUniqueIdentifier() + " ] already exists in Applications"); + return; + } + List<Cluster> clusters = new ArrayList<Cluster>(); + for (ApplicationClusterContext applicationClusterContext : applicationClusterContexts) { + Cluster cluster = new Cluster(applicationClusterContext.getCartridgeType(), + applicationClusterContext.getClusterId(), applicationClusterContext.getDeploymentPolicyName(), + applicationClusterContext.getAutoscalePolicyName(), application.getUniqueIdentifier()); + //cluster.setStatus(Status.Created); + cluster.addHostName(applicationClusterContext.getHostName()); + cluster.setTenantRange(applicationClusterContext.getTenantRange()); + clusters.add(cluster); + + Service service = applications.getService(applicationClusterContext.getCartridgeType()); + if (service != null) { + service.addCluster(cluster); + log.info("Added Cluster " + cluster.toString() + " to Applications for Application with id: " + application.getUniqueIdentifier()); + } else { + log.error("Service " + applicationClusterContext.getCartridgeType() + " not found"); + return; + } + } + + // add to Applications and update + applications.addApplication(application); + ApplicationHolder.persistApplication(applications); + + log.info("Application with id [ " + application.getUniqueIdentifier() + " ] added to Applications successfully"); + org.apache.stratos.messaging.event.applications.ApplicationCreatedEvent applicationCreatedEvent = new org.apache.stratos.messaging.event.applications.ApplicationCreatedEvent(application, clusters); + ApplicationsEventPublisher.sendApplicationCreatedEvent(applicationCreatedEvent); + + } finally { + ApplicationHolder.releaseWriteLock(); + } + }*/ + + /*public static synchronized void handleApplicationUndeployed(String applicationId) { + + Set<ClusterDataHolder> clusterData; + + // update the Application and Cluster Statuses as 'Terminating' + ApplicationHolder.acquireWriteLock(); + + try { + + Applications applications = ApplicationHolder.getApplications(); + + if (!applications.applicationExists(applicationId)) { + log.warn("Application with id [ " + applicationId + " ] doesn't exist in Applications"); + return; + } + + Application application = applications.getApplication(applicationId); + // check and update application status to 'Terminating' + if (!application.isStateTransitionValid(ApplicationStatus.Terminating)) { + log.error("Invalid state transfer from " + application.getStatus() + " to " + ApplicationStatus.Terminating); + } + // for now anyway update the status forcefully + application.setStatus(ApplicationStatus.Terminating); + + // update all the Clusters' statuses to 'Terminating' + clusterData = application.getClusterDataRecursively(); + for (ClusterDataHolder clusterDataHolder : clusterData) { + Service service = applications.getService(clusterDataHolder.getServiceType()); + if (service != null) { + Cluster aCluster = service.getCluster(clusterDataHolder.getClusterId()); + if (aCluster != null) { + // validate state transition + if (!aCluster.isStateTransitionValid(ClusterStatus.Terminating)) { + log.error("Invalid state transfer from " + aCluster.getStatus() + " to " + + ClusterStatus.Terminating); + } + // for now anyway update the status forcefully + aCluster.setStatus(ClusterStatus.Terminating); + + } else { + log.warn("Unable to find Cluster with cluster id " + clusterDataHolder.getClusterId() + + " in Applications"); + } + + } else { + log.warn("Unable to remove cluster with cluster id: " + clusterDataHolder.getClusterId() + " from Applications, " + + " associated Service [ " + clusterDataHolder.getServiceType() + " ] not found"); + } + } + + // update all Group's statuses to 'Terminating' + if (application.getGroups() != null) { + updateGroupStatusesRecursively(GroupStatus.Terminating, application.getGroups()); + } + + ApplicationHolder.persistApplication(applications); + + } finally { + ApplicationHolder.releaseWriteLock(); + } + + ApplicationsEventPublisher.sendApplicationUndeployedEvent(applicationId, clusterData); + }*/ + + public static void handleGroupTerminatedEvent(String appId, String groupId) { + Applications applications = ApplicationHolder.getApplications(); + Application application = applications.getApplication(appId); + //update the status of the Group + if (application == null) { + log.warn(String.format("Application %s does not exist", + appId)); + return; + } + + Group group = application.getGroupRecursively(groupId); + if (group == null) { + log.warn(String.format("Group %s does not exist", + groupId)); + return; + } + + try { + ApplicationHolder.acquireWriteLock(); + group.setStatus(GroupStatus.Terminated); + log.info("Group terminated adding status started for " + group.getUniqueIdentifier()); + + ApplicationHolder.persistApplication(application); + } finally { + ApplicationHolder.releaseWriteLock(); + } + //publishing data + ApplicationsEventPublisher.sendGroupTerminatedEvent(appId, groupId); + } + + public static void handleGroupActivatedEvent(String appId, String groupId) { + Applications applications = ApplicationHolder.getApplications(); + Application application = applications.getApplication(appId); + //update the status of the Group + if (application == null) { + log.warn(String.format("Application %s does not exist", + appId)); + return; + } + + Group group = application.getGroupRecursively(groupId); + if (group == null) { + log.warn(String.format("Group %s does not exist", + groupId)); + return; + } + + try { + ApplicationHolder.acquireWriteLock(); + group.setStatus(GroupStatus.Active); + log.info("Group activated adding status started for " + group.getUniqueIdentifier()); + + ApplicationHolder.persistApplication(application); + } finally { + ApplicationHolder.releaseWriteLock(); + } + //publishing data + ApplicationsEventPublisher.sendGroupActivatedEvent(application.getUniqueIdentifier(), + group.getUniqueIdentifier()); + } + + public static void handleGroupCreatedEvent(String appId, String groupId) { + Applications applications = ApplicationHolder.getApplications(); + Application application = applications.getApplication(appId); + //update the status of the Group + if (application == null) { + log.warn(String.format("Application %s does not exist", + appId)); + return; + } + + Group group = application.getGroupRecursively(groupId); + if (group == null) { + log.warn(String.format("Group %s does not exist", + groupId)); + return; + } + + try { + ApplicationHolder.acquireWriteLock(); + group.setStatus(GroupStatus.Created); + log.info("Group created adding status started for " + group.getUniqueIdentifier()); + + ApplicationHolder.persistApplication(application); + } finally { + ApplicationHolder.releaseWriteLock(); + } + //publishing data + ApplicationsEventPublisher.sendGroupCreatedEvent(appId, groupId); + } + + public static void handleGroupInActivateEvent(String appId, String groupId) { + Applications applications = ApplicationHolder.getApplications(); + Application application = applications.getApplication(appId); + //update the status of the Group + if (application == null) { + log.warn(String.format("Application %s does not exist", + appId)); + return; + } + + Group group = application.getGroupRecursively(groupId); + if (group == null) { + log.warn(String.format("Group %s does not exist", + groupId)); + return; + } + + try { + ApplicationHolder.acquireWriteLock(); + group.setStatus(GroupStatus.Inactive); + log.info("Group in-active adding status started for " + group.getUniqueIdentifier()); + + ApplicationHolder.persistApplication(application); + } finally { + ApplicationHolder.releaseWriteLock(); + } + //publishing data + ApplicationsEventPublisher.sendGroupInActivateEvent(appId, groupId); + } + + public static void handleGroupTerminatingEvent(String appId, String groupId) { + Applications applications = ApplicationHolder.getApplications(); + Application application = applications.getApplication(appId); + //update the status of the Group + if (application == null) { + log.warn(String.format("Application %s does not exist", + appId)); + return; + } + + Group group = application.getGroupRecursively(groupId); + if (group == null) { + log.warn(String.format("Group %s does not exist", + groupId)); + return; + } + + try { + ApplicationHolder.acquireWriteLock(); + group.setStatus(GroupStatus.Terminating); + log.info("Group terminating adding status started for " + group.getUniqueIdentifier()); + + ApplicationHolder.persistApplication(application); + } finally { + ApplicationHolder.releaseWriteLock(); + } + //publishing data + ApplicationsEventPublisher.sendGroupTerminatingEvent(appId, groupId); + } + + public static void handleApplicationActivatedEvent(String appId) { + Applications applications = ApplicationHolder.getApplications(); + Application application = applications.getApplication(appId); + //update the status of the Group + if (application == null) { + log.warn(String.format("Application %s does not exist", + appId)); + return; + } + + try { + ApplicationHolder.acquireWriteLock(); + application.setStatus(ApplicationStatus.Active); + log.info("Application activated adding status started for Applications"); + + ApplicationHolder.persistApplication(application); + } finally { + ApplicationHolder.releaseWriteLock(); + } + //publishing data + ApplicationsEventPublisher.sendApplicationActivatedEvent(appId); + } + + /*public static void handleApplicationCreatedEvent(ApplicationCreatedEvent event) { + Applications applications = ApplicationHolder.getApplications(); + Application application = applications.getApplication(event.getAppId()); + //update the status of the Group + if (application == null) { + log.warn(String.format("Application %s does not exist", + event.getAppId())); + return; + } + List<Cluster> clusters = new ArrayList<Cluster>(); + Set<ClusterDataHolder> allClusters = application.getClusterDataRecursively(); + + for (ClusterDataHolder clusterDataHolder : allClusters) { + String clusterId = clusterDataHolder.getClusterId(); + String serviceName = clusterDataHolder.getServiceType(); + clusters.add(ApplicationHolder.getApplications().getService(serviceName).getCluster(clusterId)); + } + org.apache.stratos.messaging.event.applications.ApplicationCreatedEvent applicationActivatedEvent = + new org.apache.stratos.messaging.event.applications.ApplicationCreatedEvent( + application, clusters); + try { + ApplicationHolder.acquireWriteLock(); + application.setStatus(ApplicationStatus.Created); + log.info("Application created adding status started for Applications"); + + ApplicationHolder.persistApplication(applications); + } finally { + ApplicationHolder.releaseWriteLock(); + } + //publishing data + ApplicationsEventPublisher.sendApplicationCreatedEvent(applicationActivatedEvent); + }*/ + + public static void handleApplicationTerminatingEvent(String appId) { + + String applicationId = appId; + + // update the Application Status as 'Terminating' + ApplicationHolder.acquireWriteLock(); + + try { + + Applications applications = ApplicationHolder.getApplications(); + + if (!applications.applicationExists(applicationId)) { + log.warn("Application with id [ " + applicationId + " ] doesn't exist in Applications"); + return; + } + + Application application = applications.getApplication(applicationId); + // check and update application status to 'Terminating' + if (!application.isStateTransitionValid(ApplicationStatus.Terminating)) { + log.error("Invalid state transfer from " + application.getStatus() + " to " + ApplicationStatus.Terminating); + } + // for now anyway update the status forcefully + application.setStatus(ApplicationStatus.Terminating); + log.info("Application " + applicationId + "'s status updated to " + ApplicationStatus.Terminating); + + } finally { + ApplicationHolder.releaseWriteLock(); + } + + ApplicationsEventPublisher.sendApplicationTerminatingEvent(applicationId); + } + + private static void updateGroupStatusesRecursively(GroupStatus groupStatus, Collection<Group> groups) { + + for (Group group : groups) { + if (!group.isStateTransitionValid(groupStatus)) { + log.error("Invalid state transfer from " + group.getStatus() + " to " + groupStatus); + } + // force update for now + group.setStatus(groupStatus); + + // go recursively and update + if (group.getGroups() != null) { + updateGroupStatusesRecursively(groupStatus, group.getGroups()); + } + } + } + + public static void handleApplicationTerminatedEvent(String appId) { + + Applications applications = ApplicationHolder.getApplications(); + + try { + ApplicationHolder.acquireWriteLock(); + + if (!applications.applicationExists(appId)) { + log.warn("Application with id [ " + appId + " ] doesn't exist in Applications"); + //ApplicationsEventPublisher.sendApplicationRemovedEvent(applicationId, tenantId, tenantDomain); + + } else { + Application application = applications.getApplication(appId); + + if (!application.isStateTransitionValid(ApplicationStatus.Terminated)) { + log.error("Invalid status change from " + application.getStatus() + " to " + ApplicationStatus.Terminated); + } + // forcefully set status for now + application.setStatus(ApplicationStatus.Terminated); + + int tenantId = application.getTenantId(); + String tenantDomain = application.getTenantDomain(); + Set<ClusterDataHolder> clusterData = application.getClusterDataRecursively(); + // remove clusters + /*for (ClusterDataHolder clusterDataHolder : clusterData) { + Service service = applications.getService(clusterDataHolder.getServiceType()); + if (service != null) { + // remove Cluster + service.removeCluster(clusterDataHolder.getClusterId()); + + if (log.isDebugEnabled()) { + log.debug("Removed cluster with id " + clusterDataHolder.getClusterId()); + } + } else { + log.warn("Unable to remove cluster with cluster id: " + clusterDataHolder.getClusterId() + " from Applications, " + + " associated Service [ " + clusterDataHolder.getServiceType() + " ] npt found"); + } + + // remove runtime data + FasterLookUpDataHolder dataHolder = FasterLookUpDataHolder.getInstance(); + dataHolder.removeClusterContext(clusterDataHolder.getClusterId()); + if (log.isDebugEnabled()) { + log.debug("Removed Cluster Context for Cluster id: " + clusterDataHolder.getClusterId()); + } + + try { + RegistryManager.getInstance().persist(dataHolder); + } catch (RegistryException e) { + log.error("Unable to persist data in Registry", e); + } + } + + + // remove application + applications.removeApplication(event.getAppId()); + ApplicationHolder.persistApplication(applications); + + deleteAppResourcesFromMetadataService(event); + + log.info("Removed application [ " + event.getAppId() + " ] from Applications"); + + ApplicationsEventPublisher.sendApplicationTerminatedEvent(new org.apache.stratos.messaging.event.applications.ApplicationTerminatedEvent(event.getAppId(), + clusterData, tenantId, tenantDomain))*/ + ; + } + + } finally { + ApplicationHolder.releaseWriteLock(); + } + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationsEventPublisher.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationsEventPublisher.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationsEventPublisher.java new file mode 100644 index 0000000..f8d989f --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationsEventPublisher.java @@ -0,0 +1,236 @@ +package org.apache.stratos.autoscaler.applications.topic; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.messaging.broker.publish.EventPublisher; +import org.apache.stratos.messaging.broker.publish.EventPublisherPool; +import org.apache.stratos.messaging.domain.applications.*; +import org.apache.stratos.messaging.event.Event; +import org.apache.stratos.messaging.event.applications.*; +import org.apache.stratos.messaging.message.receiver.topology.TopologyManager; +import org.apache.stratos.messaging.util.Constants; + +import java.util.Set; + +/** + * This will publish application related events to application status topic. + */ +public class ApplicationsEventPublisher { + private static final Log log = LogFactory.getLog(ApplicationsEventPublisher.class); + + + public static void sendGroupCreatedEvent(String appId, String groupId) { + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + Group group = application.getGroupRecursively(groupId); + if (group.isStateTransitionValid(GroupStatus.Created)) { + if (log.isInfoEnabled()) { + log.info("Publishing Group created event for [application]: " + appId + + " [group]: " + groupId); + } + GroupCreatedEvent groupCreatedEvent = + new GroupCreatedEvent(appId, groupId); + + publishEvent(groupCreatedEvent); + } else { + log.warn("Created is not in the possible state list of [group] " + groupId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void sendGroupActivatedEvent(String appId, String groupId) { + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + Group group = application.getGroupRecursively(groupId); + if (group.isStateTransitionValid(GroupStatus.Active)) { + if (log.isInfoEnabled()) { + log.info("Publishing Group activated event for [application]: " + appId + + " [group]: " + groupId); + } + GroupActivatedEvent groupActivatedEvent = + new GroupActivatedEvent(appId, groupId); + + publishEvent(groupActivatedEvent); + } else { + log.warn("Active is not in the possible state list of [group] " + groupId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void sendGroupInActivateEvent(String appId, String groupId) { + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + Group group = application.getGroupRecursively(groupId); + if (group.isStateTransitionValid(GroupStatus.Inactive)) { + if (log.isInfoEnabled()) { + log.info("Publishing Group in-activate event for [application]: " + appId + + " [group]: " + groupId); + } + AppStatusGroupInactivateEvent appStatusGroupInactivateEvent = new + AppStatusGroupInactivateEvent(appId, groupId); + + publishEvent(appStatusGroupInactivateEvent); + } else { + log.warn("InActive is not in the possible state list of [group] " + groupId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void sendGroupTerminatingEvent(String appId, String groupId) { + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + Group group = application.getGroupRecursively(groupId); + if (group.isStateTransitionValid(GroupStatus.Terminating)) { + if (log.isInfoEnabled()) { + log.info("Publishing Group terminating event for [application]: " + appId + + " [group]: " + groupId); + } + GroupTerminatingEvent groupInTerminatingEvent = + new GroupTerminatingEvent(appId, groupId); + publishEvent(groupInTerminatingEvent); + } else { + log.warn("Terminating is not in the possible state list of [group] " + groupId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void sendGroupTerminatedEvent(String appId, String groupId) { + + if (log.isInfoEnabled()) { + log.info("Publishing Group terminated event for [application]: " + appId + + " [group]: " + groupId); + } + + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + Group group = application.getGroupRecursively(groupId); + if (group.isStateTransitionValid(GroupStatus.Terminated)) { + GroupTerminatedEvent groupInTerminatedEvent = + new GroupTerminatedEvent(appId, groupId); + publishEvent(groupInTerminatedEvent); + } else { + log.warn("Terminated is not in the possible state list of [group] " + groupId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + + + } + + public static void sendApplicationActivatedEvent(String appId) { + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + if (application.isStateTransitionValid(ApplicationStatus.Active)) { + if (log.isInfoEnabled()) { + log.info("Publishing Application activated event for [application]: " + appId); + } + ApplicationActivatedEvent applicationActivatedEvent = + new ApplicationActivatedEvent(appId); + + publishEvent(applicationActivatedEvent); + } else { + log.warn("Active is not in the possible state list of [application] " + appId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void sendApplicationInactivatedEvent(String appId) { + if (log.isInfoEnabled()) { + log.info("Publishing Application In-activated event for [application]: " + appId); + } + + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + if (application.isStateTransitionValid(ApplicationStatus.Inactive)) { + ApplicationInactivatedEvent applicationInActivatedEvent = + new ApplicationInactivatedEvent(appId); + publishEvent(applicationInActivatedEvent); + } else { + log.warn("Inactive is not in the possible state list of [application] " + appId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void sendApplicationTerminatingEvent(String appId) { + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + if (application.isStateTransitionValid(ApplicationStatus.Terminating)) { + if (log.isInfoEnabled()) { + log.info("Publishing Application terminated event for [application]: " + appId); + } + ApplicationTerminatingEvent applicationTerminatingEvent = + new ApplicationTerminatingEvent(appId); + publishEvent(applicationTerminatingEvent); + } else { + log.warn("Terminating is not in the possible state list of [application] " + appId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void sendApplicationTerminatedEvent(String appId, Set<ClusterDataHolder> clusterData) { + try { + TopologyManager.acquireReadLockForApplication(appId); + Application application = TopologyManager.getTopology().getApplication(appId); + if (application != null) { + if (application.isStateTransitionValid(ApplicationStatus.Terminated)) { + if (log.isInfoEnabled()) { + log.info("Publishing Application terminated event for [application]: " + appId); + } + ApplicationTerminatedEvent applicationTerminatedEvent = + new ApplicationTerminatedEvent(appId, clusterData); + publishEvent(applicationTerminatedEvent); + } else { + log.warn("Terminated is not in the possible state list of [application] " + appId); + } + } + } finally { + TopologyManager.releaseReadLockForApplication(appId); + } + } + + public static void publishEvent(Event event) { + //publishing events to application status topic + EventPublisher eventPublisher = EventPublisherPool.getPublisher(Constants.APPLICATIONS_TOPIC); + eventPublisher.publish(event); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java deleted file mode 100644 index bf1233f..0000000 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.stratos.autoscaler.grouping.dependency; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.*; -import org.apache.stratos.autoscaler.exception.DependencyBuilderException; -import org.apache.stratos.autoscaler.grouping.dependency.context.ApplicationContext; -import org.apache.stratos.autoscaler.grouping.dependency.context.ApplicationContextFactory; -import org.apache.stratos.messaging.domain.applications.*; - -import java.util.Set; - -/** - * This is to build the startup/termination dependencies - * across immediate children according to the start order defined. - */ -public class DependencyBuilder { - private static final Log log = LogFactory.getLog(DependencyBuilder.class); - - private DependencyBuilder() { - - } - - private static class Holder { - private static final DependencyBuilder INSTANCE = new DependencyBuilder(); - } - - public static DependencyBuilder getInstance() { - return Holder.INSTANCE; - } - - /** - * This will build the dependency tree based on the given dependency order - * @param component it will give the necessary information to build the tree - * @return the dependency tree out of the dependency orders - */ - public DependencyTree buildDependency(ParentComponent component) throws DependencyBuilderException{ - - String identifier = component.getUniqueIdentifier(); - DependencyTree dependencyTree = new DependencyTree(identifier); - DependencyOrder dependencyOrder = component.getDependencyOrder(); - - if (dependencyOrder != null) { - log.info("Building dependency for the Application/Group " + identifier); - - //Parsing the kill behaviour - String terminationBehaviour = dependencyOrder.getTerminationBehaviour(); - - if (Constants.TERMINATE_NONE.equals(terminationBehaviour)) { - dependencyTree.setKillNone(true); - } else if (Constants.TERMINATE_ALL.equals(terminationBehaviour)) { - dependencyTree.setKillAll(true); - } else if (Constants.TERMINATE_DEPENDENTS.equals(terminationBehaviour)) { - dependencyTree.setKillDependent(true); - } - - log.info("Setting the [terminationBehaviour] " + terminationBehaviour + " to the " + - "[dependency-tree] " + dependencyTree.getId()); - - - //Parsing the start up order - Set<StartupOrder> startupOrders = dependencyOrder.getStartupOrders(); - ApplicationContext foundContext; - ApplicationContext parentContext; - - if (startupOrders != null) { - for (StartupOrder startupOrder : startupOrders) { - foundContext = null; - parentContext = null; - for (String start : startupOrder.getStartList()) { - - if (start != null) { - ApplicationContext applicationContext = ApplicationContextFactory. - getApplicationContext(start, component, dependencyTree); - String id = applicationContext.getId(); - - ApplicationContext existingApplicationContext = - dependencyTree.findApplicationContextWithId(id); - if (existingApplicationContext == null) { - if (parentContext != null) { - //appending the start up order to already added parent group/cluster - parentContext.addApplicationContext(applicationContext); - parentContext = applicationContext; - if (log.isDebugEnabled()) { - log.debug("Found an existing [dependency] " + parentContext.getId() + - " and adding the [dependency] " + id + " as the child"); - } - } else { - //adding list of startup order to the dependency tree - dependencyTree.addApplicationContext(applicationContext); - parentContext = applicationContext; - } - } else { - if (foundContext == null) { - //if existing context found, add it to child of existing context and - //set the existing context as the next parent - existingApplicationContext.addApplicationContext(applicationContext); - parentContext = existingApplicationContext; - if (log.isDebugEnabled()) { - log.debug("Found an existing [dependency] " + id + " and setting it " + - "for the next dependency to follow"); - } - } else { - String msg = "Startup order is not consistent. It contains the group/cluster " + - "which has been used more than one in another startup order"; - throw new DependencyBuilderException(msg); - } - - } - } - } - - } - } - //TODO need to parser the scalable dependencies - } - - - //adding the rest of the children who are independent to the top level - // as they can start in parallel. - for (Group group1 : component.getAliasToGroupMap().values()) { - if (dependencyTree.findApplicationContextWithId(group1.getAlias()) == null) { - ApplicationContext context = ApplicationContextFactory. - getGroupContext(group1.getAlias(), dependencyTree.isKillDependent()); - dependencyTree.addApplicationContext(context); - } - } - for (ClusterDataHolder dataHolder : component.getClusterDataMap().values()) { - if (dependencyTree.findApplicationContextWithId(dataHolder.getClusterId()) == null) { - ApplicationContext context = ApplicationContextFactory.getClusterContext(dataHolder, - dependencyTree.isKillDependent()); - dependencyTree.addApplicationContext(context); - - } - } - return dependencyTree; - } -} http://git-wip-us.apache.org/repos/asf/stratos/blob/686d0e06/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyTree.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyTree.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyTree.java deleted file mode 100644 index 05769a6..0000000 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyTree.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.stratos.autoscaler.grouping.dependency; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.grouping.dependency.context.ApplicationContext; - -import java.util.ArrayList; -import java.util.List; - -/** - * This is to contain the dependency tree of an application/group - */ -public class DependencyTree { - private static final Log log = LogFactory.getLog(DependencyTree.class); - - private List<ApplicationContext> applicationContextList; - - private boolean started; - - private boolean terminated; - - private boolean killAll; - - private boolean killNone; - - private boolean killDependent; - - private boolean startupOder; - - private boolean reverseStartupOrder; - - private String id; - - public DependencyTree(String id) { - applicationContextList = new ArrayList<ApplicationContext>(); - this.setId(id); - if (log.isDebugEnabled()) { - log.debug("Starting a dependency tree for the [group/application] " + id); - } - } - - public List<ApplicationContext> getApplicationContextList() { - return applicationContextList; - } - - public void setApplicationContextList(List<ApplicationContext> applicationContextList) { - this.applicationContextList = applicationContextList; - } - - public void addApplicationContext(ApplicationContext applicationContext) { - applicationContextList.add(applicationContext); - - } - - /** - * Find an ApplicationContext from dependency tree with the given id - * - * @param id the alias/id of group/cluster - * @return ApplicationContext of the given id - */ - public ApplicationContext findApplicationContextWithId(String id) { - return findApplicationContextWithId(id, applicationContextList); - } - - /** - * Find the ApplicationContext using Breadth first search. - * - * @param id the alias/id of group/cluster - * @param contexts the list of contexts in the same level of the tree - * @return ApplicationContext of the given id - */ - private ApplicationContext findApplicationContextWithId(String id, List<ApplicationContext> contexts) { - for (ApplicationContext context : contexts) { - //TODO check for the status - if (context.getId().equals(id)) { - return context; - } - } - //if not found in the top level search recursively - for (ApplicationContext context : contexts) { - return findApplicationContextWithId(id, context.getApplicationContextList()); - } - return null; - } - - public ApplicationContext findParentContextWithId(String id) { - return findParentContextWithId(null, id, this.applicationContextList); - } - - public List<ApplicationContext> findAllParentContextWithId(String id) { - List<ApplicationContext> applicationContexts = new ArrayList<ApplicationContext>(); - return findAllParent(applicationContexts, id); - } - - private List<ApplicationContext> findAllParent(List<ApplicationContext> parentContexts, String id) { - ApplicationContext context = findParentContextWithId(null, id, this.applicationContextList); - if (context != null) { - parentContexts.add(context); - findAllParent(parentContexts, context.getId()); - } - return parentContexts; - } - - - private ApplicationContext findParentContextWithId(ApplicationContext parent, String id, - List<ApplicationContext> contexts) { - for (ApplicationContext context : contexts) { - //TODO check for the status - if (context.getId().equals(id)) { - return parent; - } - } - //if not found in the top level search recursively - for (ApplicationContext context : this.applicationContextList) { - return findParentContextWithId(context, id, context.getApplicationContextList()); - } - return null; - } - - /** - * Getting the next start able dependencies upon the activate event - * received for a group/cluster which is part of this tree. - * - * @param id the alias/id of group/cluster which received the activated event. - * @return list of dependencies - */ - public List<ApplicationContext> getStarAbleDependencies(String id) { - //finding the application context which received the activated event and - // returning it's immediate children as the dependencies. - ApplicationContext context = findApplicationContextWithId(id); - return context.getApplicationContextList(); - } - - /** - * Getting the next start able dependencies upon the monitor initialization. - * - * @return list of dependencies - */ - public List<ApplicationContext> getStarAbleDependencies() { - //returning the top level as the monitor is in initializing state - return this.applicationContextList; - } - - public List<ApplicationContext> getStarAbleDependenciesByTermination() { - //Breadth First search over the graph to find out which level has the terminated contexts - return traverseGraphByLevel(this.applicationContextList); - } - - - private List<ApplicationContext> traverseGraphByLevel(List<ApplicationContext> contexts) { - for(ApplicationContext context : contexts) { - if(context.isTerminated()) { - return contexts; - } - } - - for(ApplicationContext context : contexts) { - return traverseGraphByLevel(context.getApplicationContextList()); - } - return null; - } - - - - /** - * When one group/cluster terminates/in_maintenance, need to consider about other - * dependencies - * - * @param id the alias/id of group/cluster in which terminated event received - * @return all the kill able children dependencies - */ - public List<ApplicationContext> getTerminationDependencies(String id) { - List<ApplicationContext> allChildrenOfAppContext = new ArrayList<ApplicationContext>(); - ApplicationContext applicationContext = findApplicationContextWithId(id); - - if (this.killDependent) { - //finding the ApplicationContext of the given id - //finding all the children of the found application context - allChildrenOfAppContext.add(applicationContext); - findAllChildrenOfAppContext(applicationContext.getApplicationContextList(), - allChildrenOfAppContext); - return allChildrenOfAppContext; - } else if (this.killAll) { - //killall will be killed by the monitor from it's list. - findAllChildrenOfAppContext(this.applicationContextList, - allChildrenOfAppContext); - - } - //return empty for the kill-none case, what ever returns here will be killed in - return allChildrenOfAppContext; - } - - /** - * This will help to find out all the children of a particular node - * - * @param applicationContexts app contexts of the particular node - * @param childContexts contains the children of the node - * @return all the children of the given node - */ - public List<ApplicationContext> findAllChildrenOfAppContext(List<ApplicationContext> applicationContexts, - List<ApplicationContext> childContexts) { - for (ApplicationContext context : applicationContexts) { - childContexts.add(context); - findAllChildrenOfAppContext(context.getApplicationContextList(), childContexts); - } - return childContexts; - } - - public boolean isKillAll() { - return killAll; - } - - public void setKillAll(boolean killAll) { - this.killAll = killAll; - } - - public boolean isKillNone() { - return killNone; - } - - public void setKillNone(boolean killNone) { - this.killNone = killNone; - } - - public boolean isStarted() { - return started; - } - - public void setStarted(boolean started) { - this.started = started; - } - - public boolean isTerminated() { - return terminated; - } - - public void setTerminated(boolean terminated) { - this.terminated = terminated; - } - - public boolean isKillDependent() { - return killDependent; - } - - public void setKillDependent(boolean killDependent) { - this.killDependent = killDependent; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public boolean isStartupOder() { - return startupOder; - } - - public void setStartupOder(boolean startupOder) { - this.startupOder = startupOder; - } - - public boolean isReverseStartupOrder() { - return reverseStartupOrder; - } - - public void setReverseStartupOrder(boolean reverseStartupOrder) { - this.reverseStartupOrder = reverseStartupOrder; - } -}
