You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by im...@apache.org on 2014/12/07 08:58:25 UTC
[2/4] stratos git commit: Introducing a mock iaas for cloud controller
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsIaasUtil.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsIaasUtil.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsIaasUtil.java
new file mode 100644
index 0000000..b361f5c
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsIaasUtil.java
@@ -0,0 +1,90 @@
+/*
+ * 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.iaases;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderException;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.jclouds.compute.ComputeService;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * jclouds IaaS utility methods.
+ */
+public class JcloudsIaasUtil {
+ private static final Log log = LogFactory.getLog(JcloudsIaasUtil.class);
+
+ public static void buildComputeServiceAndTemplate(IaasProvider iaasProvider) throws InvalidIaasProviderException {
+ if(iaasProvider.getImage() != null) {
+ buildComputeServiceAndTemplateFromImage(iaasProvider);
+ } else {
+ buildDefaultComputeService(iaasProvider);
+ }
+ }
+
+ private static void buildComputeServiceAndTemplateFromImage(IaasProvider iaasProvider) throws InvalidIaasProviderException {
+ try {
+ JcloudsIaas iaas = (JcloudsIaas) iaasProvider.getIaas();
+ iaas.buildComputeServiceAndTemplate();
+ } catch (Exception e) {
+ String msg = "Could not build iaas of type: " + iaasProvider.getType();
+ log.error(msg, e);
+ throw new InvalidIaasProviderException(msg, e);
+ }
+ }
+
+ private static void buildDefaultComputeService(IaasProvider iaasProvider) throws InvalidIaasProviderException {
+ try {
+ ComputeService computeService = ComputeServiceBuilderUtil.buildDefaultComputeService(iaasProvider);
+ iaasProvider.setComputeService(computeService);
+ } catch (Exception e) {
+ String msg = "Unable to build the jclouds object for iaas "
+ + "of type: " + iaasProvider.getType();
+ log.error(msg, e);
+ throw new InvalidIaasProviderException(msg, e);
+ }
+ }
+
+ public static Iaas createIaasInstance(IaasProvider iaasProvider)
+ throws InvalidIaasProviderException {
+ try {
+
+ if(iaasProvider.getClassName() == null) {
+ String msg = "You have not specified a class which represents the iaas of type: ["
+ + iaasProvider.getType() + "].";
+ log.error(msg);
+ throw new InvalidIaasProviderException(msg);
+ }
+
+ Constructor<?> c = Class.forName(iaasProvider.getClassName()).getConstructor(IaasProvider.class);
+ Iaas iaas = (Iaas) c.newInstance(iaasProvider);
+ return iaas;
+ } catch (Exception e) {
+ String msg = "Class [" + iaasProvider.getClassName()
+ + "] which represents the iaas of type: ["
+ + iaasProvider.getType() + "] has failed to instantiate.";
+ log.error(msg, e);
+ throw new InvalidIaasProviderException(msg, e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsOpenstackIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsOpenstackIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsOpenstackIaas.java
new file mode 100644
index 0000000..e16a074
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsOpenstackIaas.java
@@ -0,0 +1,559 @@
+/*
+ * 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.iaases;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.domain.NetworkInterface;
+import org.apache.stratos.cloud.controller.exception.CloudControllerException;
+import org.apache.stratos.cloud.controller.exception.InvalidHostException;
+import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
+import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
+import org.apache.stratos.cloud.controller.iaases.openstack.networking.NeutronNetworkingApi;
+import org.apache.stratos.cloud.controller.iaases.openstack.networking.NovaNetworkingApi;
+import org.apache.stratos.cloud.controller.iaases.openstack.networking.OpenstackNetworkingApi;
+import org.apache.stratos.cloud.controller.iaases.validators.OpenstackNovaPartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
+import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
+import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
+import org.jclouds.openstack.nova.v2_0.domain.Network;
+import org.jclouds.openstack.nova.v2_0.domain.Volume;
+import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.AvailabilityZone;
+import org.jclouds.openstack.nova.v2_0.extensions.AvailabilityZoneApi;
+import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi;
+import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
+import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi;
+import org.jclouds.openstack.nova.v2_0.extensions.VolumeAttachmentApi;
+import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
+
+import com.google.common.base.Optional;
+
+public class JcloudsOpenstackIaas extends JcloudsIaas {
+
+ private static final Log log = LogFactory.getLog(JcloudsOpenstackIaas.class);
+ private static final String SUCCESSFUL_LOG_LINE = "A key-pair is created successfully in ";
+ private static final String FAILED_LOG_LINE = "Key-pair is unable to create in ";
+
+ private OpenstackNetworkingApi openstackNetworkingApi;
+
+ public JcloudsOpenstackIaas(IaasProvider iaasProvider) {
+ super(iaasProvider);
+ setOpenstackNetworkingApi(iaasProvider);
+ }
+
+ private void setOpenstackNetworkingApi(IaasProvider iaasProvider) {
+ String openstackNetworkingProvider = iaasProvider.getProperty(CloudControllerConstants.OPENSTACK_NETWORKING_PROVIDER);
+ if (openstackNetworkingProvider != null &&
+ openstackNetworkingProvider.equals(CloudControllerConstants.OPENSTACK_NEUTRON_NETWORKING)) {
+ if (log.isDebugEnabled()) {
+ String msg = String.format("Openstack networking provider is %s. Trying to instanstiate %s",
+ openstackNetworkingProvider, NeutronNetworkingApi.class.getName());
+ log.debug(msg);
+ }
+ openstackNetworkingApi = new NeutronNetworkingApi(iaasProvider);
+ } else {
+ if (log.isDebugEnabled()) {
+ String msg = String.format("Openstack networking provider is %s. Hence trying to instanstiate %s",
+ openstackNetworkingProvider, NovaNetworkingApi.class.getName());
+ log.debug(msg);
+ }
+ openstackNetworkingApi = new NovaNetworkingApi(iaasProvider);
+ }
+ }
+
+ @Override
+ public void buildComputeServiceAndTemplate() {
+ // builds and sets Compute Service
+ ComputeService computeService = ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
+ getIaasProvider().setComputeService(computeService);
+
+ // builds and sets Template
+ buildTemplate();
+ }
+
+ public void buildTemplate() {
+ IaasProvider iaasProvider = getIaasProvider();
+
+ if (iaasProvider.getComputeService() == null) {
+ throw new CloudControllerException(
+ "Compute service is null for IaaS provider: "
+ + iaasProvider.getName());
+ }
+
+ TemplateBuilder templateBuilder = iaasProvider.getComputeService()
+ .templateBuilder();
+ templateBuilder.imageId(iaasProvider.getImage());
+ if(!(iaasProvider instanceof IaasProvider)) {
+ templateBuilder.locationId(iaasProvider.getType());
+ }
+
+ // to avoid creation of template objects in each and every time, we
+ // create all at once!
+
+ String instanceType;
+
+ // set instance type
+ if (((instanceType = iaasProvider.getProperty(CloudControllerConstants.INSTANCE_TYPE)) != null)) {
+
+ templateBuilder.hardwareId(instanceType);
+ }
+
+ Template template = templateBuilder.build();
+
+ // In Openstack the call to IaaS should be blocking, in order to retrieve
+ // IP addresses.
+ boolean blockUntilRunning = true;
+ if(iaasProvider.getProperty(CloudControllerConstants.BLOCK_UNTIL_RUNNING) != null) {
+ blockUntilRunning = Boolean.parseBoolean(iaasProvider.getProperty(
+ CloudControllerConstants.BLOCK_UNTIL_RUNNING));
+ }
+ template.getOptions().as(TemplateOptions.class)
+ .blockUntilRunning(blockUntilRunning);
+
+ // this is required in order to avoid creation of additional security
+ // groups by Jclouds.
+ template.getOptions().as(TemplateOptions.class)
+ .inboundPorts(new int[] {});
+
+ if (iaasProvider.getProperty(CloudControllerConstants.SECURITY_GROUPS) != null) {
+ template.getOptions()
+ .as(NovaTemplateOptions.class)
+ .securityGroupNames(
+ iaasProvider.getProperty(CloudControllerConstants.SECURITY_GROUPS).split(
+ CloudControllerConstants.ENTRY_SEPARATOR));
+ }
+
+ if (iaasProvider.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
+ template.getOptions().as(NovaTemplateOptions.class)
+ .keyPairName(iaasProvider.getProperty(CloudControllerConstants.KEY_PAIR));
+ }
+
+ if (iaasProvider.getNetworkInterfaces() != null) {
+ Set<Network> novaNetworksSet = new LinkedHashSet<Network>(iaasProvider.getNetworkInterfaces().length);
+ for (NetworkInterface ni:iaasProvider.getNetworkInterfaces()) {
+ novaNetworksSet.add(Network.builder().networkUuid(ni.getNetworkUuid()).fixedIp(ni.getFixedIp())
+ .portUuid(ni.getPortUuid()).build());
+ }
+ template.getOptions().as(NovaTemplateOptions.class).novaNetworks(novaNetworksSet);
+ }
+
+ if (iaasProvider.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+ template.getOptions().as(NovaTemplateOptions.class)
+ .availabilityZone(iaasProvider.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
+ }
+
+ //TODO
+// if (iaas.getProperty(CloudControllerConstants.HOST) != null) {
+// template.getOptions().as(NovaTemplateOptions.class)
+// .(CloudControllerConstants.HOST);
+// }
+
+ // set Template
+ iaasProvider.setTemplate(template);
+ }
+
+ @Override
+ public void setDynamicPayload(byte[] payload) {
+ if (getIaasProvider().getTemplate() != null) {
+ getIaasProvider().getTemplate().getOptions().as(NovaTemplateOptions.class).userData(payload);
+ }
+ }
+
+ @Override
+ public synchronized boolean createKeyPairFromPublicKey(String region, String keyPairName,
+ String publicKey) {
+
+ IaasProvider iaasInfo = getIaasProvider();
+
+ String openstackNovaMsg = " Openstack-nova. Region: " + region
+ + " - Name: ";
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ KeyPairApi api = novaApi.getKeyPairExtensionForZone(region).get();
+
+ KeyPair keyPair = api.createWithPublicKey(keyPairName, publicKey);
+
+ if (keyPair != null) {
+
+ iaasInfo.getTemplate().getOptions().as(NovaTemplateOptions.class)
+ .keyPairName(keyPair.getName());
+
+ log.info(SUCCESSFUL_LOG_LINE + openstackNovaMsg + keyPair.getName());
+ return true;
+ }
+
+ log.error(FAILED_LOG_LINE + openstackNovaMsg);
+ return false;
+
+ }
+
+ @Override
+ public synchronized String associateAddress(NodeMetadata node) {
+ //TODO return the list of IP addresses once the topology changes is done
+ return openstackNetworkingApi.associateAddresses(node).iterator().next();
+ }
+
+ @Override
+ public synchronized String associatePredefinedAddress (NodeMetadata node, String ip) {
+ return openstackNetworkingApi.associatePredefinedAddress(node, ip);
+ }
+
+ @Override
+ public synchronized void releaseAddress(String ip) {
+ openstackNetworkingApi.releaseAddress(ip);
+ }
+
+ @Override
+ public boolean isValidRegion(String region) throws InvalidRegionException {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ // jclouds' zone = region in openstack
+ if (region == null || iaasInfo == null) {
+ String msg =
+ "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " +
+ iaasInfo;
+ log.error(msg);
+ throw new InvalidRegionException(msg);
+ }
+
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ Set<String> zones = novaApi.getConfiguredZones();
+ for (String configuredZone : zones) {
+ if (region.equalsIgnoreCase(configuredZone)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Found a matching region: " + region);
+ }
+ return true;
+ }
+ }
+
+ String msg = "Invalid region: " + region +" in the iaas: "+iaasInfo.getType();
+ log.error(msg);
+ throw new InvalidRegionException(msg);
+ }
+
+ @Override
+ public boolean isValidZone(String region, String zone) throws InvalidZoneException {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ // jclouds availability zone = stratos zone
+ if (region == null || zone == null || iaasInfo == null) {
+ String msg = "Host or Zone or IaaSProvider is null: region: " + region + " - zone: " +
+ zone + " - IaaSProvider: " + iaasInfo;
+ log.error(msg);
+ throw new InvalidZoneException(msg);
+ }
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ Optional<? extends AvailabilityZoneApi> availabilityZoneApi = novaApi.getAvailabilityZoneApi(region);
+ for (AvailabilityZone z : availabilityZoneApi.get().list()) {
+
+ if (zone.equalsIgnoreCase(z.getName())) {
+ if (log.isDebugEnabled()) {
+ log.debug("Found a matching availability zone: " + zone);
+ }
+ return true;
+ }
+ }
+
+ String msg = "Invalid zone: " + zone +" in the region: "+region+ " and of the iaas: "+iaasInfo.getType();
+ log.error(msg);
+ throw new InvalidZoneException(msg);
+
+ }
+
+ @Override
+ public boolean isValidHost(String zone, String host) throws InvalidHostException {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ if (host == null || zone == null || iaasInfo == null) {
+ String msg = String.format("Host or Zone or IaaSProvider is null: host: %s - zone: %s - IaaSProvider: %s", host, zone, iaasInfo);
+ log.error(msg);
+ throw new InvalidHostException(msg);
+ }
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ HostAggregateApi hostApi = novaApi.getHostAggregateExtensionForZone(zone).get();
+ for (HostAggregate hostAggregate : hostApi.list()) {
+ for (String configuredHost : hostAggregate.getHosts()) {
+ if (host.equalsIgnoreCase(configuredHost)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Found a matching host: " + host);
+ }
+ return true;
+ }
+ }
+ }
+
+ String msg = String.format("Invalid host: %s in the zone: %s and of the iaas: %s", host, zone, iaasInfo.getType());
+ log.error(msg);
+ throw new InvalidHostException(msg);
+ }
+
+ @Override
+ public PartitionValidator getPartitionValidator() {
+ return new OpenstackNovaPartitionValidator();
+ }
+
+ @Override
+ public String createVolume(int sizeGB, String snapshotId) {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ if (iaasInfo == null) {
+ log.fatal(String.format("Cannot create a new volume with snapshot ID : %s", snapshotId));
+ return null;
+ }
+
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+ String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+
+ if (region == null) {
+ log.fatal(String.format("Cannot create a new volume. Extracted region is null for Iaas : %s", iaasInfo));
+ return null;
+ }
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ VolumeApi volumeApi = novaApi.getVolumeExtensionForZone(region).get();
+ Volume volume;
+ if(StringUtils.isEmpty(snapshotId)){
+ if(log.isDebugEnabled()){
+ log.info("Creating a volume in the zone " + zone);
+ }
+ volume = volumeApi.create(sizeGB, CreateVolumeOptions.Builder.availabilityZone(zone));
+ }else{
+ if(log.isDebugEnabled()){
+ log.info("Creating a volume in the zone " + zone + " from the shanpshot " + snapshotId);
+ }
+ volume = volumeApi.create(sizeGB, CreateVolumeOptions.Builder.availabilityZone(zone).snapshotId(snapshotId));
+ }
+
+ if (volume == null) {
+ log.fatal(String.format("Volume creation was unsuccessful. [region] : %s [zone] : %s of Iaas : %s", region, zone, iaasInfo));
+ return null;
+ }
+
+ String volumeId = volume.getId();
+ /*
+ Volume.Status volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
+
+ if(!(volumeStatus == Volume.Status.AVAILABLE || volumeStatus == Volume.Status.CREATING)){
+ log.error(String.format("Error while creating [volume id] %s. Volume status is %s", volumeId, volumeStatus));
+ return volumeId;
+ }
+ try {
+ if(!waitForStatus(volumeApi, volumeId, Volume.Status.AVAILABLE)){
+ log.error("Volume did not become AVAILABLE. Current status is " + volume.getStatus());
+ }
+ } catch (TimeoutException e) {
+ log.error("[Volume ID] " + volumeId + "did not become AVAILABLE within expected timeout");
+ return volumeId;
+ }
+ */
+ log.info(String.format("Successfully created a new volume [id]: %s in [region] : %s [zone] : %s of Iaas : %s [Volume ID]%s", volume.getId(), region, zone, iaasInfo, volume.getId()));
+ return volumeId;
+ }
+
+ private boolean waitForStatus(String volumeId, Volume.Status expectedStatus, int timeoutInMins) throws TimeoutException {
+ int timeout = 1000 * 60 * timeoutInMins;
+ long timout = System.currentTimeMillis() + timeout;
+
+ IaasProvider iaasInfo = getIaasProvider();
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();;
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ VolumeApi volumeApi = novaApi.getVolumeExtensionForZone(region).get();
+ Volume.Status volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
+
+ while(volumeStatus != expectedStatus){
+ try {
+ if(log.isDebugEnabled()){
+ log.debug(String.format("Volume %s is still NOT in %s. Current State=%s", volumeId, expectedStatus, volumeStatus));
+ }
+ if(volumeStatus == Volume.Status.ERROR){
+ log.error("Volume " + volumeId + " is in state ERROR");
+ return false;
+ }
+ Thread.sleep(1000);
+ volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
+ if (System.currentTimeMillis()> timout) {
+ throw new TimeoutException();
+ }
+ } catch (InterruptedException e) {
+ // Ignoring the exception
+ }
+ }
+ if(log.isDebugEnabled()){
+ log.debug(String.format("Volume %s status became %s", volumeId, expectedStatus));
+ }
+
+ return true;
+ }
+
+ @Override
+ public String attachVolume(String instanceId, String volumeId, String deviceName) {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ if (StringUtils.isEmpty(volumeId)) {
+ log.error("Volume provided to attach can not be null");
+ }
+
+ if (StringUtils.isEmpty(instanceId)) {
+ log.error("Instance provided to attach can not be null");
+ }
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+ String device = deviceName == null ? "/dev/vdc" : deviceName;
+
+ if (region == null) {
+ log.fatal(String.format("Cannot attach the volume [id]: %s. Extracted region is null for Iaas : %s", volumeId, iaasInfo));
+ return null;
+ }
+
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ VolumeApi volumeApi = novaApi.getVolumeExtensionForZone(region).get();
+ VolumeAttachmentApi volumeAttachmentApi = novaApi.getVolumeAttachmentExtensionForZone(region).get();
+
+ Volume.Status volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Volume " + volumeId + " is in state " + volumeStatus);
+ }
+
+ if (!(volumeStatus == Volume.Status.AVAILABLE || volumeStatus == Volume.Status.CREATING)) {
+ log.error(String.format("Volume %s can not be attached. Volume status is %s", volumeId, volumeStatus));
+ return null;
+ }
+
+ boolean volumeBecameAvailable = false, volumeBecameAttached = false;
+ try {
+ volumeBecameAvailable = waitForStatus(volumeId, Volume.Status.AVAILABLE, 5);
+ } catch (TimeoutException e) {
+ log.error("[Volume ID] " + volumeId + "did not become AVAILABLE within expected timeout");
+ }
+
+ VolumeAttachment attachment = null;
+ if (volumeBecameAvailable) {
+ attachment = volumeAttachmentApi.attachVolumeToServerAsDevice(volumeId, instanceId, device);
+
+ try {
+ volumeBecameAttached = waitForStatus(volumeId, Volume.Status.IN_USE, 2);
+ } catch (TimeoutException e) {
+ log.error("[Volume ID] " + volumeId + "did not become IN_USE within expected timeout");
+ }
+ }
+ try {
+ // waiting 5seconds till volumes are actually attached.
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ if (attachment == null) {
+ log.fatal(String.format("Volume [id]: %s attachment for instance [id]: %s was unsuccessful. [region] : %s of Iaas : %s", volumeId, instanceId, region, iaasInfo));
+ return null;
+ }
+
+ if(! volumeBecameAttached){
+ log.error(String.format("[Volume ID] %s attachment is called, but not yet became attached", volumeId));
+ }
+
+ log.info(String.format("Volume [id]: %s attachment for instance [id]: %s was successful [status]: Attaching. [region] : %s of Iaas : %s", volumeId, instanceId, region, iaasInfo));
+ return "Attaching";
+ }
+
+ @Override
+ public void detachVolume(String instanceId, String volumeId) {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+
+ if(region == null) {
+ log.fatal(String.format("Cannot detach the volume [id]: %s from the instance [id]: %s. Extracted region is null for Iaas : %s", volumeId, instanceId, iaasInfo));
+ return;
+ }
+ if(log.isDebugEnabled()) {
+ log.debug(String.format("Starting to detach volume %s from the instance %s", volumeId, instanceId));
+ }
+
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ VolumeAttachmentApi api = novaApi.getVolumeAttachmentExtensionForZone(region).get();
+ if (api.detachVolumeFromServer(volumeId, instanceId)) {
+ log.info(String.format("Detachment of Volume [id]: %s from instance [id]: %s was successful. [region] : %s of Iaas : %s", volumeId, instanceId, region, iaasInfo));
+ }else{
+ log.error(String.format("Detachment of Volume [id]: %s from instance [id]: %s was unsuccessful. [volume Status] : %s", volumeId, instanceId, region, iaasInfo));
+ }
+
+ }
+
+ @Override
+ public void deleteVolume(String volumeId) {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+
+ if(region == null) {
+ log.fatal(String.format("Cannot delete the volume [id]: %s. Extracted region is null for Iaas : %s", volumeId, iaasInfo));
+ return;
+ }
+
+ NovaApi novaApi = context.unwrapApi(NovaApi.class);
+ VolumeApi api = novaApi.getVolumeExtensionForZone(region).get();
+ if (api.delete(volumeId)) {
+ log.info(String.format("Deletion of Volume [id]: %s was successful. [region] : %s of Iaas : %s", volumeId, region, iaasInfo));
+ }
+ }
+
+ @Override
+ public String getIaasDevice(String device) {
+ return device;
+ }
+
+ private Volume.Status getVolumeStatus(VolumeApi volumeApi, String volumeId){
+ return volumeApi.get(volumeId).getStatus();
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsVCloudIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsVCloudIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsVCloudIaas.java
new file mode 100644
index 0000000..9f87dd4
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsVCloudIaas.java
@@ -0,0 +1,261 @@
+/*
+ * 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.iaases;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.exception.CloudControllerException;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.validators.VCloudPartitionValidator;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
+import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
+import org.wso2.carbon.utils.CarbonUtils;
+
+import java.io.File;
+import java.io.IOException;
+
+public class JcloudsVCloudIaas extends JcloudsIaas {
+
+
+ private static final Log log = LogFactory.getLog(JcloudsVCloudIaas.class);
+
+ private static final String SHELL_TYPE = "shellType";
+ private static final String SCRIPTS_PATH = "scripts";
+ private static final String CUSTOMIZATION_SCRIPT = "customization";
+ private static final String PAYLOAD = "PAYLOAD";
+
+ public JcloudsVCloudIaas(IaasProvider iaasProvider) {
+ super(iaasProvider);
+ }
+
+ @Override
+ public void buildComputeServiceAndTemplate() {
+ // builds and sets Compute Service
+ ComputeService computeService = ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
+ getIaasProvider().setComputeService(computeService);
+
+ // builds and sets Template
+ buildTemplate();
+
+ }
+
+ public void buildTemplate() {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ if (iaasInfo.getComputeService() == null) {
+ String msg = "Compute service is null for IaaS provider: "
+ + iaasInfo.getName();
+ log.fatal(msg);
+ throw new CloudControllerException(msg);
+ }
+
+ TemplateBuilder templateBuilder = iaasInfo.getComputeService()
+ .templateBuilder();
+
+ // set image id specified
+ templateBuilder.imageId(iaasInfo.getImage());
+
+ // build the Template
+ Template template = templateBuilder.build();
+
+ // if you wish to auto assign IPs, instance spawning call should be
+ // blocking, but if you
+ // wish to assign IPs manually, it can be non-blocking.
+ // is auto-assign-ip mode or manual-assign-ip mode? - default mode is
+ // non-blocking
+ boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
+ .getProperty("autoAssignIp"));
+ template.getOptions().as(TemplateOptions.class)
+ .blockUntilRunning(blockUntilRunning);
+
+ // this is required in order to avoid creation of additional security
+ // groups by Jclouds.
+ template.getOptions().as(TemplateOptions.class)
+ .inboundPorts(22, 80, 8080, 443, 8243);
+
+ template.getOptions().as(VCloudTemplateOptions.class)
+ .ipAddressAllocationMode(IpAddressAllocationMode.POOL);
+
+ // set Template
+ iaasInfo.setTemplate(template);
+ }
+
+ @Override
+ public void setDynamicPayload(byte[] payload) {
+ // in vCloud case we need to run a script
+ IaasProvider iaasProvider = getIaasProvider();
+
+ if (iaasProvider.getTemplate() == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Payload for vCloud not found");
+ }
+ return;
+ }
+
+ String shellType = iaasProvider.getProperty(SHELL_TYPE);
+
+ if (shellType == null || shellType.isEmpty()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Shell Type for vCloud Customization script not found from properties");
+ }
+ return;
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Shell Type '%s' will be used for vCloud Customization script", shellType));
+ }
+
+ // Payload is a String value
+ String payloadStr = new String(payload);
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Payload '%s' will be used for vCloud Customization script", payload));
+ }
+
+ Template template = iaasProvider.getTemplate();
+
+ File scriptPath = new File(CarbonUtils.getCarbonConfigDirPath(), SCRIPTS_PATH);
+
+ File customizationScriptFile = new File(new File(scriptPath, shellType), CUSTOMIZATION_SCRIPT);
+
+ if (!customizationScriptFile.exists()) {
+ if (log.isWarnEnabled()) {
+ log.warn(String.format("The vCloud Customization script '%s' does not exist",
+ customizationScriptFile.getAbsolutePath()));
+ }
+ return;
+ }
+
+ String customizationScript = null;
+
+ try {
+ customizationScript = FileUtils.readFileToString(customizationScriptFile);
+ } catch (IOException e) {
+ if (log.isErrorEnabled()) {
+ log.error(
+ String.format("Error reading the vCloud Customization script '%s'",
+ customizationScriptFile.getAbsolutePath()), e);
+ }
+ }
+
+ if (StringUtils.isEmpty(customizationScript)) {
+ if (log.isDebugEnabled()) {
+ log.debug("No content vCloud Customization script not found from properties");
+ }
+ return;
+ }
+
+ // Set payload
+ customizationScript = customizationScript.replaceAll(PAYLOAD, payloadStr);
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("The vCloud Customization script\n%s", customizationScript));
+ }
+
+ // Run the script
+ template.getOptions().runScript(customizationScript);
+ }
+
+ @Override
+ public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
+
+ // TODO
+ return false;
+ }
+
+ @Override
+ public String associateAddress(NodeMetadata node) {
+
+ // TODO
+ return "";
+
+ }
+
+ @Override
+ public String associatePredefinedAddress(NodeMetadata node, String ip) {
+ return "";
+ }
+
+ @Override
+ public void releaseAddress(String ip) {
+ // TODO
+ }
+
+ @Override
+ public boolean isValidRegion(String region) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isValidZone(String region, String zone) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ public boolean isValidHost(String zone, String host) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ public PartitionValidator getPartitionValidator() {
+ return new VCloudPartitionValidator();
+ }
+
+ @Override
+ public String createVolume(int sizeGB, String snapshotId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String attachVolume(String instanceId, String volumeId, String deviceName) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void detachVolume(String instanceId, String volumeId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void deleteVolume(String volumeId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String getIaasDevice(String device) {
+ return device;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
deleted file mode 100644
index 2740397..0000000
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.stratos.cloud.controller.iaases;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.stratos.cloud.controller.domain.IaasProvider;
-import org.apache.stratos.cloud.controller.domain.NetworkInterface;
-import org.apache.stratos.cloud.controller.exception.CloudControllerException;
-import org.apache.stratos.cloud.controller.exception.InvalidHostException;
-import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
-import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
-import org.apache.stratos.cloud.controller.iaases.openstack.networking.NeutronNetworkingApi;
-import org.apache.stratos.cloud.controller.iaases.openstack.networking.NovaNetworkingApi;
-import org.apache.stratos.cloud.controller.iaases.openstack.networking.OpenstackNetworkingApi;
-import org.apache.stratos.cloud.controller.iaases.validators.OpenstackNovaPartitionValidator;
-import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
-import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
-import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.openstack.nova.v2_0.NovaApi;
-import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
-import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
-import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
-import org.jclouds.openstack.nova.v2_0.domain.Network;
-import org.jclouds.openstack.nova.v2_0.domain.Volume;
-import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.AvailabilityZone;
-import org.jclouds.openstack.nova.v2_0.extensions.AvailabilityZoneApi;
-import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi;
-import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
-import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi;
-import org.jclouds.openstack.nova.v2_0.extensions.VolumeAttachmentApi;
-import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
-
-import com.google.common.base.Optional;
-
-public class OpenstackNovaIaas extends Iaas {
-
- private static final Log log = LogFactory.getLog(OpenstackNovaIaas.class);
- private static final String SUCCESSFUL_LOG_LINE = "A key-pair is created successfully in ";
- private static final String FAILED_LOG_LINE = "Key-pair is unable to create in ";
-
- private OpenstackNetworkingApi openstackNetworkingApi;
-
- public OpenstackNovaIaas(IaasProvider iaasProvider) {
- super(iaasProvider);
- setOpenstackNetworkingApi(iaasProvider);
- }
-
- private void setOpenstackNetworkingApi(IaasProvider iaasProvider) {
- String openstackNetworkingProvider = iaasProvider.getProperty(CloudControllerConstants.OPENSTACK_NETWORKING_PROVIDER);
- if (openstackNetworkingProvider != null &&
- openstackNetworkingProvider.equals(CloudControllerConstants.OPENSTACK_NEUTRON_NETWORKING)) {
- if (log.isDebugEnabled()) {
- String msg = String.format("Openstack networking provider is %s. Trying to instanstiate %s",
- openstackNetworkingProvider, NeutronNetworkingApi.class.getName());
- log.debug(msg);
- }
- openstackNetworkingApi = new NeutronNetworkingApi(iaasProvider);
- } else {
- if (log.isDebugEnabled()) {
- String msg = String.format("Openstack networking provider is %s. Hence trying to instanstiate %s",
- openstackNetworkingProvider, NovaNetworkingApi.class.getName());
- log.debug(msg);
- }
- openstackNetworkingApi = new NovaNetworkingApi(iaasProvider);
- }
- }
-
- @Override
- public void buildComputeServiceAndTemplate() {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- // builds and sets Compute Service
- ComputeServiceBuilderUtil.buildDefaultComputeService(iaasInfo);
-
- // builds and sets Template
- buildTemplate();
-
- }
-
- public void buildTemplate() {
- IaasProvider iaasInfo = getIaasProvider();
-
- if (iaasInfo.getComputeService() == null) {
- throw new CloudControllerException(
- "Compute service is null for IaaS provider: "
- + iaasInfo.getName());
- }
-
- TemplateBuilder templateBuilder = iaasInfo.getComputeService()
- .templateBuilder();
- templateBuilder.imageId(iaasInfo.getImage());
- if(!(iaasInfo instanceof IaasProvider)) {
- templateBuilder.locationId(iaasInfo.getType());
- }
-
- // to avoid creation of template objects in each and every time, we
- // create all at once!
-
- String instanceType;
-
- // set instance type
- if (((instanceType = iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE)) != null)) {
-
- templateBuilder.hardwareId(instanceType);
- }
-
- Template template = templateBuilder.build();
-
- // In Openstack the call to IaaS should be blocking, in order to retrieve
- // IP addresses.
- boolean blockUntilRunning = true;
- if(iaasInfo.getProperty(CloudControllerConstants.BLOCK_UNTIL_RUNNING) != null) {
- blockUntilRunning = Boolean.parseBoolean(iaasInfo.getProperty(
- CloudControllerConstants.BLOCK_UNTIL_RUNNING));
- }
- template.getOptions().as(TemplateOptions.class)
- .blockUntilRunning(blockUntilRunning);
-
- // this is required in order to avoid creation of additional security
- // groups by Jclouds.
- template.getOptions().as(TemplateOptions.class)
- .inboundPorts(new int[] {});
-
- if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS) != null) {
- template.getOptions()
- .as(NovaTemplateOptions.class)
- .securityGroupNames(
- iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS).split(
- CloudControllerConstants.ENTRY_SEPARATOR));
- }
-
- if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
- template.getOptions().as(NovaTemplateOptions.class)
- .keyPairName(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
- }
-
- if (iaasInfo.getNetworkInterfaces() != null) {
- Set<Network> novaNetworksSet = new LinkedHashSet<Network>(iaasInfo.getNetworkInterfaces().length);
- for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) {
- novaNetworksSet.add(Network.builder().networkUuid(ni.getNetworkUuid()).fixedIp(ni.getFixedIp())
- .portUuid(ni.getPortUuid()).build());
- }
- template.getOptions().as(NovaTemplateOptions.class).novaNetworks(novaNetworksSet);
- }
-
- if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
- template.getOptions().as(NovaTemplateOptions.class)
- .availabilityZone(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
- }
-
- //TODO
-// if (iaas.getProperty(CloudControllerConstants.HOST) != null) {
-// template.getOptions().as(NovaTemplateOptions.class)
-// .(CloudControllerConstants.HOST);
-// }
-
- // set Template
- iaasInfo.setTemplate(template);
- }
-
- @Override
- public void setDynamicPayload() {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- if (iaasInfo.getTemplate() != null && iaasInfo.getPayload() != null) {
-
- iaasInfo.getTemplate().getOptions().as(NovaTemplateOptions.class)
- .userData(iaasInfo.getPayload());
- }
-
- }
-
- @Override
- public synchronized boolean createKeyPairFromPublicKey(String region, String keyPairName,
- String publicKey) {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- String openstackNovaMsg = " Openstack-nova. Region: " + region
- + " - Name: ";
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- KeyPairApi api = novaApi.getKeyPairExtensionForZone(region).get();
-
- KeyPair keyPair = api.createWithPublicKey(keyPairName, publicKey);
-
- if (keyPair != null) {
-
- iaasInfo.getTemplate().getOptions().as(NovaTemplateOptions.class)
- .keyPairName(keyPair.getName());
-
- log.info(SUCCESSFUL_LOG_LINE + openstackNovaMsg + keyPair.getName());
- return true;
- }
-
- log.error(FAILED_LOG_LINE + openstackNovaMsg);
- return false;
-
- }
-
- @Override
- public synchronized String associateAddress(NodeMetadata node) {
- //TODO return the list of IP addresses once the topology changes is done
- return openstackNetworkingApi.associateAddresses(node).iterator().next();
- }
-
- @Override
- public synchronized String associatePredefinedAddress (NodeMetadata node, String ip) {
- return openstackNetworkingApi.associatePredefinedAddress(node, ip);
- }
-
- @Override
- public synchronized void releaseAddress(String ip) {
- openstackNetworkingApi.releaseAddress(ip);
- }
-
- @Override
- public boolean isValidRegion(String region) throws InvalidRegionException {
- IaasProvider iaasInfo = getIaasProvider();
-
- // jclouds' zone = region in openstack
- if (region == null || iaasInfo == null) {
- String msg =
- "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " +
- iaasInfo;
- log.error(msg);
- throw new InvalidRegionException(msg);
- }
-
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- Set<String> zones = novaApi.getConfiguredZones();
- for (String configuredZone : zones) {
- if (region.equalsIgnoreCase(configuredZone)) {
- if (log.isDebugEnabled()) {
- log.debug("Found a matching region: " + region);
- }
- return true;
- }
- }
-
- String msg = "Invalid region: " + region +" in the iaas: "+iaasInfo.getType();
- log.error(msg);
- throw new InvalidRegionException(msg);
- }
-
- @Override
- public boolean isValidZone(String region, String zone) throws InvalidZoneException {
- IaasProvider iaasInfo = getIaasProvider();
-
- // jclouds availability zone = stratos zone
- if (region == null || zone == null || iaasInfo == null) {
- String msg = "Host or Zone or IaaSProvider is null: region: " + region + " - zone: " +
- zone + " - IaaSProvider: " + iaasInfo;
- log.error(msg);
- throw new InvalidZoneException(msg);
- }
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- Optional<? extends AvailabilityZoneApi> availabilityZoneApi = novaApi.getAvailabilityZoneApi(region);
- for (AvailabilityZone z : availabilityZoneApi.get().list()) {
-
- if (zone.equalsIgnoreCase(z.getName())) {
- if (log.isDebugEnabled()) {
- log.debug("Found a matching availability zone: " + zone);
- }
- return true;
- }
- }
-
- String msg = "Invalid zone: " + zone +" in the region: "+region+ " and of the iaas: "+iaasInfo.getType();
- log.error(msg);
- throw new InvalidZoneException(msg);
-
- }
-
- @Override
- public boolean isValidHost(String zone, String host) throws InvalidHostException {
- IaasProvider iaasInfo = getIaasProvider();
-
- if (host == null || zone == null || iaasInfo == null) {
- String msg = String.format("Host or Zone or IaaSProvider is null: host: %s - zone: %s - IaaSProvider: %s", host, zone, iaasInfo);
- log.error(msg);
- throw new InvalidHostException(msg);
- }
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- HostAggregateApi hostApi = novaApi.getHostAggregateExtensionForZone(zone).get();
- for (HostAggregate hostAggregate : hostApi.list()) {
- for (String configuredHost : hostAggregate.getHosts()) {
- if (host.equalsIgnoreCase(configuredHost)) {
- if (log.isDebugEnabled()) {
- log.debug("Found a matching host: " + host);
- }
- return true;
- }
- }
- }
-
- String msg = String.format("Invalid host: %s in the zone: %s and of the iaas: %s", host, zone, iaasInfo.getType());
- log.error(msg);
- throw new InvalidHostException(msg);
- }
-
- @Override
- public PartitionValidator getPartitionValidator() {
- return new OpenstackNovaPartitionValidator();
- }
-
- @Override
- public String createVolume(int sizeGB, String snapshotId) {
- IaasProvider iaasInfo = getIaasProvider();
-
- if (iaasInfo == null) {
- log.fatal(String.format("Cannot create a new volume with snapshot ID : %s", snapshotId));
- return null;
- }
-
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
- String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
-
- if (region == null) {
- log.fatal(String.format("Cannot create a new volume. Extracted region is null for Iaas : %s", iaasInfo));
- return null;
- }
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
-
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- VolumeApi volumeApi = novaApi.getVolumeExtensionForZone(region).get();
- Volume volume;
- if(StringUtils.isEmpty(snapshotId)){
- if(log.isDebugEnabled()){
- log.info("Creating a volume in the zone " + zone);
- }
- volume = volumeApi.create(sizeGB, CreateVolumeOptions.Builder.availabilityZone(zone));
- }else{
- if(log.isDebugEnabled()){
- log.info("Creating a volume in the zone " + zone + " from the shanpshot " + snapshotId);
- }
- volume = volumeApi.create(sizeGB, CreateVolumeOptions.Builder.availabilityZone(zone).snapshotId(snapshotId));
- }
-
- if (volume == null) {
- log.fatal(String.format("Volume creation was unsuccessful. [region] : %s [zone] : %s of Iaas : %s", region, zone, iaasInfo));
- return null;
- }
-
- String volumeId = volume.getId();
- /*
- Volume.Status volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
-
- if(!(volumeStatus == Volume.Status.AVAILABLE || volumeStatus == Volume.Status.CREATING)){
- log.error(String.format("Error while creating [volume id] %s. Volume status is %s", volumeId, volumeStatus));
- return volumeId;
- }
- try {
- if(!waitForStatus(volumeApi, volumeId, Volume.Status.AVAILABLE)){
- log.error("Volume did not become AVAILABLE. Current status is " + volume.getStatus());
- }
- } catch (TimeoutException e) {
- log.error("[Volume ID] " + volumeId + "did not become AVAILABLE within expected timeout");
- return volumeId;
- }
- */
- log.info(String.format("Successfully created a new volume [id]: %s in [region] : %s [zone] : %s of Iaas : %s [Volume ID]%s", volume.getId(), region, zone, iaasInfo, volume.getId()));
- return volumeId;
- }
-
- private boolean waitForStatus(String volumeId, Volume.Status expectedStatus, int timeoutInMins) throws TimeoutException {
- int timeout = 1000 * 60 * timeoutInMins;
- long timout = System.currentTimeMillis() + timeout;
-
- IaasProvider iaasInfo = getIaasProvider();
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();;
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- VolumeApi volumeApi = novaApi.getVolumeExtensionForZone(region).get();
- Volume.Status volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
-
- while(volumeStatus != expectedStatus){
- try {
- if(log.isDebugEnabled()){
- log.debug(String.format("Volume %s is still NOT in %s. Current State=%s", volumeId, expectedStatus, volumeStatus));
- }
- if(volumeStatus == Volume.Status.ERROR){
- log.error("Volume " + volumeId + " is in state ERROR");
- return false;
- }
- Thread.sleep(1000);
- volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
- if (System.currentTimeMillis()> timout) {
- throw new TimeoutException();
- }
- } catch (InterruptedException e) {
- // Ignoring the exception
- }
- }
- if(log.isDebugEnabled()){
- log.debug(String.format("Volume %s status became %s", volumeId, expectedStatus));
- }
-
- return true;
- }
-
- @Override
- public String attachVolume(String instanceId, String volumeId, String deviceName) {
- IaasProvider iaasInfo = getIaasProvider();
-
- if (StringUtils.isEmpty(volumeId)) {
- log.error("Volume provided to attach can not be null");
- }
-
- if (StringUtils.isEmpty(instanceId)) {
- log.error("Instance provided to attach can not be null");
- }
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
- String device = deviceName == null ? "/dev/vdc" : deviceName;
-
- if (region == null) {
- log.fatal(String.format("Cannot attach the volume [id]: %s. Extracted region is null for Iaas : %s", volumeId, iaasInfo));
- return null;
- }
-
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- VolumeApi volumeApi = novaApi.getVolumeExtensionForZone(region).get();
- VolumeAttachmentApi volumeAttachmentApi = novaApi.getVolumeAttachmentExtensionForZone(region).get();
-
- Volume.Status volumeStatus = this.getVolumeStatus(volumeApi, volumeId);
-
- if (log.isDebugEnabled()) {
- log.debug("Volume " + volumeId + " is in state " + volumeStatus);
- }
-
- if (!(volumeStatus == Volume.Status.AVAILABLE || volumeStatus == Volume.Status.CREATING)) {
- log.error(String.format("Volume %s can not be attached. Volume status is %s", volumeId, volumeStatus));
- return null;
- }
-
- boolean volumeBecameAvailable = false, volumeBecameAttached = false;
- try {
- volumeBecameAvailable = waitForStatus(volumeId, Volume.Status.AVAILABLE, 5);
- } catch (TimeoutException e) {
- log.error("[Volume ID] " + volumeId + "did not become AVAILABLE within expected timeout");
- }
-
- VolumeAttachment attachment = null;
- if (volumeBecameAvailable) {
- attachment = volumeAttachmentApi.attachVolumeToServerAsDevice(volumeId, instanceId, device);
-
- try {
- volumeBecameAttached = waitForStatus(volumeId, Volume.Status.IN_USE, 2);
- } catch (TimeoutException e) {
- log.error("[Volume ID] " + volumeId + "did not become IN_USE within expected timeout");
- }
- }
- try {
- // waiting 5seconds till volumes are actually attached.
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- if (attachment == null) {
- log.fatal(String.format("Volume [id]: %s attachment for instance [id]: %s was unsuccessful. [region] : %s of Iaas : %s", volumeId, instanceId, region, iaasInfo));
- return null;
- }
-
- if(! volumeBecameAttached){
- log.error(String.format("[Volume ID] %s attachment is called, but not yet became attached", volumeId));
- }
-
- log.info(String.format("Volume [id]: %s attachment for instance [id]: %s was successful [status]: Attaching. [region] : %s of Iaas : %s", volumeId, instanceId, region, iaasInfo));
- return "Attaching";
- }
-
- @Override
- public void detachVolume(String instanceId, String volumeId) {
- IaasProvider iaasInfo = getIaasProvider();
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
-
- if(region == null) {
- log.fatal(String.format("Cannot detach the volume [id]: %s from the instance [id]: %s. Extracted region is null for Iaas : %s", volumeId, instanceId, iaasInfo));
- return;
- }
- if(log.isDebugEnabled()) {
- log.debug(String.format("Starting to detach volume %s from the instance %s", volumeId, instanceId));
- }
-
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- VolumeAttachmentApi api = novaApi.getVolumeAttachmentExtensionForZone(region).get();
- if (api.detachVolumeFromServer(volumeId, instanceId)) {
- log.info(String.format("Detachment of Volume [id]: %s from instance [id]: %s was successful. [region] : %s of Iaas : %s", volumeId, instanceId, region, iaasInfo));
- }else{
- log.error(String.format("Detachment of Volume [id]: %s from instance [id]: %s was unsuccessful. [volume Status] : %s", volumeId, instanceId, region, iaasInfo));
- }
-
- }
-
- @Override
- public void deleteVolume(String volumeId) {
- IaasProvider iaasInfo = getIaasProvider();
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
-
- if(region == null) {
- log.fatal(String.format("Cannot delete the volume [id]: %s. Extracted region is null for Iaas : %s", volumeId, iaasInfo));
- return;
- }
-
- NovaApi novaApi = context.unwrapApi(NovaApi.class);
- VolumeApi api = novaApi.getVolumeExtensionForZone(region).get();
- if (api.delete(volumeId)) {
- log.info(String.format("Deletion of Volume [id]: %s was successful. [region] : %s of Iaas : %s", volumeId, region, iaasInfo));
- }
- }
-
- @Override
- public String getIaasDevice(String device) {
- return device;
- }
-
- private Volume.Status getVolumeStatus(VolumeApi volumeApi, String volumeId){
- return volumeApi.get(volumeId).getStatus();
- }
-}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
deleted file mode 100644
index 6e10628..0000000
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.stratos.cloud.controller.iaases;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.stratos.cloud.controller.exception.CloudControllerException;
-import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
-import org.apache.stratos.cloud.controller.domain.IaasProvider;
-import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
-import org.apache.stratos.cloud.controller.iaases.validators.VCloudPartitionValidator;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
-import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
-import org.wso2.carbon.utils.CarbonUtils;
-
-import java.io.File;
-import java.io.IOException;
-
-public class VCloudIaas extends Iaas {
-
-
- private static final Log log = LogFactory.getLog(VCloudIaas.class);
-
- private static final String SHELL_TYPE = "shellType";
- private static final String SCRIPTS_PATH = "scripts";
- private static final String CUSTOMIZATION_SCRIPT = "customization";
- private static final String PAYLOAD = "PAYLOAD";
-
- public VCloudIaas(IaasProvider iaasProvider) {
- super(iaasProvider);
- }
-
- @Override
- public void buildComputeServiceAndTemplate() {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- // builds and sets Compute Service
- ComputeServiceBuilderUtil.buildDefaultComputeService(iaasInfo);
-
- // builds and sets Template
- buildTemplate();
-
- }
-
- public void buildTemplate() {
- IaasProvider iaasInfo = getIaasProvider();
-
- if (iaasInfo.getComputeService() == null) {
- String msg = "Compute service is null for IaaS provider: "
- + iaasInfo.getName();
- log.fatal(msg);
- throw new CloudControllerException(msg);
- }
-
- TemplateBuilder templateBuilder = iaasInfo.getComputeService()
- .templateBuilder();
-
- // set image id specified
- templateBuilder.imageId(iaasInfo.getImage());
-
- // build the Template
- Template template = templateBuilder.build();
-
- // if you wish to auto assign IPs, instance spawning call should be
- // blocking, but if you
- // wish to assign IPs manually, it can be non-blocking.
- // is auto-assign-ip mode or manual-assign-ip mode? - default mode is
- // non-blocking
- boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
- .getProperty("autoAssignIp"));
- template.getOptions().as(TemplateOptions.class)
- .blockUntilRunning(blockUntilRunning);
-
- // this is required in order to avoid creation of additional security
- // groups by Jclouds.
- template.getOptions().as(TemplateOptions.class)
- .inboundPorts(22, 80, 8080, 443, 8243);
-
- template.getOptions().as(VCloudTemplateOptions.class)
- .ipAddressAllocationMode(IpAddressAllocationMode.POOL);
-
- // set Template
- iaasInfo.setTemplate(template);
- }
-
- @Override
- public void setDynamicPayload() {
- // in vCloud case we need to run a script
- IaasProvider iaasInfo = getIaasProvider();
-
- if (iaasInfo.getTemplate() == null || iaasInfo.getPayload() == null) {
- if (log.isDebugEnabled()) {
- log.debug("Payload for vCloud not found");
- }
- return;
- }
-
- String shellType = iaasInfo.getProperty(SHELL_TYPE);
-
- if (shellType == null || shellType.isEmpty()) {
- if (log.isDebugEnabled()) {
- log.debug("Shell Type for vCloud Customization script not found from properties");
- }
- return;
- }
-
- if (log.isDebugEnabled()) {
- log.debug(String.format("Shell Type '%s' will be used for vCloud Customization script", shellType));
- }
-
- // Payload is a String value
- String payload = new String(iaasInfo.getPayload());
-
- if (log.isDebugEnabled()) {
- log.debug(String.format("Payload '%s' will be used for vCloud Customization script", payload));
- }
-
- Template template = iaasInfo.getTemplate();
-
- File scriptPath = new File(CarbonUtils.getCarbonConfigDirPath(), SCRIPTS_PATH);
-
- File customizationScriptFile = new File(new File(scriptPath, shellType), CUSTOMIZATION_SCRIPT);
-
- if (!customizationScriptFile.exists()) {
- if (log.isWarnEnabled()) {
- log.warn(String.format("The vCloud Customization script '%s' does not exist",
- customizationScriptFile.getAbsolutePath()));
- }
- return;
- }
-
- String customizationScript = null;
-
- try {
- customizationScript = FileUtils.readFileToString(customizationScriptFile);
- } catch (IOException e) {
- if (log.isErrorEnabled()) {
- log.error(
- String.format("Error reading the vCloud Customization script '%s'",
- customizationScriptFile.getAbsolutePath()), e);
- }
- }
-
- if (StringUtils.isEmpty(customizationScript)) {
- if (log.isDebugEnabled()) {
- log.debug("No content vCloud Customization script not found from properties");
- }
- return;
- }
-
- // Set payload
- customizationScript = customizationScript.replaceAll(PAYLOAD, payload);
-
- if (log.isDebugEnabled()) {
- log.debug(String.format("The vCloud Customization script\n%s", customizationScript));
- }
-
- // Run the script
- template.getOptions().runScript(customizationScript);
- }
-
- @Override
- public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
-
- // TODO
- return false;
- }
-
- @Override
- public String associateAddress(NodeMetadata node) {
-
- // TODO
- return "";
-
- }
-
- @Override
- public String associatePredefinedAddress(NodeMetadata node, String ip) {
- return "";
- }
-
- @Override
- public void releaseAddress(String ip) {
- // TODO
- }
-
- @Override
- public boolean isValidRegion(String region) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean isValidZone(String region, String zone) {
- // TODO Auto-generated method stub
- return true;
- }
-
- @Override
- public boolean isValidHost(String zone, String host) {
- // TODO Auto-generated method stub
- return true;
- }
-
- @Override
- public PartitionValidator getPartitionValidator() {
- return new VCloudPartitionValidator();
- }
-
- @Override
- public String createVolume(int sizeGB, String snapshotId) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public String attachVolume(String instanceId, String volumeId, String deviceName) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void detachVolume(String instanceId, String volumeId) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void deleteVolume(String volumeId) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public String getIaasDevice(String device) {
- return device;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIPAddressPool.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIPAddressPool.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIPAddressPool.java
new file mode 100644
index 0000000..610c00b
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIPAddressPool.java
@@ -0,0 +1,99 @@
+/*
+ * 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.iaases.mock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.registry.RegistryManager;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+
+import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Mock IP address pool is a singleton class for managing private and public IP addresses.
+ */
+public class MockIPAddressPool {
+ private static final Log log = LogFactory.getLog(MockIPAddressPool.class);
+ private static final String MOCK_IAAS_PRIVATE_IP_SEQUENCE = "/mock/iaas/private-ip-sequence";
+ private static final String MOCK_IAAS_PUBLIC_IP_SEQUENCE = "/mock/iaas/public-ip-sequence";
+ private static final String PRIVATE_IP_PREFIX = "10.0.0.";
+ private static final String PUBLIC_IP_PREFIX = "20.0.0.";
+
+ private static volatile MockIPAddressPool instance;
+
+ private AtomicInteger privateIpSequence;
+ private AtomicInteger publicIpSequence;
+
+ private MockIPAddressPool() {
+ privateIpSequence = readFromRegistry(MOCK_IAAS_PRIVATE_IP_SEQUENCE);
+ if (privateIpSequence == null) {
+ privateIpSequence = new AtomicInteger();
+ }
+
+ publicIpSequence = readFromRegistry(MOCK_IAAS_PUBLIC_IP_SEQUENCE);
+ if (publicIpSequence == null) {
+ publicIpSequence = new AtomicInteger();
+ }
+ }
+
+ public static MockIPAddressPool getInstance() {
+ if (instance == null) {
+ synchronized (MockIPAddressPool.class) {
+ if (instance == null) {
+ instance = new MockIPAddressPool();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public String getNextPrivateIpAddress() {
+ int nextSequence = privateIpSequence.incrementAndGet();
+ String ipAddress = PRIVATE_IP_PREFIX + nextSequence;
+ persistInRegistry(MOCK_IAAS_PRIVATE_IP_SEQUENCE, privateIpSequence);
+ if (log.isInfoEnabled()) {
+ log.info("Mock private IP address allocated: " + ipAddress);
+ }
+ return ipAddress;
+ }
+
+ public String getNextPublicIpAddress() {
+ int nextSequence = publicIpSequence.incrementAndGet();
+ String ipAddress = PUBLIC_IP_PREFIX + nextSequence;
+ persistInRegistry(MOCK_IAAS_PRIVATE_IP_SEQUENCE, publicIpSequence);
+ if (log.isInfoEnabled()) {
+ log.info("Mock public IP address allocated: " + ipAddress);
+ }
+ return ipAddress;
+ }
+
+ private void persistInRegistry(String resourcePath, Serializable serializable) {
+ try {
+ RegistryManager.getInstance().persist(resourcePath, serializable);
+ } catch (RegistryException e) {
+ log.error(String.format("Could not persist mock iaas ip sequence [%s] in registry", resourcePath), e);
+ }
+ }
+
+ private AtomicInteger readFromRegistry(String resourcePath) {
+ return (AtomicInteger) RegistryManager.getInstance().read(resourcePath);
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIaas.java
new file mode 100644
index 0000000..82d6c59
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockIaas.java
@@ -0,0 +1,176 @@
+/*
+ * 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.iaases.mock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.domain.ClusterContext;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.domain.MemberContext;
+import org.apache.stratos.cloud.controller.domain.Partition;
+import org.apache.stratos.cloud.controller.exception.*;
+import org.apache.stratos.cloud.controller.iaases.Iaas;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+import org.apache.stratos.cloud.controller.registry.RegistryManager;
+import org.apache.stratos.common.threading.StratosThreadPool;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Created by imesh on 12/6/14.
+ */
+public class MockIaas extends Iaas {
+
+ private static final Log log = LogFactory.getLog(MockIaas.class);
+ private static final String MOCK_IAAS_MEMBERS = "/mock/iaas/members";
+
+ private ExecutorService executorService;
+ private MockPartitionValidator partitionValidator;
+ private ConcurrentHashMap<String, MockMember> membersMap;
+
+ public MockIaas(IaasProvider iaasProvider) {
+ super(iaasProvider);
+ executorService = StratosThreadPool.getExecutorService("MOCK_IAAS_THREAD_EXECUTOR", 100);
+ partitionValidator = new MockPartitionValidator();
+ membersMap = readFromRegistry();
+ if(membersMap != null) {
+ // Start existing members
+ for(MockMember mockMember : membersMap.values()) {
+ executorService.submit(mockMember);
+ }
+ } else {
+ // No members found in registry, create new map
+ membersMap = new ConcurrentHashMap<String, MockMember>();
+ }
+ }
+
+ @Override
+ public void initialize() {
+ }
+
+ @Override
+ public NodeMetadata createInstance(ClusterContext clusterContext, MemberContext memberContext) {
+ // Create mock member instance
+ MockMemberContext mockMemberContext = new MockMemberContext(clusterContext.getCartridgeType(),
+ clusterContext.getClusterId(), memberContext.getMemberId(), memberContext.getNetworkPartitionId(),
+ memberContext.getPartition().getId(), memberContext.getInstanceId());
+ MockMember mockMember = new MockMember(mockMemberContext);
+ membersMap.put(mockMember.getMockMemberContext().getMemberId(), mockMember);
+ executorService.submit(mockMember);
+
+ // Prepare node metadata
+ MockNodeMetadata nodeMetadata = new MockNodeMetadata();
+ nodeMetadata.setId(UUID.randomUUID().toString());
+
+ // Persist changes
+ persistInRegistry();
+
+ return nodeMetadata;
+ }
+
+ private void persistInRegistry() {
+ try {
+ RegistryManager.getInstance().persist(MOCK_IAAS_MEMBERS, membersMap);
+ } catch (RegistryException e) {
+ log.error("Could not persist mock iaas members in registry", e);
+ };
+ }
+
+ private ConcurrentHashMap<String, MockMember> readFromRegistry() {
+ return (ConcurrentHashMap<String, MockMember>) RegistryManager.getInstance().read(MOCK_IAAS_MEMBERS);
+ }
+
+ @Override
+ public void allocateIpAddress(String clusterId, MemberContext memberContext, Partition partition,
+ String cartridgeType, NodeMetadata node) {
+ // Allocate mock ip addresses
+ memberContext.setPrivateIpAddress(MockIPAddressPool.getInstance().getNextPrivateIpAddress());
+ memberContext.setPublicIpAddress(MockIPAddressPool.getInstance().getNextPublicIpAddress());
+ }
+
+ @Override
+ public void releaseAddress(String ip) {
+
+ }
+
+ @Override
+ public boolean isValidRegion(String region) throws InvalidRegionException {
+ return true;
+ }
+
+ @Override
+ public boolean isValidZone(String region, String zone) throws InvalidZoneException, InvalidRegionException {
+ return true;
+ }
+
+ @Override
+ public boolean isValidHost(String zone, String host) throws InvalidHostException {
+ return true;
+ }
+
+ @Override
+ public PartitionValidator getPartitionValidator() {
+ return partitionValidator;
+ }
+
+ @Override
+ public String createVolume(int sizeGB, String snapshotId) {
+ return null;
+ }
+
+ @Override
+ public String attachVolume(String instanceId, String volumeId, String deviceName) {
+ return null;
+ }
+
+ @Override
+ public void detachVolume(String instanceId, String volumeId) {
+
+ }
+
+ @Override
+ public void deleteVolume(String volumeId) {
+
+ }
+
+ @Override
+ public String getIaasDevice(String device) {
+ return null;
+ }
+
+ @Override
+ public void setDynamicPayload(byte[] payload) {
+
+ }
+
+ @Override
+ public void terminateInstance(MemberContext memberContext) throws InvalidCartridgeTypeException, InvalidMemberException {
+ MockMember mockMember = membersMap.get(memberContext.getMemberId());
+ if(mockMember != null) {
+ mockMember.terminate();
+ membersMap.remove(memberContext.getMemberId());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMember.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMember.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMember.java
new file mode 100644
index 0000000..898de35
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMember.java
@@ -0,0 +1,85 @@
+/*
+ * 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.iaases.mock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.iaases.mock.statistics.MockHealthStatisticsNotifier;
+
+import java.io.Serializable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Mock member definition.
+ */
+public class MockMember implements Runnable, Serializable {
+
+ private static final Log log = LogFactory.getLog(MockMember.class);
+ private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+
+ private MockMemberContext mockMemberContext;
+ private boolean terminated;
+
+ public MockMember(MockMemberContext mockMemberContext) {
+ this.mockMemberContext = mockMemberContext;
+ }
+
+ @Override
+ public void run() {
+ MockMemberEventPublisher.publishInstanceStartedEvent(mockMemberContext);
+ sleep(5000);
+ MockMemberEventPublisher.publishInstanceActivatedEvent(mockMemberContext);
+
+
+ if (log.isInfoEnabled()) {
+ log.info("Starting health statistics notifier");
+ }
+ final ScheduledFuture<?> scheduledFuture = scheduler.scheduleAtFixedRate(
+ new MockHealthStatisticsNotifier(mockMemberContext), 15, 15, TimeUnit.SECONDS);
+
+ if (log.isInfoEnabled()) {
+ log.info("Health statistics notifier started");
+ }
+
+ while(!terminated) {
+ sleep(1000);
+ }
+ }
+
+ private void sleep(long time) {
+ try {
+ Thread.sleep(time);
+ } catch (InterruptedException ignore) {
+ terminate();
+ }
+ }
+
+ public MockMemberContext getMockMemberContext() {
+ return mockMemberContext;
+ }
+
+ public void terminate() {
+ terminated = true;
+ scheduler.shutdownNow();
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMemberContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMemberContext.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMemberContext.java
new file mode 100644
index 0000000..7189d11
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMemberContext.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.cloud.controller.iaases.mock;
+
+import java.io.Serializable;
+
+/**
+ * Mock member context.
+ */
+public class MockMemberContext implements Serializable {
+ private final String serviceName;
+ private final String clusterId;
+ private final String memberId;
+ private final String networkPartitionId;
+ private final String partitionId;
+ private final String instanceId;
+
+ public MockMemberContext(String serviceName, String clusterId, String memberId,
+ String networkPartitionId, String partitionId, String instanceId) {
+ this.serviceName = serviceName;
+ this.clusterId = clusterId;
+ this.memberId = memberId;
+ this.networkPartitionId = networkPartitionId;
+ this.partitionId = partitionId;
+ this.instanceId = instanceId;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public String getClusterId() {
+ return clusterId;
+ }
+
+ public String getMemberId() {
+ return memberId;
+ }
+
+ public String getNetworkPartitionId() {
+ return networkPartitionId;
+ }
+
+ public String getPartitionId() {
+ return partitionId;
+ }
+
+ public String getInstanceId() {
+ return instanceId;
+ }
+}