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:58 UTC
[23/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.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/impl/AutoscalerServiceImpl.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/impl/AutoscalerServiceImpl.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/impl/AutoscalerServiceImpl.java
new file mode 100644
index 0000000..b87cb50
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/impl/AutoscalerServiceImpl.java
@@ -0,0 +1,1389 @@
+/**
+ * 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.service.impl;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.synapse.SynapseException;
+import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadata.Status;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.domain.internal.NodeMetadataImpl;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
+import org.apache.stratos.autoscaler.service.IAutoscalerService;
+import org.apache.stratos.autoscaler.service.exception.AutoscalerServiceException;
+import org.apache.stratos.autoscaler.service.exception.DeserializationException;
+import org.apache.stratos.autoscaler.service.exception.SerializationException;
+import org.apache.stratos.autoscaler.service.io.Deserializer;
+import org.apache.stratos.autoscaler.service.io.Serializer;
+import org.apache.stratos.autoscaler.service.jcloud.ComputeServiceBuilder;
+import org.apache.stratos.autoscaler.service.util.AutoscalerConstant;
+import org.apache.stratos.autoscaler.service.util.IaasContext;
+import org.apache.stratos.autoscaler.service.util.IaasProvider;
+import org.apache.stratos.autoscaler.service.util.InstanceContext;
+import org.apache.stratos.autoscaler.service.util.ServiceTemplate;
+import org.apache.stratos.autoscaler.service.xml.ElasticScalerConfigFileReader;
+import org.apache.stratos.lb.common.conf.util.Constants;
+import org.wso2.carbon.utils.CarbonUtils;
+
+/**
+ * Autoscaler Service is responsible for starting up new server instances, terminating already
+ * started instances, providing pending instance count.
+ *
+ */
+public class AutoscalerServiceImpl implements IAutoscalerService {
+
+
+ private static final Log log = LogFactory.getLog(AutoscalerServiceImpl.class);
+
+ /**
+ * pointer to Carbon Home directory.
+ */
+ private static final String CARBON_HOME = CarbonUtils.getCarbonHome();
+
+ /**
+ * pointer to Carbon Temp directory.
+ */
+ private static final String CARBON_TEMP = CarbonUtils.getTmpDir();
+
+ /**
+ * Tenant id Delimiter
+ */
+ private static final String TENANT_ID_DELIMITER = "/t/";
+
+ /**
+ * This directory will be used to store serialized objects.
+ */
+ private String serializationDir;
+
+ /**
+ * List of all <code>IaaSProviders</code> specified in the config file.
+ */
+ private List<IaasProvider> iaasProviders;
+
+ /**
+ * List of all <code>ServiceTemplate</code> objects.
+ */
+ private List<ServiceTemplate> serviceTemps;
+
+ /**
+ * We keep an enum which contains all supported IaaSes.
+ */
+ public enum Iaases {
+ ec2, openstack
+ };
+
+ /**
+ * List which keeps <code>IaasContext</code> objects.
+ */
+ private List<IaasContext> iaasContextList = new ArrayList<IaasContext>();
+
+ /**
+ * We keep track of the IaaS where the last instance of a domain and a sub domain combination is spawned.
+ * This is required when there are multiple <code>IaasProvider</code>s defined.
+ * Key - domain
+ * Value - a map which has a Key - sub domain and Value - name of the {@link IaasProvider}.
+ */
+ private Map<String, Map<String, String>> lastlyUsedIaasMap = new HashMap<String, Map<String, String>>();
+
+ /**
+ * To track whether the {@link #initAutoscaler(boolean)} method has been called.
+ */
+ boolean isInitialized = false;
+
+ @Override
+ public boolean initAutoscaler(boolean isSpi) {
+
+ if (!isInitialized) {
+
+ log.debug("InitAutoscaler has started ... IsSPI : " + isSpi);
+
+ // load configuration file
+ ElasticScalerConfigFileReader configReader = new ElasticScalerConfigFileReader();
+
+ // read serialization directory from config file if specified, else will use the
+ // default.
+ if ("".equals(serializationDir = configReader.getSerializationDir())) {
+ serializationDir = CARBON_TEMP;
+
+ log.debug("Directory to be used to serialize objects: " + serializationDir);
+ }
+
+ // let's deserialize and load the serialized objects.
+ deserialize();
+
+ // from config file, we grab the details unique to IaaS providers.
+ iaasProviders = configReader.getIaasProvidersList();
+
+ // from config file, we grab the details related to each service domain.
+ serviceTemps = configReader.getTemplates();
+
+ // we iterate through each IaaSProvider which is loaded from the config file.
+ for (IaasProvider iaas : iaasProviders) {
+
+ // build the JClouds specific ComputeService object
+ ComputeService computeService = ComputeServiceBuilder.buildComputeService(iaas);
+ IaasContext entity;
+
+ // let's see whether there's a serialized entity
+ entity = findIaasContext(iaas.getType());
+
+ if (entity != null) {
+
+ log.debug("Serializable object is loaded for IaaS " + iaas.getType());
+
+ // ComputeService isn't serializable, hence we need to set it in the
+ // deserialized
+ // object.
+ entity.setComputeService(computeService);
+ }
+
+ // build JClouds Template objects according to different IaaSes
+ if (iaas.getType().equalsIgnoreCase(Iaases.ec2.toString())) {
+
+ // initiate the IaasContext object, if it is null.
+ entity =
+ (entity == null) ? (entity =
+ new IaasContext(Iaases.ec2,
+ computeService)) : entity;
+
+ // we should build the templates only if this is not SPI stuff
+ if (!isSpi) {
+ // Build the Template
+ buildEC2Templates(entity, iaas.getTemplate(), isSpi);
+
+ } else {
+ // add to data structure
+ iaasContextList.add(entity);
+ }
+
+ } else if (iaas.getType().equalsIgnoreCase(Iaases.openstack.toString())) {
+
+ // initiate the IaasContext object, if it is null.
+ entity =
+ (entity == null) ? (entity =
+ new IaasContext(Iaases.openstack,
+ computeService)) : entity;
+
+ // we should build the templates only if this is not SPI stuff
+ if (!isSpi) {
+ // Build the Template
+ buildLXCTemplates(entity, iaas.getTemplate(), isSpi, null);
+
+ } else {
+ // add to data structure
+ iaasContextList.add(entity);
+ }
+
+ } else {
+ // unsupported IaaS detected. We only complain, since there could be other
+ // IaaSes.
+ String msg =
+ "Unsupported IaasProvider is specified in the config file: " +
+ iaas.getType() + ". Supported IaasProviders are " +
+ print(Iaases.values());
+ log.warn(msg);
+ continue;
+ }
+
+ // populate scale up order
+ fillInScaleUpOrder();
+
+ // populate scale down order
+ fillInScaleDownOrder();
+
+ // serialize the objects
+ serialize();
+ }
+
+ // we couldn't locate any valid IaaS providers from config file, thus shouldn't proceed.
+ if (iaasContextList.size() == 0) {
+ String msg = "No valid IaaS provider specified in the config file!";
+ log.error(msg);
+ throw new AutoscalerServiceException(msg);
+ }
+
+ // initialization completed.
+ isInitialized = true;
+
+ log.info("Autoscaler service initialized successfully!!");
+
+ return true;
+ }
+
+ log.debug("Autoscaler Service is already initialized!");
+ return false;
+ }
+
+
+ @Override
+ public boolean startInstance(String domainName, String subDomainName) {
+
+ // initialize the service, if it's not already initialized.
+ initAutoscaler(false);
+
+ ComputeService computeService;
+ Template template;
+
+ subDomainName = checkSubDomain(subDomainName);
+
+ log.info("Starting new instance of domain : " + domainName+" and sub domain : "+subDomainName);
+
+ // sort the IaasContext entities according to scale up order
+ Collections.sort(iaasContextList,
+ IaasContextComparator.ascending(IaasContextComparator.getComparator(IaasContextComparator.SCALE_UP_SORT)));
+
+ // traverse through IaasContext object instances in scale up order
+ for (IaasContext iaasCtxt : iaasContextList) {
+
+ // get the ComputeService
+ computeService = iaasCtxt.getComputeService();
+
+ // from the list grab the Template corresponds to this domain
+ template = iaasCtxt.getTemplate(domainName, subDomainName);
+
+ if(template == null){
+ String msg = "Failed to start an instance in " + iaasCtxt.getName().toString() +
+ ". Reason : Template is null. You have not specify a matching service " +
+ "element in the configuration file of Autoscaler.\n Hence, will try to " +
+ "start in another IaaS if available.";
+ log.error(msg);
+ continue;
+ }
+
+ // generate the group id from domain name and sub domain name.
+ // Should have lower-case ASCII letters, numbers, or dashes.
+ String str = domainName.concat("-"+subDomainName);
+ String group = str.replaceAll("[^a-z0-9-]", "");
+
+ try {
+ // create and start a node
+ Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(group,
+ 1,
+ template);
+
+ NodeMetadata node = nodes.iterator().next();
+
+// // add the details of the started node to maps
+// iaasCtxt.addNodeIdToDomainMap(node.getId(), domainName);
+
+ String ip="";
+
+ // set public Ip, if it's available
+ if (node.getPublicAddresses().size() > 0) {
+ ip = node.getPublicAddresses().iterator().next();
+// iaasCtxt.addPublicIpToDomainMap(publicIp, domainName);
+// iaasCtxt.addPublicIpToNodeIdMap(publicIp, node.getId());
+ } else if(node.getPrivateAddresses().size() > 0) { // set private IPs if no public IP s are returned
+ ip = node.getPrivateAddresses().iterator().next();
+// iaasCtxt.addPublicIpToDomainMap(privateIp, domainName);
+// iaasCtxt.addPublicIpToNodeIdMap(privateIp, node.getId());
+ } else{
+ log.debug("Public IP of the node : "+node.getId()+" cannot be found.");
+ }
+
+
+ if (iaasCtxt.getInstanceContext(domainName, subDomainName) == null) {
+ String msg = "Failed to start an instance in " + iaasCtxt.getName().toString() +
+ ". Reason : InstanceContext is null. Hence, will try to start in another IaaS if available.";
+ log.error(msg);
+ continue;
+ }
+
+ if(node.getId() == null){
+ String msg = "Node id of the starting instance is null.\n"+ node.toString();
+ log.fatal(msg);
+ throw new AutoscalerServiceException(msg);
+ }
+
+ // add run time data to InstanceContext
+ iaasCtxt.addNodeDetails(domainName, subDomainName, node.getId(), ip);
+
+ // since we modified the IaasContext instance, let's replace it.
+ replaceIaasContext(iaasCtxt);
+
+ // update the lastlyUsedIaasMap
+ addToLastlyUsedIaasMap(domainName, subDomainName, iaasCtxt.getName().toString());
+// lastlyUsedIaasMap.put(domainName, iaasCtxt.getName().toString());
+
+ if (log.isDebugEnabled()) {
+ log.debug("Node details: \n" + node.toString() +
+ "\n***************\n");
+ }
+
+ } catch (RunNodesException e) {
+ log.warn("Failed to start an instance in " + iaasCtxt.getName().toString() +
+ ". Hence, will try to start in another IaaS if available.", e);
+ continue;
+ }
+
+ log.info("Instance is successfully starting up in IaaS " + iaasCtxt.getName()
+ .toString() + " ...");
+
+ // serialize the objects
+ serialize();
+
+ return true;
+ }
+
+ log.info("Failed to start instance, in any available IaaS.");
+
+ return false;
+
+ }
+
+ private String checkSubDomain(String subDomainName) {
+ // if sub domain is null, we assume it as default one.
+ if (subDomainName == null || "null".equalsIgnoreCase(subDomainName)) {
+ subDomainName = Constants.DEFAULT_SUB_DOMAIN;
+ log.debug("Sub domain is null, hence using the default value : " + subDomainName);
+ }
+
+ return subDomainName;
+ }
+
+
+ private void addToLastlyUsedIaasMap(String domainName, String subDomainName, String iaasName) {
+
+ Map<String, String> map;
+
+ if(lastlyUsedIaasMap.get(domainName) == null){
+ map = new HashMap<String, String>();
+
+ } else{
+ map = lastlyUsedIaasMap.get(domainName);
+ }
+
+ map.put(subDomainName, iaasName);
+ lastlyUsedIaasMap.put(domainName, map);
+
+ }
+
+
+ @Override
+ public String startSpiInstance(String domainName, String subDomainName, String imageId) {
+
+ log.debug("Starting an SPI instance ... | domain: " + domainName + " | sub domain: " +
+ subDomainName + " | ImageId: " + imageId);
+
+ // initialize the service, if it's not already initialized.
+ initAutoscaler(true);
+
+ String tenantId = null;
+ String spiDomainName = null;
+
+ if(domainName != null) {
+ // domainName will have the pattern <domainName>/t/<tenantId>
+ String[] arr = domainName.split(TENANT_ID_DELIMITER);
+ if(arr.length != 2) {
+ String msg = "Domain name does not match with the expected pattern. Expected " +
+ "pattern is <domainName>/t/<tenantId>";
+ log.error(msg);
+ throw new AutoscalerServiceException(msg);
+ }
+ spiDomainName = arr[0];
+ tenantId = arr[1];
+ }
+
+ IaasContext entry;
+
+ // FIXME: Build the Templates, for now we're doing a hack here. I don't know whether
+ // there's a proper fix.
+ // handle openstack case
+ if (imageId.startsWith("nova") && ((entry = findIaasContext(Iaases.openstack)) != null)) {
+
+ buildLXCTemplates(entry, imageId, true, tenantId);
+
+ } else if (((entry = findIaasContext(Iaases.ec2)) != null)) {
+
+ buildEC2Templates(entry, imageId, true);
+
+ } else {
+ String msg = "Invalid image id: " + imageId;
+ log.error(msg);
+ throw new AutoscalerServiceException(msg);
+ }
+
+ // let's start the instance
+ if (startInstance(spiDomainName, subDomainName)) {
+
+ // if it's successful, get the public IP of the started instance.
+ // FIXME remove --> String publicIP =
+ // findIaasContext(iaas).getLastMatchingPublicIp(domainName);
+ String publicIP = entry.getLastMatchingPublicIp(spiDomainName, subDomainName);
+
+ // if public IP is null, return an empty string, else return public IP.
+ return (publicIP == null) ? "" : publicIP;
+
+ }
+
+ return "";
+
+ }
+
+ @Override
+ public boolean terminateInstance(String domainName, String subDomainName) {
+
+ // initialize the service, if it's not already initialized.
+ initAutoscaler(false);
+
+ subDomainName = checkSubDomain(subDomainName);
+
+ log.info("Starting to terminate an instance of domain : " + domainName + " and sub domain : "+subDomainName);
+
+ // sort the IaasContext entities according to scale down order.
+ Collections.sort(iaasContextList,
+ IaasContextComparator.ascending(IaasContextComparator.getComparator(IaasContextComparator.SCALE_DOWN_SORT)));
+
+ // traverse in scale down order
+ for (IaasContext iaasTemp : iaasContextList) {
+
+ String msg = "Failed to terminate an instance in " + iaasTemp.getName().toString() +
+ ". Hence, will try to terminate an instance in another IaaS if possible.";
+
+ String nodeId = null;
+
+ // grab the node ids related to the given domain and traverse
+ for (String id : iaasTemp.getNodeIds(domainName, subDomainName)) {
+ if (id != null) {
+ nodeId = id;
+ break;
+ }
+ }
+
+ // if no matching node id can be found.
+ if (nodeId == null) {
+
+ log.warn(msg + " : Reason- No matching instance found for domain: " +
+ domainName + " and sub domain: "+subDomainName+
+ ".");
+ continue;
+ }
+
+ // terminate it!
+ terminate(iaasTemp, nodeId);
+
+ return true;
+
+ }
+
+ log.info("Termination of an instance which is belong to domain '" + domainName +
+ "' and sub domain '"+subDomainName+"' , failed!\n Reason: No matching " +
+ "running instance found in any available IaaS.");
+
+ return false;
+
+ }
+
+ @Override
+ public boolean terminateLastlySpawnedInstance(String domainName, String subDomainName) {
+
+ // initialize the service, if it's not already initialized.
+ initAutoscaler(false);
+
+ subDomainName = checkSubDomain(subDomainName);
+
+ // see whether there is a matching IaaS, where we spawn an instance belongs to given domain.
+ if (lastlyUsedIaasMap.containsKey(domainName)) {
+
+ // grab the name of the IaaS
+ String iaas = lastlyUsedIaasMap.get(domainName).get(subDomainName);
+
+ // find the corresponding IaasContext
+ IaasContext iaasTemp = findIaasContext(iaas);
+
+ String msg = "Failed to terminate the lastly spawned instance of '" + domainName +
+ "' service domain.";
+
+ if (iaasTemp == null) {
+ log.error(msg + " : Reason- Iaas' data cannot be located!");
+ return false;
+ }
+
+ // find the instance spawned at last of this IaasContext
+ String nodeId = iaasTemp.getLastMatchingNode(domainName, subDomainName);
+
+ if (nodeId == null) {
+ log.error(msg + " : Reason- No matching instance found for domain: " +
+ domainName + " and sub domain: "+subDomainName+
+ ".");
+ return false;
+ }
+
+ // terminate it!
+ terminate(iaasTemp, nodeId);
+
+ return true;
+
+ }
+
+ log.info("Termination of an instance which is belong to domain '" + domainName +
+ "' and sub domain '"+subDomainName+"' , failed!\n Reason: No matching instance found.");
+
+ return false;
+ }
+
+ @Override
+ public boolean terminateSpiInstance(String publicIp) {
+
+ // initialize the service, if it's not already initialized.
+ initAutoscaler(true);
+
+ // sort the IaasContext entities according to scale down order.
+ Collections.sort(iaasContextList,
+ IaasContextComparator.ascending(IaasContextComparator.getComparator(IaasContextComparator.SCALE_DOWN_SORT)));
+
+ // traverse in scale down order
+ for (IaasContext iaasTemp : iaasContextList) {
+
+ String msg = "Failed to terminate an instance in " + iaasTemp.getName().toString() +
+ "" +
+ ". Hence, will try to terminate an instance in another IaaS if possible.";
+
+ // grab the node maps with the given public IP address
+ String nodeId = iaasTemp.getNodeWithPublicIp(publicIp);
+
+ if (nodeId == null) {
+ log.warn(msg + " : Reason- No matching instance found for public ip '" +
+ publicIp +
+ "'.");
+ continue;
+ }
+
+ // terminate it!
+ terminate(iaasTemp, nodeId);
+
+ return true;
+ }
+
+ log.info("Termination of an instance which has the public IP '" + publicIp + "', failed!");
+
+ return false;
+ }
+
+ @Override
+ public int getPendingInstanceCount(String domainName, String subDomain) {
+
+ // initialize the service, if it's not already initialized.
+ initAutoscaler(false);
+
+ subDomain = checkSubDomain(subDomain);
+
+ int pendingInstanceCount = 0;
+
+ // traverse through IaasContexts
+ for (IaasContext entry : iaasContextList) {
+
+ ComputeService computeService = entry.getComputeService();
+
+ // get list of node Ids which are belong to the requested domain
+ List<String> nodeIds = entry.getNodeIds(domainName, subDomain);
+
+ if(nodeIds.isEmpty()){
+ log.debug("Zero nodes spawned in the IaaS "+entry.getName()+
+ " of domain: "+domainName+" and sub domain: "+subDomain);
+ continue;
+ }
+
+ // get all the nodes spawned by this IaasContext
+ Set<? extends ComputeMetadata> set = computeService.listNodes();
+
+ Iterator<? extends ComputeMetadata> iterator = set.iterator();
+
+ // traverse through all nodes of this ComputeService object
+ while (iterator.hasNext()) {
+ NodeMetadataImpl nodeMetadata = (NodeMetadataImpl) iterator.next();
+
+ // if this node belongs to the requested domain
+ if (nodeIds.contains(nodeMetadata.getId())) {
+
+ // get the status of the node
+ Status nodeStatus = nodeMetadata.getStatus();
+
+ // count nodes that are in pending state
+ if (nodeStatus.toString().equalsIgnoreCase("PENDING")) {
+ pendingInstanceCount++;
+ }
+ }
+
+ }
+ }
+
+ log.info("Pending instance count of domain '" + domainName + "' and sub domain '"+
+ subDomain+"' is " + pendingInstanceCount);
+
+ return pendingInstanceCount;
+
+ }
+
+ /**
+ * Returns matching IaasContext for the given {@link Iaases} entry.
+ */
+ private IaasContext findIaasContext(Enum<Iaases> iaas) {
+
+ for (IaasContext entry : iaasContextList) {
+ if (entry.getName().equals(iaas)) {
+ return entry;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns matching IaasContext for the given iaas type.
+ */
+ private IaasContext findIaasContext(String iaasType) {
+
+ for (IaasContext entry : iaasContextList) {
+ if (entry.getName().toString().equals(iaasType)) {
+ return entry;
+ }
+ }
+
+ return null;
+ }
+
+ private void fillInScaleDownOrder() {
+
+ for (IaasProvider iaas : iaasProviders) {
+ if (findIaasContext(iaas.getType()) != null) {
+ findIaasContext(iaas.getType()).setScaleDownOrder(iaas.getScaleDownOrder());
+ }
+ }
+
+ }
+
+ private void fillInScaleUpOrder() {
+
+ for (IaasProvider iaas : iaasProviders) {
+ if (findIaasContext(iaas.getType()) != null) {
+ findIaasContext(iaas.getType()).setScaleUpOrder(iaas.getScaleUpOrder());
+ }
+ }
+
+ }
+
+ private byte[] getUserData(String payloadFileName, String tenantId) {
+
+ byte[] bytes = null;
+ File outputFile = null;
+ String tempfilename = UUID.randomUUID().toString();
+ try {
+ File file = new File(payloadFileName);
+ if (!file.exists()) {
+ handleException("Payload file " + payloadFileName + " does not exist");
+ }
+ if (!file.canRead()) {
+ handleException("Payload file " + payloadFileName + " does cannot be read");
+ }
+ if(tenantId != null) {
+ // Tenant Id is available. This is an spi scenario. Edit the payload content
+ editPayload(tenantId,file,tempfilename);
+ outputFile = new File(CARBON_HOME + File.separator + AutoscalerConstant.RESOURCES_DIR + File.separator + tempfilename+".zip");
+ } else {
+ outputFile = file;
+ }
+ bytes = getBytesFromFile(outputFile);
+
+ } catch (IOException e) {
+ handleException("Cannot read data from payload file " + payloadFileName, e);
+ }
+
+ // Remove temporary payload file
+ if (tenantId != null) {
+ outputFile.delete();
+ }
+
+ return bytes;
+ }
+
+
+ private void editPayload(String tenantName, File file, String tempfileName) {
+
+ unzipFile(file, tempfileName);
+ editContent(tenantName, file, tempfileName);
+ zipPayloadFile(tempfileName);
+ }
+
+
+ /**
+ * unzips the payload file
+ *
+ * @param file
+ * @param tempfileName
+ */
+ private void unzipFile(File file, String tempfileName) {
+
+ int buffer = 2048;
+ BufferedOutputStream dest = null;
+ ZipInputStream zis = null;
+
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ zis = new ZipInputStream(new BufferedInputStream(fis));
+ ZipEntry entry;
+
+ while ((entry = zis.getNextEntry()) != null) {
+
+ log.debug("Extracting: " + entry);
+
+ int count;
+ byte data[] = new byte[buffer];
+ String outputFilename = tempfileName + File.separator + entry.getName();
+ createDirIfNeeded(tempfileName, entry);
+
+ // write the files to the disk
+ if (!entry.isDirectory()) {
+ FileOutputStream fos = new FileOutputStream(outputFilename);
+ dest = new BufferedOutputStream(fos, buffer);
+ while ((count = zis.read(data, 0, buffer)) != -1) {
+ dest.write(data, 0, count);
+ }
+ dest.flush();
+ dest.close();
+ }
+ }
+
+ } catch (Exception e) {
+ log.error("Exception is occurred in unzipping payload file. Reason:" + e.getMessage());
+ throw new AutoscalerServiceException(e.getMessage(), e);
+ } finally {
+ closeStream(zis);
+ closeStream(dest);
+ }
+ }
+
+
+ private void closeStream(Closeable stream) {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ log.error(" Exception is occurred when closing stream. Reason :" + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ *
+ * Modify contents (tenantName) of the debian_cron_script.sh file
+ *
+ * @param tenantName
+ * @param file
+ */
+ private void editContent(String tenantName, File file, String tempfileName) {
+
+ File f = new File(CARBON_HOME + File.separator + tempfileName
+ + File.separator + AutoscalerConstant.PAYLOAD_DIR + File.separator
+ + AutoscalerConstant.PARAMS_FILE_NAME);
+
+ FileInputStream fs = null;
+ InputStreamReader in = null;
+ BufferedReader br = null;
+
+ StringBuffer sb = new StringBuffer();
+
+ String textinLine;
+
+ try {
+ fs = new FileInputStream(f);
+ in = new InputStreamReader(fs);
+ br = new BufferedReader(in);
+
+ while (true) {
+
+ textinLine=br.readLine();
+ if(textinLine==null)
+ break;
+ sb.append(editLine(textinLine, tenantName));
+ }
+ } catch (Exception e) {
+ log.error("Exception is occurred in editing payload content. Reason: "+e.getMessage());
+ throw new AutoscalerServiceException(e.getMessage(), e);
+ } finally {
+ closeStream(fs);
+ closeStream(in);
+ closeStream(br);
+ }
+
+ writeChangesBackToFile(f, sb);
+ }
+
+
+ private String editLine(String textinLine, String tenantName) {
+
+ // Format of the line will be <IP>=<IPvalue>,<Path>=<PathValue>..
+
+ StringBuffer outputBuffer = new StringBuffer();
+ Map<String, String> paramMap = new HashMap<String, String>();
+ String[] params = textinLine.split(AutoscalerConstant.ENTRY_SEPARATOR);
+
+ for (int i = 0; i < params.length; i++) {
+
+ // split the params one by one
+ String param = params[i];
+ String[] values = param.split(AutoscalerConstant.VALUE_SEPARATOR);
+
+ if(values.length != 2) {
+ throw new AutoscalerServiceException("Incorrect format in parameters file");
+ }
+
+ String key = values[0];
+ String value = values[1];
+
+ String updatedValue = value;
+
+ if (AutoscalerConstant.TENANT_KEY.equals(key)) {
+ updatedValue = tenantName;
+ } else if (AutoscalerConstant.APP_PATH_KEY.equals(key)) {
+ updatedValue = getAppPathForTenant(tenantName,value);
+ }
+ paramMap.put(key, updatedValue);
+ }
+
+ // Loop through the map and put values into a string
+ reOrganizeContent(outputBuffer, paramMap);
+
+ // cleanup output buffer
+ if (outputBuffer.substring(0, 1).equals(AutoscalerConstant.ENTRY_SEPARATOR)) {
+ outputBuffer.delete(0, 1);
+ }
+
+ return outputBuffer.toString();
+ }
+
+
+ private void reOrganizeContent(StringBuffer outputBuffer, Map<String, String> paramMap) {
+
+ for (Map.Entry<String, String> entry : paramMap.entrySet()) {
+ outputBuffer.append(AutoscalerConstant.ENTRY_SEPARATOR).append(entry.getKey()).append(AutoscalerConstant.VALUE_SEPARATOR)
+ .append(entry.getValue());
+ }
+ }
+
+
+ private String getAppPathForTenant(String tenantName, String appPath) {
+ // Assumes app path is /opt/wso2-app/repository/
+ StringBuffer updatedAppPath = new StringBuffer();
+ if(tenantName.equals(AutoscalerConstant.SUPER_TENANT_ID)){
+ updatedAppPath.append(appPath).append("deployment").append(File.separator).append("server")
+ .append(File.separator).append("phpapps");
+ }else{
+ updatedAppPath.append(appPath).append(tenantName).append(File.separator).append("phpapps");
+ }
+ return updatedAppPath.toString();
+ }
+
+
+ private void writeChangesBackToFile(File f, StringBuffer sb) {
+ FileWriter fstream = null;
+ BufferedWriter outobj = null;
+
+ try {
+ fstream = new FileWriter(f);
+ outobj = new BufferedWriter(fstream);
+ outobj.write(sb.toString());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ closeStream(outobj);
+ }
+ }
+
+ /**
+ *
+ * Compress the modified files back into payload.zip
+ * @param tempfileName
+ *
+ */
+ private void zipPayloadFile(String tempfileName) {
+
+ int buffer = 2048;
+ BufferedInputStream origin = null;
+ ZipOutputStream out = null;
+
+ try {
+
+ FileOutputStream dest = new
+ FileOutputStream(CARBON_HOME + File.separator + AutoscalerConstant.RESOURCES_DIR + File.separator + tempfileName+".zip");
+ out = new ZipOutputStream(new BufferedOutputStream(dest));
+ byte data[] = new byte[buffer];
+
+ File f = new File(CARBON_HOME + File.separator + tempfileName + File.separator + AutoscalerConstant.PAYLOAD_DIR);
+ String files[] = f.list();
+
+ for (int i=0; i<files.length; i++) {
+ FileInputStream fi = new FileInputStream(CARBON_HOME + File.separator + tempfileName
+ + File.separator + AutoscalerConstant.PAYLOAD_DIR + File.separator + files[i]);
+ origin = new BufferedInputStream(fi, buffer);
+ ZipEntry entry = new ZipEntry(AutoscalerConstant.PAYLOAD_DIR + File.separator + files[i]);
+ out.putNextEntry(entry);
+
+ int count;
+ while((count = origin.read(data, 0, buffer)) != -1) {
+ out.write(data, 0, count);
+ }
+ origin.close();
+ }
+
+ // delete temp files
+ deleteDir(f);
+ File fl = new File(CARBON_HOME + File.separator + tempfileName);
+ fl.delete();
+
+ } catch(Exception e) {
+ log.error("Exception is occurred in zipping payload file after modification. Reason:" + e.getMessage());
+ throw new AutoscalerServiceException(e.getMessage(),e);
+ } finally {
+ closeStream(origin);
+ closeStream(out);
+ }
+ }
+
+ private static boolean deleteDir(File dir) {
+ if (dir.isDirectory()) {
+ String[] children = dir.list();
+ for (int i=0; i<children.length; i++) {
+ boolean success = deleteDir(new File(dir, children[i]));
+ if (!success) {
+ return false;
+ }
+ }
+ }
+
+ // The directory is now empty so delete it
+ return dir.delete();
+ }
+
+ private void createDirIfNeeded(String destDirectory, ZipEntry entry) {
+
+ String name = entry.getName();
+
+ if(name.contains("/"))
+ {
+ log.debug("directory will need to be created");
+
+ int index = name.lastIndexOf("/");
+ String dirSequence = name.substring(0, index);
+
+ File newDirs = new File(destDirectory + File.separator + dirSequence);
+
+ //create the directory
+ newDirs.mkdirs();
+ }
+
+ }
+
+
+ /**
+ * Returns the contents of the file in a byte array
+ *
+ * @param file
+ * - Input File
+ * @return Bytes from the file
+ * @throws java.io.IOException
+ * , if retrieving the file contents failed.
+ */
+ private byte[] getBytesFromFile(File file) throws IOException {
+ if (!file.exists()) {
+ log.error("Payload file " + file.getAbsolutePath() + " does not exist");
+ return null;
+ }
+ InputStream is = new FileInputStream(file);
+ byte[] bytes;
+
+ try {
+ // Get the size of the file
+ long length = file.length();
+
+ // You cannot create an array using a long type.
+ // It needs to be an int type.
+ // Before converting to an int type, check
+ // to ensure that file is not larger than Integer.MAX_VALUE.
+ if (length > Integer.MAX_VALUE) {
+ if (log.isDebugEnabled()) {
+ log.debug("File is too large");
+ }
+ }
+
+ // Create the byte array to hold the data
+ bytes = new byte[(int) length];
+
+ // Read in the bytes
+ int offset = 0;
+ int numRead;
+ while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
+ offset += numRead;
+ }
+
+ // Ensure all the bytes have been read in
+ if (offset < bytes.length) {
+ throw new IOException("Could not completely read file " + file.getName());
+ }
+ } finally {
+ // Close the input stream and return bytes
+ is.close();
+ }
+
+ return bytes;
+ }
+
+ /**
+ * handles the exception
+ *
+ * @param msg
+ * exception message
+ */
+ private void handleException(String msg) {
+ log.error(msg);
+ throw new SynapseException(msg);
+ }
+
+ /**
+ * handles the exception
+ *
+ * @param msg
+ * exception message
+ * @param e
+ * exception
+ */
+ private static void handleException(String msg, Exception e) {
+ log.error(msg, e);
+ throw new SynapseException(msg, e);
+ }
+
+
+ /**
+ * This will replace an existing entry in iaasEntities list, if there's such.
+ * If not this will add the replacement value to the list.
+ *
+ * @param replacement
+ * IaasContext entry to be added.
+ */
+ private void replaceIaasContext(IaasContext replacement) {
+ for (IaasContext entry : iaasContextList) {
+ if (entry.equals(replacement)) {
+ int idx = iaasContextList.indexOf(entry);
+ iaasContextList.remove(idx);
+ iaasContextList.add(idx, replacement);
+ return;
+ }
+ }
+ iaasContextList.add(replacement);
+
+ }
+
+ /**
+ * Builds the LXC Template object.
+ */
+ private void buildLXCTemplates(IaasContext entity, String imageId, boolean blockUntilRunning, String tenantId) {
+
+ if (entity.getComputeService() == null) {
+ throw new AutoscalerServiceException("Compute service is null for IaaS provider: " + entity.getName());
+ }
+
+// // if domain to template map is null
+// if (entity.getDomainToTemplateMap() == null) {
+// // we initialize it
+// entity.setDomainToTemplateMap(new HashMap<String, Template>());
+// }
+
+ TemplateBuilder templateBuilder = entity.getComputeService().templateBuilder();
+ templateBuilder.imageId(imageId);
+
+ // to avoid creation of template objects in each and every time, we create all
+ // at once!
+ for (ServiceTemplate temp : serviceTemps) {
+
+ String instanceType;
+
+ // set instance type
+ if (((instanceType = temp.getProperty("instanceType." + Iaases.openstack.toString())) != null) ) {
+
+ templateBuilder.hardwareId(instanceType);
+ }
+
+ Template template = templateBuilder.build();
+
+ template.getOptions().as(TemplateOptions.class).blockUntilRunning(blockUntilRunning);
+
+ template.getOptions()
+ .as(NovaTemplateOptions.class)
+ .securityGroupNames(temp.getProperty("securityGroups").split(AutoscalerConstant.ENTRY_SEPARATOR));
+
+ if (temp.getProperty(AutoscalerConstant.PAYLOAD_DIR) != null) {
+ template.getOptions()
+ .as(NovaTemplateOptions.class)
+ .userData(getUserData(CARBON_HOME + File.separator +
+ temp.getProperty(AutoscalerConstant.PAYLOAD_DIR), tenantId));
+ }
+
+ template.getOptions()
+ .as(NovaTemplateOptions.class)
+ .keyPairName(temp.getProperty("keyPair"));
+
+ // add to the data structure
+ if (entity.getInstanceContext(temp.getDomainName(), temp.getSubDomainName()) == null) {
+ entity.addInstanceContext(new InstanceContext(temp.getDomainName(),
+ temp.getSubDomainName(), template));
+ }
+ else{
+ entity.getInstanceContext(temp.getDomainName(), temp.getSubDomainName()).setTemplate(template);
+ }
+
+ }
+
+ // since we modified the Context, we need to replace
+ replaceIaasContext(entity);
+ }
+
+ /**
+ * Builds EC2 Template object
+ *
+ */
+ private void buildEC2Templates(IaasContext entity, String imageId, boolean blockUntilRunning) {
+
+ if (entity.getComputeService() == null) {
+ throw new AutoscalerServiceException("Compute service is null for IaaS provider: " + entity.getName());
+ }
+
+// // if domain to template map is null
+// if (entity.getDomainToTemplateMap() == null) {
+// // we initialize it
+// entity.setDomainToTemplateMap(new HashMap<String, Template>());
+// }
+
+ TemplateBuilder templateBuilder = entity.getComputeService().templateBuilder();
+
+ // set image id specified
+ templateBuilder.imageId(imageId);
+
+ // to avoid creation of template objects in each and every time, we create all
+ // at once! FIXME we could use caching and lazy loading
+ for (ServiceTemplate temp : serviceTemps) {
+
+ if (temp.getProperty("instanceType." + Iaases.ec2.toString()) != null) {
+ // set instance type eg: m1.large
+ templateBuilder.hardwareId(temp.getProperty("instanceType." + Iaases.ec2.toString()));
+ }
+
+ // build the Template
+ Template template = templateBuilder.build();
+
+ // make it non blocking
+ template.getOptions().as(TemplateOptions.class).blockUntilRunning(blockUntilRunning);
+
+ // set EC2 specific options
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .placementGroup(temp.getProperty("availabilityZone"));
+
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .securityGroups(temp.getProperty("securityGroups").split(AutoscalerConstant.ENTRY_SEPARATOR));
+
+ if (temp.getProperty(AutoscalerConstant.PAYLOAD_DIR) != null) {
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .userData(getUserData(CARBON_HOME + File.separator +
+ temp.getProperty(AutoscalerConstant.PAYLOAD_DIR), null));
+ }
+
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .keyPair(temp.getProperty("keyPair"));
+
+ // add to the data structure
+ if (entity.getInstanceContext(temp.getDomainName(), temp.getSubDomainName()) == null) {
+ entity.addInstanceContext(new InstanceContext(temp.getDomainName(),
+ temp.getSubDomainName(), template));
+ }
+ else{
+ entity.getInstanceContext(temp.getDomainName(), temp.getSubDomainName()).setTemplate(template);
+ }
+
+ }
+
+ // since we modified the Context, we need to replace
+ replaceIaasContext(entity);
+
+ }
+
+ private String print(Iaases[] values) {
+ String str = "";
+ for (Iaases iaases : values) {
+ str = iaases.name() + ", ";
+ }
+ str = str.trim();
+ return str.endsWith(AutoscalerConstant.ENTRY_SEPARATOR) ? str.substring(0, str.length() - 1) : str;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void deserialize() {
+
+ String path;
+
+ try {
+ path = serializationDir + File.separator +
+ AutoscalerConstant.IAAS_CONTEXT_LIST_SERIALIZING_FILE;
+
+ Object obj = Deserializer.deserialize(path);
+ if (obj != null) {
+ iaasContextList = (List<IaasContext>) obj;
+ log.debug("Deserialization was successful from file: " + path);
+ }
+
+ path = serializationDir + File.separator +
+ AutoscalerConstant.LASTLY_USED_IAAS_MAP_SERIALIZING_FILE;
+
+ obj = Deserializer.deserialize(path);
+
+ if (obj != null) {
+ lastlyUsedIaasMap = (Map<String, Map<String, String>>) obj;
+ log.debug("Deserialization was successful from file: " + path);
+ }
+
+ } catch (Exception e) {
+ String msg = "Deserialization of objects failed!";
+ log.fatal(msg, e);
+ throw new DeserializationException(msg, e);
+ }
+
+ }
+
+ /**
+ * Does all the serialization stuff!
+ */
+ private void serialize() {
+
+ try {
+ Serializer.serialize(iaasContextList,
+ serializationDir + File.separator +
+ AutoscalerConstant.IAAS_CONTEXT_LIST_SERIALIZING_FILE);
+
+ Serializer.serialize(lastlyUsedIaasMap,
+ serializationDir + File.separator +
+ AutoscalerConstant.LASTLY_USED_IAAS_MAP_SERIALIZING_FILE);
+
+ } catch (IOException e) {
+ String msg = "Serialization of objects failed!";
+ log.fatal(msg, e);
+ throw new SerializationException(msg, e);
+ }
+ }
+
+ /**
+ * A helper method to terminate an instance.
+ */
+ private void terminate(IaasContext iaasTemp, String nodeId) {
+
+ // this is just to be safe
+ if (iaasTemp.getComputeService() == null) {
+ String msg = "Unexpeced error occured! IaasContext's ComputeService is null!";
+ log.error(msg);
+ throw new AutoscalerServiceException(msg);
+ }
+
+ // destroy the node
+ iaasTemp.getComputeService().destroyNode(nodeId);
+
+ // remove the node id from the Context
+ iaasTemp.removeNodeId(nodeId);
+
+ // replace this IaasContext instance, as it reflects the new changes.
+ replaceIaasContext(iaasTemp);
+
+ // serialize the objects
+ serialize();
+
+ log.info("Node with Id: '" + nodeId + "' is terminated!");
+ }
+
+ /**
+ * Comparator to compare IaasContexts on different attributes.
+ */
+ public enum IaasContextComparator implements Comparator<IaasContext> {
+ SCALE_UP_SORT {
+ public int compare(IaasContext o1, IaasContext o2) {
+ return Integer.valueOf(o1.getScaleUpOrder()).compareTo(o2.getScaleUpOrder());
+ }
+ },
+ SCALE_DOWN_SORT {
+ public int compare(IaasContext o1, IaasContext o2) {
+ return Integer.valueOf(o1.getScaleDownOrder()).compareTo(o2.getScaleDownOrder());
+ }
+ };
+
+ public static Comparator<IaasContext> ascending(final Comparator<IaasContext> other) {
+ return new Comparator<IaasContext>() {
+ public int compare(IaasContext o1, IaasContext o2) {
+ return other.compare(o1, o2);
+ }
+ };
+ }
+
+ public static Comparator<IaasContext>
+ getComparator(final IaasContextComparator... multipleOptions) {
+ return new Comparator<IaasContext>() {
+ public int compare(IaasContext o1, IaasContext o2) {
+ for (IaasContextComparator option : multipleOptions) {
+ int result = option.compare(o1, o2);
+ if (result != 0) {
+ return result;
+ }
+ }
+ return 0;
+ }
+ };
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/internal/AutoscalerServiceDSComponent.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/internal/AutoscalerServiceDSComponent.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/internal/AutoscalerServiceDSComponent.java
new file mode 100644
index 0000000..71df23c
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/internal/AutoscalerServiceDSComponent.java
@@ -0,0 +1,48 @@
+/**
+ * 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.service.internal;
+
+import org.apache.stratos.autoscaler.service.impl.AutoscalerServiceImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.apache.stratos.autoscaler.service.IAutoscalerService;
+
+/**
+ * Registering Autoscaler Service.
+ * @scr.component name="org.apache.stratos.autoscaler.service" immediate="true"
+ */
+public class AutoscalerServiceDSComponent {
+
+ private static final Log log = LogFactory.getLog(AutoscalerServiceDSComponent.class);
+
+ protected void activate(ComponentContext context) {
+ try {
+ BundleContext bundleContext = context.getBundleContext();
+ bundleContext.registerService(IAutoscalerService.class.getName(),
+ new AutoscalerServiceImpl(), null);
+
+ log.debug("******* Autoscaler Service bundle is activated ******* ");
+ } catch (Exception e) {
+ log.error("******* Autoscaler Service bundle is failed to activate ****", e);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Deserializer.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Deserializer.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Deserializer.java
new file mode 100644
index 0000000..8732094
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Deserializer.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.autoscaler.service.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class Deserializer {
+
+ private static final Log log = LogFactory.getLog(Deserializer.class);
+
+ /**
+ * We deserialize only if the path to the serialized object file is exists.
+ * @param filePath path to the serialized object file
+ * @return the object obtained after deserialization or null if file isn't valid.
+ * @throws Exception
+ */
+ public static Object deserialize(String filePath) throws Exception {
+
+ ObjectInputStream objIn = null;
+ Object obj = null;
+
+ if(!new File(filePath).isFile()){
+ return obj;
+ }
+
+ try {
+
+ objIn = new ObjectInputStream(new FileInputStream(filePath));
+ obj = objIn.readObject();
+
+ } catch (IOException e) {
+ log.error("Failed to deserialize the file at "+filePath , e);
+ throw e;
+
+ } catch (ClassNotFoundException e) {
+ log.error("Failed to deserialize the file at "+filePath , e);
+ throw e;
+
+ } finally{
+ objIn.close();
+ }
+
+ return obj;
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Serializer.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Serializer.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Serializer.java
new file mode 100644
index 0000000..16f27c4
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/io/Serializer.java
@@ -0,0 +1,61 @@
+/**
+ * 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.service.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class Serializer {
+
+ private static final Log log = LogFactory.getLog(Serializer.class);
+
+ public static void serialize(Object serializableObj, String filePath) throws IOException {
+
+ File outFile = new File(filePath);
+ ObjectOutput ObjOut = null;
+
+ try {
+
+ if(outFile.createNewFile()){
+ log.debug("Serialization file is created at "+filePath);
+ } else{
+ log.debug("Serialization file is already existing at "+filePath);
+ }
+
+ ObjOut = new ObjectOutputStream(new FileOutputStream(outFile));
+ ObjOut.writeObject(serializableObj);
+
+ } catch (IOException e) {
+ log.error("Failed to serialize the object "+serializableObj.toString()
+ + " to file "+filePath , e);
+ throw e;
+
+ } finally{
+ ObjOut.close();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/jcloud/ComputeServiceBuilder.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/jcloud/ComputeServiceBuilder.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/jcloud/ComputeServiceBuilder.java
new file mode 100644
index 0000000..b8d5615
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/jcloud/ComputeServiceBuilder.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.autoscaler.service.jcloud;
+
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.stratos.autoscaler.service.util.IaasProvider;
+import org.jclouds.ContextBuilder;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.enterprise.config.EnterpriseConfigurationModule;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.sshj.config.SshjSshClientModule;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+
+/**
+ * This class is responsible for creating a JClouds specific ComputeService object instances.
+ */
+public class ComputeServiceBuilder {
+
+ public static ComputeService buildComputeService(IaasProvider iaas) {
+
+ Properties properties = new Properties();
+
+ // load properties
+ for (Map.Entry<String, String> entry : iaas.getProperties().entrySet()) {
+ properties.put(entry.getKey(), entry.getValue());
+ }
+
+ // set modules
+ Iterable<Module> modules =
+ ImmutableSet.<Module> of(new SshjSshClientModule(), new SLF4JLoggingModule(),
+ new EnterpriseConfigurationModule());
+
+ // build context
+ ContextBuilder builder =
+ ContextBuilder.newBuilder(iaas.getProvider())
+ .credentials(iaas.getIdentity(), iaas.getCredential()).modules(modules)
+ .overrides(properties);
+
+ // return the compute service object
+ return builder.buildView(ComputeServiceContext.class).getComputeService();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/AutoscalerConstant.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/AutoscalerConstant.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/AutoscalerConstant.java
new file mode 100644
index 0000000..ba07a0b
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/AutoscalerConstant.java
@@ -0,0 +1,73 @@
+/**
+ * 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.service.util;
+
+public final class AutoscalerConstant {
+
+ /**
+ * elastic-scaler-config XML file's elements
+ */
+ public static final String SERIALIZATION_DIR_ELEMENT = "serializationDir";
+ public static final String IAAS_PROVIDER_ELEMENT = "iaasProvider";
+ public static final String IAAS_PROVIDER_TYPE_ATTR = "type";
+ public static final String IAAS_PROVIDER_NAME_ATTR = "name";
+ public static final String PROPERTY_ELEMENT = "property";
+ public static final String PROPERTY_NAME_ATTR= "name";
+ public static final String PROPERTY_VALUE_ATTR = "value";
+ public static final String IMAGE_ID_ELEMENT = "imageId";
+ public static final String SCALE_DOWN_ORDER_ELEMENT = "scaleDownOrder";
+ public static final String SCALE_UP_ORDER_ELEMENT = "scaleUpOrder";
+ public static final String PROVIDER_ELEMENT = "provider";
+ public static final String IDENTITY_ELEMENT = "identity";
+ public static final String CREDENTIAL_ELEMENT = "credential";
+ public static final String DEFAULT_SERVICE_ELEMENT = "default";
+ public static final String SERVICE_ELEMENT = "service";
+ public static final String SERVICE_DOMAIN_ATTR = "domain";
+ public static final String SERVICE_SUB_DOMAIN_ATTR = "subDomain";
+
+ /**
+ * Secret Manager related aliases.
+ */
+ public static final String EC2_IDENTITY_ALIAS = "elastic.scaler.ec2.identity";
+ public static final String EC2_CREDENTIAL_ALIAS = "elastic.scaler.ec2.credential";
+ public static final String OPENSTACK_IDENTITY_ALIAS = "elastic.scaler.openstack.identity";
+ public static final String OPENSTACK_CREDENTIAL_ALIAS = "elastic.scaler.openstack.credential";
+
+ /**
+ * Serializer related constants
+ */
+ public static final String IAAS_CONTEXT_LIST_SERIALIZING_FILE = "iaas-context-list.txt";
+ public static final String LASTLY_USED_IAAS_MAP_SERIALIZING_FILE = "lastly-used-iaas.txt";
+
+ /**
+ * Payload related constants
+ */
+ public static final String PAYLOAD_DIR = "payload";
+ public static final String PARAMS_FILE_NAME = "launch-params";
+ public static final String RESOURCES_DIR = "resources";
+ public static final String VALUE_SEPARATOR = "=";
+ public static final String ENTRY_SEPARATOR = ",";
+ public static final String APP_PATH_KEY = "APP_PATH";
+ public static final String TENANT_KEY = "TENANT";
+
+ /**
+ * Super tenant id
+ */
+ public static final String SUPER_TENANT_ID = "-1234";
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasContext.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasContext.java
new file mode 100644
index 0000000..82f5473
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasContext.java
@@ -0,0 +1,391 @@
+/**
+ * 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.service.util;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.stratos.autoscaler.service.impl.AutoscalerServiceImpl;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Template;
+
+/**
+ * This object holds all IaaS related runtime data.
+ */
+public class IaasContext implements Serializable{
+
+ private static final long serialVersionUID = -922284976926131383L;
+
+ // name of the IaaS
+ private Enum<AutoscalerServiceImpl.Iaases> name;
+
+ /* We keep following maps in order to make the look up time, low.*/
+
+ /**
+ * Key - domain
+ * Value - is another map
+ * key - sub domain
+ * value - <code>InstanceContext</code>
+ */
+ private Map<String, Map<String, InstanceContext>> instanceCtxts;
+
+ /**
+ * Key - public IP
+ * Value - <code>InstanceContext</code>
+ */
+ private Map<String, InstanceContext> publicIpToInstanceCtxt;
+
+ /**
+ * Key - node id
+ * Value - <code>InstanceContext</code>
+ */
+ private Map<String, InstanceContext> nodeIdToInstanceCtxt;
+
+
+// private transient Map<String, Template> domainToTemplateMap;
+ private transient ComputeService computeService;
+
+ // Since Jclouds' NodeMetadata object contains unserializable objects, I had to use 3 maps.
+// private Map<String, String> nodeIdToDomainMap = new LinkedHashMap<String, String>();
+// private Map<String, String> publicIpToDomainMap = new LinkedHashMap<String, String>();
+// private Map<String, String> publicIpToNodeIdMap = new LinkedHashMap<String, String>();
+
+ private int scaleUpOrder, scaleDownOrder;
+
+ public IaasContext(Enum<AutoscalerServiceImpl.Iaases> name, ComputeService computeService) {
+ this.name = name;
+ this.computeService = computeService;
+ instanceCtxts = new LinkedHashMap<String, Map<String,InstanceContext>>();
+ publicIpToInstanceCtxt = new LinkedHashMap<String, InstanceContext>();
+ nodeIdToInstanceCtxt = new LinkedHashMap<String, InstanceContext>();
+ }
+
+ public Enum<AutoscalerServiceImpl.Iaases> getName() {
+ return name;
+ }
+
+ public void addInstanceContext(InstanceContext ctx) {
+
+ if(ctx == null){
+ return;
+ }
+
+ String domain = ctx.getDomain();
+ String subDomain = ctx.getSubDomain();
+
+ if(domain != null && subDomain != null){
+ addToInstanceCtxts(domain, subDomain, ctx);
+ }
+
+ }
+
+ public void addNodeDetails(String domain, String subDomain, String nodeId, String ip) {
+
+ if(getInstanceContext(domain, subDomain) != null){
+ getInstanceContext(domain, subDomain).addNode(nodeId, ip);
+
+ nodeIdToInstanceCtxt.put(nodeId, getInstanceContext(domain, subDomain));
+ publicIpToInstanceCtxt.put(ip, getInstanceContext(domain, subDomain));
+ }
+ }
+
+ private void addToInstanceCtxts(String domainName, String subDomainName, InstanceContext ctx) {
+
+ Map<String, InstanceContext> map;
+
+ if(instanceCtxts.get(domainName) == null){
+ map = new HashMap<String, InstanceContext>();
+
+ } else{
+ map = instanceCtxts.get(domainName);
+ }
+
+ map.put(subDomainName, ctx);
+ instanceCtxts.put(domainName, map);
+
+ }
+
+// public void addToDomainToTemplateMap(String key, Template value) {
+// domainToTemplateMap.put(key, value);
+// }
+
+ public Template getTemplate(String domain, String subDomain) {
+ if(getInstanceContext(domain, subDomain) == null){
+ return null;
+ }
+ return getInstanceContext(domain, subDomain).getTemplate();
+ }
+
+ public InstanceContext getInstanceContext(String domain, String subDomain) {
+ if (instanceCtxts.get(domain) != null) {
+ return instanceCtxts.get(domain).get(subDomain);
+ }
+ return null;
+ }
+
+ public ComputeService getComputeService() {
+ return computeService;
+ }
+
+ public void setComputeService(ComputeService computeService) {
+ this.computeService = computeService;
+ }
+
+// public void addNodeIdToDomainMap(String nodeId, String domain) {
+// nodeIdToDomainMap.put(nodeId, domain);
+// }
+//
+// public void addPublicIpToDomainMap(String ip, String domain) {
+// publicIpToDomainMap.put(ip, domain);
+// }
+//
+// public void addPublicIpToNodeIdMap(String ip, String nodeId) {
+// publicIpToNodeIdMap.put(ip, nodeId);
+// }
+
+ /**
+ * This will return the node id of the node which is belong to the
+ * requesting domain, sub domain and which is the most recently created. If it cannot find a
+ * matching node id, this will return <code>null</code>.
+ * @param domain service domain.
+ * @param subDomain service sub domain.
+ * @return the node Id of the node
+ */
+ public String getLastMatchingNode(String domain, String subDomain) {
+
+ InstanceContext ctx = getInstanceContext(domain, subDomain);
+
+ if(ctx == null){
+ return null;
+ }
+
+ // iterate in reverse order
+ ListIterator<String> iter =
+ new ArrayList<String>(ctx.getNodeIdToIpMap().keySet()).
+ listIterator(ctx.getNodeIdToIpMap().size());
+
+ if (iter.hasPrevious()) {
+ return iter.previous();
+ }
+
+ return null;
+ }
+
+ /**
+ * This will return the public IP of the node which is belong to the
+ * requesting domain, sub domain and which is the most recently created. If it cannot find a
+ * matching public IP, this will return <code>null</code>.
+ * @param domain service domain.
+ * @param subDomain service sub domain.
+ * @return the public IP of the node
+ */
+ public String getLastMatchingPublicIp(String domain, String subDomain) {
+
+ InstanceContext ctx = getInstanceContext(domain, subDomain);
+
+ if(ctx == null){
+ return null;
+ }
+
+ // iterate in reverse order
+ ListIterator<String> iter =
+ new ArrayList<String>(ctx.getNodeIdToIpMap().keySet()).
+ listIterator(ctx.getNodeIdToIpMap().size());
+
+ while (iter.hasPrevious()) {
+ return ctx.getNodeIdToIpMap().get(iter.previous());
+ }
+
+ return null;
+
+// // traverse from the last entry of the map
+// ListIterator<Map.Entry<String, String>> iter =
+// new ArrayList<Entry<String, String>>(publicIpToDomainMap.entrySet()).
+// listIterator(publicIpToDomainMap.size());
+//
+// while (iter.hasPrevious()) {
+// Map.Entry<String, String> entry = iter.previous();
+// if (entry.getValue().equals(domain)) {
+// return entry.getKey();
+// }
+// }
+//
+// return null;
+ }
+
+ /**
+ * This will return the node id of the node which is belong to the
+ * requesting domain, sub domain and which is created at first. If it cannot find a
+ * matching node id, this will return <code>null</code>.
+ * @param domain service domain.
+ * @param subDomain service sub domain.
+ * @return node id of the node
+ */
+ public String getFirstMatchingNode(String domain, String subDomain) {
+
+ InstanceContext ctx = getInstanceContext(domain, subDomain);
+
+ if(ctx == null){
+ return null;
+ }
+
+ // iterate in added order
+ ListIterator<String> iter =
+ new ArrayList<String>(ctx.getNodeIdToIpMap().keySet()).
+ listIterator(0);
+
+ while (iter.hasNext()) {
+ return iter.next();
+ }
+
+ return null;
+
+// for (Entry<String, String> entry : nodeIdToDomainMap.entrySet()) {
+// if (entry.getValue().equals(domain)) {
+// return entry.getKey();
+// }
+// }
+// return null;
+ }
+
+ /**
+ * This will return the node id of the node which has the given public IP.
+ * If it cannot find a matching node id, this will return
+ * <code>null</code>.
+ * @param publicIp public IP of a node.
+ * @return node id of the matching node.
+ */
+ public String getNodeWithPublicIp(String publicIp) {
+
+ InstanceContext ctx;
+
+ for (String ip : publicIpToInstanceCtxt.keySet()) {
+
+ if (ip.equals(publicIp)) {
+
+ ctx = publicIpToInstanceCtxt.get(ip);
+
+ for (String nodeId : nodeIdToInstanceCtxt.keySet()) {
+ if (ctx.equals(nodeIdToInstanceCtxt.get(nodeId))) {
+ return nodeId;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * This will return a list of node Ids that are started in this IaaS and that are
+ * belong to the given domain, sub domain.
+ * @param domain service domain.
+ * @param subDomain service sub domain.
+ * @return List of node Ids.
+ */
+ public List<String> getNodeIds(String domain, String subDomain) {
+
+ InstanceContext ctx = getInstanceContext(domain, subDomain);
+
+ if(ctx == null){
+ return new ArrayList<String>();
+ }
+
+ return new ArrayList<String>(ctx.getNodeIdToIpMap().keySet());
+
+
+// List<String> nodeIds = new ArrayList<String>();
+//
+// for (Entry<String, String> entry : nodeIdToDomainMap.entrySet()) {
+// if (entry.getValue().equals(domain)) {
+// nodeIds.add(entry.getKey());
+// }
+// }
+//
+// return nodeIds;
+ }
+
+ /**
+ * Removes a specific node id and related entries.
+ * @param node id of the node to be removed.
+ */
+ public void removeNodeId(String nodeId) {
+
+ InstanceContext ctx;
+
+ if(nodeIdToInstanceCtxt.containsKey(nodeId)){
+ // remove from node id map
+ ctx = nodeIdToInstanceCtxt.remove(nodeId);
+
+ // remove from public ip map
+ publicIpToInstanceCtxt.remove(ctx.getNodeIdToIpMap().get(nodeId));
+
+ // remove from main map
+ instanceCtxts.get(ctx.getDomain()).get(ctx.getSubDomain()).removeNode(nodeId);
+
+ }
+ }
+
+ public boolean equals(Object obj) {
+
+ if (obj instanceof IaasContext) {
+ return new EqualsBuilder().append(getName(), ((IaasContext) obj).getName()).isEquals();
+ }
+ return false;
+
+ }
+
+ public int hashCode() {
+ return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
+ append(name).
+ toHashCode();
+ }
+
+ public int getScaleDownOrder() {
+ return scaleDownOrder;
+ }
+
+ public void setScaleDownOrder(int scaleDownOrder) {
+ this.scaleDownOrder = scaleDownOrder;
+ }
+
+ public int getScaleUpOrder() {
+ return scaleUpOrder;
+ }
+
+ public void setScaleUpOrder(int scaleUpOrder) {
+ this.scaleUpOrder = scaleUpOrder;
+ }
+
+// public void setDomainToTemplateMap(Map<String, Template> map) {
+// domainToTemplateMap = map;
+// }
+//
+// public Map<String, Template> getDomainToTemplateMap() {
+// return domainToTemplateMap;
+// }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasProvider.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasProvider.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasProvider.java
new file mode 100644
index 0000000..aa123ac
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/IaasProvider.java
@@ -0,0 +1,141 @@
+/**
+ * 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.service.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This is the basic data structure which holds an IaaS specific details.
+ */
+public class IaasProvider {
+
+ /**
+ * Unique id to identify this IaaS provider.
+ */
+ private String type;
+
+ /**
+ * human description of this IaaS provider
+ */
+ private String name;
+
+ /**
+ * Property map for this IaaS provider.
+ */
+ private Map<String, String> properties = new HashMap<String, String>();
+
+ /**
+ * Image identifier.
+ */
+ private String template;
+
+ /**
+ * Scale up order and scale down order of the IaaS.
+ */
+ private int scaleUpOrder, scaleDownOrder;
+
+ private String provider, identity, credential;
+
+// public enum SortParameter {
+// SCALE_UP, SCALE_DOWN
+// }
+
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String id) {
+ this.type = id;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ public void setProperty(String key, String value) {
+
+ if(key != null && value != null){
+ properties.put(key, value);
+ }
+ }
+
+ public void setProperties(Map<String, String> properties) {
+ this.properties = properties;
+ }
+
+ public String getTemplate() {
+ return template;
+ }
+
+ public void setTemplate(String template) {
+ this.template = template;
+ }
+
+ public int getScaleUpOrder() {
+ return scaleUpOrder;
+ }
+
+ public void setScaleUpOrder(int scaleUpOrder) {
+ this.scaleUpOrder = scaleUpOrder;
+ }
+
+ public int getScaleDownOrder() {
+ return scaleDownOrder;
+ }
+
+ public void setScaleDownOrder(int scaleDownOrder) {
+ this.scaleDownOrder = scaleDownOrder;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getProvider() {
+ return provider;
+ }
+
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
+ public String getIdentity() {
+ return identity;
+ }
+
+ public void setIdentity(String identity) {
+ this.identity = identity;
+ }
+
+ public String getCredential() {
+ return credential;
+ }
+
+ public void setCredential(String credential) {
+ this.credential = credential;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/ac065d73/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/InstanceContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/InstanceContext.java b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/InstanceContext.java
new file mode 100644
index 0000000..a1544bf
--- /dev/null
+++ b/components/org.apache.stratos.autoscaler.service/src/main/java/org/apache/stratos/autoscaler/service/util/InstanceContext.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.autoscaler.service.util;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.jclouds.compute.domain.Template;
+
+/**
+ * This will hold the run-time data related to an instance.
+ * Instance can be an EC2 one, Openstack one etc.
+ */
+public class InstanceContext implements Serializable {
+
+ private static final long serialVersionUID = -2604902942512629140L;
+ private String domain;
+ private String subDomain;
+ private transient Template template;
+
+ /**
+ * Key - node Id
+ * Value - IP
+ */
+ private Map<String, String> nodeIdToIpMap;
+
+ public InstanceContext(String domain, String subDomain, Template temp) {
+ this.domain = domain;
+ this.subDomain = subDomain;
+ this.template = temp;
+ nodeIdToIpMap = new LinkedHashMap<String, String>();
+ }
+//
+// public InstanceContext(String domain, String subDomain, Template temp, String nodeId, String publicIp) {
+// this.domain = domain;
+// this.subDomain = subDomain;
+// this.template = temp;
+// this.nodeId = nodeId;
+// this.publicIp = publicIp;
+// }
+
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public String getSubDomain() {
+ return subDomain;
+ }
+
+ public Template getTemplate() {
+ return template;
+ }
+
+ public void setTemplate(Template temp) {
+ this.template = temp;
+ }
+
+ public void addNode(String nodeId, String ip) {
+ if("".equals(ip)){
+ ip = null;
+ }
+ nodeIdToIpMap.put(nodeId, ip);
+ }
+
+ public void removeNode(String nodeId) {
+ nodeIdToIpMap.remove(nodeId);
+ }
+
+
+ public Map<String, String> getNodeIdToIpMap() {
+ return nodeIdToIpMap;
+ }
+
+
+}