moving Application Parsing to Autoscaler
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/b9aabfdc Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/b9aabfdc Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/b9aabfdc Branch: refs/heads/4.0.0-grouping Commit: b9aabfdcaca069ae77b3977c361215da80c53265 Parents: 7d7cd50 Author: Isuru Haththotuwa <[email protected]> Authored: Fri Oct 31 18:47:32 2014 +0530 Committer: Isuru Haththotuwa <[email protected]> Committed: Fri Oct 31 18:49:07 2014 +0530 ---------------------------------------------------------------------- .../autoscaler/api/AutoScalerServiceImpl.java | 27 +- .../applications/ApplicationHolder.java | 15 +- .../ApplicationSynchronizeTask.java | 2 +- .../applications/ApplicationUtils.java | 289 ++++++++ .../applications/ClusterInformation.java | 27 + .../applications/MTClusterInformation.java | 47 ++ .../applications/STClusterInformation.java | 57 ++ .../applications/parser/ApplicationParser.java | 51 ++ .../parser/DefaultApplicationParser.java | 657 +++++++++++++++++++ .../applications/parser/ParserUtils.java | 142 ++++ .../ApplicationCartridgePayloadData.java | 27 + .../applications/payload/BasicPayloadData.java | 311 +++++++++ .../payload/DataCartridgePayloadData.java | 27 + .../payload/FrameworkCartridgePayloadData.java | 27 + .../LoadBalancerCartridgePayloadData.java | 27 + .../applications/payload/PayloadData.java | 69 ++ .../applications/payload/PayloadFactory.java | 59 ++ .../pojo/ApplicationClusterContext.java | 137 ++++ .../applications/pojo/ApplicationContext.java | 93 +++ .../applications/pojo/ComponentContext.java | 54 ++ .../applications/pojo/DependencyContext.java | 44 ++ .../applications/pojo/GroupContext.java | 84 +++ .../applications/pojo/SubscribableContext.java | 44 ++ .../pojo/SubscribableInfoContext.java | 103 +++ .../applications/topic/ApplicationBuilder.java | 44 ++ .../topic/ApplicationsEventPublisher.java | 14 +- .../cloud/controller/CloudControllerClient.java | 16 + .../ApplicationDefinitionException.java | 48 ++ .../CartridgeInformationException.java | 47 ++ .../interfaces/AutoScalerServiceInterface.java | 18 + .../autoscaler/registry/RegistryManager.java | 5 + .../stratos/autoscaler/util/AutoscalerUtil.java | 4 + 32 files changed, 2603 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/api/AutoScalerServiceImpl.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/api/AutoScalerServiceImpl.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/api/AutoScalerServiceImpl.java index 8c4bf2e..4938b4c 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/api/AutoScalerServiceImpl.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/api/AutoScalerServiceImpl.java @@ -22,6 +22,10 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.autoscaler.NetworkPartitionLbHolder; +import org.apache.stratos.autoscaler.applications.parser.ApplicationParser; +import org.apache.stratos.autoscaler.applications.parser.DefaultApplicationParser; +import org.apache.stratos.autoscaler.applications.pojo.ApplicationContext; +import org.apache.stratos.autoscaler.applications.topic.ApplicationBuilder; import org.apache.stratos.autoscaler.client.cloud.controller.CloudControllerClient; import org.apache.stratos.autoscaler.deployment.policy.DeploymentPolicy; import org.apache.stratos.autoscaler.exception.*; @@ -34,7 +38,7 @@ import org.apache.stratos.autoscaler.policy.PolicyManager; import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy; import org.apache.stratos.autoscaler.registry.RegistryManager; import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; -import org.wso2.carbon.registry.api.RegistryException; +import org.apache.stratos.messaging.domain.applications.Application; import java.text.MessageFormat; import java.util.ArrayList; @@ -248,8 +252,25 @@ public class AutoScalerServiceImpl implements AutoScalerServiceInterface{ return null; } - - public boolean checkClusterLBExistenceAgainstPolicy(String clusterId, String deploymentPolicyId) { + + @Override + public void deployApplicationDefinition(ApplicationContext applicationContext) + throws ApplicationDefinitionException { + + ApplicationParser applicationParser = new DefaultApplicationParser(); + Application application = applicationParser.parse(applicationContext); + ApplicationBuilder.handleApplicationCreated(application, + applicationParser.getApplicationClusterContexts()); + } + + @Override + public void unDeployApplicationDefinition(String applicationId, int tenantId, String tenantDomain) + throws ApplicationDefinitionException { + + ApplicationBuilder.handleApplicationUndeployed(applicationId); + } + + public boolean checkClusterLBExistenceAgainstPolicy(String clusterId, String deploymentPolicyId) { for (PartitionGroup partitionGroup : PolicyManager.getInstance().getDeploymentPolicy(deploymentPolicyId).getPartitionGroups()) { http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java index e147d1b..6d16677 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java @@ -94,9 +94,6 @@ public class ApplicationHolder { public static void persistApplication (Application application) { synchronized (ApplicationHolder.class) { - if (log.isDebugEnabled()) { - log.debug("Updating topology"); - } applications.addApplication(application); AutoscalerUtil.persistApplication(application); if (log.isDebugEnabled()) { @@ -106,6 +103,18 @@ public class ApplicationHolder { } + public static void removeApplication (String applicationId) { + + synchronized (ApplicationHolder.class) { + applications.removeApplication(applicationId); + AutoscalerUtil.removeApplication(applicationId); + if (log.isDebugEnabled()) { + log.debug("Application [ " + applicationId + " ] removed from Applications"); + } + } + + } + private static String toJson(Object object) { Gson gson = new Gson(); return gson.toJson(object); http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationSynchronizeTask.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationSynchronizeTask.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationSynchronizeTask.java index e18cd12..9f0ca8c 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationSynchronizeTask.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationSynchronizeTask.java @@ -36,7 +36,7 @@ public class ApplicationSynchronizeTask implements Task { } // publish to the topic if (ApplicationHolder.getApplications() != null) { - ApplicationsEventPublisher.sendCompleteTopologyEvent(ApplicationHolder.getApplications()); + ApplicationsEventPublisher.sendCompleteApplicationsEvent(ApplicationHolder.getApplications()); } } http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationUtils.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationUtils.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationUtils.java new file mode 100644 index 0000000..e82882c --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationUtils.java @@ -0,0 +1,289 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.applications.payload.BasicPayloadData; +import org.apache.stratos.autoscaler.applications.payload.PayloadData; +import org.apache.stratos.autoscaler.applications.payload.PayloadFactory; +import org.apache.stratos.autoscaler.exception.ApplicationDefinitionException; +import org.apache.stratos.cloud.controller.stub.pojo.CartridgeInfo; +import org.apache.stratos.cloud.controller.stub.pojo.PortMapping; +import org.apache.stratos.cloud.controller.stub.pojo.Property; + +import java.util.*; +import java.util.regex.Pattern; + +public class ApplicationUtils { + private static final Log log = LogFactory.getLog(ApplicationUtils.class); + + public static boolean isAliasValid (String alias) { + + String patternString = "([a-z0-9]+([-][a-z0-9])*)+"; + Pattern pattern = Pattern.compile(patternString); + + return pattern.matcher(alias).matches(); + } + + public static boolean isValid (String arg) { + + if (arg == null || arg.isEmpty()) { + return false; + } else { + return true; + } + } + + public static Properties getGlobalPayloadData () { + + Properties globalProperties = new Properties(); + + if (System.getProperty("puppet.ip") != null) { + globalProperties.setProperty("PUPPET_IP", System.getProperty("puppet.ip")); + } + if (System.getProperty("puppet.hostname") != null) { + globalProperties.setProperty("PUPPET_HOSTNAME", System.getProperty("puppet.hostname")); + } + if (System.getProperty("puppet.env") != null) { + globalProperties.setProperty("PUPPET_ENV", System.getProperty("puppet.env")); + } + if (System.getProperty("puppet.dns.available") != null) { + globalProperties.setProperty("PUPPET_DNS_AVAILABLE", System.getProperty("puppet.dns.available")); + } + + return globalProperties; + } + +// public static MetaDataHolder getClusterLevelPayloadData (String appId, String groupName, int tenantId, String key, +// String hostname, String tenantRange, String clusterId, +// SubscribableContext subscribableCtxt, +// SubscribableInfoContext subscribableInfoCtxt, +// Cartridge cartridge) { +// +// MetaDataHolder metaDataHolder; +// if (groupName != null) { +// metaDataHolder = new MetaDataHolder(appId, groupName, clusterId); +// } else { +// metaDataHolder = new MetaDataHolder(appId, clusterId); +// } +// +// Properties clusterLevelPayloadProperties = new Properties(); +// // app id +// clusterLevelPayloadProperties.setProperty("APP_ID", appId); +// // group name +// if (groupName != null) { +// clusterLevelPayloadProperties.setProperty("GROUP_NAME", groupName); +// } +// // service name +// if (subscribableCtxt.getType() != null) { +// clusterLevelPayloadProperties.put("SERVICE_NAME", subscribableCtxt.getType()); +// } +// // host name +// if (hostname != null) { +// clusterLevelPayloadProperties.put("HOST_NAME", hostname); +// } +// // multi tenant +// clusterLevelPayloadProperties.put("MULTITENANT", String.valueOf(cartridge.isMultiTenant())); +// // tenant range +// if (tenantRange != null) { +// clusterLevelPayloadProperties.put("TENANT_RANGE", tenantRange); +// } +// // cartridge alias +// if (subscribableCtxt.getAlias() != null) { +// clusterLevelPayloadProperties.put("CARTRIDGE_ALIAS", subscribableCtxt.getAlias()); +// } +// // cluster id +// if (clusterId != null) { +// clusterLevelPayloadProperties.put("CLUSTER_ID", clusterId); +// } +// // repo url +// if (subscribableInfoCtxt.getRepoUrl() != null) { +// clusterLevelPayloadProperties.put("REPO_URL", subscribableInfoCtxt.getRepoUrl()); +// } +// // ports +//// if (createPortMappingPayloadString(cartridge) != null) { +//// clusterLevelPayloadProperties.put("PORTS", createPortMappingPayloadString(cartridge)); +//// } +// // provider +// if (cartridge.getProvider() != null) { +// clusterLevelPayloadProperties.put("PROVIDER", cartridge.getProvider()); +// } +// // tenant id +// clusterLevelPayloadProperties.setProperty("TENANT_ID", String.valueOf(tenantId)); +// // cartridge key +// clusterLevelPayloadProperties.setProperty("CARTRIDGE_KEY", key); +// // get global payload params +// //clusterLevelPayloadProperties.putAll(ApplicationUtils.getGlobalPayloadData()); +// +// metaDataHolder.setProperties(clusterLevelPayloadProperties); +// return metaDataHolder; +// } + + private static String createPortMappingPayloadString (CartridgeInfo cartridge) { + + // port mappings + StringBuilder portMapBuilder = new StringBuilder(); + PortMapping[] portMappings = cartridge.getPortMappings(); + for (PortMapping portMapping : portMappings) { + String port = portMapping.getPort(); + portMapBuilder.append(port).append("|"); + } + + // remove last "|" character + String portMappingString = portMapBuilder.toString().replaceAll("\\|$", ""); + + return portMappingString; + } + + public static StringBuilder getTextPayload (String appId, String groupName, String clusterId) { + + StringBuilder payloadBuilder = new StringBuilder(); + payloadBuilder.append("APP_ID=" + appId); + if (groupName != null) { + payloadBuilder.append(","); + payloadBuilder.append("GROUP_NAME=" + groupName); + } + payloadBuilder.append(","); + payloadBuilder.append("CLUSTER_ID=" + clusterId); + // puppet related + if (System.getProperty("puppet.ip") != null) { + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_IP=" + System.getProperty("puppet.ip")); + } + if (System.getProperty("puppet.hostname") != null) { + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_HOSTNAME=" + System.getProperty("puppet.hostname")); + } + if (System.getProperty("puppet.env") != null) { + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_ENV=" + System.getProperty("puppet.env")); + } + if (System.getProperty("puppet.dns.available") != null) { + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_DNS_AVAILABLE=" + System.getProperty("puppet.dns.available")); + } + // meta data endpoint + // if (MetaDataClientConfig.getInstance().getMetaDataServiceBaseUrl() != null) { + // TODO + //payloadBuilder.append(","); + //payloadBuilder.append("METADATA_ENDPOINT=" + MetaDataClientConfig.getInstance().getMetaDataServiceBaseUrl()); + // } + payloadBuilder.append(","); + + return payloadBuilder; + } + + public static PayloadData createPayload(String appId, String groupName, CartridgeInfo cartridgeInfo, String subscriptionKey, int tenantId, String clusterId, + String hostName, String repoUrl, String alias, Map<String, String> customPayloadEntries, String[] dependencyAliases) + throws ApplicationDefinitionException { + + //Create the payload + BasicPayloadData basicPayloadData = createBasicPayload(appId, groupName, cartridgeInfo, subscriptionKey, + clusterId, hostName, repoUrl, alias, tenantId, dependencyAliases); + //Populate the basic payload details + basicPayloadData.populatePayload(); + + PayloadData payloadData = PayloadFactory.getPayloadDataInstance(cartridgeInfo.getProvider(), + cartridgeInfo.getType(), basicPayloadData); + + boolean isDeploymentParam = false; + // get the payload parameters defined in the cartridgeInfo definition file for this cartridgeInfo type + if (cartridgeInfo.getProperties() != null && cartridgeInfo.getProperties().length != 0) { + + for (Property propertyEntry : cartridgeInfo.getProperties()) { + // check if a property is related to the payload. Currently this is done by checking if the + // property name starts with 'payload_parameter.' suffix. If so the payload param name will + // be taken as the substring from the index of '.' to the end of the property name. + if (propertyEntry.getName() + .startsWith("payload_parameter.")) { + String payloadParamName = propertyEntry.getName(); + String payloadParamSubstring = payloadParamName.substring(payloadParamName.indexOf(".") + 1); + if("DEPLOYMENT".equals(payloadParamSubstring)) { + isDeploymentParam = true; + } + payloadData.add(payloadParamSubstring, propertyEntry.getValue()); + } + } + } + + // DEPLOYMENT payload param must be set because its used by puppet agent + // to generate the hostname. Therefore, if DEPLOYMENT is not set in cartridgeInfo properties, + // adding the DEPLOYMENT="default" param + if(!isDeploymentParam) { + payloadData.add("DEPLOYMENT", "default"); + } + //check if there are any custom payload entries defined + if (customPayloadEntries != null) { + //add them to the payload + Set<Map.Entry<String,String>> entrySet = customPayloadEntries.entrySet(); + for (Map.Entry<String, String> entry : entrySet) { + payloadData.add(entry.getKey(), entry.getValue()); + } + } + + return payloadData; + } + + private static BasicPayloadData createBasicPayload(String appId, String groupName, CartridgeInfo cartridge, + String subscriptionKey, String clusterId, + String hostName, String repoUrl, String alias, + int tenantId, String[] dependencyAliases) { + + BasicPayloadData basicPayloadData = new BasicPayloadData(); + basicPayloadData.setAppId(appId); + basicPayloadData.setGroupName(groupName); + basicPayloadData.setApplicationPath(cartridge.getBaseDir()); + basicPayloadData.setSubscriptionKey(subscriptionKey); + //basicPayloadData.setDeployment("default");//currently hard coded to default + basicPayloadData.setMultitenant(String.valueOf(cartridge.getMultiTenant())); + basicPayloadData.setPortMappings(createPortMappingPayloadString(cartridge)); + basicPayloadData.setServiceName(cartridge.getType()); + basicPayloadData.setProvider(cartridge.getProvider()); + + if(repoUrl != null) { + basicPayloadData.setGitRepositoryUrl(repoUrl); + } + + if (clusterId != null) { + basicPayloadData.setClusterId(clusterId); + } + + if (hostName != null) { + basicPayloadData.setHostName(hostName); + } + + if (alias != null) { + basicPayloadData.setSubscriptionAlias(alias); + } + + basicPayloadData.setTenantId(tenantId); + + basicPayloadData.setTenantRange("*"); + basicPayloadData.setDependencyAliases(dependencyAliases); +// if(cartridge.getExportingProperties() != null){ +// basicPayloadData.setExportingProperties(cartridge.getExportingProperties()); +// log.info("testing1 getExportingProperties " + cartridge.getExportingProperties()); +// +// } + + return basicPayloadData; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ClusterInformation.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ClusterInformation.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ClusterInformation.java new file mode 100644 index 0000000..5fd6d57 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ClusterInformation.java @@ -0,0 +1,27 @@ +/* + * 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.cloud.controller.application; + +public interface ClusterInformation { + + public String getClusterId (String alias, String cartridgeType); + + public String getHostName (String alias, String cartridgeDefinitionHostName); +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/MTClusterInformation.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/MTClusterInformation.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/MTClusterInformation.java new file mode 100644 index 0000000..a0a59d4 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/MTClusterInformation.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications; + +import org.apache.stratos.cloud.controller.application.ClusterInformation; + +public class MTClusterInformation implements ClusterInformation { + + @Override + public String getClusterId(String alias, String cartridgeType) { + + if (!ApplicationUtils.isValid(cartridgeType)) { + // cannot happen + throw new IllegalArgumentException("Invalid cartridge type value provided: [ " + cartridgeType + " ]"); + } + + return cartridgeType + ".domain"; + } + + @Override + public String getHostName(String alias, String cartridgeDefinitionHostName) { + + if (!ApplicationUtils.isValid(cartridgeDefinitionHostName)) { + // cannot happen + throw new IllegalArgumentException("Invalid host name value provided: [ " + cartridgeDefinitionHostName + " ]"); + } + + return cartridgeDefinitionHostName; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/STClusterInformation.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/STClusterInformation.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/STClusterInformation.java new file mode 100644 index 0000000..9a5bea8 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/STClusterInformation.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications; + +import org.apache.stratos.cloud.controller.application.ClusterInformation; + +public class STClusterInformation implements ClusterInformation { + + @Override + public String getClusterId(String alias, String cartridgeType) { + + if (!ApplicationUtils.isValid(alias)) { + // cannot happen + throw new IllegalArgumentException("Invalid alias value provided: [ " + alias + " ]"); + } + + if (!ApplicationUtils.isValid(cartridgeType)) { + // cannot happen + throw new IllegalArgumentException("Invalid cartridge type value provided: [ " + cartridgeType + " ]"); + } + + return alias + "." + cartridgeType + ".domain"; + } + + @Override + public String getHostName(String alias, String cartridgeDefinitionHostName) { + + if (!ApplicationUtils.isValid(alias)) { + // cannot happen + throw new IllegalArgumentException("Invalid alias value provided: [ " + alias + " ]"); + } + + if (!ApplicationUtils.isValid(cartridgeDefinitionHostName)) { + // cannot happen + throw new IllegalArgumentException("Invalid host name value provided: [ " + cartridgeDefinitionHostName + " ]"); + } + + return alias + "." + cartridgeDefinitionHostName; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ApplicationParser.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ApplicationParser.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ApplicationParser.java new file mode 100644 index 0000000..529c1f8 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ApplicationParser.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.parser; + + +import org.apache.stratos.autoscaler.applications.pojo.ApplicationClusterContext; +import org.apache.stratos.autoscaler.exception.ApplicationDefinitionException; +import org.apache.stratos.messaging.domain.applications.Application; + +import java.util.Set; + + +public interface ApplicationParser { + + /** + * Parses the Application Definition + * + * @param obj Object with the Application Definition. An Object is used here since there can be + * significant changes between the way composite Applications are defined in different + * conventions + * @return Application structure denoting the parsed Application + * @throws ApplicationDefinitionException If the Application Definition is invalid + */ + public Application parse (Object obj) throws ApplicationDefinitionException; + + /** + * Returns a set of ApplicationClusterContext which will comprise of cluster related information + * extracted from the Application definition + * + * @return Set of ApplicationClusterContext objects + * @throws ApplicationDefinitionException if any error occurs + */ + public Set<ApplicationClusterContext> getApplicationClusterContexts() throws ApplicationDefinitionException; +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/DefaultApplicationParser.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/DefaultApplicationParser.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/DefaultApplicationParser.java new file mode 100644 index 0000000..8184743 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/DefaultApplicationParser.java @@ -0,0 +1,657 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.parser; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.applications.ApplicationUtils; +import org.apache.stratos.autoscaler.applications.MTClusterInformation; +import org.apache.stratos.autoscaler.applications.STClusterInformation; +import org.apache.stratos.autoscaler.applications.pojo.ApplicationContext; +import org.apache.stratos.autoscaler.applications.pojo.GroupContext; +import org.apache.stratos.autoscaler.applications.pojo.SubscribableContext; +import org.apache.stratos.autoscaler.applications.pojo.SubscribableInfoContext; +import org.apache.stratos.autoscaler.client.cloud.controller.CloudControllerClient; +import org.apache.stratos.autoscaler.exception.ApplicationDefinitionException; +import org.apache.stratos.autoscaler.exception.CartridgeInformationException; +import org.apache.stratos.autoscaler.pojo.ServiceGroup; +import org.apache.stratos.autoscaler.registry.RegistryManager; +import org.apache.stratos.cloud.controller.application.ClusterInformation; +import org.apache.stratos.cloud.controller.pojo.ApplicationClusterContext; +import org.apache.stratos.cloud.controller.stub.pojo.CartridgeInfo; +import org.apache.stratos.messaging.domain.applications.Application; +import org.apache.stratos.messaging.domain.applications.ClusterDataHolder; +import org.apache.stratos.messaging.domain.applications.DependencyOrder; +import org.apache.stratos.messaging.domain.applications.Group; + +import java.util.*; + +public class DefaultApplicationParser implements ApplicationParser { + + private static Log log = LogFactory.getLog(DefaultApplicationParser.class); + +// private static FasterLookUpDataHolder dataHolder = FasterLookUpDataHolder.getInstance(); + + private Set<ApplicationClusterContext> applicationClusterContexts; + + public DefaultApplicationParser () { + + this.applicationClusterContexts = new HashSet<ApplicationClusterContext>(); + } + + @Override + public Application parse(Object obj) throws ApplicationDefinitionException { + + ApplicationContext applicationCtxt = (ApplicationContext) obj; + + if (applicationCtxt == null) { + handleError("Invalid Composite Application Definition"); + } + + assert applicationCtxt != null; + if (applicationCtxt.getAlias() == null || applicationCtxt.getAlias().isEmpty()) { + handleError("Invalid alias specified"); + } + + if (applicationCtxt.getApplicationId() == null || applicationCtxt.getApplicationId().isEmpty()) { + handleError("Invalid Composite App id specified"); + } + + // get the defined groups + Map<String, GroupContext> definedGroups = getDefinedGroups(applicationCtxt); + if (log.isDebugEnabled()) { + if (definedGroups != null) { + Set<Map.Entry<String, GroupContext>> groupEntries = definedGroups.entrySet(); + log.debug("Defined Groups: [ "); + for (Map.Entry<String, GroupContext> groupEntry : groupEntries) { + log.debug("Group alias: " + groupEntry.getKey()); + } + log.debug(" ]"); + } else { + log.debug("No Group definitions found in app id " + applicationCtxt.getApplicationId()); + } + } + + // get the Subscribables Information + Map<String, SubscribableInfoContext> subscribablesInfo = getSubscribableInformation(applicationCtxt); + if (log.isDebugEnabled()) { + Set<Map.Entry<String, SubscribableInfoContext>> subscribableInfoCtxtEntries = subscribablesInfo.entrySet(); + log.debug("Defined Subscribable Information: [ "); + for (Map.Entry<String, SubscribableInfoContext> subscribableInfoCtxtEntry : subscribableInfoCtxtEntries) { + log.debug("Subscribable Information alias: " + subscribableInfoCtxtEntry.getKey()); + } + log.debug(" ]"); + } + + if (subscribablesInfo == null) { + handleError("Invalid Composite Application Definition, no Subscribable Information specified"); + } + + return buildCompositeAppStructure (applicationCtxt, definedGroups, subscribablesInfo); + } + + @Override + public Set<ApplicationClusterContext> getApplicationClusterContexts() throws ApplicationDefinitionException { + return applicationClusterContexts; + } + + /** + * Extract Group information from Application Definition + * + * @param appCtxt ApplicationContext object with Application information + * @return Map [group alias -> Group] + * + * @throws ApplicationDefinitionException if the Group information is invalid + */ + private Map<String, GroupContext> getDefinedGroups (ApplicationContext appCtxt) throws + ApplicationDefinitionException { + + // map [group alias -> Group Definition] + Map<String, GroupContext> definedGroups = null; + + if (appCtxt.getComponents() != null) { + if (appCtxt.getComponents().getGroupContexts() != null) { + definedGroups = new HashMap<String, GroupContext>(); + + for (GroupContext groupContext : appCtxt.getComponents().getGroupContexts()) { + + // check validity of group name + if (StringUtils.isEmpty(groupContext.getName())) { + handleError("Invalid Group name specified"); + } + + // check if group is deployed + if(!isGroupDeployed(groupContext.getName())) { + handleError("Group with name " + groupContext.getName() + " not deployed"); + } + + // check validity of group alias + + if (StringUtils.isEmpty(groupContext.getAlias()) || !ApplicationUtils.isAliasValid(groupContext.getAlias())) { + handleError("Invalid Group alias specified: [ " + groupContext.getAlias() + " ]"); + } + + // check if a group is already defined under the same alias + if(definedGroups.get(groupContext.getAlias()) != null) { + // a group with same alias already exists, can't continue + handleError("A Group with alias " + groupContext.getAlias() + " already exists"); + } + + definedGroups.put(groupContext.getAlias(), groupContext); + if (log.isDebugEnabled()) { + log.debug("Added Group Definition [ " + groupContext.getName() +" , " + groupContext.getAlias() + " ] to map [group alias -> Group Definition]"); + } + } + } + } + + return definedGroups; + } + + /** + * Extract Subscription Information from the Application Definition + * + * @param appCtxt ApplicationContext object with Application information + * @return Map [cartridge alias -> Group] + * + * @throws ApplicationDefinitionException if the Subscription information is invalid + */ + private Map<String, SubscribableInfoContext> getSubscribableInformation (ApplicationContext appCtxt) throws + ApplicationDefinitionException { + + // map [cartridge alias -> Subscribable Information] + Map<String, SubscribableInfoContext> subscribableInformation = null; + + if (appCtxt.getSubscribableInfoContext() != null) { + subscribableInformation = new HashMap<String, SubscribableInfoContext>(); + + for (SubscribableInfoContext subscribableInfoCtxt : appCtxt.getSubscribableInfoContext()) { + + if (StringUtils.isEmpty(subscribableInfoCtxt.getAlias()) || + !ApplicationUtils.isAliasValid(subscribableInfoCtxt.getAlias())) { + handleError("Invalid alias specified for Subscribable Information Obj: [ " + subscribableInfoCtxt.getAlias() + " ]"); + } + + // check if a group is already defined under the same alias + if(subscribableInformation.get(subscribableInfoCtxt.getAlias()) != null) { + // a group with same alias already exists, can't continue + handleError("A Subscribable Info obj with alias " + subscribableInfoCtxt.getAlias() + " already exists"); + } + + subscribableInformation.put(subscribableInfoCtxt.getAlias(), subscribableInfoCtxt); + if (log.isDebugEnabled()) { + log.debug("Added Subcribables Info obj [ " + subscribableInfoCtxt.getAlias() + " ] to map [cartridge alias -> Subscribable Information]"); + } + } + } + + return subscribableInformation; + } + + /** + * Check if a Group Definition is deployed + * + * @param serviceGroupName Group name + * @return true if the Group is deployed, else false + * + * @throws ApplicationDefinitionException + */ + private boolean isGroupDeployed (String serviceGroupName) throws ApplicationDefinitionException { + + try { + return RegistryManager.getInstance().getServiceGroup(serviceGroupName) != null; + } catch (Exception e) { + String errorMsg = "Error in checking if Service Group Definition [ " + serviceGroupName + + " ] already exists"; + log.error(errorMsg, e); + throw new ApplicationDefinitionException(errorMsg, e); + } + } + + /** + * Builds the Application structure + * + * @param appCtxt ApplicationContext object with Application information + * @param definedGroupCtxts Map [cartridge alias -> Group] with extracted Group Information + * @param subscribableInfoCtxts Map [cartridge alias -> Group] with extracted Subscription Information + * @return Application Application object denoting the Application structure + * + * @throws ApplicationDefinitionException If an error occurs in building the Application structure + */ + private Application buildCompositeAppStructure (ApplicationContext appCtxt, + Map<String, GroupContext> definedGroupCtxts, + Map<String, SubscribableInfoContext> subscribableInfoCtxts) + throws ApplicationDefinitionException { + + Application application = new Application(appCtxt.getApplicationId()); + + // set tenant related information + application.setTenantId(appCtxt.getTenantId()); + application.setTenantDomain(appCtxt.getTenantDomain()); + application.setTenantAdminUserName(appCtxt.getTeantAdminUsername()); + + // following keeps track of all Clusters created for this application + //Set<Cluster> clusters = new HashSet<Cluster>(); + //ClusterDataHolder clusterDataHolder = null; + Map<String, ClusterDataHolder> clusterDataMap; + + if (appCtxt.getComponents() != null) { + // get top level Subscribables + if (appCtxt.getComponents().getSubscribableContexts() != null) { + clusterDataMap = parseLeafLevelSubscriptions(appCtxt.getApplicationId(), appCtxt.getTenantId(), + application.getKey(), null, Arrays.asList(appCtxt.getComponents().getSubscribableContexts()), + subscribableInfoCtxts); + application.setClusterData(clusterDataMap); + //clusters.addAll(clusterDataHolder.getApplicationClusterContexts()); + } + + // get Groups + if (appCtxt.getComponents().getGroupContexts() != null) { + application.setGroups(parseGroups(appCtxt.getApplicationId(), appCtxt.getTenantId(), + application.getKey(), Arrays.asList(appCtxt.getComponents().getGroupContexts()), + subscribableInfoCtxts, definedGroupCtxts)); + } + + // get top level Dependency definitions + if (appCtxt.getComponents().getDependencyContext() != null) { + DependencyOrder appDependencyOrder = new DependencyOrder(); + String [] startupOrders = appCtxt.getComponents().getDependencyContext().getStartupOrdersContexts(); + if (startupOrders != null) { + if (log.isDebugEnabled()) { + log.debug("parsing application ... buildCompositeAppStructure: startupOrders != null for app alias: " + + appCtxt.getAlias() + " #: " + startupOrders.length); + } + appDependencyOrder.setStartupOrders(ParserUtils.convert(startupOrders)); + } else { + if (log.isDebugEnabled()) { + log.debug("parsing application ... buildCompositeAppStructure: startupOrders == null for app alias: " + appCtxt.getAlias()); + } + } + String terminationBehavior = appCtxt.getComponents().getDependencyContext().getTerminationBehaviour(); + validateTerminationBehavior(terminationBehavior); + appDependencyOrder.setTerminationBehaviour(terminationBehavior); + + application.setDependencyOrder(appDependencyOrder); + } + } + + log.info("Application with id " + appCtxt.getApplicationId() + " parsed successfully"); + + return application; + } + + /** + * Validates terminationBehavior. The terminationBehavior should be one of the following: + * 1. terminate-none + * 2. terminate-dependents + * 3. terminate-all + * + * @throws ApplicationDefinitionException if terminationBehavior is different to what is + * listed above + */ + private static void validateTerminationBehavior (String terminationBehavior) throws ApplicationDefinitionException { + + if (!(terminationBehavior == null || "terminate-none".equals(terminationBehavior) || + "terminate-dependents".equals(terminationBehavior) || "terminate-all".equals(terminationBehavior))) { + throw new ApplicationDefinitionException("Invalid Termination Behaviour specified: [ " + + terminationBehavior + " ], should be one of 'terminate-none', 'terminate-dependents', " + + " 'terminate-all' "); + } + } + + /** + * Parse Group information + * + * @param appId Application id + * @param tenantId tenant id of tenant which deployed the Application + * @param key Generated key for the Application + * @param groupCtxts Group information + * @param subscribableInformation Subscribable Information + * @param definedGroupCtxts Map [group alias -> Group] with extracted Group Information + * @return Map [alias -> Group] + * + * @throws ApplicationDefinitionException if an error occurs in parsing Group Information + */ + private Map<String, Group> parseGroups (String appId, int tenantId, String key, List<GroupContext> groupCtxts, + Map<String, SubscribableInfoContext> subscribableInformation, + Map<String, GroupContext> definedGroupCtxts) + throws ApplicationDefinitionException { + + Map<String, Group> groupAliasToGroup = new HashMap<String, Group>(); + + for (GroupContext groupCtxt : groupCtxts) { + Group group = parseGroup(appId, tenantId, key, groupCtxt, subscribableInformation, definedGroupCtxts); + groupAliasToGroup.put(group.getAlias(), group); + } + + //Set<GroupContext> topLevelGroupContexts = getTopLevelGroupContexts(groupAliasToGroup); + Set<Group> nestedGroups = new HashSet<Group>(); + getNestedGroupContexts(nestedGroups, groupAliasToGroup.values()); + filterDuplicatedGroupContexts(groupAliasToGroup.values(), nestedGroups); + + return groupAliasToGroup; + } + + /** + * Extracts nested Group information recursively + * + * @param nestedGroups Nested Groups set to be populated recursively + * @param groups Collection of Groups + */ + private void getNestedGroupContexts (Set<Group> nestedGroups, Collection<Group> groups) { + + if (groups != null) { + for (Group group : groups) { + if (group.getGroups() != null) { + nestedGroups.addAll(group.getGroups()); + getNestedGroupContexts(nestedGroups, group.getGroups()); + } + } + } + } + + /** + * Filters duplicated Groups from top level + * + * @param topLevelGroups Top level Groups + * @param nestedGroups nested Groups + */ + private void filterDuplicatedGroupContexts (Collection<Group> topLevelGroups, Set<Group> nestedGroups) { + + for (Group nestedGroup : nestedGroups) { + filterNestedGroupFromTopLevel(topLevelGroups, nestedGroup); + } + } + + private void filterNestedGroupFromTopLevel (Collection<Group> topLevelGroups, Group nestedGroup) { + + Iterator<Group> parentIterator = topLevelGroups.iterator(); + while (parentIterator.hasNext()) { + Group parentGroup = parentIterator.next(); + // if there is an exactly similar nested Group Context and a top level Group Context + // it implies that they are duplicates. Should be removed from top level. + if (parentGroup.equals(nestedGroup)) { + parentIterator.remove(); + } + } + } + + /** + * Parses an individual Group + * + * @param appId Application id + * @param tenantId tenant id of tenant which deployed the Application + * @param key Generated key for the Application + * @param groupCtxt Group definition information + * @param subscribableInfoCtxts Map [cartridge alias -> Group] with extracted Subscription Information + * @param definedGroupCtxts Map [group alias -> Group] with extracted Group Information + * @return Group object + * + * @throws ApplicationDefinitionException if unable to parse + */ + private Group parseGroup (String appId, int tenantId, String key, GroupContext groupCtxt, + Map<String, SubscribableInfoContext> subscribableInfoCtxts, + Map<String, GroupContext> definedGroupCtxts) + throws ApplicationDefinitionException { + + // check if are in the defined Group set + GroupContext definedGroupDef = definedGroupCtxts.get(groupCtxt.getAlias()); + if (definedGroupDef == null) { + handleError("Group Definition with name: " + groupCtxt.getName() + ", alias: " + + groupCtxt.getAlias() + " is not found in the all Group Definitions collection"); + } + + Group group = new Group(appId, groupCtxt.getName(), groupCtxt.getAlias()); + + group.setAutoscalingPolicy(groupCtxt.getAutoscalingPolicy()); + group.setDeploymentPolicy(groupCtxt.getDeploymentPolicy()); + DependencyOrder dependencyOrder = new DependencyOrder(); + // create the Dependency Ordering + String [] startupOrders = getStartupOrderForGroup(groupCtxt); + if (startupOrders != null) { + dependencyOrder.setStartupOrders(ParserUtils.convert(startupOrders, groupCtxt)); + } + dependencyOrder.setTerminationBehaviour(getKillbehaviour(groupCtxt.getName())); + group.setDependencyOrder(dependencyOrder); + + Map<String, ClusterDataHolder> clusterDataMap; + + // get group level Subscribables + if (groupCtxt.getSubscribableContexts() != null) { + clusterDataMap = parseLeafLevelSubscriptions(appId, tenantId, key, groupCtxt.getName(), + Arrays.asList(groupCtxt.getSubscribableContexts()), subscribableInfoCtxts); + group.setClusterData(clusterDataMap); + } + + // get nested groups + if (groupCtxt.getGroupContexts() != null) { + Map<String, Group> nestedGroups = new HashMap<String, Group>(); + // check sub groups + for (GroupContext subGroupCtxt : groupCtxt.getGroupContexts()) { + // get the complete Group Definition + subGroupCtxt = definedGroupCtxts.get(subGroupCtxt.getAlias()); + Group nestedGroup = parseGroup(appId, tenantId, key, subGroupCtxt, + subscribableInfoCtxts, + definedGroupCtxts); + nestedGroups.put(nestedGroup.getAlias(), nestedGroup); + } + + group.setGroups(nestedGroups); + } + + return group; + } + + /** + * Find the startup order + * + * @param groupContext GroupContext with Group defintion information + * @return Set of Startup Orders which are defined in the Group + * + * @throws ApplicationDefinitionException + */ + private String [] getStartupOrderForGroup(GroupContext groupContext) throws ApplicationDefinitionException { + + ServiceGroup serviceGroup = null; + try { + serviceGroup = RegistryManager.getInstance().getServiceGroup(groupContext.getName()); + } catch (Exception e) { + String errorMsg = "Error in getting Service Group Definition for [ " + groupContext.getName() + + " ] from Registry"; + log.error(errorMsg, e); + throw new ApplicationDefinitionException(errorMsg, e); + } + + if (serviceGroup == null) { + handleError("Service Group Definition not found for name " + groupContext.getName()); + } + + if (log.isDebugEnabled()) { + log.debug("parsing application ... getStartupOrderForGroup: " + groupContext.getName()); + } + + assert serviceGroup != null; + if (serviceGroup.getDependencies() != null) { + if (log.isDebugEnabled()) { + log.debug("parsing application ... getStartupOrderForGroup: dependencies != null " ); + } + if (serviceGroup.getDependencies().getStartupOrders() != null) { + + String [] startupOrders = serviceGroup.getDependencies().getStartupOrders(); + if (log.isDebugEnabled()) { + log.debug("parsing application ... getStartupOrderForGroup: startupOrders != null # of: " + startupOrders.length); + } + return startupOrders; + } + } + + return null; + } + + /** + * Get kill behaviour related to a Group + * + * @param serviceGroupName Group name + * @return String indicating the kill behavior + * + * @throws ApplicationDefinitionException if an error occurs + */ + private String getKillbehaviour (String serviceGroupName) throws ApplicationDefinitionException { + + ServiceGroup serviceGroup = null; + try { + serviceGroup = RegistryManager.getInstance().getServiceGroup(serviceGroupName); + } catch (Exception e) { + String errorMsg = "Error in getting Service Group Definition for [ " + serviceGroupName + + " ] from Registry"; + log.error(errorMsg, e); + throw new ApplicationDefinitionException(errorMsg, e); + } + + if (serviceGroup == null) { + handleError("Service Group Definition not found for name " + serviceGroupName); + } + + assert serviceGroup != null; + if (serviceGroup.getDependencies() != null) { + return serviceGroup.getDependencies().getKillBehaviour(); + } + + return null; + + } + + /** + * Parse Subscription Information + * + * @param appId Application id + * @param tenantId Tenant id of tenant which deployed the Application + * @param key Generated key for the Application + * @param groupName Group name (if relevant) + * @param subscribableCtxts Subscribable Information + * @param subscribableInfoCtxts Map [cartridge alias -> Group] with extracted Subscription Information + * @return Map [subscription alias -> ClusterDataHolder] + * + * @throws ApplicationDefinitionException + */ + private Map<String, ClusterDataHolder> parseLeafLevelSubscriptions (String appId, int tenantId, String key, String groupName, + List<SubscribableContext> subscribableCtxts, + Map<String, SubscribableInfoContext> subscribableInfoCtxts) + throws ApplicationDefinitionException { + + Map<String, ClusterDataHolder> clusterDataMap = new HashMap<String, ClusterDataHolder>(); + + for (SubscribableContext subscribableCtxt : subscribableCtxts) { + + // check is there is a related Subscribable Information + SubscribableInfoContext subscribableInfoCtxt = subscribableInfoCtxts.get(subscribableCtxt.getAlias()); + if (subscribableInfoCtxt == null) { + handleError("Related Subscribable Information Ctxt not found for Subscribable with alias: " + + subscribableCtxt.getAlias()); + } + + // check if Cartridge Type is valid + if (StringUtils.isEmpty(subscribableCtxt.getType())) { + handleError("Invalid Cartridge Type specified : [ " + + subscribableCtxt.getType() + " ]"); + } + + // check if a cartridgeInfo with relevant type is already deployed. else, can't continue + CartridgeInfo cartridgeInfo = getCartridge(subscribableCtxt.getType()); + if (cartridgeInfo == null) { + handleError("No deployed Cartridge found with type [ " + subscribableCtxt.getType() + + " ] for Composite Application"); + } + + // get hostname and cluster id + ClusterInformation clusterInfo; + assert cartridgeInfo != null; + if (cartridgeInfo.getMultiTenant()) { + clusterInfo = new MTClusterInformation(); + } else { + clusterInfo = new STClusterInformation(); + } + + String hostname = clusterInfo.getHostName(subscribableCtxt.getAlias(), cartridgeInfo.getHostName()); + String clusterId = clusterInfo.getClusterId(subscribableCtxt.getAlias(), subscribableCtxt.getType()); + + // create and collect this cluster's information + assert subscribableInfoCtxt != null; + ApplicationClusterContext appClusterCtxt = createApplicationClusterContext(appId, groupName, cartridgeInfo, + key, tenantId, subscribableInfoCtxt.getRepoUrl(), subscribableCtxt.getAlias(), + clusterId, hostname, subscribableInfoCtxt.getDeploymentPolicy(), false, subscribableInfoCtxt.getDependencyAliases()); + + appClusterCtxt.setAutoscalePolicyName(subscribableInfoCtxt.getAutoscalingPolicy()); + this.applicationClusterContexts.add(appClusterCtxt); + + // add relevant information to the map + clusterDataMap.put(subscribableCtxt.getAlias(), new ClusterDataHolder(subscribableCtxt.getType(), clusterId)); + } + + return clusterDataMap; + } + + /** + * Creates a ApplicationClusterContext object to keep information related to a Cluster in this Application + * + * @param appId Application id + * @param groupName Group name + * @param cartridgeInfo Cartridge information + * @param subscriptionKey Generated key for the Application + * @param tenantId Tenant Id of the tenant which deployed the Application + * @param repoUrl Repository URL + * @param alias alias specified for this Subscribable in the Application Definition + * @param clusterId Cluster id + * @param hostname Hostname + * @param deploymentPolicy Deployment policy used + * @param isLB if this cluster is an LB + * @return ApplicationClusterContext object with relevant information + * + * @throws ApplicationDefinitionException If any error occurs + */ + private ApplicationClusterContext createApplicationClusterContext (String appId, String groupName, CartridgeInfo cartridgeInfo, + String subscriptionKey, int tenantId, String repoUrl, + String alias, String clusterId, String hostname, + String deploymentPolicy, boolean isLB, String[] dependencyAliases) + throws ApplicationDefinitionException { + + // Create text payload + String textPayload = ApplicationUtils.createPayload(appId, groupName, cartridgeInfo, subscriptionKey, tenantId, clusterId, + hostname, repoUrl, alias, null, dependencyAliases).toString(); + + return new ApplicationClusterContext(cartridgeInfo.getType(), clusterId, hostname, textPayload, deploymentPolicy, isLB); + } + + private CartridgeInfo getCartridge (String cartridgeType) throws ApplicationDefinitionException { + + try { + return CloudControllerClient.getInstance().getCartrdgeInformation(cartridgeType); + } catch (CartridgeInformationException e) { + throw new ApplicationDefinitionException(e); + } + } + + private void handleError (String errorMsg) throws ApplicationDefinitionException { + log.error(errorMsg); + throw new ApplicationDefinitionException(errorMsg); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ParserUtils.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ParserUtils.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ParserUtils.java new file mode 100644 index 0000000..162ead7 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/parser/ParserUtils.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.parser; + +import org.apache.stratos.autoscaler.applications.pojo.GroupContext; +import org.apache.stratos.autoscaler.applications.pojo.SubscribableContext; +import org.apache.stratos.autoscaler.exception.ApplicationDefinitionException; +import org.apache.stratos.messaging.domain.applications.StartupOrder; + +import java.util.*; + +public class ParserUtils { + + public static Set<StartupOrder> convert (String [] startupOrderArr) throws ApplicationDefinitionException { + + Set<StartupOrder> startupOrders = new HashSet<StartupOrder>(); + + if (startupOrderArr == null) { + return startupOrders; + } + + for (String commaSeparatedStartupOrder : startupOrderArr) { + startupOrders.add(getStartupOrder(commaSeparatedStartupOrder)); + } + + return startupOrders; + } + + private static StartupOrder getStartupOrder (String commaSeparatedStartupOrder) throws ApplicationDefinitionException{ + + List<String> startupOrders = new ArrayList<String>(); + + for (String startupOrder : Arrays.asList(commaSeparatedStartupOrder.split(","))) { + startupOrder = startupOrder.trim(); + if (!startupOrder.startsWith("cartridge.") && !startupOrder.startsWith("group.")) { + throw new ApplicationDefinitionException("Incorrect Startup Order specified, should start with 'cartridge.' or 'group.'"); + } + + startupOrders.add(startupOrder); + } + + return new StartupOrder(startupOrders); + } + + public static Set<StartupOrder> convert (String [] startupOrderArr, GroupContext groupContext) + throws ApplicationDefinitionException { + + Set<StartupOrder> startupOrders = new HashSet<StartupOrder>(); + + if (startupOrderArr == null) { + return startupOrders; + } + + + for (String commaSeparatedStartupOrder : startupOrderArr) { + // convert all Startup Orders to aliases-based + List<String> components = Arrays.asList(commaSeparatedStartupOrder.split(",")); + startupOrders.add(getStartupOrder(components, groupContext)); + } + + return startupOrders; + } + + private static StartupOrder getStartupOrder (List<String> components, GroupContext groupContext) + throws ApplicationDefinitionException { + + List<String> aliasBasedComponents = new ArrayList<String>(); + + for (String component : components) { + component = component.trim(); + + String aliasBasedComponent; + if (component.startsWith("cartridge.")) { + String cartridgeType = component.substring(10); + aliasBasedComponent = getAliasForServiceType(cartridgeType, groupContext); + if (aliasBasedComponent == null) { + throw new ApplicationDefinitionException("Unable convert Startup Order to alias-based; " + + "cannot find the matching alias for Service type " + cartridgeType); + } + + aliasBasedComponent = "cartridge.".concat(aliasBasedComponent); + + } else if (component.startsWith("group.")) { + String groupName = component.substring(6); + aliasBasedComponent = getAliasForGroupName(groupName, groupContext); + if (aliasBasedComponent == null) { + throw new ApplicationDefinitionException("Unable convert Startup Order to alias-based; " + + "cannot find the matching alias for Group name " + groupName); + } + + aliasBasedComponent = "group.".concat(aliasBasedComponent); + + } else { + throw new ApplicationDefinitionException("Incorrect Startup Order specified, " + + "should start with 'cartridge.' or 'group.'"); + } + aliasBasedComponents.add(aliasBasedComponent); + } + + return new StartupOrder(aliasBasedComponents); + } + + private static String getAliasForGroupName (String groupName, GroupContext groupContext) { + + for (GroupContext groupCtxt : groupContext.getGroupContexts()) { + if (groupName.equals(groupCtxt.getName())) { + return groupCtxt.getAlias(); + } + } + + return null; + } + + + private static String getAliasForServiceType (String serviceType, GroupContext groupContext) { + + for (SubscribableContext subCtxt : groupContext.getSubscribableContexts()) { + if (serviceType.equals(subCtxt.getType())) { + return subCtxt.getAlias(); + } + } + + return null; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/ApplicationCartridgePayloadData.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/ApplicationCartridgePayloadData.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/ApplicationCartridgePayloadData.java new file mode 100644 index 0000000..d80894a --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/ApplicationCartridgePayloadData.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.payload; + +public class ApplicationCartridgePayloadData extends PayloadData { + + public ApplicationCartridgePayloadData(BasicPayloadData basicPayloadData) { + super(basicPayloadData); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/BasicPayloadData.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/BasicPayloadData.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/BasicPayloadData.java new file mode 100644 index 0000000..b0e4588 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/BasicPayloadData.java @@ -0,0 +1,311 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.payload; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Serializable; + +/** + * Contains basic payload data fields + */ +public class BasicPayloadData implements Serializable { + + private static Log log = LogFactory.getLog(BasicPayloadData.class); + + private String appId; + private String groupName; + private String serviceName; + private String clusterId; + private String hostName; + private int tenantId; + private String tenantRange; + private String subscriptionAlias; + private String deployment; + private String puppetIp; + private String puppetHostName; + private String puppetEnvironment; + private String subscriptionKey; + private String applicationPath; + private String gitRepositoryUrl; + private String portMappings; + private String multitenant; + private String provider; + private String[] dependencyAliases; + private String[] exportingProperties; + + protected StringBuilder payloadBuilder; + + public BasicPayloadData() { + + } + + public void populatePayload () { + + payloadBuilder = new StringBuilder(); + + payloadBuilder.append("APP_ID=" + getAppId()); + payloadBuilder.append(","); + payloadBuilder.append("GROUP_NAME=" + getGroupName()); + payloadBuilder.append(","); + payloadBuilder.append("SERVICE_NAME=" + getServiceName()); + payloadBuilder.append(","); + payloadBuilder.append("HOST_NAME=" + getHostName()); + payloadBuilder.append(","); + payloadBuilder.append("MULTITENANT=" + getMultitenant()); + payloadBuilder.append(","); + payloadBuilder.append("TENANT_ID=" + getTenantId()); + payloadBuilder.append(","); + payloadBuilder.append("TENANT_RANGE=" + getTenantRange()); + payloadBuilder.append(","); + payloadBuilder.append("CARTRIDGE_ALIAS=" + getSubscriptionAlias()); + payloadBuilder.append(","); + payloadBuilder.append("CLUSTER_ID=" + getClusterId()); + payloadBuilder.append(","); + payloadBuilder.append("CARTRIDGE_KEY=" + getSubscriptionKey()); + payloadBuilder.append(","); + //payloadBuilder.append("DEPLOYMENT=" + getDeployment()); + //payloadBuilder.append(","); + //payloadBuilder.append("APP_PATH=" + getApplicationPath()); + //payloadBuilder.append(","); + payloadBuilder.append("REPO_URL=" + getGitRepositoryUrl()); + payloadBuilder.append(","); + payloadBuilder.append("PORTS=" + getPortMappings()); + payloadBuilder.append(","); + payloadBuilder.append("PROVIDER=" + getProvider()); + + //Payload Data exposed as system variables + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_IP=" + System.getProperty("puppet.ip")); + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_HOSTNAME=" + System.getProperty("puppet.hostname")); + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_DNS_AVAILABLE=" + System.getProperty("puppet.env")); + payloadBuilder.append(","); + payloadBuilder.append("PUPPET_ENV=" + System.getProperty("puppet.dns.available")); + payloadBuilder.append(","); + if(getDependencyAliasesPayloadString() != null){ + payloadBuilder.append("DEPENDECNY_ALIASES=" + getDependencyAliasesPayloadString()); + } + payloadBuilder.append(","); + if(getExportingPropertiesPayloadString() != null){ + payloadBuilder.append("EXPORTING_PROPERTIES=" + getExportingPropertiesPayloadString()); + } + + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getClusterId() { + return clusterId; + } + + public void setClusterId(String clusterId) { + this.clusterId = clusterId; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getTenantRange() { + return tenantRange; + } + + public void setTenantRange(String tenantRange) { + this.tenantRange = tenantRange; + } + + public String getSubscriptionAlias() { + return subscriptionAlias; + } + + public void setSubscriptionAlias(String subscriptionAlias) { + this.subscriptionAlias = subscriptionAlias; + } + + public String getDeployment() { + return deployment; + } + + public void setDeployment(String deployment) { + this.deployment = deployment; + } + + public String getPuppetIp() { + return puppetIp; + } + + public void setPuppetIp(String puppetIp) { + this.puppetIp = puppetIp; + } + + public String getSubscriptionKey() { + return subscriptionKey; + } + + public void setSubscriptionKey(String subscriptionKey) { + this.subscriptionKey = subscriptionKey; + } + + public StringBuilder getPayloadData () { + + return payloadBuilder; + } + + public String getApplicationPath() { + return applicationPath; + } + + public void setApplicationPath(String applicationPath) { + this.applicationPath = applicationPath; + } + + public String getGitRepositoryUrl() { + return gitRepositoryUrl; + } + + public void setGitRepositoryUrl(String gitRepositoryUrl) { + this.gitRepositoryUrl = gitRepositoryUrl; + } + + public String getPortMappings() { + return portMappings; + } + + public void setPortMappings(String portMappings) { + this.portMappings = portMappings; + } + + public String getMultitenant() { + return multitenant; + } + + public void setMultitenant(String multitenant) { + this.multitenant = multitenant; + } + + public String getPuppetHostName() { + return puppetHostName; + } + + public void setPuppetHostName(String puppetHostName) { + this.puppetHostName = puppetHostName; + } + + public String getPuppetEnvironment() { + return puppetEnvironment; + } + + public void setPuppetEnvironment(String puppetEnvironment) { + this.puppetEnvironment = puppetEnvironment; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String[] getDependencyAliases() { + return dependencyAliases; + } + + public void setDependencyAliases(String[] dependencyAliases) { + this.dependencyAliases = dependencyAliases; + } + + private String getDependencyAliasesPayloadString(){ + if(dependencyAliases == null){ + return null; + } + + StringBuilder dependencyAliasesPayload = new StringBuilder(); + for(int i=0; i< dependencyAliases.length; i++){ + dependencyAliasesPayload.append(dependencyAliases[i]); + if(i != dependencyAliases.length -1){ + dependencyAliasesPayload.append("|"); + } + } + log.info("testing1 getDependencyAliasesPayloadString " + dependencyAliasesPayload); + return dependencyAliasesPayload.toString(); + } + + private String getExportingPropertiesPayloadString(){ + if(exportingProperties == null){ + return null; + } + + StringBuilder exportingPropertiesPayload = new StringBuilder(); + for(int i=0; i< exportingProperties.length; i++){ + exportingPropertiesPayload.append(exportingProperties[i]); + if(i != exportingProperties.length -1){ + exportingPropertiesPayload.append("|"); + } + } + log.info("testing1 getExportingPropertiesPayloadString " + exportingPropertiesPayload); + return exportingPropertiesPayload.toString(); + } + + public String[] getExportingProperties() { + return exportingProperties; + } + + public void setExportingProperties(String[] exportingProperties) { + this.exportingProperties = exportingProperties; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/DataCartridgePayloadData.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/DataCartridgePayloadData.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/DataCartridgePayloadData.java new file mode 100644 index 0000000..84ef25a --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/DataCartridgePayloadData.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.payload; + +public class DataCartridgePayloadData extends PayloadData { + + public DataCartridgePayloadData(BasicPayloadData basicPayloadData) { + super(basicPayloadData); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/FrameworkCartridgePayloadData.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/FrameworkCartridgePayloadData.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/FrameworkCartridgePayloadData.java new file mode 100644 index 0000000..03b2ed1 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/FrameworkCartridgePayloadData.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.payload; + +public class FrameworkCartridgePayloadData extends PayloadData { + + public FrameworkCartridgePayloadData(BasicPayloadData basicPayloadData) { + super(basicPayloadData); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b9aabfdc/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/LoadBalancerCartridgePayloadData.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/LoadBalancerCartridgePayloadData.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/LoadBalancerCartridgePayloadData.java new file mode 100644 index 0000000..d4949cc --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/payload/LoadBalancerCartridgePayloadData.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.applications.payload; + +public class LoadBalancerCartridgePayloadData extends PayloadData { + + public LoadBalancerCartridgePayloadData(BasicPayloadData basicPayloadData) { + super(basicPayloadData); + } +}
