You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by is...@apache.org on 2013/07/10 18:51:45 UTC
[10/45] fixing component version issues and adding currently
refactored components to the parent pom
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/pom.xml
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/pom.xml b/components/org.apache.stratos.mediator.autoscale/pom.xml
new file mode 100644
index 0000000..e07b9d0
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/pom.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+
+
+<!--
+We need to modify this file since this copied from branch
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.stratos</groupId>
+ <artifactId>stratos-components-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.stratos</groupId>
+ <artifactId>org.apache.stratos.mediator.autoscale</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Stratos - Autoscale Mediator BE</name>
+ <url>http://apache.org</url>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Bundle-Name>${project.artifactId}</Bundle-Name>
+ <Export-Package>
+ !org.org.apache.stratos.mediator.autoscale.lbautoscale.internal,
+ org.apache.stratos.mediator.autoscale.*
+ </Export-Package>
+ <Private-Package>org.apache.stratos.mediator.autoscale.lbautoscale.internal</Private-Package>
+ <Import-Package>
+ !javax.xml.namespace,
+ javax.xml.namespace; version=0.0.0,
+ !org.apache.commons.logging,
+ org.apache.commons.logging; version=0.0.0,
+ org.apache.axis2.*,
+ org.apache.synapse.*,
+ org.wso2.carbon.task.*; version=0.0.0,
+ org.wso2.carbon.core.*,
+ org.apache.stratos.lb.common.*,
+ org.apache.stratos.load.balance.cartridge.autoscaler.service.stub.*; version=0.0.0,
+ org.wso2.carbon.utils.*,
+ org.apache.axiom.om; version="${axiom.osgi.version.range}",
+ org.apache.stratos.cloud.controller.*,
+ *; resolution:=optional
+ </Import-Package>
+ <DynamicImport-Package>*</DynamicImport-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.axis2.wso2</groupId>
+ <artifactId>axis2</artifactId>
+ <version>1.6.1.wso2v9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.synapse</groupId>
+ <artifactId>synapse-core</artifactId>
+ <version>${synapse.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stratos</groupId>
+ <artifactId>org.apache.stratos.load.balance.cartridge.autoscaler.service.stub</artifactId>
+ <version>${apache.stratos.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wso2.carbon</groupId>
+ <artifactId>org.wso2.carbon.core</artifactId>
+ <version>${wso2carbon.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wso2.carbon</groupId>
+ <artifactId>org.wso2.carbon.utils</artifactId>
+ <version>${wso2carbon.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stratos</groupId>
+ <artifactId>org.apache.stratos.lb.common</artifactId>
+ <version>${apache.stratos.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stratos</groupId>
+ <artifactId>org.apache.stratos.cloud.controller</artifactId>
+ <version>${apache.stratos.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wso2.carbon</groupId>
+ <artifactId>org.wso2.carbon.task</artifactId>
+ <version>${wso2carbon.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.synapse</groupId>
+ <artifactId>synapse-tasks</artifactId>
+ <version>2.1.1-wso2v4</version>
+ </dependency>
+
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AppNodeSanityCheckCallable.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AppNodeSanityCheckCallable.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AppNodeSanityCheckCallable.java
new file mode 100644
index 0000000..c535489
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AppNodeSanityCheckCallable.java
@@ -0,0 +1,86 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.callables;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.lb.common.conf.LoadBalancerConfiguration.ServiceConfiguration;
+import org.apache.stratos.mediator.autoscale.lbautoscale.clients.CloudControllerClient;
+import org.apache.stratos.mediator.autoscale.lbautoscale.context.AppDomainContext;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscaleUtil;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+
+import java.util.concurrent.Callable;
+
+/** Performing sanity checks for each service domain, sub domain combination **/
+public class AppNodeSanityCheckCallable implements Callable<Boolean> {
+
+ private static final Log log = LogFactory.getLog(AppNodeSanityCheckCallable.class);
+ private String domain;
+ private String subDomain;
+ private CloudControllerClient client;
+ private AppDomainContext appDomainContext;
+ private ServiceConfiguration serviceConfig;
+
+ public AppNodeSanityCheckCallable(String domain, String subDomain, CloudControllerClient client, AppDomainContext appCtxt){
+ this.domain = domain;
+ this.subDomain = subDomain;
+ this.client = client;
+ this.appDomainContext = appCtxt;
+ serviceConfig =
+ AutoscalerTaskDSHolder.getInstance().getWholeLoadBalancerConfig().getServiceConfig(this.domain,
+ this.subDomain);
+ }
+
+ @Override
+ public Boolean call() throws Exception {
+
+ if (appDomainContext != null) {
+ int currentInstances = 0;
+ // we're considering both running and pending instance count
+ currentInstances = appDomainContext.getInstances();
+
+ int requiredInstances = serviceConfig.getMinAppInstances();
+
+ // we try to maintain the minimum number of instances required
+ if (currentInstances < requiredInstances) {
+ log.debug("App domain Sanity check failed for " +
+ AutoscaleUtil.domainSubDomainString(domain, subDomain) +
+ " . Current instances: " +
+ currentInstances +
+ ". Required instances: " +
+ requiredInstances);
+
+ int diff = requiredInstances - currentInstances;
+
+ // Launch diff number of App instances
+ log.debug("Launching " +
+ diff +
+ " App instances for " +AutoscaleUtil.domainSubDomainString(domain, subDomain));
+
+ // FIXME: should we need to consider serviceConfig.getInstancesPerScaleUp()?
+ AutoscaleUtil.runInstances(client, appDomainContext, this.domain, this.subDomain, diff);
+ }
+ }
+
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AutoscaleDeciderCallable.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AutoscaleDeciderCallable.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AutoscaleDeciderCallable.java
new file mode 100644
index 0000000..84705bb
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/AutoscaleDeciderCallable.java
@@ -0,0 +1,241 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.callables;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.lb.common.conf.LoadBalancerConfiguration.ServiceConfiguration;
+import org.apache.stratos.mediator.autoscale.lbautoscale.clients.CloudControllerClient;
+import org.apache.stratos.mediator.autoscale.lbautoscale.context.AppDomainContext;
+import org.apache.stratos.mediator.autoscale.lbautoscale.state.check.TerminatingInstancesStateChecker;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscaleUtil;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+
+import java.util.concurrent.Callable;
+
+/** Take auto-scaling decisions for each service domain, sub domain combination **/
+public class AutoscaleDeciderCallable implements Callable<Boolean> {
+
+ private static final Log log = LogFactory.getLog(AutoscaleDeciderCallable.class);
+ private String domain;
+ private String subDomain;
+ private CloudControllerClient client;
+ private AppDomainContext appDomainContext;
+ private ServiceConfiguration serviceConfig;
+ private String clusterStr;
+
+ public AutoscaleDeciderCallable(String domain, String subDomain, CloudControllerClient client, AppDomainContext appCtxt){
+ this.domain = domain;
+ this.subDomain = subDomain;
+ this.client = client;
+ this.appDomainContext = appCtxt;
+ clusterStr = AutoscaleUtil.domainSubDomainString(domain, subDomain);
+ }
+
+ @Override
+ public Boolean call() throws Exception {
+
+ // expire tokens
+ if (appDomainContext != null) {
+ appDomainContext.expireRequestTokens();
+
+ serviceConfig = appDomainContext.getServiceConfig();
+
+ appDomainContext.recordRequestTokenListLength();
+ if (!appDomainContext.canMakeScalingDecision()) {
+ return true;
+ }
+
+ long average = appDomainContext.getAverageRequestsInFlight();
+ int runningAppInstances = appDomainContext.getRunningInstanceCount();
+ int terminatingAppInstances = appDomainContext.getTerminatingInstanceCount();
+
+ int maxRPS = serviceConfig.getMaxRequestsPerSecond();
+ double taskInterval =
+ AutoscalerTaskDSHolder
+ .getInstance()
+ .getWholeLoadBalancerConfig()
+ .getLoadBalancerConfig()
+ .getAutoscalerTaskInterval() / (double)1000;
+ double aur = serviceConfig.getAlarmingUpperRate();
+ double alr = serviceConfig.getAlarmingLowerRate();
+ double scaleDownFactor = serviceConfig.getScaleDownFactor();
+
+ // scale up early
+ double maxhandleableReqs = maxRPS * taskInterval * aur;
+ // scale down slowly
+ double minhandleableReqs = maxRPS * taskInterval * alr * scaleDownFactor;
+
+ if (log.isDebugEnabled()) {
+ log.debug(clusterStr +": Average requests in flight: " + average + " **** Handleable requests: " +
+ (runningAppInstances * maxhandleableReqs));
+ }
+ if (average > (runningAppInstances * maxhandleableReqs) && maxhandleableReqs > 0) {
+
+ // estimate number of instances we might want to spawn
+ int requiredInstances = (int) Math.ceil(average/maxhandleableReqs);
+
+ log.debug(clusterStr+" : Required instance count: "+requiredInstances);
+
+ // current average is higher than that can be handled by current nodes.
+ scaleUp(requiredInstances - runningAppInstances);
+ } else if (terminatingAppInstances == 0 && average < ((runningAppInstances - 1) * minhandleableReqs)) {
+ // current average is less than that can be handled by (current nodes - 1).
+ scaleDown();
+ }
+ }
+
+ return true;
+ }
+
+ private void scaleDown() {
+
+ int runningInstances = appDomainContext.getRunningInstanceCount();
+// int pendingInstances = appDomainContext.getPendingInstanceCount();
+ int terminatingInstances = appDomainContext.getTerminatingInstanceCount();
+ int minAppInstances = serviceConfig.getMinAppInstances();
+// int serverStartupDelay = AutoscalerTaskDSHolder
+// .getInstance()
+// .getWholeLoadBalancerConfig()
+// .getLoadBalancerConfig()
+// .getServerStartupDelay();
+
+ if ( (runningInstances - terminatingInstances) > minAppInstances) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Scale Down - " +
+ clusterStr +
+ ". Running instances:" +
+ runningInstances +
+ ". Terminating instances: " +
+ terminatingInstances +
+ ". Min instances:" +
+ minAppInstances);
+ }
+ // ask to scale down
+ try {
+ if (client.terminateInstance(domain, subDomain)) {
+
+ Thread th = new Thread(new TerminatingInstancesStateChecker(appDomainContext, domain, subDomain));
+ th.start();
+
+// log.debug(clusterStr +": There's an instance who's in shutting down state " +
+// "(but still not left ELB), hence we should wait till " +
+// "it leaves the cluster.");
+//
+// int totalWaitedTime = 0;
+//
+// log.debug(clusterStr +": Task will wait maximum of (milliseconds) : " +
+// serverStartupDelay +
+// ", to let the member leave the cluster.");
+//
+// // for each sub domain, get the clustering group management agent
+// GroupManagementAgent agent =
+// AutoscalerTaskDSHolder.getInstance().getAgent()
+// .getGroupManagementAgent(domain,
+// subDomain);
+//
+// // we give some time for the server to be terminated, we'll check time to time
+// // whether the instance has actually left the cluster.
+// while (agent.getMembers().size() == runningInstances &&
+// totalWaitedTime < serverStartupDelay) {
+//
+// try {
+// Thread.sleep(AutoscaleConstants.INSTANCE_REMOVAL_CHECK_TIME);
+// } catch (InterruptedException ignore) {
+// }
+//
+// totalWaitedTime += AutoscaleConstants.INSTANCE_REMOVAL_CHECK_TIME;
+// }
+//
+// log.debug(clusterStr+ " : task waited for (milliseconds) : " + totalWaitedTime);
+//
+// // we recalculate number of alive instances
+// runningInstances = agent.getMembers().size();
+//
+// appDomainContext.setRunningInstanceCount(runningInstances);
+//
+// log.debug(clusterStr+" : New running instance count: " + runningInstances);
+ }
+
+ } catch (Exception e) {
+ log.error("Instance termination failed for " + clusterStr, e);
+ }
+ }
+
+ }
+
+ private void scaleUp(int requiredInstanceCount) {
+
+ int maxAppInstances = serviceConfig.getMaxAppInstances();
+// int instancesPerScaleUp = serviceConfig.getInstancesPerScaleUp();
+// int runningInstances = appDomainContext.getRunningInstanceCount();
+// int pendingInstances = appDomainContext.getPendingInstanceCount();
+ int totalInstanceCount = appDomainContext.getInstances();
+
+ log.debug(AutoscaleUtil.domainSubDomainString(domain, subDomain)+ " - Total Running/Pending instance count: "+totalInstanceCount);
+
+ if(maxAppInstances > totalInstanceCount){
+
+ int availableQuotaOfInstances = maxAppInstances - totalInstanceCount;
+
+ log.debug(AutoscaleUtil.domainSubDomainString(domain, subDomain)+ " - Available Quota of Instances: "+availableQuotaOfInstances);
+
+ requiredInstanceCount = requiredInstanceCount <= availableQuotaOfInstances ? requiredInstanceCount : availableQuotaOfInstances;
+
+ log.debug(clusterStr + " - Going to start " +
+ requiredInstanceCount + " instance/s.");
+
+ AutoscaleUtil.runInstances(client, appDomainContext, domain, subDomain,
+ requiredInstanceCount);
+
+ } else if (totalInstanceCount > maxAppInstances) {
+ log.fatal("Number of running instances has over reached the maximum limit of " +
+ maxAppInstances + " of " + clusterStr);
+ }
+
+// int failedInstances = 0;
+// if (runningInstances < maxAppInstances && pendingInstances == 0) {
+//
+// log.debug(clusterStr + " - Going to start " +
+// requiredInstanceCount + " instance/s. Running instances:" + runningInstances);
+//
+// AutoscaleUtil.runInstances(client, appDomainContext, domain, subDomain,
+// requiredInstanceCount);
+
+// if (successfullyStarted != instancesPerScaleUp) {
+// failedInstances = instancesPerScaleUp - successfullyStarted;
+// if (log.isDebugEnabled()) {
+// log.debug(successfullyStarted +
+// " instances successfully started and\n" + failedInstances +
+// " instances failed to start for " + clusterStr);
+// }
+// }
+//
+// // we increment the pending instance count
+// // appDomainContext.incrementPendingInstances(instancesPerScaleUp);
+// else {
+// log.debug("Successfully started " + successfullyStarted +
+// " instances of " + clusterStr);
+// }
+
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/InstanceCountCallable.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/InstanceCountCallable.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/InstanceCountCallable.java
new file mode 100644
index 0000000..90c2c3a
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/InstanceCountCallable.java
@@ -0,0 +1,78 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.callables;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.mediator.autoscale.lbautoscale.clients.CloudControllerClient;
+import org.apache.stratos.mediator.autoscale.lbautoscale.context.AppDomainContext;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/** Calculate instances of each service domain, sub domain combination **/
+public class InstanceCountCallable implements Callable<Boolean> {
+
+ private static final Log log = LogFactory.getLog(InstanceCountCallable.class);
+ private String domain;
+ private String subDomain;
+ private CloudControllerClient client;
+ private AppDomainContext appCtxt;
+ private ExecutorService executor = Executors.newFixedThreadPool(10);
+
+ public InstanceCountCallable(String domain, String subDomain, CloudControllerClient client, AppDomainContext appCtxt){
+ this.domain = domain;
+ this.subDomain = subDomain;
+ this.client = client;
+ this.appCtxt = appCtxt;
+ }
+
+ @Override
+ public Boolean call() throws Exception {
+ log.debug("Computation of instance counts started for domain: " + this.domain +
+ " and sub domain: " + this.subDomain);
+
+ Callable<Integer> worker = new RunningInstanceCountCallable(this.domain, this.subDomain);
+ Future<Integer> runningInstanceCount = executor.submit(worker);
+
+// worker = new PendingInstanceCountCallable(this.domain, this.subDomain, client);
+// Future<Integer> pendingInstanceCount = executor.submit(worker);
+
+ int runningInstances = 0, pendingInstances = 0;
+ if (appCtxt != null) {
+
+ try {
+ // get the values of Callables
+ runningInstances = runningInstanceCount.get();
+ pendingInstances = appCtxt.getPendingInstanceCount();
+ } catch (Exception e) {
+ // no need to throw
+ log.error(e.getMessage(), e);
+ }
+
+ appCtxt.setRunningInstanceCount(runningInstances);
+ appCtxt.setPendingInstanceCount(pendingInstances);
+
+ }
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/PendingInstanceCountCallable.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/PendingInstanceCountCallable.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/PendingInstanceCountCallable.java
new file mode 100644
index 0000000..27cf50e
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/PendingInstanceCountCallable.java
@@ -0,0 +1,65 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.callables;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.mediator.autoscale.lbautoscale.clients.CloudControllerClient;
+
+import java.util.concurrent.Callable;
+
+/** Calculate pending instances of each service domain, sub domain combination **/
+public class PendingInstanceCountCallable implements Callable<Integer> {
+
+ private static final Log log = LogFactory.getLog(PendingInstanceCountCallable.class);
+ private String domain;
+ private String subDomain;
+ private CloudControllerClient client;
+
+ public PendingInstanceCountCallable(String domain, String subDomain, CloudControllerClient client){
+ this.domain = domain;
+ this.subDomain = subDomain;
+ this.client = client;
+ }
+
+ @Override
+ public Integer call() throws Exception {
+ int pendingInstanceCount = 0;
+
+ try {
+ pendingInstanceCount =
+ client.getPendingInstanceCount(this.domain,
+ this.subDomain);
+
+ } catch (Exception e) {
+ log.error("Failed to retrieve pending instance count for domain: " +
+ this.domain + " and sub domain: " + this.subDomain, e);
+ }
+
+ log.debug("Pending instance count for domain: " +
+ this.domain +
+ ", sub domain: " +
+ this.subDomain +
+ " is " +
+ pendingInstanceCount);
+
+ return pendingInstanceCount;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/RunningInstanceCountCallable.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/RunningInstanceCountCallable.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/RunningInstanceCountCallable.java
new file mode 100644
index 0000000..3bc3db5
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/callables/RunningInstanceCountCallable.java
@@ -0,0 +1,68 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.callables;
+
+import org.apache.axis2.clustering.management.GroupManagementAgent;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+
+import java.util.concurrent.Callable;
+
+/** Calculate running instances of each service domain, sub domain combination **/
+public class RunningInstanceCountCallable implements Callable<Integer> {
+
+ private static final Log log = LogFactory.getLog(RunningInstanceCountCallable.class);
+ private String domain;
+ private String subDomain;
+
+ public RunningInstanceCountCallable(String domain, String subDomain){
+ this.domain = domain;
+ this.subDomain = subDomain;
+ }
+
+ @Override
+ public Integer call() throws Exception {
+ int runningInstances;
+ // for each sub domain, get the clustering group management agent
+ GroupManagementAgent agent =
+ AutoscalerTaskDSHolder.getInstance().getAgent()
+ .getGroupManagementAgent(this.domain,
+ this.subDomain);
+
+ // if it isn't null
+ if (agent != null) {
+ // we calculate running instance count for this service domain
+ runningInstances = agent.getMembers().size();
+ } else {
+ // if agent is null, we assume no service instances are running
+ runningInstances = 0;
+ }
+
+ log.debug("Running instance count for domain: " +
+ this.domain +
+ ", sub domain: " +
+ this.subDomain +
+ " is " +
+ runningInstances);
+
+ return runningInstances;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerClient.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerClient.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerClient.java
new file mode 100644
index 0000000..ec9e1bb
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerClient.java
@@ -0,0 +1,66 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.clients;
+
+/**
+ * Each Implementation which provides access to Cloud Controller, should implement this interface.
+ */
+public abstract class CloudControllerClient {
+
+ /**
+ * Initializes the client.
+ */
+ public abstract void init();
+
+ /**
+ * Should start an instance.
+ * @param domainName clustering domain.
+ * @param subDomainName clustering sub domain.
+ * @return Public IP of the spawned instance.
+ * @throws Exception
+ */
+ public abstract String startInstance(String domainName, String subDomainName) throws Exception;
+
+ /**
+ * Terminates an instance belongs to the given cluster.
+ * @param domainName clustering domain.
+ * @param subDomainName clustering sub domain.
+ * @return whether the termination is successful or not.
+ * @throws Exception
+ */
+ public abstract boolean terminateInstance(String domainName, String subDomainName) throws Exception;
+
+ /**
+ * Terminates lastly spawned instance of the given cluster.
+ * @param domainName clustering domain.
+ * @param subDomainName clustering sub domain.
+ * @return whether the termination is successful or not.
+ * @throws Exception
+ */
+ public abstract boolean terminateLastlySpawnedInstance(String domainName, String subDomainName) throws Exception;
+
+ /**
+ * Return pending instance count of the given cluster.
+ * @param domainName clustering domain.
+ * @param subDomainName clustering sub domain.
+ * @return pending instance count.
+ * @throws Exception
+ */
+ public abstract int getPendingInstanceCount(String domainName, String subDomainName) throws Exception;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerOsgiClient.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerOsgiClient.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerOsgiClient.java
new file mode 100644
index 0000000..907a894
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerOsgiClient.java
@@ -0,0 +1,82 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.clients;
+
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.interfaces.CloudControllerService;
+
+/**
+ * This is the client class this calls Autoscaler service.
+ */
+public class CloudControllerOsgiClient extends CloudControllerClient {
+
+ private CloudControllerService cloudControllerService;
+
+ private static final Log log = LogFactory.getLog(CloudControllerOsgiClient.class);
+
+ // public CloudControllerStubClient(String epr) throws AxisFault {
+ //
+ // try {
+ //
+ // stub = new CloudControllerServiceStub(epr);
+ // stub._getServiceClient().getOptions().setTimeOutInMilliSeconds(90000);
+ //
+ // } catch (AxisFault axisFault) {
+ // String msg =
+ // "Failed to initiate AutoscalerService client. " + axisFault.getMessage();
+ // log.error(msg, axisFault);
+ // throw new AxisFault(msg, axisFault);
+ // }
+ // }
+
+ // public boolean init(boolean isSpi) throws Exception {
+ //
+ // return stub.initAutoscaler(isSpi);
+ // }
+
+ public String startInstance(String domainName, String subDomainName) throws Exception {
+
+ return cloudControllerService.startInstance(domainName, subDomainName);
+ }
+
+ public boolean terminateInstance(String domainName, String subDomainName) throws Exception {
+
+ return cloudControllerService.terminateInstance(domainName, subDomainName);
+ }
+
+ public boolean
+ terminateLastlySpawnedInstance(String domainName, String subDomainName) throws Exception {
+
+ return cloudControllerService.terminateLastlySpawnedInstance(domainName, subDomainName);
+ }
+
+ public int getPendingInstanceCount(String domainName, String subDomainName) throws Exception {
+
+ return cloudControllerService.getPendingInstanceCount(domainName, subDomainName);
+ }
+
+ @Override
+ public void init() {
+
+ cloudControllerService = AutoscalerTaskDSHolder.getInstance().getCloudControllerService();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerStubClient.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerStubClient.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerStubClient.java
new file mode 100644
index 0000000..34954e9
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/clients/CloudControllerStubClient.java
@@ -0,0 +1,93 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.clients;
+
+import org.apache.axis2.AxisFault;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.stub.CloudControllerServiceStub;
+
+/**
+ * This is the client class this calls Autoscaler service.
+ */
+public class CloudControllerStubClient extends CloudControllerClient {
+
+ private CloudControllerServiceStub stub;
+ private static final String CLOUD_CONTROLLER_EPR = AutoscalerTaskDSHolder.getInstance().getLoadBalancerConfig().getAutoscalerServiceEpr();
+
+ private static final Log log = LogFactory.getLog(CloudControllerStubClient.class);
+
+ // public CloudControllerStubClient(String epr) throws AxisFault {
+ //
+ // try {
+ //
+ // stub = new CloudControllerServiceStub(epr);
+ // stub._getServiceClient().getOptions().setTimeOutInMilliSeconds(90000);
+ //
+ // } catch (AxisFault axisFault) {
+ // String msg =
+ // "Failed to initiate AutoscalerService client. " + axisFault.getMessage();
+ // log.error(msg, axisFault);
+ // throw new AxisFault(msg, axisFault);
+ // }
+ // }
+
+ // public boolean init(boolean isSpi) throws Exception {
+ //
+ // return stub.initAutoscaler(isSpi);
+ // }
+
+ public String startInstance(String domainName, String subDomainName) throws Exception {
+
+ return stub.startInstance(domainName, subDomainName);
+ }
+
+ public boolean terminateInstance(String domainName, String subDomainName) throws Exception {
+
+ return stub.terminateInstance(domainName, subDomainName);
+ }
+
+ public boolean
+ terminateLastlySpawnedInstance(String domainName, String subDomainName) throws Exception {
+
+ return stub.terminateLastlySpawnedInstance(domainName, subDomainName);
+ }
+
+ public int getPendingInstanceCount(String domainName, String subDomainName) throws Exception {
+
+ return stub.getPendingInstanceCount(domainName, subDomainName);
+ }
+
+ @Override
+ public void init() {
+
+ try {
+
+ stub = new CloudControllerServiceStub(CLOUD_CONTROLLER_EPR);
+ stub._getServiceClient().getOptions().setTimeOutInMilliSeconds(300000);
+
+ } catch (AxisFault axisFault) {
+ String msg = "Failed to initiate AutoscalerService client. " + axisFault.getMessage();
+ log.error(msg, axisFault);
+ throw new RuntimeException(msg, axisFault);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/AppDomainContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/AppDomainContext.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/AppDomainContext.java
new file mode 100644
index 0000000..f8155a7
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/AppDomainContext.java
@@ -0,0 +1,170 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.context;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.lb.common.conf.LoadBalancerConfiguration;
+
+
+/**
+ * Contextual information related to autoscaling for a particular clustering domain
+ */
+public class AppDomainContext extends LoadBalancerContext{
+
+ private static final long serialVersionUID = 6582721801663800609L;
+
+ private static final Log log = LogFactory.getLog(AppDomainContext.class);
+
+ /**
+ * Request tokens of requests in flight
+ * <p/>
+ * Key - request token ID, Value - message received time
+ */
+ private Map<String, Long> requestTokens = new ConcurrentHashMap<String, Long>();
+ private List<Integer> requestTokenListLengths;
+ private LoadBalancerConfiguration.ServiceConfiguration serviceConfig;
+
+ public AppDomainContext(LoadBalancerConfiguration.ServiceConfiguration serviceConfig) {
+ this.serviceConfig = serviceConfig;
+ requestTokenListLengths = new Vector<Integer>(serviceConfig.getRoundsToAverage());
+ }
+
+ public LoadBalancerConfiguration.ServiceConfiguration getServiceConfig() {
+ return serviceConfig;
+ }
+
+ /**
+ * If there is insufficient number of messages we cannot make a scaling decision.
+ *
+ * @return true - if a scaling decision can be made
+ */
+ public boolean canMakeScalingDecision() {
+ return requestTokenListLengths.size() >= serviceConfig.getRoundsToAverage();
+ }
+
+ public void addRequestToken(String tokenId) {
+ requestTokens.put(tokenId, System.currentTimeMillis());
+ if (log.isDebugEnabled()) {
+ log.debug("Request Tokens Added : "+requestTokens.size());
+ }
+ }
+
+ public void removeRequestToken(String tokenId) {
+ requestTokens.remove(tokenId);
+ }
+
+// public int getRunningInstanceCount() {
+// return super.getRunningInstanceCount();
+// }
+
+ /**
+ * This will set the running instance count for this app domain
+ * and also will return the difference of current running instance count and previous count.
+ * @param runningInstanceCount current running instance count
+ * @return difference of current running instance count and previous count.
+ */
+// public int setRunningInstanceCount(int runningInstanceCount) {
+// int diff = 0;
+//
+// if(this.runningInstanceCount < runningInstanceCount){
+// diff = runningInstanceCount - this.runningInstanceCount;
+// }
+//
+// this.runningInstanceCount = runningInstanceCount;
+//
+// return diff;
+// }
+
+ public void expireRequestTokens() {
+ for (Map.Entry<String, Long> entry : requestTokens.entrySet()) {
+ if (System.currentTimeMillis() - entry.getValue() >= serviceConfig.getMessageExpiryTime()) {
+ requestTokens.remove(entry.getKey());
+ if (log.isDebugEnabled()) {
+ log.debug("Request Tokens Expired : " + requestTokens.get(entry.getKey()));
+ }
+ }
+ }
+ }
+
+ public void recordRequestTokenListLength() {
+ if (requestTokenListLengths.size() >= serviceConfig.getRoundsToAverage()) {
+ int count = requestTokenListLengths.remove(0);
+ if (log.isDebugEnabled()) {
+ log.debug("Request Tokens Removed : " + count);
+ }
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Request Tokens Added : " + requestTokens.size());
+ }
+ requestTokenListLengths.add(requestTokens.size());
+ }
+
+
+// public synchronized int getPendingInstances() {
+// return pendingInstances;
+// }
+
+// public synchronized void incrementPendingInstances() {
+// this.pendingInstances++;
+// }
+
+// public synchronized void decrementPendingInstancesIfNotZero(int diff) {
+//
+// while (diff > 0 && this.pendingInstances > 0 ){
+// this.pendingInstances--;
+// diff--;
+// }
+//
+// }
+
+// public synchronized int getInstances() {
+// return runningInstanceCount + pendingInstances;
+// }
+
+ /**
+ * Get the average requests in flight, averaged over the number of of observations rounds
+ *
+ * @return number of average requests in flight. -1 if there no requests were received
+ */
+ public long getAverageRequestsInFlight() {
+ long total = 0;
+ for (Integer messageQueueLength : requestTokenListLengths) {
+ total += messageQueueLength;
+ }
+ int size = requestTokenListLengths.size();
+ if (size == 0) {
+ return -1; // -1 means that no requests have been received
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Total Tokens : "+total+ " : Size: "+size);
+ }
+ return (long) total / size;
+ }
+
+
+// public synchronized void resetRunningPendingInstances() {
+// pendingInstances = 0;
+// runningInstanceCount = 0;
+// }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/LoadBalancerContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/LoadBalancerContext.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/LoadBalancerContext.java
new file mode 100644
index 0000000..b6a6d9b
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/context/LoadBalancerContext.java
@@ -0,0 +1,104 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.context;
+
+import java.io.Serializable;
+
+/**
+ * Contextual information related to autoscaling for a particular domain
+ */
+public class LoadBalancerContext implements Serializable{
+
+ private static final long serialVersionUID = -2022110665957598060L;
+ private int runningInstances;
+ private int pendingInstances;
+ private int terminatingInstances;
+
+ public synchronized int getTerminatingInstanceCount() {
+ return terminatingInstances;
+ }
+
+ public synchronized int getRunningInstanceCount() {
+ return runningInstances;
+ }
+
+ public synchronized int getPendingInstanceCount() {
+ return pendingInstances;
+ }
+
+ /**
+ * This will set the running instance count for a domain
+ * and also will return the difference of current running instance count and previous count.
+ * @param runningInstanceCount current running instance count
+ * @return difference of current running instance count and previous count.
+ */
+ public synchronized int setRunningInstanceCount(int count) {
+ int diff = 0;
+
+ if (this.runningInstances < count) {
+ diff = count - this.runningInstances;
+ }
+
+ this.runningInstances = count;
+
+ return diff;
+ }
+
+ public synchronized int getInstances() {
+ return runningInstances + pendingInstances;
+ }
+
+ public synchronized void setPendingInstanceCount(int count) {
+
+ this.pendingInstances = count;
+ }
+
+ public synchronized void setTerminatingInstanceCount(int count) {
+
+ this.terminatingInstances = count;
+ }
+
+ public synchronized void incrementPendingInstances(int diff) {
+
+ this.pendingInstances += diff;
+ }
+
+ public synchronized void incrementTerminatingInstances(int diff) {
+
+ this.terminatingInstances += diff;
+ }
+
+ public synchronized void decrementPendingInstancesIfNotZero(int diff) {
+
+ while (diff > 0 && this.pendingInstances > 0) {
+ this.pendingInstances--;
+ diff--;
+ }
+
+ }
+
+ public synchronized void decrementTerminatingInstancesIfNotZero(int diff) {
+
+ while (diff > 0 && this.terminatingInstances > 0) {
+ this.terminatingInstances--;
+ diff--;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/AutoscalerTaskServiceComponent.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/AutoscalerTaskServiceComponent.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/AutoscalerTaskServiceComponent.java
new file mode 100644
index 0000000..41811eb
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/AutoscalerTaskServiceComponent.java
@@ -0,0 +1,325 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.internal;
+
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.description.Parameter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.lb.common.conf.LoadBalancerConfiguration;
+import org.apache.stratos.lb.common.service.LoadBalancerConfigurationService;
+import org.apache.stratos.mediator.autoscale.lbautoscale.mediators.AutoscaleInMediator;
+import org.apache.stratos.mediator.autoscale.lbautoscale.mediators.AutoscaleOutMediator;
+import org.apache.stratos.mediator.autoscale.lbautoscale.task.*;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+import org.apache.synapse.ManagedLifecycle;
+import org.apache.synapse.Mediator;
+import org.apache.synapse.SynapseConstants;
+import org.apache.synapse.SynapseException;
+import org.apache.synapse.core.SynapseEnvironment;
+import org.apache.synapse.mediators.base.SequenceMediator;
+import org.apache.synapse.mediators.filters.InMediator;
+import org.apache.synapse.mediators.filters.OutMediator;
+import org.apache.synapse.task.Task;
+import org.apache.synapse.task.TaskConstants;
+import org.apache.synapse.task.TaskDescription;
+import org.apache.synapse.task.TaskScheduler;
+import org.apache.synapse.task.service.TaskManagementService;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.quartz.JobBuilder;
+import org.quartz.JobDetail;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.apache.stratos.cloud.controller.interfaces.CloudControllerService;
+import org.wso2.carbon.user.core.service.RealmService;
+import org.wso2.carbon.utils.Axis2ConfigurationContextObserver;
+import org.wso2.carbon.utils.ConfigurationContextService;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @scr.component name="autoscaler.task.component" immediate="true"
+ * @scr.reference name="carbon.core.configurationContextService"
+ * interface="org.wso2.carbon.utils.ConfigurationContextService"
+ * cardinality="1..1" policy="dynamic"
+ * bind="setConfigurationContextService" unbind="unsetConfigurationContextService"
+ * @scr.reference name="user.realmservice.default"
+ * interface="org.wso2.carbon.user.core.service.RealmService"
+ * cardinality="1..1" policy="dynamic" bind="setRealmService"
+ * unbind="unsetRealmService"
+ * @scr.reference name="org.apache.stratos.lb.common"
+ * interface="org.apache.stratos.lb.common.service.LoadBalancerConfigurationService"
+ * cardinality="1..1" policy="dynamic" bind="setLoadBalancerConfigurationService"
+ * unbind="unsetLoadBalancerConfigurationService"
+ * @scr.reference name="registry.service"
+ * interface="org.wso2.carbon.registry.core.service.RegistryService"
+ * cardinality="1..1" policy="dynamic"
+ * bind="setRegistryService" unbind="unsetRegistryService"
+ * @scr.reference name="org.apache.stratos.cloud.controller"
+ * interface="org.apache.stratos.cloud.controller.interfaces.CloudControllerService"
+ * cardinality="1..1" policy="dynamic" bind="setCloudControllerService"
+ * unbind="unsetCloudControllerService"
+ */
+public class AutoscalerTaskServiceComponent {
+
+ private static final Log log = LogFactory.getLog(AutoscalerTaskServiceComponent.class);
+ private ConfigurationContext configurationContext = null;
+
+ protected void activate(ComponentContext context) {
+
+ try{
+
+ // read config file
+// String configURL = System.getProperty(AutoscaleConstants.LOAD_BALANCER_CONFIG);
+// LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration();
+// lbConfig.init(configURL);
+
+ if(configurationContext == null){
+ String msg = "Configuration context is null. Autoscaler task activation failed.";
+ log.fatal(msg);
+ throw new RuntimeException(msg);
+ }
+
+ // load synapse environment
+ Parameter synEnv =
+ configurationContext.getAxisConfiguration().getParameter(SynapseConstants.SYNAPSE_ENV);
+
+ if (synEnv == null || synEnv.getValue() == null ||
+ !(synEnv.getValue() instanceof SynapseEnvironment)) {
+
+ String message = "Unable to initialize the Synapse Configuration : Can not find the ";
+ log.fatal(message + "Synapse Environment");
+ throw new SynapseException(message + "Synapse Environment");
+ }
+
+ SynapseEnvironment synapseEnv = (SynapseEnvironment) synEnv.getValue();
+
+ /** Initializing autoscaleIn and autoscaleOut Mediators.**/
+
+ LoadBalancerConfiguration lbConfig = AutoscalerTaskDSHolder.getInstance().getWholeLoadBalancerConfig();
+ // check whether autoscaling is enabled
+ if (lbConfig.getLoadBalancerConfig().isAutoscaleEnabled()) {
+
+ // get the main sequence mediator
+ SequenceMediator mainSequence =
+ (SequenceMediator) synapseEnv.getSynapseConfiguration().getSequence("main");
+
+ // iterate through its child mediators
+ for (Mediator child : mainSequence.getList()) {
+
+ // find the InMediator
+ if (child instanceof InMediator) {
+ InMediator inSequence = (InMediator) child;
+
+ // if the first child of InMediator isn't an AutoscaleInMediator
+ if (!(inSequence.getList().get(0) instanceof AutoscaleInMediator)) {
+
+ // we gonna add it!
+ inSequence.getList().add(0, new AutoscaleInMediator());
+ if (log.isDebugEnabled()) {
+ log.debug("Added Mediator: " + inSequence.getChild(0) + "" +
+ " to InMediator. Number of child mediators in InMediator" + " is " +
+ inSequence.getList().size() + ".");
+ }
+ }
+
+ }
+
+ // find the OutMediator
+ if (child instanceof OutMediator) {
+
+ OutMediator outSequence = (OutMediator) child;
+
+ // if the first child of OutMediator isn't an AutoscaleOutMediator
+ if (!(outSequence.getList().get(0) instanceof AutoscaleOutMediator)) {
+
+ // we gonna add it!
+ outSequence.getList().add(0, new AutoscaleOutMediator());
+
+ if (log.isDebugEnabled()) {
+ log.debug("Added Mediator: " + outSequence.getChild(0) + "" +
+ " to OutMediator. Number of child mediators in OutMediator" +
+ " is " + outSequence.getList().size() + ".");
+ }
+
+ }
+ }
+ }
+
+ /** Initializing Autoscaler Task **/
+
+ BundleContext bundleContext = context.getBundleContext();
+ if (log.isDebugEnabled()) {
+ log.debug("Initiating Autoscaler task service component");
+ }
+
+ if (bundleContext.getServiceReference(TaskManagementService.class.getName()) != null) {
+ bundleContext.registerService(TaskManagementService.class.getName(),
+ new AutoscalerTaskMgmtAdminService(), null);
+ }
+
+
+ AutoscalerTaskInitializer listener = new AutoscalerTaskInitializer();
+
+ if (bundleContext.getServiceReference(Axis2ConfigurationContextObserver.class.getName()) != null) {
+ bundleContext.registerService(Axis2ConfigurationContextObserver.class.getName(),
+ listener, null);
+ }
+
+ if (configurationContext != null) {
+ TaskScheduler scheduler =
+ (TaskScheduler) configurationContext.getProperty(AutoscalerTaskInitializer.CARBON_TASK_SCHEDULER);
+ if (scheduler == null) {
+ scheduler = new TaskScheduler(TaskConstants.TASK_SCHEDULER);
+ scheduler.init(null);
+ configurationContext.setProperty(AutoscalerTaskInitializer.CARBON_TASK_SCHEDULER,
+ scheduler);
+ } else if (!scheduler.isInitialized()) {
+ scheduler.init(null);
+ }
+ }
+
+ String autoscalerClass = lbConfig.getLoadBalancerConfig().getAutoscalerTaskClass();
+ Task task;
+ if (autoscalerClass != null) {
+ try {
+ task = (Task) Class.forName(autoscalerClass).newInstance();
+ } catch (Exception e) {
+ String msg = "Cannot instantiate Autoscaling Task. Class: " + autoscalerClass
+ +". It should implement 'org.apache.synapse.task.Task' and "
+ +"'org.apache.synapse.ManagedLifecycle' interfaces.";
+ log.error(msg, e);
+ throw new RuntimeException(msg, e);
+ }
+ } else {
+ task = new ServiceRequestsInFlightAutoscaler();
+ }
+
+// ServiceRequestsInFlightAutoscaler autoscalerTask =
+// new ServiceRequestsInFlightAutoscaler();
+
+ ((ManagedLifecycle) task).init(synapseEnv);
+
+ // specify scheduler task details
+ JobBuilder jobBuilder = JobBuilder.newJob(AutoscalingJob.class)
+ .withIdentity("autoscalerJob");
+ JobDetail job = jobBuilder.build();
+
+ Map<String, Object> dataMap = job.getJobDataMap();
+ dataMap.put(AutoscalingJob.AUTOSCALER_TASK, task);
+ dataMap.put(AutoscalingJob.SYNAPSE_ENVI, synapseEnv);
+
+ final TaskDescription taskDescription = new TaskDescription();
+ taskDescription.setTaskClass(ServiceRequestsInFlightAutoscaler.class.getName());
+ taskDescription.setName("autoscaler");
+ //taskDescription.setCount(SimpleTrigger.REPEAT_INDEFINITELY);
+
+ int interval = AutoscalerTaskDSHolder.getInstance().getLoadBalancerConfig().getAutoscalerTaskInterval();
+ taskDescription.setInterval(interval);
+ taskDescription.setStartTime(new Date(System.currentTimeMillis() + (interval*2)));
+
+ TaskSchedulingManager scheduler = new TaskSchedulingManager();
+ scheduler.scheduleTask(taskDescription, dataMap, configurationContext);
+
+
+ } else {
+
+ log.info("Autoscaling is disabled.");
+ }
+ } catch (Throwable e) {
+ log.error("Failed to activate Autoscaler Task Service Component. ", e);
+ }
+ }
+
+
+ protected void deactivate(ComponentContext ctx) {
+ AutoscalerTaskDSHolder.getInstance().setConfigurationContextService(null);
+ if (log.isDebugEnabled()) {
+ log.debug("Autoscaler task bundle is deactivated");
+ }
+ }
+
+ protected void setCloudControllerService(CloudControllerService cc) {
+ AutoscalerTaskDSHolder.getInstance().setCloudControllerService(cc);
+ }
+
+ protected void unsetCloudControllerService(CloudControllerService cc) {
+ AutoscalerTaskDSHolder.getInstance().setCloudControllerService(null);
+ }
+
+ protected void setConfigurationContextService(ConfigurationContextService context) {
+ if (log.isDebugEnabled()) {
+ log.debug("ConfigurationContextService bound to the Autoscaler task initialization process");
+ }
+ this.configurationContext = context.getServerConfigContext();
+ AutoscalerTaskDSHolder.getInstance().setConfigurationContextService(context);
+ }
+
+ protected void unsetConfigurationContextService(ConfigurationContextService configurationContextService) {
+ if (log.isDebugEnabled()) {
+ log.debug("ConfigurationContextService unbound from the Autoscaler task");
+ }
+ this.configurationContext = null;
+ AutoscalerTaskDSHolder.getInstance().setConfigurationContextService(null);
+ }
+
+ protected void setRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Bound realm service from the Autoscaler task");
+ }
+ AutoscalerTaskDSHolder.getInstance().setRealmService(realmService);
+ }
+
+ protected void unsetRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unbound realm service from the Autoscaler task");
+ }
+ AutoscalerTaskDSHolder.getInstance().setRealmService(null);
+ }
+
+ protected void setLoadBalancerConfigurationService(LoadBalancerConfigurationService lbConfigSer){
+ AutoscalerTaskDSHolder.getInstance().setLbConfigService(lbConfigSer);
+ }
+
+ protected void unsetLoadBalancerConfigurationService(LoadBalancerConfigurationService lbConfigSer){
+ AutoscalerTaskDSHolder.getInstance().setLbConfigService(null);
+ }
+
+ protected void setRegistryService(RegistryService regService) {
+ if (log.isDebugEnabled()) {
+ log.debug("RegistryService bound to the endpoint component");
+ }
+ try {
+ AutoscalerTaskDSHolder.getInstance().setConfigRegistry(regService.getConfigSystemRegistry());
+ AutoscalerTaskDSHolder.getInstance().setGovernanceRegistry(regService.getGovernanceSystemRegistry());
+ } catch (RegistryException e) {
+ log.error("Couldn't retrieve the registry from the registry service");
+ }
+ }
+
+ protected void unsetRegistryService(RegistryService regService) {
+ if (log.isDebugEnabled()) {
+ log.debug("RegistryService unbound from the endpoint component");
+ }
+ AutoscalerTaskDSHolder.getInstance().setConfigRegistry(null);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/RegistryManager.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/RegistryManager.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/RegistryManager.java
new file mode 100644
index 0000000..0f5a03d
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/internal/RegistryManager.java
@@ -0,0 +1,54 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.internal;
+
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.lb.common.util.DomainMapping;
+import org.wso2.carbon.registry.core.Resource;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+import org.wso2.carbon.registry.core.session.UserRegistry;
+
+public class RegistryManager {
+ UserRegistry governanceRegistry = AutoscalerTaskDSHolder.getInstance().getGovernanceRegistry();
+ private static final Log log = LogFactory.getLog(RegistryManager.class);
+ /**
+ *
+ */
+ private Resource resource = null;
+ public static final String HOST_INFO = "hostinfo/";
+ public static final String ACTUAL_HOST = "actual.host";
+
+ public DomainMapping getMapping(String hostName) {
+ DomainMapping domainMapping;
+ try {
+ if (governanceRegistry.resourceExists(HOST_INFO + hostName)) {
+ resource = governanceRegistry.get(HOST_INFO + hostName);
+ domainMapping = new DomainMapping(hostName);
+ domainMapping.setActualHost(resource.getProperty(ACTUAL_HOST));
+ return domainMapping;
+ }
+ } catch (RegistryException e) {
+ log.info("Error while getting registry resource");
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleInMediator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleInMediator.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleInMediator.java
new file mode 100644
index 0000000..6ec1da3
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleInMediator.java
@@ -0,0 +1,174 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.mediators;
+
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.stratos.mediator.autoscale.lbautoscale.context.AppDomainContext;
+import org.apache.stratos.mediator.autoscale.lbautoscale.internal.RegistryManager;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscaleConstants;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscaleUtil;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscalerTaskDSHolder;
+import org.apache.http.protocol.HTTP;
+import org.apache.synapse.ManagedLifecycle;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.core.SynapseEnvironment;
+import org.apache.synapse.core.axis2.Axis2MessageContext;
+import org.apache.synapse.mediators.AbstractMediator;
+import org.apache.stratos.lb.common.conf.LoadBalancerConfiguration;
+import org.apache.stratos.lb.common.conf.util.HostContext;
+import org.apache.stratos.lb.common.cache.URLMappingCache;
+import org.apache.stratos.lb.common.util.DomainMapping;
+
+import java.util.Map;
+
+/**
+ * This Synapse mediator generates a token per request received. These tokens are used for tracking
+ * the number of requests in flight. Once a response is received, the relevant token will be removed
+ * by the {@link AutoscaleOutMediator}
+ *
+ * @see AutoscaleOutMediator
+ */
+public class AutoscaleInMediator extends AbstractMediator implements ManagedLifecycle {
+
+ private LoadBalancerConfiguration lbConfig;
+ private Map<String, HostContext> hostCtxts;
+ /**
+ * keep the size of cache which used to keep hostNames of url mapping.
+ */
+ private URLMappingCache mappingCache;
+ private RegistryManager registryManager;
+ private int sizeOfCache;
+
+ public AutoscaleInMediator() {
+
+ this.lbConfig = AutoscalerTaskDSHolder.getInstance().getWholeLoadBalancerConfig();
+ hostCtxts = lbConfig.getHostContextMap();
+ sizeOfCache = lbConfig.getLoadBalancerConfig().getSizeOfCache();
+ mappingCache = URLMappingCache.getInstance(sizeOfCache);
+ }
+
+ public boolean mediate(MessageContext synCtx) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Mediation started .......... " + AutoscaleInMediator.class.getName());
+
+ }
+
+ ConfigurationContext configCtx =
+ ((Axis2MessageContext) synCtx).getAxis2MessageContext()
+ .getConfigurationContext();
+ String uuid = org.apache.axiom.util.UIDGenerator.generateUID();
+ synCtx.setProperty(AutoscaleConstants.REQUEST_ID, uuid);
+
+ Map<String, Map<String, ?>> appDomainContexts =
+ AutoscaleUtil.getAppDomainContexts(configCtx,
+ lbConfig);
+ org.apache.axis2.context.MessageContext axis2MessageContext =
+ ((Axis2MessageContext) synCtx).getAxis2MessageContext();
+ Map<String, String> transportHeaders = (Map<String, String>) axis2MessageContext.
+ getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
+ String targetHost = transportHeaders.get(HTTP.TARGET_HOST);
+
+ String toAddress = synCtx.getTo().getAddress();
+ if (targetHost.contains(":")) {
+ targetHost = targetHost.substring(0, targetHost.indexOf(':'));
+ }
+
+ int tenantId = AutoscaleUtil.getTenantId(synCtx.getTo().toString());
+
+ String domain = null, subDomain = null;
+
+ log.debug("************ Target Host: "+targetHost + " -- Tenant id : "+tenantId);
+
+ HostContext ctxt = hostCtxts.get(targetHost);
+
+ if (ctxt == null) {
+
+ DomainMapping domainMapping = mappingCache.getMapping(targetHost);
+ if (domainMapping == null) {
+ registryManager = new RegistryManager();
+ domainMapping = registryManager.getMapping(targetHost);
+ mappingCache.addValidMapping(targetHost, domainMapping);
+ }
+ if (domainMapping != null) {
+
+ String actualHost = domainMapping.getActualHost();
+
+ // get the HostContext from the actual host name in the case of domain
+ // mapping.
+ ctxt = hostCtxts.get(actualHost);
+
+ }
+ }
+
+ if (ctxt == null) {
+ log.debug("Host Context is null.");
+ // we don't need to do anything
+ return true;
+ }
+
+
+ // gets the corresponding domain
+ domain = ctxt.getDomainFromTenantId(tenantId);
+ synCtx.setProperty(AutoscaleConstants.TARGET_DOMAIN, domain);
+
+ // gets the corresponding sub domain
+ subDomain = ctxt.getSubDomainFromTenantId(tenantId);
+ synCtx.setProperty(AutoscaleConstants.TARGET_SUB_DOMAIN, subDomain);
+
+ if (appDomainContexts.get(domain) == null) {
+ // if we do not find a correct context, we just ignore
+ log.debug("AppDomainContext not found for domain " + domain);
+
+ } else {
+ AppDomainContext appDomainContext = (AppDomainContext) appDomainContexts.get(domain).get(subDomain);
+
+ if (appDomainContext != null) {
+ appDomainContext.addRequestToken(uuid);
+ System.setProperty(AutoscaleConstants.IS_TOUCHED, "true");
+
+ } else {
+ // if we do not find a correct context, we just ignore
+ log.debug("AppDomainContext not found for sub domain: " + subDomain +
+ " of domain: " + domain);
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void destroy() {
+
+ log.info("Mediator destroyed! " + AutoscaleInMediator.class.getName());
+ }
+
+ @Override
+ public void init(SynapseEnvironment arg0) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Mediator initialized! " + AutoscaleInMediator.class.getName());
+ }
+ }
+
+ private void throwException(String msg){
+ log.error(msg);
+ throw new RuntimeException(msg);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleOutMediator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleOutMediator.java b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleOutMediator.java
new file mode 100644
index 0000000..3640c08
--- /dev/null
+++ b/components/org.apache.stratos.mediator.autoscale/src/main/java/org/apache/stratos/mediator/autoscale/lbautoscale/mediators/AutoscaleOutMediator.java
@@ -0,0 +1,78 @@
+/**
+ * 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.mediator.autoscale.lbautoscale.mediators;
+
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.stratos.mediator.autoscale.lbautoscale.util.AutoscaleConstants;
+import org.apache.synapse.ManagedLifecycle;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.core.SynapseEnvironment;
+import org.apache.synapse.core.axis2.Axis2MessageContext;
+import org.apache.synapse.mediators.AbstractMediator;
+import org.apache.stratos.mediator.autoscale.lbautoscale.context.AppDomainContext;
+
+import java.util.Map;
+
+/**
+ * This Synapse mediator removes the request token generated by the {@link AutoscaleInMediator}
+ *
+ * @see AutoscaleInMediator
+ */
+public class AutoscaleOutMediator extends AbstractMediator implements ManagedLifecycle {
+
+ public boolean mediate(MessageContext synCtx) {
+
+ log.debug("Mediation started ....... " + AutoscaleOutMediator.class.getName());
+
+ ConfigurationContext configCtx =
+ ((Axis2MessageContext) synCtx).getAxis2MessageContext().getConfigurationContext();
+
+ String domain = (String) synCtx.getProperty(AutoscaleConstants.TARGET_DOMAIN);
+ // gets the corresponding sub domain
+ String subDomain = (String) synCtx.getProperty(AutoscaleConstants.TARGET_SUB_DOMAIN);
+
+ String tokenId = (String) synCtx.getProperty(AutoscaleConstants.REQUEST_ID);
+ @SuppressWarnings("unchecked")
+ Map<String, Map<String, AppDomainContext>> appDomainContexts =
+ (Map<String, Map<String, AppDomainContext>>) configCtx.getPropertyNonReplicable(AutoscaleConstants.APP_DOMAIN_CONTEXTS);
+ AppDomainContext appDomainContext = null ;
+
+ if(appDomainContexts.get(domain) != null){
+ appDomainContext = appDomainContexts.get(domain).get(subDomain);
+ }
+
+ if (appDomainContext != null) {
+ appDomainContext.removeRequestToken(tokenId);
+ System.setProperty(AutoscaleConstants.IS_TOUCHED, "true");
+ } else {
+ log.debug("AppDomainContext not found for domain " + domain+" and sub domain : "+subDomain);
+ }
+ return true;
+ }
+
+ @Override
+ public void destroy() {
+ log.debug("Autoscale out mediator destroyed...");
+ }
+
+ @Override
+ public void init(SynapseEnvironment arg0) {
+ log.debug("Autoscale out mediator started...");
+ }
+}