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:24 UTC
[1/4] stratos git commit: Introducing a mock iaas for cloud controller
Repository: stratos
Updated Branches:
refs/heads/mock-iaas [created] 2ec3ff0ed
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/MockMemberEventPublisher.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMemberEventPublisher.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMemberEventPublisher.java
new file mode 100644
index 0000000..6d06c85
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockMemberEventPublisher.java
@@ -0,0 +1,122 @@
+/*
+ * 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.messaging.broker.publish.EventPublisher;
+import org.apache.stratos.messaging.broker.publish.EventPublisherPool;
+import org.apache.stratos.messaging.event.instance.status.InstanceActivatedEvent;
+import org.apache.stratos.messaging.event.instance.status.InstanceMaintenanceModeEvent;
+import org.apache.stratos.messaging.event.instance.status.InstanceReadyToShutdownEvent;
+import org.apache.stratos.messaging.event.instance.status.InstanceStartedEvent;
+import org.apache.stratos.messaging.util.Util;
+
+/**
+ * Mock member event publisher.
+ */
+public class MockMemberEventPublisher {
+
+ private static final Log log = LogFactory.getLog(MockMemberEventPublisher.class);
+
+ public static void publishInstanceStartedEvent(MockMemberContext mockMemberContext) {
+ if (log.isInfoEnabled()) {
+ log.info("Publishing instance started event");
+ }
+ InstanceStartedEvent event = new InstanceStartedEvent(
+ mockMemberContext.getServiceName(),
+ mockMemberContext.getClusterId(),
+ mockMemberContext.getNetworkPartitionId(),
+ mockMemberContext.getPartitionId(),
+ mockMemberContext.getMemberId(),
+ mockMemberContext.getInstanceId());
+ String topic = Util.getMessageTopicName(event);
+ EventPublisher eventPublisher = EventPublisherPool
+ .getPublisher(topic);
+ eventPublisher.publish(event);
+ if (log.isInfoEnabled()) {
+ log.info("Instance started event published");
+ }
+ }
+
+ public static void publishInstanceActivatedEvent(MockMemberContext mockMemberContext) {
+ if (log.isInfoEnabled()) {
+ log.info("Publishing instance activated event");
+ }
+ InstanceActivatedEvent event = new InstanceActivatedEvent(
+ mockMemberContext.getServiceName(),
+ mockMemberContext.getClusterId(),
+ mockMemberContext.getNetworkPartitionId(),
+ mockMemberContext.getPartitionId(),
+ mockMemberContext.getMemberId(),
+ mockMemberContext.getInstanceId());
+
+ // Event publisher connection will
+ String topic = Util.getMessageTopicName(event);
+ EventPublisher eventPublisher = EventPublisherPool
+ .getPublisher(topic);
+ eventPublisher.publish(event);
+ if (log.isInfoEnabled()) {
+ log.info("Instance activated event published");
+ }
+ }
+
+ public static void publishInstanceReadyToShutdownEvent(MockMemberContext mockMemberContext) {
+ if (log.isInfoEnabled()) {
+ log.info("Publishing instance activated event");
+ }
+ InstanceReadyToShutdownEvent event = new InstanceReadyToShutdownEvent(
+ mockMemberContext.getServiceName(),
+ mockMemberContext.getClusterId(),
+ mockMemberContext.getNetworkPartitionId(),
+ mockMemberContext.getPartitionId(),
+ mockMemberContext.getMemberId(),
+ mockMemberContext.getInstanceId());
+ String topic = Util.getMessageTopicName(event);
+ EventPublisher eventPublisher = EventPublisherPool
+ .getPublisher(topic);
+ eventPublisher.publish(event);
+ if (log.isInfoEnabled()) {
+ log.info("Instance ReadyToShutDown event published");
+ }
+
+ }
+
+ public static void publishMaintenanceModeEvent(MockMemberContext mockMemberContext) {
+ if (log.isInfoEnabled()) {
+ log.info("Publishing instance maintenance mode event");
+ }
+ InstanceMaintenanceModeEvent event = new InstanceMaintenanceModeEvent(
+ mockMemberContext.getServiceName(),
+ mockMemberContext.getClusterId(),
+ mockMemberContext.getNetworkPartitionId(),
+ mockMemberContext.getPartitionId(),
+ mockMemberContext.getMemberId(),
+ mockMemberContext.getInstanceId());
+ String topic = Util.getMessageTopicName(event);
+ EventPublisher eventPublisher = EventPublisherPool
+ .getPublisher(topic);
+ eventPublisher.publish(event);
+ if (log.isInfoEnabled()) {
+ log.info("Instance Maintenance mode event published");
+ }
+ }
+
+}
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/MockNodeMetadata.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockNodeMetadata.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockNodeMetadata.java
new file mode 100644
index 0000000..34b3fe9
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockNodeMetadata.java
@@ -0,0 +1,143 @@
+/*
+ * 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.jclouds.compute.domain.ComputeType;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.domain.ResourceMetadata;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by imesh on 12/6/14.
+ */
+public class MockNodeMetadata implements NodeMetadata {
+ private String id;
+
+ @Override
+ public String getHostname() {
+ return null;
+ }
+
+ @Override
+ public String getGroup() {
+ return null;
+ }
+
+ @Override
+ public Hardware getHardware() {
+ return null;
+ }
+
+ @Override
+ public String getImageId() {
+ return null;
+ }
+
+ @Override
+ public OperatingSystem getOperatingSystem() {
+ return null;
+ }
+
+ @Override
+ public int getLoginPort() {
+ return 0;
+ }
+
+ @Override
+ public LoginCredentials getCredentials() {
+ return null;
+ }
+
+ @Override
+ public Set<String> getPublicAddresses() {
+ return null;
+ }
+
+ @Override
+ public Set<String> getPrivateAddresses() {
+ return null;
+ }
+
+ @Override
+ public Status getStatus() {
+ return null;
+ }
+
+ @Override
+ public String getBackendStatus() {
+ return null;
+ }
+
+ @Override
+ public ComputeType getType() {
+ return null;
+ }
+
+ @Override
+ public String getProviderId() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public URI getUri() {
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getUserMetadata() {
+ return null;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public Set<String> getTags() {
+ return null;
+ }
+
+ @Override
+ public int compareTo(ResourceMetadata<ComputeType> computeTypeResourceMetadata) {
+ return 0;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+}
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/MockPartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockPartitionValidator.java
new file mode 100644
index 0000000..ef7ae94
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/MockPartitionValidator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+
+import java.util.Properties;
+
+/**
+ * Mock partition validator.
+ */
+public class MockPartitionValidator implements PartitionValidator {
+
+ private IaasProvider iaasProvider;
+
+ @Override
+ public void setIaasProvider(IaasProvider iaasProvider) {
+ this.iaasProvider = iaasProvider;
+ }
+
+ @Override
+ public IaasProvider validate(String partitionId, Properties properties) throws InvalidPartitionException {
+ return iaasProvider;
+ }
+}
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/statistics/MockHealthStatisticsNotifier.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/statistics/MockHealthStatisticsNotifier.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/statistics/MockHealthStatisticsNotifier.java
new file mode 100644
index 0000000..882696d
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/statistics/MockHealthStatisticsNotifier.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.stratos.cloud.controller.iaases.mock.statistics;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.iaases.mock.MockMemberContext;
+
+/**
+ * Health statistics notifier thread for publishing statistics periodically to CEP.
+ */
+public class MockHealthStatisticsNotifier implements Runnable {
+ private static final Log log = LogFactory.getLog(MockHealthStatisticsNotifier.class);
+
+ public static final String MEMORY_CONSUMPTION = "memory_consumption";
+ public static final String LOAD_AVERAGE = "load_average";
+
+ private final MockMemberContext mockMemberContext;
+ private final MockHealthStatisticsPublisher statsPublisher;
+ private final double memoryConsumption = 20.0;
+ private final double loadAvereage = 40.0;
+
+ public MockHealthStatisticsNotifier(MockMemberContext mockMemberContext) {
+ this.mockMemberContext = mockMemberContext;
+ this.statsPublisher = new MockHealthStatisticsPublisher();
+ this.statsPublisher.setEnabled(true);
+ }
+
+ @Override
+ public void run() {
+ try {
+ if (statsPublisher.isEnabled()) {
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Publishing memory consumption: %f", memoryConsumption));
+ }
+ statsPublisher.publish(
+ mockMemberContext.getClusterId(),
+ mockMemberContext.getNetworkPartitionId(),
+ mockMemberContext.getMemberId(),
+ mockMemberContext.getPartitionId(),
+ MEMORY_CONSUMPTION,
+ memoryConsumption
+ );
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Publishing load average: %f", loadAvereage));
+ }
+ statsPublisher.publish(
+ mockMemberContext.getClusterId(),
+ mockMemberContext.getNetworkPartitionId(),
+ mockMemberContext.getMemberId(),
+ mockMemberContext.getPartitionId(),
+ LOAD_AVERAGE,
+ loadAvereage
+ );
+ } else if (log.isWarnEnabled()) {
+ log.warn("Statistics publisher is disabled");
+ }
+ } catch (Exception e) {
+ if (log.isErrorEnabled()) {
+ log.error("Could not publish health statistics", 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/mock/statistics/MockHealthStatisticsPublisher.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/statistics/MockHealthStatisticsPublisher.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/statistics/MockHealthStatisticsPublisher.java
new file mode 100644
index 0000000..e4a525a
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/mock/statistics/MockHealthStatisticsPublisher.java
@@ -0,0 +1,89 @@
+/*
+ * 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.statistics;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.common.statistics.publisher.WSO2CEPStatisticsPublisher;
+import org.wso2.carbon.databridge.commons.Attribute;
+import org.wso2.carbon.databridge.commons.AttributeType;
+import org.wso2.carbon.databridge.commons.StreamDefinition;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Health statistics publisher for publishing statistics to CEP.
+ */
+public class MockHealthStatisticsPublisher extends WSO2CEPStatisticsPublisher {
+ private static final Log log = LogFactory.getLog(MockHealthStatisticsPublisher.class);
+
+ private static final String DATA_STREAM_NAME = "cartridge_agent_health_stats";
+ private static final String VERSION = "1.0.0";
+
+ private static StreamDefinition createStreamDefinition() {
+ try {
+ StreamDefinition streamDefinition = new StreamDefinition(DATA_STREAM_NAME, VERSION);
+ streamDefinition.setNickName("agent health stats");
+ streamDefinition.setDescription("agent health stats");
+ // Payload definition
+ List<Attribute> payloadData = new ArrayList<Attribute>();
+ payloadData.add(new Attribute("cluster_id", AttributeType.STRING));
+ payloadData.add(new Attribute("network_partition_id", AttributeType.STRING));
+ payloadData.add(new Attribute("member_id", AttributeType.STRING));
+ payloadData.add(new Attribute("partition_id", AttributeType.STRING));
+ payloadData.add(new Attribute("health_description", AttributeType.STRING));
+ payloadData.add(new Attribute("value", AttributeType.DOUBLE));
+ streamDefinition.setPayloadData(payloadData);
+ return streamDefinition;
+ } catch (Exception e) {
+ throw new RuntimeException("Could not create stream definition", e);
+ }
+ }
+
+ public MockHealthStatisticsPublisher() {
+ super(createStreamDefinition());
+ }
+
+ /**
+ * Publish health statistics to cep.
+ * @param clusterId
+ * @param networkPartitionId
+ * @param memberId
+ * @param partitionId
+ * @param health
+ * @param value
+ */
+ public void publish(String clusterId, String networkPartitionId, String memberId, String partitionId, String health, double value) {
+ if(log.isDebugEnabled()) {
+ log.debug(String.format("Publishing health statistics: [cluster] %s [network-partition] %s [partition] %s [member] %s [health] %s [value] %f",
+ clusterId, networkPartitionId, partitionId, memberId, health, value));
+ }
+ List<Object> payload = new ArrayList<Object>();
+ // Payload values
+ payload.add(clusterId);
+ payload.add(networkPartitionId);
+ payload.add(memberId);
+ payload.add(partitionId);
+ payload.add(health);
+ payload.add(value);
+ super.publish(payload.toArray());
+ }
+}
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/validators/AWSEC2PartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/AWSEC2PartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/AWSEC2PartitionValidator.java
index b8ecfdb..4d16c87 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/AWSEC2PartitionValidator.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/AWSEC2PartitionValidator.java
@@ -24,8 +24,8 @@ import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderExceptio
import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
import org.apache.stratos.cloud.controller.iaases.Iaas;
import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
-import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
import org.apache.stratos.messaging.domain.topology.Scope;
import java.util.Properties;
@@ -62,14 +62,14 @@ public class AWSEC2PartitionValidator implements PartitionValidator {
IaasProvider updatedIaasProvider = new IaasProvider(iaasProvider);
- Iaas updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ Iaas updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
if (properties.containsKey(Scope.zone.toString())) {
String zone = properties.getProperty(Scope.zone.toString());
iaas.isValidZone(region, zone);
updatedIaasProvider.setProperty(CloudControllerConstants.AVAILABILITY_ZONE, zone);
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
}
@@ -93,7 +93,7 @@ public class AWSEC2PartitionValidator implements PartitionValidator {
Properties properties) {
Iaas updatedIaas;
try {
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
for (Object property : properties.keySet()) {
if (property instanceof String) {
@@ -106,7 +106,7 @@ public class AWSEC2PartitionValidator implements PartitionValidator {
}
}
}
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
} catch (InvalidIaasProviderException ignore) {
}
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/validators/CloudstackPartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/CloudstackPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/CloudstackPartitionValidator.java
index 9b3d159..5264e58 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/CloudstackPartitionValidator.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/CloudstackPartitionValidator.java
@@ -5,8 +5,8 @@ import org.apache.commons.logging.LogFactory;
import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
import org.apache.stratos.cloud.controller.iaases.Iaas;
import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
-import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
import org.apache.stratos.messaging.domain.topology.Scope;
import java.util.Properties;
@@ -31,14 +31,14 @@ public class CloudstackPartitionValidator implements PartitionValidator {
try {
IaasProvider updatedIaasProvider = new IaasProvider(iaasProvider);
- Iaas updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ Iaas updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
if (properties.containsKey(Scope.zone.toString())) {
String zone = properties.getProperty(Scope.zone.toString());
iaas.isValidZone(null, zone);
updatedIaasProvider.setProperty(CloudControllerConstants.AVAILABILITY_ZONE, zone);
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
}
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/validators/DockerPartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/DockerPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/DockerPartitionValidator.java
index 5c00c4c..4bc6d39 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/DockerPartitionValidator.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/DockerPartitionValidator.java
@@ -23,10 +23,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderException;
import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
-import org.apache.stratos.cloud.controller.iaases.AWSEC2Iaas;
+import org.apache.stratos.cloud.controller.iaases.JcloudsEC2Iaas;
import org.apache.stratos.cloud.controller.iaases.Iaas;
import org.apache.stratos.cloud.controller.domain.IaasProvider;
-import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
import java.util.Properties;
@@ -34,7 +34,7 @@ import java.util.Properties;
* Docker partition validator definition.
*/
public class DockerPartitionValidator implements PartitionValidator {
- private static final Log log = LogFactory.getLog(AWSEC2Iaas.class);
+ private static final Log log = LogFactory.getLog(JcloudsEC2Iaas.class);
private IaasProvider iaasProvider;
@@ -56,7 +56,7 @@ public class DockerPartitionValidator implements PartitionValidator {
Properties properties) {
Iaas updatedIaas;
try {
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
for (Object property : properties.keySet()) {
if (property instanceof String) {
@@ -69,7 +69,7 @@ public class DockerPartitionValidator implements PartitionValidator {
}
}
}
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
} catch (InvalidIaasProviderException ignore) {
}
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/validators/OpenstackNovaPartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/OpenstackNovaPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/OpenstackNovaPartitionValidator.java
index 1983e08..8de7fdb 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/OpenstackNovaPartitionValidator.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/validators/OpenstackNovaPartitionValidator.java
@@ -24,8 +24,8 @@ import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderExceptio
import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
import org.apache.stratos.cloud.controller.iaases.Iaas;
import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
-import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
import org.apache.stratos.messaging.domain.topology.Scope;
import java.util.Properties;
@@ -61,7 +61,7 @@ public class OpenstackNovaPartitionValidator implements PartitionValidator {
iaas.isValidRegion(region);
IaasProvider updatedIaasProvider = new IaasProvider(iaasProvider);
- Iaas updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ Iaas updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
if (properties.containsKey(Scope.zone.toString())) {
@@ -69,7 +69,7 @@ public class OpenstackNovaPartitionValidator implements PartitionValidator {
iaas.isValidZone(region, zone);
updatedIaasProvider.setProperty(CloudControllerConstants.AVAILABILITY_ZONE, zone);
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
}
@@ -92,7 +92,7 @@ public class OpenstackNovaPartitionValidator implements PartitionValidator {
Properties properties) {
Iaas updatedIaas;
try {
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
for (Object property : properties.keySet()) {
if (property instanceof String) {
@@ -105,7 +105,7 @@ public class OpenstackNovaPartitionValidator implements PartitionValidator {
}
}
}
- updatedIaas = CloudControllerUtil.getIaas(updatedIaasProvider);
+ updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
updatedIaas.setIaasProvider(updatedIaasProvider);
} catch (InvalidIaasProviderException ignore) {
}
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/services/impl/CloudControllerServiceImpl.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
index 3b5eef5..afa4723 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
@@ -111,7 +111,7 @@ public class CloudControllerServiceImpl implements CloudControllerService {
}
for (IaasProvider iaasProvider : iaasProviders) {
- CloudControllerUtil.getIaas(iaasProvider);
+ CloudControllerServiceUtil.buildIaas(iaasProvider);
}
}
@@ -413,7 +413,7 @@ public class CloudControllerServiceImpl implements CloudControllerService {
log.debug("Iaas is null of Iaas Provider: " + type + ". Trying to build IaaS...");
}
try {
- iaas = CloudControllerUtil.getIaas(iaasProvider);
+ iaas = CloudControllerServiceUtil.buildIaas(iaasProvider);
} catch (InvalidIaasProviderException e) {
String msg = "Instance start up failed. " + memberContext.toString() +
"Unable to build Iaas of this IaasProvider [Provider] : " + type + ". Cause: " + e.getMessage();
@@ -439,16 +439,7 @@ public class CloudControllerServiceImpl implements CloudControllerService {
addToPayload(payload, "PERSISTENCE_MAPPING", getPersistencePayload(ctxt, iaas).toString());
}
iaasProvider.setPayload(payload.toString().getBytes());
- iaas.setDynamicPayload();
-
- if (iaasProvider.getTemplate() == null) {
- String msg =
- "Failed to start an instance. " +
- memberContext.toString() +
- ". Reason : Jclouds Template is null for iaas provider [type]: " + iaasProvider.getType();
- log.error(msg);
- throw new InvalidIaasProviderException(msg);
- }
+ iaas.setDynamicPayload(iaasProvider.getPayload());
//Start instance start up in a new thread
ThreadExecutor exec = ThreadExecutor.getInstance();
@@ -533,25 +524,25 @@ public class CloudControllerServiceImpl implements CloudControllerService {
handleNullObject(memberId, "Termination failed. Null member id.");
- MemberContext ctxt = CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId);
+ MemberContext memberContext = CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId);
- if (ctxt == null) {
+ if (memberContext == null) {
String msg = "Termination failed. Invalid Member Id: " + memberId;
log.error(msg);
throw new InvalidMemberException(msg);
}
- if (ctxt.getNodeId() == null && ctxt.getInstanceId() == null) {
+ if (memberContext.getNodeId() == null && memberContext.getInstanceId() == null) {
// sending member terminated since this instance isn't reachable.
if (log.isInfoEnabled()){
log.info(String.format(
"Member cannot be terminated because it is not reachable. [member] %s [nodeId] %s [instanceId] %s. Removing member from topology.",
- ctxt.getMemberId(),
- ctxt.getNodeId(),
- ctxt.getInstanceId()));
+ memberContext.getMemberId(),
+ memberContext.getNodeId(),
+ memberContext.getInstanceId()));
}
- CloudControllerServiceUtil.logTermination(ctxt);
+ CloudControllerServiceUtil.logTermination(memberContext);
}
// check if status == active, if true, then this is a termination on member faulty
@@ -563,10 +554,10 @@ public class CloudControllerServiceImpl implements CloudControllerService {
TopologyManager.releaseReadLock();
}
- org.apache.stratos.messaging.domain.topology.Service service = topology.getService(ctxt.getCartridgeType());
+ org.apache.stratos.messaging.domain.topology.Service service = topology.getService(memberContext.getCartridgeType());
if (service != null) {
- Cluster cluster = service.getCluster(ctxt.getClusterId());
+ Cluster cluster = service.getCluster(memberContext.getClusterId());
if (cluster != null) {
Member member = cluster.getMember(memberId);
@@ -575,19 +566,19 @@ public class CloudControllerServiceImpl implements CloudControllerService {
// change member status if termination on a faulty member
if(fixMemberStatus(member, topology)){
// set the time this member was added to ReadyToShutdown status
- ctxt.setObsoleteInitTime(System.currentTimeMillis());
+ memberContext.setObsoleteInitTime(System.currentTimeMillis());
}
// check if ready to shutdown member is expired and send
// member terminated if it is.
- if (isMemberExpired(member, ctxt.getObsoleteInitTime(), ctxt.getObsoleteExpiryTime())) {
+ if (isMemberExpired(member, memberContext.getObsoleteInitTime(), memberContext.getObsoleteExpiryTime())) {
if (log.isInfoEnabled()) {
log.info(String.format(
"Member pending termination in ReadyToShutdown state exceeded expiry time. This member has to be manually deleted: %s",
- ctxt.getMemberId()));
+ memberContext.getMemberId()));
}
- CloudControllerServiceUtil.logTermination(ctxt);
+ CloudControllerServiceUtil.logTermination(memberContext);
return;
}
}
@@ -595,7 +586,7 @@ public class CloudControllerServiceImpl implements CloudControllerService {
}
ThreadExecutor exec = ThreadExecutor.getInstance();
- exec.execute(new InstanceTerminator(ctxt));
+ exec.execute(new InstanceTerminator(memberContext));
}
@@ -890,7 +881,7 @@ public class CloudControllerServiceImpl implements CloudControllerService {
for (Volume volume : ctxt.getVolumes()) {
if (volume.getId() != null) {
String iaasType = volume.getIaasType();
- //Iaas iaas = CloudControllerContext.getInstance().getIaasProvider(iaasType).getIaas();
+ //Iaas iaas = CloudControllerContext.getInstance().getIaasProvider(iaasType).buildComputeServiceAndTemplate();
Iaas iaas = cartridge.getIaasProvider(iaasType).getIaas();
if (iaas != null) {
try {
@@ -1062,7 +1053,7 @@ public class CloudControllerServiceImpl implements CloudControllerService {
if (iaas == null) {
try {
- iaas = CloudControllerUtil.getIaas(iaasProvider);
+ iaas = CloudControllerServiceUtil.buildIaas(iaasProvider);
} catch (InvalidIaasProviderException e) {
String msg =
"Invalid Partition - " + partition.toString() +
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/services/impl/CloudControllerServiceUtil.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceUtil.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceUtil.java
index 056d991..0afb524 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceUtil.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceUtil.java
@@ -32,10 +32,13 @@ import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderExceptio
import org.apache.stratos.cloud.controller.iaases.Iaas;
import org.apache.stratos.cloud.controller.messaging.publisher.CartridgeInstanceDataPublisher;
import org.apache.stratos.cloud.controller.messaging.topology.TopologyBuilder;
-import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
import org.apache.stratos.messaging.domain.topology.MemberStatus;
+import org.jclouds.compute.ComputeService;
import org.jclouds.rest.ResourceNotFoundException;
+import java.lang.reflect.Constructor;
+
/**
* Cloud controller service utility methods.
*/
@@ -43,6 +46,12 @@ public class CloudControllerServiceUtil {
private static final Log log = LogFactory.getLog(CloudControllerServiceUtil.class);
+ public static Iaas buildIaas(IaasProvider iaasProvider) throws InvalidIaasProviderException {
+ Iaas iaas = iaasProvider.getIaas();
+ iaas.initialize();
+ return iaas;
+ }
+
/**
* A helper method to terminate an instance.
*
@@ -55,9 +64,8 @@ public class CloudControllerServiceUtil {
String nodeId, MemberContext ctxt) {
Iaas iaas = iaasProvider.getIaas();
if (iaas == null) {
-
try {
- iaas = CloudControllerUtil.getIaas(iaasProvider);
+ iaas = buildIaas(iaasProvider);
} catch (InvalidIaasProviderException e) {
String msg =
"Instance termination failed. " + ctxt.toString() +
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/services/impl/InstanceCreator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java
index 033dc6f..a1f38a9 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java
@@ -26,6 +26,7 @@ import org.apache.stratos.cloud.controller.context.CloudControllerContext;
import org.apache.stratos.cloud.controller.domain.*;
import org.apache.stratos.cloud.controller.exception.CloudControllerException;
import org.apache.stratos.cloud.controller.iaases.Iaas;
+import org.apache.stratos.cloud.controller.iaases.JcloudsIaas;
import org.apache.stratos.cloud.controller.messaging.publisher.CartridgeInstanceDataPublisher;
import org.apache.stratos.cloud.controller.messaging.topology.TopologyBuilder;
import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
@@ -64,225 +65,80 @@ public class InstanceCreator implements Runnable {
String clusterId = memberContext.getClusterId();
Partition partition = memberContext.getPartition();
- ClusterContext ctxt = CloudControllerContext.getInstance().getClusterContext(clusterId);
+ ClusterContext clusterContext = CloudControllerContext.getInstance().getClusterContext(clusterId);
Iaas iaas = iaasProvider.getIaas();
- String publicIp = null;
- NodeMetadata node = null;
- // generate the group id from domain name and sub domain name.
- // Should have lower-case ASCII letters, numbers, or dashes.
- // Should have a length between 3-15
- String str = clusterId.length() > 10 ? clusterId.substring(0, 10) : clusterId.substring(0, clusterId.length());
- String group = str.replaceAll("[^a-z0-9-]", "");
+ // Create instance
+ NodeMetadata node = createInstance(iaas, clusterContext, memberContext);
- try {
- ComputeService computeService = iaasProvider.getComputeService();
- Template template = iaasProvider.getTemplate();
+ // Attach volumes
+ attachVolumes(iaas, clusterContext, memberContext);
- if (log.isDebugEnabled()) {
- log.debug("Cloud Controller is delegating request to start an instance for "
- + memberContext + " to Jclouds layer.");
- }
- // create and start a node
- Set<? extends NodeMetadata> nodes = computeService
- .createNodesInGroup(group, 1, template);
- node = nodes.iterator().next();
- if (log.isDebugEnabled()) {
- log.debug("Cloud Controller received a response for the request to start "
- + memberContext + " from Jclouds layer.");
- }
-
- if (node == null) {
- String msg = "Null response received for instance start-up request to Jclouds.\n"
- + memberContext.toString();
- log.error(msg);
- throw new IllegalStateException(msg);
- }
-
- // node id
- String nodeId = node.getId();
- if (nodeId == null) {
- String msg = "Node id of the starting instance is null.\n"
- + memberContext.toString();
- log.fatal(msg);
- throw new IllegalStateException(msg);
- }
+ // Allocate IP address
+ iaas.allocateIpAddress(clusterId, memberContext, partition, cartridgeType, node);
- memberContext.setNodeId(nodeId);
- if (log.isDebugEnabled()) {
- log.debug("Node id was set. " + memberContext.toString());
- }
- // attach volumes
- if (ctxt.isVolumeRequired()) {
- // remove region prefix
- String instanceId = nodeId.indexOf('/') != -1 ? nodeId
- .substring(nodeId.indexOf('/') + 1, nodeId.length())
- : nodeId;
- memberContext.setInstanceId(instanceId);
- if (ctxt.getVolumes() != null) {
- for (Volume volume : ctxt.getVolumes()) {
- try {
- iaas.attachVolume(instanceId, volume.getId(),
- volume.getDevice());
- } catch (Exception e) {
- // continue without throwing an exception, since
- // there is an instance already running
- log.error("Attaching Volume to Instance [ "
- + instanceId + " ] failed!", e);
- }
- }
- }
- }
+ // Update topology
+ TopologyBuilder.handleMemberSpawned(cartridgeType, clusterId,
+ partition.getId(), memberContext.getPrivateIpAddress(), memberContext.getPublicIpAddress(),
+ memberContext);
- } catch (Exception e) {
- String msg = "Failed to start an instance. " + memberContext.toString() + " Cause: " + e.getMessage();
- log.error(msg, e);
- throw new IllegalStateException(msg, e);
+ // Publish instance creation statistics to BAM
+ CartridgeInstanceDataPublisher.publish(memberContext.getMemberId(),
+ memberContext.getPartition().getId(),
+ memberContext.getNetworkPartitionId(),
+ memberContext.getClusterId(),
+ cartridgeType,
+ MemberStatus.Created.toString(),
+ node);
+ } finally {
+ if(lock != null) {
+ CloudControllerContext.getInstance().releaseWriteLock(lock);
}
+ }
+ }
- try {
- if (log.isDebugEnabled()) {
- log.debug("IP allocation process started for " + memberContext);
- }
- String autoAssignIpProp =
- iaasProvider.getProperty(CloudControllerConstants.AUTO_ASSIGN_IP_PROPERTY);
-
- String pre_defined_ip =
- iaasProvider.getProperty(CloudControllerConstants.FLOATING_IP_PROPERTY);
-
- // reset ip
- String ip = "";
-
- // default behavior is autoIpAssign=false
- if (autoAssignIpProp == null ||
- (autoAssignIpProp != null && autoAssignIpProp.equals("false"))) {
-
- // check if floating ip is well defined in cartridge definition
- if (pre_defined_ip != null) {
- if (CloudControllerServiceUtil.isValidIpAddress(pre_defined_ip)) {
- if (log.isDebugEnabled()) {
- log.debug("CloudControllerServiceImpl:IpAllocator:pre_defined_ip: invoking associatePredefinedAddress" + pre_defined_ip);
- }
- ip = iaas.associatePredefinedAddress(node, pre_defined_ip);
-
- if (ip == null || "".equals(ip) || !pre_defined_ip.equals(ip)) {
- // throw exception and stop instance creation
- String msg = "Error occurred while allocating predefined floating ip address: " + pre_defined_ip +
- " / allocated ip:" + ip +
- " - terminating node:" + memberContext.toString();
- log.error(msg);
- // terminate instance
- CloudControllerServiceUtil.terminate(iaasProvider,
- node.getId(), memberContext);
- throw new CloudControllerException(msg);
- }
- } else {
- String msg = "Invalid floating ip address configured: " + pre_defined_ip +
- " - terminating node:" + memberContext.toString();
- log.error(msg);
- // terminate instance
- CloudControllerServiceUtil.terminate(iaasProvider,
- node.getId(), memberContext);
- throw new CloudControllerException(msg);
- }
-
- } else {
- if (log.isDebugEnabled()) {
- log.debug("CloudControllerServiceImpl:IpAllocator:no (valid) predefined floating ip configured, "
- + "selecting available one from pool");
- }
- // allocate an IP address - manual IP assigning mode
- ip = iaas.associateAddress(node);
-
- if (ip != null) {
- memberContext.setAllocatedIpAddress(ip);
- if (log.isDebugEnabled()) {
- log.debug("Allocated an ip address: "
- + memberContext.toString());
- } else if (log.isInfoEnabled()) {
- log.info("Allocated ip address [ " + memberContext.getAllocatedIpAddress() +
- " ] to member with id: " + memberContext.getMemberId());
- }
- }
- }
-
- if (ip == null) {
- String msg = "No IP address found. IP allocation failed for " + memberContext;
- log.error(msg);
- throw new CloudControllerException(msg);
- }
+ private NodeMetadata createInstance(Iaas iaas, ClusterContext clusterContext, MemberContext memberContext) {
+ NodeMetadata node = iaas.createInstance(clusterContext, memberContext);
- // build the node with the new ip
- node = NodeMetadataBuilder.fromNodeMetadata(node)
- .publicAddresses(ImmutableSet.of(ip)).build();
- }
+ // node id
+ String nodeId = node.getId();
+ if (nodeId == null) {
+ String msg = "Node id of the starting instance is null\n" + memberContext.toString();
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ memberContext.setNodeId(nodeId);
+ CloudControllerContext.getInstance().updateMemberContext(memberContext);
+ CloudControllerContext.getInstance().persist();
- // public ip
- if (node.getPublicAddresses() != null &&
- node.getPublicAddresses().iterator().hasNext()) {
- ip = node.getPublicAddresses().iterator().next();
- publicIp = ip;
- memberContext.setPublicIpAddress(ip);
- if (log.isDebugEnabled()) {
- log.debug("Retrieving Public IP Address : " + memberContext.toString());
- } else if (log.isInfoEnabled()) {
- log.info("Retrieving Public IP Address: " + memberContext.getPublicIpAddress() +
- ", member id: " + memberContext.getMemberId());
- }
- }
+ if (log.isDebugEnabled()) {
+ log.debug("Instance created: [node-metadata] " + node.toString());
+ }
+ return node;
+ }
- // private IP
- if (node.getPrivateAddresses() != null &&
- node.getPrivateAddresses().iterator().hasNext()) {
- ip = node.getPrivateAddresses().iterator().next();
- memberContext.setPrivateIpAddress(ip);
- if (log.isDebugEnabled()) {
- log.debug("Retrieving Private IP Address. " + memberContext.toString());
- } else if (log.isInfoEnabled()) {
- log.info("Retrieving Private IP Address: " + memberContext.getPrivateIpAddress() +
- ", member id: " + memberContext.getMemberId());
+ public void attachVolumes(Iaas iaas, ClusterContext clusterContext, MemberContext memberContext) {
+ // attach volumes
+ if (clusterContext.isVolumeRequired()) {
+ // remove region prefix
+ String nodeId = memberContext.getNodeId();
+ String instanceId = nodeId.indexOf('/') != -1 ? nodeId
+ .substring(nodeId.indexOf('/') + 1, nodeId.length())
+ : nodeId;
+ memberContext.setInstanceId(instanceId);
+ if (clusterContext.getVolumes() != null) {
+ for (Volume volume : clusterContext.getVolumes()) {
+ try {
+ iaas.attachVolume(instanceId, volume.getId(), volume.getDevice());
+ } catch (Exception e) {
+ // continue without throwing an exception, since
+ // there is an instance already running
+ log.error("Attaching volume to instance [ "
+ + instanceId + " ] failed!", e);
}
}
-
- CloudControllerContext.getInstance().addMemberContext(memberContext);
-
- // persist in registry
- CloudControllerContext.getInstance().persist();
-
-
- // trigger topology
- TopologyBuilder.handleMemberSpawned(cartridgeType, clusterId,
- partition.getId(), ip, publicIp, memberContext);
-
- String memberID = memberContext.getMemberId();
-
- // update the topology with the newly spawned member
- // publish data
- CartridgeInstanceDataPublisher.publish(memberID,
- memberContext.getPartition().getId(),
- memberContext.getNetworkPartitionId(),
- memberContext.getClusterId(),
- cartridgeType,
- MemberStatus.Created.toString(),
- node);
- if (log.isDebugEnabled()) {
- log.debug("Node details: " + node.toString());
- }
-
- if (log.isDebugEnabled()) {
- log.debug("IP allocation process ended for " + memberContext);
- }
-
- } catch (Exception e) {
- String msg = "Error occurred while allocating an ip address. " + memberContext.toString();
- log.error(msg, e);
- throw new CloudControllerException(msg, e);
- }
- } finally {
- if(lock != null) {
- CloudControllerContext.getInstance().releaseWriteLock(lock);
}
}
}
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/services/impl/InstanceTerminator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceTerminator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceTerminator.java
index 374537d..34c07e3 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceTerminator.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceTerminator.java
@@ -21,13 +21,12 @@ package org.apache.stratos.cloud.controller.services.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.config.CloudControllerConfig;
import org.apache.stratos.cloud.controller.context.CloudControllerContext;
-import org.apache.stratos.cloud.controller.domain.Cartridge;
import org.apache.stratos.cloud.controller.domain.IaasProvider;
import org.apache.stratos.cloud.controller.domain.MemberContext;
import org.apache.stratos.cloud.controller.exception.CloudControllerException;
-import org.apache.stratos.cloud.controller.exception.InvalidCartridgeTypeException;
-import org.apache.stratos.cloud.controller.exception.InvalidMemberException;
+import org.apache.stratos.cloud.controller.iaases.Iaas;
import java.util.concurrent.locks.Lock;
@@ -38,56 +37,24 @@ public class InstanceTerminator implements Runnable {
private static final Log log = LogFactory.getLog(InstanceTerminator.class);
- private MemberContext ctxt;
+ private Iaas iaas;
+ private MemberContext memberContext;
- public InstanceTerminator(MemberContext ctxt) {
- this.ctxt = ctxt;
+ public InstanceTerminator(MemberContext memberContext) {
+ String provider = memberContext.getPartition().getProvider();
+ IaasProvider iaasProvider = CloudControllerConfig.getInstance().getIaasProvider(provider);
+ this.iaas = iaasProvider.getIaas();
+ this.memberContext = memberContext;
}
@Override
public void run() {
- String memberId = ctxt.getMemberId();
- String clusterId = ctxt.getClusterId();
- String partitionId = ctxt.getPartition().getId();
- String cartridgeType = ctxt.getCartridgeType();
- String nodeId = ctxt.getNodeId();
-
Lock lock = null;
try {
- CloudControllerContext.getInstance().acquireMemberContextWriteLock();
-
- Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(cartridgeType);
- log.info("Starting to terminate an instance with member id : " + memberId +
- " in partition id: " + partitionId + " of cluster id: " + clusterId +
- " and of cartridge type: " + cartridgeType);
-
- if (cartridge == null) {
- String msg = "Termination of Member Id: " + memberId + " failed. " +
- "Cannot find a matching Cartridge for type: " +
- cartridgeType;
- log.error(msg);
- throw new InvalidCartridgeTypeException(msg);
- }
-
- // if no matching node id can be found.
- if (nodeId == null) {
- String msg = "Termination failed. Cannot find a node id for Member Id: " + memberId;
-
- // log information
- CloudControllerServiceUtil.logTermination(ctxt);
- log.error(msg);
- throw new InvalidMemberException(msg);
- }
-
- IaasProvider iaasProvider = cartridge.getIaasProviderOfPartition(partitionId);
-
- // terminate it!
- CloudControllerServiceUtil.terminate(iaasProvider, nodeId, ctxt);
-
- // log information
- CloudControllerServiceUtil.logTermination(ctxt);
+ lock = CloudControllerContext.getInstance().acquireMemberContextWriteLock();
+ iaas.terminateInstance(memberContext);
} catch (Exception e) {
- String msg = "Instance termination failed. " + ctxt.toString();
+ String msg = "Instance termination failed! " + memberContext.toString();
log.error(msg, e);
throw new CloudControllerException(msg, e);
} finally {
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/util/CloudControllerUtil.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java
index 2e4e505..2d8470b 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java
@@ -223,72 +223,8 @@ public class CloudControllerUtil {
return carInfo;
}
-
- public static Iaas setIaas(IaasProvider iaasProvider) throws InvalidIaasProviderException {
-
- Iaas iaas = loadIaas(iaasProvider);
-
- try {
- iaas.buildComputeServiceAndTemplate();
- iaasProvider.setIaas(iaas);
- return iaas;
- } 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 getIaas(IaasProvider iaasProvider) throws InvalidIaasProviderException {
- if(iaasProvider.getImage() != null) {
- return setIaas(iaasProvider);
- } else {
- return setDefaultIaas(iaasProvider);
- }
- }
-
- public static Iaas setDefaultIaas(IaasProvider iaasProvider) throws InvalidIaasProviderException {
-
- Iaas iaas = loadIaas(iaasProvider);
-
- try {
- ComputeServiceBuilderUtil.buildDefaultComputeService(iaasProvider);
- iaasProvider.setIaas(iaas);
- return iaas;
- } 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);
- }
- }
- private static Iaas loadIaas(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);
- }
- }
-
- public static void sleep(long time){
+ public static void sleep(long time){
try {
Thread.sleep(time);
} catch (InterruptedException ignore) {}
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/util/ComputeServiceBuilderUtil.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/ComputeServiceBuilderUtil.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/ComputeServiceBuilderUtil.java
index 0da7025..2cffcfb 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/ComputeServiceBuilderUtil.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/ComputeServiceBuilderUtil.java
@@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.stratos.cloud.controller.exception.CloudControllerException;
import org.apache.stratos.cloud.controller.domain.IaasProvider;
import org.jclouds.ContextBuilder;
+import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.enterprise.config.EnterpriseConfigurationModule;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
@@ -64,12 +65,12 @@ public class ComputeServiceBuilderUtil {
}
- public static void buildDefaultComputeService(IaasProvider iaas) {
+ public static ComputeService buildDefaultComputeService(IaasProvider iaasProvider) {
Properties properties = new Properties();
// load properties
- for (Map.Entry<String, String> entry : iaas.getProperties().entrySet()) {
+ for (Map.Entry<String, String> entry : iaasProvider.getProperties().entrySet()) {
properties.put(entry.getKey(), entry.getValue());
}
@@ -80,12 +81,11 @@ public class ComputeServiceBuilderUtil {
// build context
ContextBuilder builder =
- ContextBuilder.newBuilder(iaas.getProvider())
- .credentials(iaas.getIdentity(), iaas.getCredential()).modules(modules)
+ ContextBuilder.newBuilder(iaasProvider.getProvider())
+ .credentials(iaasProvider.getIdentity(), iaasProvider.getCredential()).modules(modules)
.overrides(properties);
- // set the compute service object
- iaas.setComputeService(builder.buildView(ComputeServiceContext.class).getComputeService());
+ return builder.buildView(ComputeServiceContext.class).getComputeService();
}
public static String extractRegion(IaasProvider iaas) {
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/features/cloud-controller/org.apache.stratos.cloud.controller.feature/src/main/resources/conf/cloud-controller.xml
----------------------------------------------------------------------
diff --git a/features/cloud-controller/org.apache.stratos.cloud.controller.feature/src/main/resources/conf/cloud-controller.xml b/features/cloud-controller/org.apache.stratos.cloud.controller.feature/src/main/resources/conf/cloud-controller.xml
index 8817d9a..8b6f405 100644
--- a/features/cloud-controller/org.apache.stratos.cloud.controller.feature/src/main/resources/conf/cloud-controller.xml
+++ b/features/cloud-controller/org.apache.stratos.cloud.controller.feature/src/main/resources/conf/cloud-controller.xml
@@ -50,7 +50,7 @@
same property over and over again. -->
<iaasProviders>
<!-- iaasProvider type="openstack" name="openstack specific details">
- <className>org.apache.stratos.cloud.controller.iaases.OpenstackNovaIaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsOpenstackIaas</className>
<provider>openstack-nova</provider>
<identity svns:secretAlias="cloud.controller.openstack.identity">demo:demo</identity>
<credential svns:secretAlias="cloud.controller.openstack.credential">openstack</credential>
@@ -62,10 +62,16 @@
<property name="Y" value="y" />
</iaasProvider -->
<iaasProvider type="docker" name="Docker">
- <className>org.apache.stratos.cloud.controller.iaases.DockerIaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsDockerIaas</className>
<provider>docker</provider>
<identity svns:secretAlias="cloud.controller.docker.identity">identity</identity>
<credential svns:secretAlias="cloud.controller.docker.credential">credential</credential>
</iaasProvider>
+ <iaasProvider type="mock" name="Mock">
+ <className>org.apache.stratos.cloud.controller.iaases.mock.MockIaas</className>
+ <provider>mock</provider>
+ <identity svns:secretAlias="cloud.controller.docker.identity">identity</identity>
+ <credential svns:secretAlias="cloud.controller.docker.credential">credential</credential>
+ </iaasProvider>
</iaasProviders>
</cloudController>
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/products/stratos/modules/distribution/src/bin/stratos.sh
----------------------------------------------------------------------
diff --git a/products/stratos/modules/distribution/src/bin/stratos.sh b/products/stratos/modules/distribution/src/bin/stratos.sh
index a289a87..64ed7b6 100755
--- a/products/stratos/modules/distribution/src/bin/stratos.sh
+++ b/products/stratos/modules/distribution/src/bin/stratos.sh
@@ -300,6 +300,8 @@ do
-Dfile.encoding=UTF8 \
-Ddisable.cassandra.server.startup=true \
-Djndi.properties.dir="$CARBON_HOME/repository/conf" \
+ -Dthrift.receiver.ip=localhost \
+ -Dthrift.receiver.port=7611 \
-DMETADATA_CLIENT_CONFIG_FILE="$CARBON_HOME/repository/conf/metadataservice.xml" \
org.wso2.carbon.bootstrap.Bootstrap $*
status=$?
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/tools/stratos-installer/config/all/repository/conf/cloud-controller.xml
----------------------------------------------------------------------
diff --git a/tools/stratos-installer/config/all/repository/conf/cloud-controller.xml b/tools/stratos-installer/config/all/repository/conf/cloud-controller.xml
index ee8ffe8..fe52a22 100644
--- a/tools/stratos-installer/config/all/repository/conf/cloud-controller.xml
+++ b/tools/stratos-installer/config/all/repository/conf/cloud-controller.xml
@@ -50,7 +50,7 @@
same property over and over again. -->
<iaasProviders>
<EC2_PROVIDER_STARTiaasProvider type="ec2" name="ec2 specific details">
- <className>org.apache.stratos.cloud.controller.iaases.AWSEC2Iaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsEC2Iaas</className>
<provider>aws-ec2</provider>
<identity svns:secretAlias="cloud.controller.ec2.identity">EC2_IDENTITY</identity>
<credential svns:secretAlias="cloud.controller.ec2.credential">EC2_CREDENTIAL</credential>
@@ -61,7 +61,7 @@
<property name="keyPair" value="EC2_KEYPAIR"/>
</iaasProviderEC2_PROVIDER_END>
<OPENSTACK_PROVIDER_STARTiaasProvider type="openstack" name="openstack specific details">
- <className>org.apache.stratos.cloud.controller.iaases.OpenstackNovaIaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsOpenstackIaas</className>
<provider>openstack-nova</provider>
<identity svns:secretAlias="cloud.controller.openstack.identity">OPENSTACK_IDENTITY</identity>
<credential svns:secretAlias="cloud.controller.openstack.credential">OPENSTACK_CREDENTIAL</credential>
@@ -75,7 +75,7 @@
<property name="keyPair" value="OPENSTACK_KEYPAIR"/>
</iaasProviderOPENSTACK_PROVIDER_END>
<VCLOUD_PROVIDER_STARTiaasProvider type="vcloud" name="VMware vCloud specific details">
- <className>org.apache.stratos.cloud.controller.iaases.VCloudIaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsVCloudIaas</className>
<provider>vcloud</provider>
<identity svns:secretAlias="cloud.controller.vcloud.identity">VCLOUD_IDENTITY</identity>
<credential svns:secretAlias="cloud.controller.vcloud.credential">VCLOUD_CREDENTIAL</credential>
@@ -87,7 +87,7 @@
<property name="Y" value="y" />
</iaasProviderVCLOUD_PROVIDER_END>
<GCE_PROVIDER_STARTiaasProvider type="gce" name="GCE specific details">
- <className>org.apache.stratos.cloud.controller.iaas.GCEIaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsGCEIaas</className>
<provider>google-compute-engine</provider>
<identity svns:secretAlias="cloud.controller.gce.identity">GCE_IDENTITY</identity>
<credential svns:secretAlias="cloud.controller.gce.credential">GCE_CREDENTIAL</credential>
http://git-wip-us.apache.org/repos/asf/stratos/blob/2ec3ff0e/tools/stratos-installer/config/cc/repository/conf/cloud-controller.xml
----------------------------------------------------------------------
diff --git a/tools/stratos-installer/config/cc/repository/conf/cloud-controller.xml b/tools/stratos-installer/config/cc/repository/conf/cloud-controller.xml
index 73369f1..b512eeb 100644
--- a/tools/stratos-installer/config/cc/repository/conf/cloud-controller.xml
+++ b/tools/stratos-installer/config/cc/repository/conf/cloud-controller.xml
@@ -51,7 +51,7 @@
same property over and over again. -->
<iaasProviders>
<EC2_PROVIDER_STARTiaasProvider type="ec2" name="ec2 specific details">
- <className>org.apache.stratos.cloud.controller.iaases.AWSEC2Iaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsEC2Iaas</className>
<provider>aws-ec2</provider>
<identity svns:secretAlias="cloud.controller.ec2.identity">EC2_IDENTITY</identity>
<credential svns:secretAlias="cloud.controller.ec2.credential">EC2_CREDENTIAL</credential>
@@ -62,7 +62,7 @@
<property name="keyPair" value="EC2_KEYPAIR"/>
</iaasProviderEC2_PROVIDER_END>
<OPENSTACK_PROVIDER_STARTiaasProvider type="openstack" name="openstack specific details">
- <className>org.apache.stratos.cloud.controller.iaases.OpenstackNovaIaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsOpenstackIaas</className>
<provider>openstack-nova</provider>
<identity svns:secretAlias="cloud.controller.openstack.identity">OPENSTACK_IDENTITY</identity>
<credential svns:secretAlias="cloud.controller.openstack.credential">OPENSTACK_CREDENTIAL</credential>
@@ -76,7 +76,7 @@
<property name="keyPair" value="OPENSTACK_KEYPAIR"/>
</iaasProviderOPENSTACK_PROVIDER_END>
<VCLOUD_PROVIDER_STARTiaasProvider type="vcloud" name="VMware vCloud specific details">
- <className>org.apache.stratos.cloud.controller.iaases.VCloudIaas</className>
+ <className>org.apache.stratos.cloud.controller.iaases.JcloudsVCloudIaas</className>
<provider>vcloud</provider>
<identity svns:secretAlias="cloud.controller.vcloud.identity">VCLOUD_IDENTITY</identity>
<credential svns:secretAlias="cloud.controller.vcloud.credential">VCLOUD_CREDENTIAL</credential>
[3/4] stratos git commit: Introducing a mock iaas for cloud controller
Posted by im...@apache.org.
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/JcloudsCloudStackIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsCloudStackIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsCloudStackIaas.java
new file mode 100644
index 0000000..bfe3af2
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsCloudStackIaas.java
@@ -0,0 +1,543 @@
+package org.apache.stratos.cloud.controller.iaases;
+
+
+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.exception.InvalidHostException;
+import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
+import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.cloud.controller.iaases.validators.CloudstackPartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+import org.jclouds.cloudstack.CloudStackApi;
+import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.cloudstack.domain.*;
+import org.jclouds.cloudstack.features.VolumeApi;
+import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
+import org.jclouds.cloudstack.options.ListZonesOptions;
+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.domain.Location;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
+public class JcloudsCloudStackIaas extends JcloudsIaas {
+
+ private static final Log log = LogFactory.getLog(JcloudsCloudStackIaas.class);
+
+ public JcloudsCloudStackIaas(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();
+ }
+
+ @Override
+ public void buildTemplate() {
+
+ IaasProvider iaasInfo = getIaasProvider();
+
+ //if compute service is not available
+ if (iaasInfo.getComputeService() == null) {
+ String msg = "Compute service is null for IaaS provider: "
+ + iaasInfo.getName();
+ log.error(msg);
+ throw new CloudControllerException(msg);
+ }
+
+ //create templateBuilder
+ TemplateBuilder templateBuilder = iaasInfo.getComputeService()
+ .templateBuilder();
+
+ //**SET PROPERTIES TO templateBuilder OBJECT**//
+
+ /**
+ * PROPERTY - 1
+ * set image id specified
+ */
+ templateBuilder.imageId(iaasInfo.getImage());
+
+ /**
+ * PROPERTY-2
+ * if user has specified a zone in cloud-controller.xml, set the zone into templateBuilder object
+ * (user should provide the zone id for this, because zone name is not unique in cloudstack)
+ */
+ if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+ Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
+ for (Location location : locations) {
+ if (location.getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
+ //if the zone is valid set the zone to templateBuilder Object
+ templateBuilder.locationId(location.getId());
+ log.info("Zone has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
+ + " with id: " + location.getId());
+ break;
+ }
+ }
+ }
+
+ /**
+ * PROPERTY-3
+ * if user has specified an instance type in cloud-controller.xml, set the instance type into templateBuilder
+ * object.(service offering)
+ *Important:Specify the Service Offering type ID. Not the name. Because the name is not unique in cloudstack.
+ */
+ if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
+ templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
+ }
+
+ //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?
+ */
+ boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
+ .getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
+ 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[]{});
+
+
+ //**SET CLOUDSTACK SPECIFIC PROPERTIES TO TEMPLATE OBJECT**//
+
+ //set security group - If you are using basic zone
+ if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
+ template.getOptions()
+ .as(CloudStackTemplateOptions.class)
+ .securityGroupIds(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
+ .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+ }
+
+
+ /**
+ * set network ID - If you are using advanced zone
+ * in cloudstack sometimes we get unautorized exception if we didn't specify the
+ * domain ID and user name
+ */
+ if (iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS) != null) {
+ template.getOptions()
+ .as(CloudStackTemplateOptions.class)
+ .networks(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS)
+ .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+ }
+
+ //set user name
+ if (iaasInfo.getProperty(CloudControllerConstants.USER_NAME) != null) {
+ template.getOptions().as(CloudStackTemplateOptions.class)
+ .account(iaasInfo.getProperty(CloudControllerConstants.USER_NAME));
+ }
+ //set domain ID
+ if (iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID) != null) {
+ template.getOptions().as(CloudStackTemplateOptions.class)
+ .domainId(iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID));
+ }
+
+ /**
+ *Set key pair
+ * in cloudstack sometimes we get unauthorized exception if we didn't specify the
+ * domain ID and user name
+ */
+ if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
+ template.getOptions().as(CloudStackTemplateOptions.class)
+ .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
+ }
+
+ // ability to define tags
+ if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
+ template.getOptions()
+ .as(CloudStackTemplateOptions.class)
+ .tags(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.TAGS)
+ .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+ }
+ //set disk offering to the instance
+ if (iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING) != null) {
+ template.getOptions()
+ .as(CloudStackTemplateOptions.class)
+ .diskOfferingId(iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING));
+ }
+
+ // set Template
+ iaasInfo.setTemplate(template);
+ }
+
+ @Override
+ public void setDynamicPayload(byte[] payload) {
+ IaasProvider iaasProvider = getIaasProvider();
+ if (iaasProvider.getTemplate() != null) {
+ iaasProvider.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
+ .userMetadata(convertByteArrayToHashMap(payload));
+ }
+ }
+
+ /**
+ * IMPORTANT
+ * In cloudstack we can assign public IPs, if we are using an advanced zone only. If we are using a basic zone
+ * we cannot assign public ips.
+ * <p/>
+ * When we use an advanced zone, a public IP address will get automatically assigned to the vm. So we don't need
+ * to find an unallocated IP address and assign that address to the vm. If you are using a basic zone you cannot
+ * assign public IPs
+ * <p/>
+ * So this method will find the IP that has been assigned to the vm and return it.
+ */
+ @Override
+ public String associateAddress(NodeMetadata node) {
+
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+ String ip = null;
+
+ // get all allocated IPs
+ ListPublicIPAddressesOptions listPublicIPAddressesOptions = new ListPublicIPAddressesOptions();
+ listPublicIPAddressesOptions.zoneId(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
+
+ Set<PublicIPAddress> publicIPAddresses = cloudStackApi.getAddressApi()
+ .listPublicIPAddresses(listPublicIPAddressesOptions);
+
+ String id = node.getProviderId(); //vm ID
+
+ for (PublicIPAddress publicIPAddress : publicIPAddresses) {
+ if (publicIPAddress.getVirtualMachineId().equals(id)) { //check whether this instance has
+ // already got an public ip or not
+ ip = publicIPAddress.getIPAddress(); //A public ip has been successfully assigned to the vm
+ log.info("Successfully associated an IP address " + ip
+ + " for node with id: " + node.getId());
+ break;
+ }
+
+ }
+
+ if (ip == null || ip.isEmpty()) { //IP has not been successfully assigned to VM(That means there are
+ // no more IPs available for the VM)
+ String msg = "No address associated for node with id: " + node.getId();
+ log.warn(msg);
+ throw new CloudControllerException(msg);
+ }
+
+ return ip;
+ }
+
+ @Override
+ public String associatePredefinedAddress(NodeMetadata node, String ip) {
+ return "";
+ }
+
+ @Override
+ public void releaseAddress(String ip) {
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+ cloudStackApi.getAddressApi().disassociateIPAddress(ip);
+ }
+
+ @Override
+ public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
+
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+ SshKeyPair sshKeyPair = cloudStackApi.getSSHKeyPairApi().createSSHKeyPair(keyPairName);
+
+ if (sshKeyPair != null) {
+
+ iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
+ .keyPair(sshKeyPair.getName());
+
+ log.info("A key-pair is created successfully - Key Pair Name: " + sshKeyPair.getName());
+ return true;
+ }
+ log.error("Key-pair is unable to create");
+ return false;
+ }
+
+ @Override
+ public boolean isValidRegion(String region) throws InvalidRegionException {
+
+ IaasProvider iaasInfo = getIaasProvider();
+ //no such method in Jclouds cloudstack api
+ 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();
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+ ListZonesOptions listZonesOptions = new ListZonesOptions();
+ listZonesOptions.available(true);
+ Set<Zone> zoneSet = cloudStackApi.getZoneApi().listZones(listZonesOptions);
+
+ for (org.jclouds.cloudstack.domain.Zone configuredZone : zoneSet) {
+ if (configuredZone.getName().equalsIgnoreCase(zone)) {
+ return true;
+ }
+ }
+ String msg = "Invalid zone: " + zone + " in the iaas: " + iaasInfo.getType();
+ log.error(msg);
+ throw new InvalidZoneException(msg);
+ }
+
+ @Override
+ public boolean isValidHost(String zone, String host) throws InvalidHostException {
+
+ IaasProvider iaasInfo = getIaasProvider();
+ // there's no such method in jclouds cloustack api
+ String msg = "Invalid host: " + host + " in the zone: " + zone + " and of the iaas: " + iaasInfo.getType();
+ log.error(msg);
+ throw new InvalidHostException(msg);
+
+ }
+
+ @Override
+ public PartitionValidator getPartitionValidator() {
+ return new CloudstackPartitionValidator();
+ }
+
+ @Override
+ public String createVolume(int sizeGB, String snapshotId) {
+
+ // Snapshot id is not there in IaaS.createVolume() method in stratos 4.0.0
+ //todo return volume ID if volume is created
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+ String diskOfferingID = iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
+ .getDiskOfferingId();
+ if (zone == null && diskOfferingID == null) {
+ log.error("Could not create a volume in the , [zone] : " + zone + " of Iaas : " + iaasInfo);
+ return null;
+ }
+
+ VolumeApi volumeApi = context.unwrapApi(CloudStackApi.class).getVolumeApi();
+
+ Volume volume;
+ if (StringUtils.isEmpty(snapshotId)) {
+ if (log.isInfoEnabled()) {
+ log.info("Creating a volume in the zone " + zone);
+ }
+
+ //cloudstack jcloud api does not return a volume object
+ volumeApi.createVolumeFromCustomDiskOfferingInZone(null, diskOfferingID, zone, sizeGB);
+
+ // volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
+ } else {
+ if (log.isInfoEnabled()) {
+ log.info("Creating a volume in the zone " + zone + " from the snapshot " + snapshotId);
+ }
+ volumeApi.createVolumeFromSnapshotInZone(null, diskOfferingID, zone);
+ }
+
+ return null;
+ }
+
+ @Override
+ public String attachVolume(String instanceId, String volumeId, String deviceName) {
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+
+ //get volume
+ org.jclouds.cloudstack.domain.Volume volume = cloudStackApi.getVolumeApi().getVolume(volumeId);
+
+ //get current volume state
+ Volume.State volumeState = volume.getState();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Volume " + volumeId + " is in state " + volumeState);
+ }
+
+ //if volume is not available, not allocated or cannot use
+ //volume state ALLOCATED means that volume has not been attached to any instance.
+
+ //TODO there is an error with logic.
+ if (!(volumeState == Volume.State.ALLOCATED || volumeState == Volume.State.CREATING
+ || volumeState == Volume.State.READY)) {
+ log.error(String.format("Volume %s can not be attached. Volume status is %s", volumeId, volumeState));
+ }
+
+ //check whether the account of volume and instance is same
+ if (!volume.getAccount().equals(cloudStackApi.getVirtualMachineApi()
+ .getVirtualMachine(instanceId).getAccount())) {
+ log.error(String.format("Volume %s can not be attached. Instance account and Volume account " +
+ "are not the same ", volumeId));
+ }
+
+ boolean volumeBecameAvailable = false, volumeBecameAttached = false;
+
+ try {
+ if (volumeState == Volume.State.CREATING) {
+
+ volumeBecameAvailable = waitForStatus(volumeId, Volume.State.ALLOCATED, 5);
+
+ } else if (volumeState == Volume.State.READY) {
+ volumeBecameAvailable = true;
+ }
+
+ } catch (TimeoutException e) {
+ log.error("[Volume ID] " + volumeId + "did not become ALLOCATED within expected timeout");
+ }
+
+ //if volume state is 'ALLOCATED'
+ if (volumeBecameAvailable) {
+
+ //attach volume into instance
+ cloudStackApi.getVolumeApi().attachVolume(volumeId, instanceId);
+
+ try {
+ volumeBecameAttached = waitForStatus(volumeId, Volume.State.READY, 2);
+ } catch (TimeoutException e) {
+ log.error("[Volume ID] " + volumeId + "did not become READY within expected timeout");
+ }
+ }
+
+ try {
+ // waiting 5seconds till volumes are actually attached.
+ Thread.sleep(5000);
+ } catch (InterruptedException ignored) {
+
+ }
+
+ //If volume state is not 'READY'
+ 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." +
+ " of Iaas : %s", volumeId, instanceId, iaasInfo));
+
+ return "Attaching";
+
+ }
+
+ @Override
+ public void detachVolume(String instanceId, String volumeId) {
+
+
+ IaasProvider iaasInfo = getIaasProvider();
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Starting to detach volume %s from the instance %s", volumeId, instanceId));
+ }
+
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+
+ cloudStackApi.getVolumeApi().detachVolume(volumeId);
+
+ try {
+ //TODO this is true only for newly created volumes
+ if (waitForStatus(volumeId, Volume.State.ALLOCATED, 5)) {
+ log.info(String.format("Detachment of Volume [id]: %s from instance [id]: %s was successful of Iaas : %s", volumeId, instanceId, iaasInfo));
+ }
+ } catch (TimeoutException e) {
+ log.error(String.format("Detachment of Volume [id]: %s from instance [id]: %s was unsuccessful. [volume Status] : %s", volumeId, instanceId, iaasInfo));
+ }
+
+ }
+
+ @Override
+ public void deleteVolume(String volumeId) {
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+ cloudStackApi.getVolumeApi().deleteVolume(volumeId);
+ log.info("Deletion of Volume [id]: " + volumeId + " was successful. "
+ + " of Iaas : " + iaasInfo);
+ }
+
+ @Override
+ public String getIaasDevice(String device) {//todo implement this method(auto generated method)
+ return null;
+ }
+
+ private boolean waitForStatus(String volumeId, Volume.State expectedStatus, int timeoutInMilliseconds) throws TimeoutException {
+ int timeout = 1000 * 60 * timeoutInMilliseconds;
+ long timout = System.currentTimeMillis() + timeout;
+
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+
+ //get volume
+ org.jclouds.cloudstack.domain.Volume volume = cloudStackApi.getVolumeApi().getVolume(volumeId);
+
+ Volume.State volumeState = volume.getState();
+
+ while (volumeState != expectedStatus) {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Volume %s is still NOT in %s. Current State=%s", volumeId, expectedStatus, volumeState));
+ }
+ if (volumeState == Volume.State.FAILED || volumeState == Volume.State.DESTROYED || volumeState == Volume.State.UNRECOGNIZED) {
+ log.error("Volume " + volumeId + " is in state" + volumeState);
+ return false;
+ }
+
+ Thread.sleep(1000);
+ volumeState = volume.getState();
+ 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;
+ }
+
+ private Map<String, String> convertByteArrayToHashMap(byte[] byteArray) {
+
+ Map<String, String> map = new HashMap<String, String>();
+
+ String stringFromByteArray = new String(byteArray);
+ String[] keyValuePairs = stringFromByteArray.split(",");
+
+ for (String keyValuePair : keyValuePairs) {
+ String[] keyValue = keyValuePair.split("=");
+ if (keyValue.length > 1) {
+ map.put(keyValue[0], keyValue[1]);
+ }
+ }
+
+ return map;
+ }
+}
\ No newline at end of file
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/JcloudsDockerIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsDockerIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsDockerIaas.java
new file mode 100644
index 0000000..22feae0
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsDockerIaas.java
@@ -0,0 +1,152 @@
+/*
+ * 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.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.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.iaases.validators.DockerPartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+
+import java.util.Set;
+
+/**
+ * Docker iaas provider definition.
+ */
+public class JcloudsDockerIaas extends JcloudsIaas {
+
+ private static final Log log = LogFactory.getLog(JcloudsEC2Iaas.class);
+
+ public JcloudsDockerIaas(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();
+ }
+
+ @Override
+ public void setDynamicPayload(byte[] payload) {
+ log.warn("Not implemented: DockerIaas.setDynamicPayload()");
+ }
+
+ @Override
+ public String associateAddress(NodeMetadata node) {
+ log.warn("Not implemented: DockerIaas.associateAddress()");
+ return null;
+ }
+
+ @Override
+ public String associatePredefinedAddress(NodeMetadata node, String ip) {
+ log.warn("Not implemented: DockerIaas.associatePredefinedAddress()");
+ return null;
+ }
+
+ @Override
+ public void releaseAddress(String ip) {
+ log.warn("Not implemented: DockerIaas.releaseAddress()");
+ }
+
+ @Override
+ public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
+ return false;
+ }
+
+ @Override
+ public boolean isValidRegion(String region) throws InvalidRegionException {
+ return true;
+ }
+
+ @Override
+ public boolean isValidZone(String region, String zone) throws InvalidZoneException {
+ return true;
+ }
+
+ @Override
+ public boolean isValidHost(String zone, String host) throws InvalidHostException {
+ return true;
+ }
+
+ @Override
+ public PartitionValidator getPartitionValidator() {
+ return new DockerPartitionValidator();
+ }
+
+ @Override
+ public void buildTemplate() {
+ IaasProvider iaasProvider = getIaasProvider();
+ ComputeService computeService = iaasProvider.getComputeService();
+ Set<? extends Image> images = computeService.listImages();
+ Image image = findImage(images, iaasProvider.getImage());
+ if(image == null) {
+ throw new CloudControllerException(String.format("Docker image not found: %s", iaasProvider.getImage()));
+ }
+ Template template = computeService.templateBuilder().fromImage(image).build();
+ iaasProvider.setTemplate(template);
+ }
+
+ private Image findImage(Set<? extends Image> images, String name) {
+ for(Image image : images) {
+ if(image.getDescription().contains(name))
+ return image;
+ }
+ return null;
+ }
+
+ @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;
+ }
+}
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/JcloudsEC2Iaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsEC2Iaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsEC2Iaas.java
new file mode 100644
index 0000000..a66e656
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsEC2Iaas.java
@@ -0,0 +1,634 @@
+/*
+ * 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 com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+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.exception.InvalidHostException;
+import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
+import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.domain.NetworkInterface;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
+import org.apache.stratos.cloud.controller.iaases.validators.AWSEC2PartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
+import org.jclouds.aws.ec2.features.AWSKeyPairApi;
+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.domain.Location;
+import org.jclouds.ec2.domain.Attachment;
+import org.jclouds.ec2.domain.AvailabilityZoneInfo;
+import org.jclouds.ec2.domain.KeyPair;
+import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
+import org.jclouds.ec2.domain.Volume;
+import org.jclouds.ec2.features.AvailabilityZoneAndRegionApi;
+import org.jclouds.ec2.features.ElasticBlockStoreApi;
+import org.jclouds.ec2.features.ElasticIPAddressApi;
+import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions;
+import org.jclouds.ec2.options.DetachVolumeOptions;
+
+import java.util.*;
+
+public class JcloudsEC2Iaas extends JcloudsIaas {
+
+ public JcloudsEC2Iaas(IaasProvider iaasProvider) {
+ super(iaasProvider);
+ }
+
+ private static final Log log = LogFactory.getLog(JcloudsEC2Iaas.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 ";
+
+ @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());
+
+ if(!(iaasInfo instanceof IaasProvider)) {
+ templateBuilder.locationId(iaasInfo.getType());
+ }
+
+ if(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+ Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
+ for(Location location : locations) {
+ if(location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) &&
+ location.getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
+ templateBuilder.locationId(location.getId());
+ log.info("ZONE has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
+ + " with id: " + location.getId());
+ break;
+ }
+ }
+ }
+
+ if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
+ // set instance type eg: m1.large
+ templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
+ }
+
+ // build the Template
+ Template template = templateBuilder.build();
+
+ if(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+ if(!template.getLocation().getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
+ log.warn("couldn't find assignable ZONE of id :" +
+ iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) + " in the IaaS. " +
+ "Hence using the default location as " + template.getLocation().getScope().toString() +
+ " with the id " + template.getLocation().getId());
+ }
+ }
+
+ // 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?
+ boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
+ .getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
+ 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[] {});
+
+ // set EC2 specific options
+
+
+ if (iaasInfo.getProperty(CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS) != null) {
+ boolean associatePublicIp = Boolean.parseBoolean(iaasInfo.getProperty(
+ CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS));
+ if(associatePublicIp){
+ template.getOptions().as(AWSEC2TemplateOptions.class)
+ .associatePublicIpAddress();
+ }
+ }
+
+ if (iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID) != null) {
+ template.getOptions().as(AWSEC2TemplateOptions.class)
+ .subnetId(iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID));
+ }
+
+ if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+ template.getOptions().as(AWSEC2TemplateOptions.class)
+ .placementGroup(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
+ }
+
+ // security group names
+ if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS) != null) {
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .securityGroups(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS).split(
+ CloudControllerConstants.ENTRY_SEPARATOR));
+
+ }
+
+ // ability to define tags
+ if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .tags(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.TAGS)
+ .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+
+ }
+
+ // ability to define tags with Key-value pairs
+ Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
+
+ for (String propertyKey : iaasInfo.getProperties().keySet()){
+ if(propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) {
+ keyValuePairTagsMap.put(propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()),
+ iaasInfo.getProperties().get(propertyKey));
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .userMetadata(keyValuePairTagsMap);
+ }
+
+ }
+
+
+ if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
+ template.getOptions()
+ .as(AWSEC2TemplateOptions.class)
+ .securityGroupIds(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
+ .split(CloudControllerConstants.ENTRY_SEPARATOR));
+
+ }
+
+
+ if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
+ template.getOptions().as(AWSEC2TemplateOptions.class)
+ .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
+ }
+
+
+
+ if (iaasInfo.getNetworkInterfaces() != null) {
+ List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length);
+ for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) {
+ networks.add(ni.getNetworkUuid());
+ }
+ template.getOptions().as(AWSEC2TemplateOptions.class).networks(networks);
+ }
+
+ // set Template
+ iaasInfo.setTemplate(template);
+ }
+
+ @Override
+ public void setDynamicPayload(byte[] payload) {
+ IaasProvider iaasProvider = getIaasProvider();
+ if (iaasProvider.getTemplate() != null) {
+ iaasProvider.getTemplate().getOptions().as(AWSEC2TemplateOptions.class).userData(payload);
+ }
+ }
+
+ @Override
+ public synchronized boolean createKeyPairFromPublicKey(String region, String keyPairName,
+ String publicKey) {
+
+ IaasProvider iaasInfo = getIaasProvider();
+
+ String ec2Msg = " ec2. Region: " + region + " - Key Pair Name: ";
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ AWSKeyPairApi keyPairApi = context.unwrapApi(AWSEC2Api.class).getKeyPairApiForRegion(region).get();
+
+ KeyPair keyPair = keyPairApi.importKeyPairInRegion(region, keyPairName, publicKey);
+
+ if (keyPair != null) {
+
+ iaasInfo.getTemplate().getOptions().as(AWSEC2TemplateOptions.class)
+ .keyPair(keyPair.getKeyName());
+
+ log.info(SUCCESSFUL_LOG_LINE + ec2Msg + keyPair.getKeyName());
+ return true;
+ }
+
+ log.error(FAILED_LOG_LINE + ec2Msg);
+
+ return false;
+ }
+
+ @Override
+ public synchronized String associateAddress(NodeMetadata node) {
+
+ IaasProvider iaasInfo = getIaasProvider();
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ ElasticIPAddressApi elasticIPAddressApi = context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+
+ String ip = null;
+
+ // first try to find an unassigned IP.
+ ArrayList<PublicIpInstanceIdPair> unassignedIps = Lists
+ .newArrayList(Iterables.filter(elasticIPAddressApi.describeAddressesInRegion(region, new String[0]),
+ new Predicate<PublicIpInstanceIdPair>() {
+
+ @Override
+ public boolean apply(PublicIpInstanceIdPair arg0) {
+ return arg0.getInstanceId() == null;
+ }
+
+ }));
+
+ if (!unassignedIps.isEmpty()) {
+ // try to prevent multiple parallel launches from choosing the same
+ // ip.
+ Collections.shuffle(unassignedIps);
+ ip = Iterables.getLast(unassignedIps).getPublicIp();
+ }
+
+ // if no unassigned IP is available, we'll try to allocate an IP.
+ if (ip == null || ip.isEmpty()) {
+ try {
+ ip = elasticIPAddressApi
+ .allocateAddressInRegion(region);
+ log.info("Allocated ip [" + ip + "]");
+
+ } catch (Exception e) {
+ String msg = "Failed to allocate an IP address. All IP addresses are in use.";
+ log.error(msg, e);
+ throw new CloudControllerException(msg, e);
+ }
+ }
+
+ String id = node.getProviderId();
+
+ // wait till the fixed IP address gets assigned - this is needed before
+ // we associate a
+ // public IP
+
+ while (node.getPrivateAddresses() == null) {
+ CloudControllerUtil.sleep(1000);
+ }
+
+ int retries = 0;
+ while (retries < 12 && !associatePublicIp(elasticIPAddressApi, region, ip, id)) {
+
+ // wait for 5s
+ CloudControllerUtil.sleep(5000);
+ retries++;
+ }
+
+ log.debug("Successfully associated an IP address " + ip
+ + " for node with id: " + node.getId());
+
+ return ip;
+
+ }
+
+ @Override
+ public String associatePredefinedAddress(NodeMetadata node, String ip) {
+ return "";
+ }
+
+ /**
+ * @param addressApi
+ * @param region
+ * @param ip
+ * @param id
+ */
+ private boolean associatePublicIp(ElasticIPAddressApi addressApi, String region,
+ String ip, String id) {
+ try {
+ addressApi.associateAddressInRegion(
+ region, ip, id);
+ log.info("Successfully associated public IP ");
+ return true;
+ } catch (Exception e) {
+ log.debug("Exception in associating public IP " + e.getMessage());
+ return false;
+ }
+ }
+
+ @Override
+ public synchronized void releaseAddress(String ip) {
+
+ IaasProvider iaasInfo = getIaasProvider();
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+ ElasticIPAddressApi elasticIPAddressApi = context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+
+ elasticIPAddressApi.disassociateAddressInRegion(
+ region, ip);
+ elasticIPAddressApi.releaseAddressInRegion(region,
+ ip);
+ }
+
+ @Override
+ public boolean isValidRegion(String region) throws InvalidRegionException {
+
+ IaasProvider iaasInfo = getIaasProvider();
+
+ 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();
+ Set<String> regions = context.unwrapApi(AWSEC2Api.class).getConfiguredRegions();
+ for (String configuredRegion : regions) {
+ if (region.equalsIgnoreCase(configuredRegion)) {
+ 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();
+
+ if (zone == null || iaasInfo == null) {
+ String msg =
+ "Zone or IaaSProvider is null: zone: " + zone + " - IaaSProvider: " +
+ iaasInfo;
+ log.error(msg);
+ throw new InvalidZoneException(msg);
+ }
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ AvailabilityZoneAndRegionApi zoneRegionApi = context.unwrapApi(AWSEC2Api.class).
+ getAvailabilityZoneAndRegionApiForRegion(region).get();
+
+ Set<AvailabilityZoneInfo> availabilityZones =
+ zoneRegionApi.describeAvailabilityZonesInRegion(region,
+ new DescribeAvailabilityZonesOptions[0]);
+ for (AvailabilityZoneInfo zoneInfo : availabilityZones) {
+ String configuredZone = zoneInfo.getZone();
+ if (zone.equalsIgnoreCase(configuredZone)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Found a matching 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();
+
+ // there's no such concept in EC2
+ String msg = "Invalid host: " + host +" in the zone: "+zone+ " and of the iaas: "+iaasInfo.getType();
+ log.error(msg);
+ throw new InvalidHostException(msg);
+ }
+
+ @Override
+ public PartitionValidator getPartitionValidator() {
+ return new AWSEC2PartitionValidator();
+ }
+
+ @Override
+ public String createVolume(int sizeGB, String snapshotId) {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+ String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+
+ if(region == null || zone == null) {
+ log.fatal("Cannot create a new volume in the [region] : "+region
+ +", [zone] : "+zone+" of Iaas : "+iaasInfo);
+ return null;
+ }
+
+ ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+
+ Volume volume;
+ if(StringUtils.isEmpty(snapshotId)){
+ if(log.isDebugEnabled()){
+ log.info("Creating a volume in the zone " + zone);
+ }
+ volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
+ }else{
+ if(log.isDebugEnabled()){
+ log.info("Creating a volume in the zone " + zone + " from the shanpshot " + snapshotId);
+ }
+ volume = blockStoreApi.createVolumeFromSnapshotInAvailabilityZone(zone, snapshotId);
+ }
+
+
+ if (volume == null) {
+ log.fatal("Volume creation was unsuccessful. [region] : " + region
+ + ", [zone] : " + zone + " of Iaas : " + iaasInfo);
+ return null;
+ }
+
+ log.info("Successfully created a new volume [id]: "+volume.getId()
+ +" in [region] : "+region+", [zone] : "+zone+" of Iaas : "+iaasInfo);
+ return volume.getId();
+ }
+
+ @Override
+ public String attachVolume(String instanceId, String volumeId, String deviceName) {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ ComputeServiceContext context = iaasInfo.getComputeService()
+ .getContext();
+
+ String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+ String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+ String device = deviceName == null ? "/dev/sdh" : deviceName;
+
+ if(region == null || zone == null) {
+ log.fatal("Cannot attach the volume [id]: "+volumeId+" in the [region] : "+region
+ +", [zone] : "+zone+" of Iaas : "+iaasInfo);
+ return null;
+ }
+
+ ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+
+ Volume.Status volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);
+
+ if(log.isDebugEnabled()){
+ log.debug("Volume " + volumeId + " is in state " + volumeStatus);
+ }
+
+ while(volumeStatus != Volume.Status.AVAILABLE){
+ try {
+ // TODO Use a proper mechanism to wait till volume becomes available.
+ Thread.sleep(1000);
+ volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);
+ if(log.isDebugEnabled()){
+ log.debug("Volume " + volumeId + " is still NOT in AVAILABLE. Current State=" + volumeStatus);
+ }
+ } catch (InterruptedException e) {
+ // Ignoring the exception
+ }
+ }
+ if(log.isDebugEnabled()){
+ log.debug("Volume " + volumeId + " became AVAILABLE");
+ }
+
+ Attachment attachment = blockStoreApi.attachVolumeInRegion(region, volumeId, instanceId, device);
+
+ if (attachment == null) {
+ log.fatal("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId
+ +" was unsuccessful. [region] : " + region
+ + ", [zone] : " + zone + " of Iaas : " + iaasInfo);
+ return null;
+ }
+
+ log.info("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId
+ +" was successful [status]: "+attachment.getStatus().value()+". [region] : " + region
+ + ", [zone] : " + zone + " of Iaas : " + iaasInfo);
+ return attachment.getStatus().value();
+ }
+
+ private Volume.Status getVolumeStatus(ElasticBlockStoreApi blockStoreApi, String region, String volumeId){
+ Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId);
+ Iterator<Volume> it = volumeDescriptions.iterator();
+ return it.next().getStatus();
+ }
+
+ @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("Cannot detach the volume [id]: "+volumeId+" from the instance [id]: "+instanceId
+ +" of the [region] : "+region
+ +" of Iaas : "+iaasInfo);
+ return;
+ }
+
+ ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+
+ Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId);
+ Iterator<Volume> it = volumeDescriptions.iterator();
+
+ while(it.hasNext()){
+ Volume.Status status = it.next().getStatus();
+
+ if(status == Volume.Status.AVAILABLE){
+ log.warn(String.format("Volume %s is already in AVAILABLE state. Volume seems to be detached somehow", volumeId));
+ return;
+ }
+ }
+
+ blockStoreApi.detachVolumeInRegion(region, volumeId, true, DetachVolumeOptions.Builder.fromInstance(instanceId));
+
+ log.info("Detachment of Volume [id]: "+volumeId+" from instance [id]: "+instanceId
+ +" was successful. [region] : " + region
+ + " of Iaas : " + 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("Cannot delete the volume [id]: "+volumeId+" of the [region] : "+region
+ +" of Iaas : "+iaasInfo);
+ return;
+ }
+
+ ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+ blockStoreApi.deleteVolumeInRegion(region, volumeId);
+
+ log.info("Deletion of Volume [id]: "+volumeId+" was successful. [region] : " + region
+ + " of Iaas : " + iaasInfo);
+ }
+
+ @Override
+ /*
+ Converts the user defined volume device to Ec2 specific device.
+ For example /dev/sdf is converted to /dev/xvdf
+ */
+ public String getIaasDevice(String device) {
+ String[] split = device.split("/");
+ String x = split[split.length-1];
+ StringBuilder ec2Device = new StringBuilder();
+ ec2Device.append("/" + split[1]);
+ ec2Device.append("/xvd");
+ ec2Device.append(x.charAt(x.length()-1));
+ return ec2Device.toString();
+ }
+
+
+}
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/JcloudsGCEIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsGCEIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsGCEIaas.java
new file mode 100644
index 0000000..969f65d
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsGCEIaas.java
@@ -0,0 +1,456 @@
+/*
+ * 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.*;
+
+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.domain.NetworkInterface;
+import org.apache.stratos.cloud.controller.iaases.validators.GCEPartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
+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.jclouds.ContextBuilder;
+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.domain.Location;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.features.DiskApi;
+import org.jclouds.googlecomputeengine.features.InstanceApi;
+import org.jclouds.googlecomputeengine.features.RegionApi;
+import org.jclouds.googlecomputeengine.features.ZoneApi;
+import org.jclouds.googlecomputeengine.domain.Disk;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.Region;
+import org.jclouds.googlecomputeengine.domain.Zone;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.options.AttachDiskOptions;
+import org.jclouds.googlecomputeengine.options.AttachDiskOptions.DiskType;
+
+import com.google.inject.Key;
+import com.google.inject.Injector;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+import static org.jclouds.util.Predicates2.retry;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import com.google.common.base.Predicate;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.google.common.util.concurrent.Atomics;
+
+public class JcloudsGCEIaas extends JcloudsIaas {
+
+
+ private static final Log log = LogFactory.getLog(JcloudsGCEIaas.class);
+
+ private static final String PROJECTNAME = "projectName";
+
+ public JcloudsGCEIaas(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);
+ }
+
+ log.info("gce buildTemplate");
+
+ TemplateBuilder templateBuilder = iaasInfo.getComputeService()
+ .templateBuilder();
+
+ // set image id specified
+ templateBuilder.imageId(iaasInfo.getImage());
+
+ String zone = iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE);
+ if(zone != null) {
+ Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
+ for(Location location : locations) {
+ if(location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) &&
+ location.getId().equals(zone)) {
+ templateBuilder.locationId(location.getId());
+ log.info("ZONE has been set as " + zone
+ + " with id: " + location.getId());
+ break;
+ }
+ }
+ }
+
+ if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
+ // set instance type eg: m1.large
+ templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
+ }
+
+ // build the Template
+ Template template = templateBuilder.build();
+
+ if(zone != null) {
+ if(!template.getLocation().getId().equals(zone)) {
+ log.warn("couldn't find assignable ZONE of id :" + zone +
+ " in the IaaS. Hence using the default location as " + template.getLocation().getScope().toString() +
+ " with the id " + template.getLocation().getId());
+ }
+ }
+
+ // 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);
+
+ if (zone != null) {
+ templateBuilder.locationId(zone);
+ log.debug("setting location to " + zone);
+ }
+
+ // ability to define tags with Key-value pairs
+ Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
+
+ for (String propertyKey : iaasInfo.getProperties().keySet()){
+ if(propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) {
+ keyValuePairTagsMap.put(propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()),
+ iaasInfo.getProperties().get(propertyKey));
+ template.getOptions()
+ .userMetadata(keyValuePairTagsMap);
+ }
+ log.info("usermeta data key:"+ propertyKey + " value: " + iaasInfo.getProperties().get(propertyKey));
+ }
+
+ if (iaasInfo.getNetworkInterfaces() != null) {
+ List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length);
+ for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) {
+ networks.add(ni.getNetworkUuid());
+ log.info("using network interface " + ni.getNetworkUuid());
+ }
+ template.getOptions().as(TemplateOptions.class).networks(networks);
+ log.info("using network interface " + networks);
+ }
+
+ // set Template
+ iaasInfo.setTemplate(template);
+ }
+
+ @Override
+ public void setDynamicPayload(byte[] payload) {
+ // 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 GCE not found");
+ }
+ return;
+ }
+
+ // Payload is a String value
+ String payloadStr = new String(payload);
+
+ log.info("setDynamicPayload " + payloadStr);
+
+ Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
+ keyValuePairTagsMap.put("stratos_usermetadata", payloadStr);
+ iaasInfo.getTemplate().getOptions().userMetadata(keyValuePairTagsMap);
+ }
+
+ @Override
+ public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
+
+ // Not applicable for GCE - Not called by stratos cloud controller as well
+ 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) throws InvalidRegionException {
+ IaasProvider iaasInfo = getIaasProvider();
+
+ if (region == null || iaasInfo == null) {
+ String msg = "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " + iaasInfo;
+ log.error(msg);
+ throw new InvalidRegionException(msg);
+ }
+
+ GoogleComputeEngineApi api = getGCEApi();
+ RegionApi regionApi = api.getRegionApiForProject(iaasInfo.getProperty(PROJECTNAME));
+
+ for(IterableWithMarker<Region> page : regionApi.list()) {
+ for(Region r : page) {
+ if (region.equalsIgnoreCase(r.getName())) {
+ 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();
+
+ if (zone == null || iaasInfo == null) {
+ String msg = "Zone or IaaSProvider is null: region: " + region +
+ " zone: " + zone + " - IaaSProvider: " + iaasInfo;
+ log.error(msg);
+ throw new InvalidZoneException(msg);
+ }
+
+ GoogleComputeEngineApi api = getGCEApi();
+ ZoneApi zoneApi = api.getZoneApiForProject(iaasInfo.getProperty(PROJECTNAME));
+
+ for(IterableWithMarker<Zone> page : zoneApi.list()) {
+ for(Zone z : page) {
+ if (zone.equalsIgnoreCase(z.getName())) {
+ log.debug("Found a matching 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();
+
+ // Not called by cloud controller
+ // there's no such concept in GCE
+
+ String msg = "Invalid host: " + host + " in the zone: " + zone + " and of the iaas: " + iaasInfo.getType();
+ log.error(msg);
+ throw new InvalidHostException(msg);
+ }
+
+ @Override
+ public PartitionValidator getPartitionValidator() {
+ return new GCEPartitionValidator();
+ }
+
+ @Override
+ public String createVolume(int sizeGB, String snapshotId) {
+ // generate a random diskname
+ Random rand = new Random();
+ String diskName = "stratos-disk-" + rand.nextInt(100000);
+ DiskApi diskApi = getGCEDiskApi();
+ String zone = getZone();
+
+ log.debug("Creating volume: " + diskName + " in zone: " + zone + " of size: " + sizeGB);
+
+ Operation oper = diskApi.createInZone(diskName, sizeGB, zone);
+
+ oper = waitGCEOperationDone(oper);
+ if (oper.getStatus() != Operation.Status.DONE) {
+ log.error("Failed to create volume: " + diskName + " of size: " + sizeGB +
+ " in zone: " + zone + " operation: " + oper);
+ return null;
+ }
+
+ return diskName;
+ }
+
+ @Override
+ public String attachVolume(String instanceId, String volumeId, String deviceName) {
+ DiskApi diskApi = getGCEDiskApi();
+ InstanceApi instApi = getGCEInstanceApi();
+ String zone = getZone();
+
+ log.debug("Trying to attach volume: " + volumeId + " to instance: " + instanceId +
+ " in zone: " + zone + " at devicename: " + deviceName);
+
+ Disk disk = diskApi.getInZone(zone, volumeId);
+ if (disk == null) {
+ log.error("Failed to get volume: " + volumeId + " in zone: " + zone);
+ return null;
+ }
+
+ log.debug("Found volumeId: " + volumeId + " volume: " + disk);
+
+ Operation oper = instApi.attachDiskInZone(zone, instanceId,
+ new AttachDiskOptions().type(DiskType.PERSISTENT)
+ .source(disk.getSelfLink())
+ .mode(AttachDiskOptions.DiskMode.READ_WRITE)
+ .deviceName(deviceName));
+ oper = waitGCEOperationDone(oper);
+ if (oper.getStatus() != Operation.Status.DONE) {
+ log.error("Failed to attach volume: " + volumeId + " to instance: " + instanceId +
+ " in zone: " + zone + " at device: " + deviceName + " operation: " + oper);
+ return null;
+ }
+
+ return volumeId;
+ }
+
+ @Override
+ public void detachVolume(String instanceId, String volumeId) {
+ InstanceApi instApi = getGCEInstanceApi();
+ String zone = getZone();
+ Instance inst = instApi.getInZone(zone, instanceId);
+
+ log.debug("Trying to detach volume: " + volumeId + " from instance: " + instanceId +
+ " " + inst + " in zone: " + zone);
+
+ if (inst == null) {
+ log.error("Failed to find instance: " + instanceId + " in zone: " + zone);
+ return;
+ }
+
+ for(Instance.AttachedDisk disk : inst.getDisks()) {
+ Instance.PersistentAttachedDisk persistentDisk = (Instance.PersistentAttachedDisk)disk;
+
+ log.debug("Found disk - src: " + persistentDisk.getSourceDiskName() +
+ " devicename: " + persistentDisk.getDeviceName());
+
+ if (persistentDisk.getSourceDiskName().equals(volumeId)) {
+ Operation oper = instApi.detachDiskInZone(zone, instanceId, persistentDisk.getDeviceName().get());
+ oper = waitGCEOperationDone(oper);
+ if (oper.getStatus() != Operation.Status.DONE) {
+ log.error("Failed to detach volume: " + volumeId + " to instance: " + instanceId +
+ " in zone: " + zone + " at device: " + persistentDisk.getDeviceName() +
+ " result operation: " + oper);
+ }
+ return;
+ }
+ }
+
+ log.error("Cannot find volume: " + volumeId + " in instance: " + instanceId);
+ }
+
+ @Override
+ public void deleteVolume(String volumeId) {
+ DiskApi diskApi = getGCEDiskApi();
+ String zone = getZone();
+
+ log.debug("Deleting volume: " + volumeId + " in zone: " + zone);
+
+ Operation oper = diskApi.deleteInZone(zone, volumeId);
+
+ oper = waitGCEOperationDone(oper);
+ if (oper.getStatus() != Operation.Status.DONE) {
+ log.error("Failed to delete volume: " + volumeId + " in zone: " + zone +
+ " operation: " + oper);
+ }
+ }
+
+ @Override
+ public String getIaasDevice(String device) {
+ return device;
+ }
+
+ private String getZone() {
+ IaasProvider iaasInfo = getIaasProvider();
+ return iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE);
+ }
+
+ private GoogleComputeEngineApi getGCEApi() {
+ IaasProvider iaasInfo = getIaasProvider();
+ ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+ GoogleComputeEngineApi api = context.unwrapApi(GoogleComputeEngineApi.class);
+
+ return api;
+ }
+
+ private DiskApi getGCEDiskApi() {
+ IaasProvider iaasInfo = getIaasProvider();
+ String projectName = iaasInfo.getProperty(PROJECTNAME);
+ return getGCEApi().getDiskApiForProject(projectName);
+ }
+
+ private InstanceApi getGCEInstanceApi() {
+ IaasProvider iaasInfo = getIaasProvider();
+ String projectName = iaasInfo.getProperty(PROJECTNAME);
+ return getGCEApi().getInstanceApiForProject(projectName);
+ }
+
+ private Operation waitGCEOperationDone(Operation operation) {
+ int maxWaitTime = 15; // 15 seconds
+ IaasProvider iaasInfo = getIaasProvider();
+ Injector injector = ContextBuilder.newBuilder(iaasInfo.getProvider())
+ .credentials(iaasInfo.getIdentity(), iaasInfo.getCredential())
+ .buildInjector();
+ Predicate<AtomicReference<Operation>> zoneOperationDonePredicate =
+ injector.getInstance(Key.get(new TypeLiteral<Predicate<AtomicReference<Operation>>>() {
+ }, Names.named("zone")));
+ AtomicReference<Operation> operationReference = Atomics.newReference(operation);
+ retry(zoneOperationDonePredicate, maxWaitTime, 1, SECONDS).apply(operationReference);
+
+ return operationReference.get();
+ }
+}
+
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/JcloudsIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsIaas.java
new file mode 100644
index 0000000..5d0e1ac
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/JcloudsIaas.java
@@ -0,0 +1,306 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.context.CloudControllerContext;
+import org.apache.stratos.cloud.controller.domain.*;
+import org.apache.stratos.cloud.controller.exception.CloudControllerException;
+import org.apache.stratos.cloud.controller.exception.InvalidCartridgeTypeException;
+import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderException;
+import org.apache.stratos.cloud.controller.exception.InvalidMemberException;
+import org.apache.stratos.cloud.controller.messaging.publisher.CartridgeInstanceDataPublisher;
+import org.apache.stratos.cloud.controller.messaging.topology.TopologyBuilder;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.messaging.domain.topology.MemberStatus;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.domain.Template;
+
+import java.util.Set;
+
+/**
+ * An abstraction for defining jclouds IaaS features.
+ */
+public abstract class JcloudsIaas extends Iaas {
+
+ private static final Log log = LogFactory.getLog(JcloudsIaas.class);
+
+ public JcloudsIaas(IaasProvider iaasProvider) {
+ super(iaasProvider);
+ }
+
+ /**
+ * This should build the {@link org.jclouds.compute.ComputeService} object and the {@link org.jclouds.compute.domain.Template} object,
+ * using the information from {@link org.apache.stratos.cloud.controller.domain.IaasProvider} and should set the built
+ * {@link org.jclouds.compute.ComputeService} object in the {@link org.apache.stratos.cloud.controller.domain.IaasProvider#setComputeService(org.jclouds.compute.ComputeService)}
+ * and also should set the built {@link org.jclouds.compute.domain.Template} object in the
+ * {@link org.apache.stratos.cloud.controller.domain.IaasProvider#setTemplate(org.jclouds.compute.domain.Template)}.
+ */
+ public abstract void buildComputeServiceAndTemplate();
+
+ /**
+ * Builds only the jclouds {@link org.jclouds.compute.domain.Template}
+ */
+ public abstract void buildTemplate();
+
+ /**
+ * This method should create a Key Pair corresponds to a given public key in the respective region having the name given.
+ * Also should override the value of the key pair in the {@link org.jclouds.compute.domain.Template} of this IaaS.
+ * @param region region that the key pair will get created.
+ * @param keyPairName name of the key pair. NOTE: Jclouds adds a prefix : <code>jclouds#</code>
+ * @param publicKey public key, from which the key pair will be created.
+ * @return whether the key pair creation is successful or not.
+ */
+ public abstract boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey);
+
+ /**
+ * This will obtain an IP address from the allocated list and associate that IP with this node.
+ * @param node Node to be associated with an IP.
+ * @return associated public IP.
+ */
+ public abstract String associateAddress(NodeMetadata node);
+
+ /**
+ * This will obtain a predefined IP address and associate that IP with this node, if ip is already in use allocate ip from pool
+ * (through associateAddress())
+ * @param node Node to be associated with an IP.
+ * @ip preallocated floating Ip
+ * @return associated public IP.
+ */
+ public abstract String associatePredefinedAddress(NodeMetadata node, String ip);
+
+ @Override
+ public void initialize() {
+ try {
+ JcloudsIaasUtil.buildComputeServiceAndTemplate(getIaasProvider());
+ } catch (InvalidIaasProviderException e) {
+ log.error("Could not initialize jclouds IaaS", e);
+ }
+ }
+
+ @Override
+ public NodeMetadata createInstance(ClusterContext clusterContext, MemberContext memberContext) {
+ NodeMetadata node = null;
+ // generate the group id from domain name and sub domain name.
+ // Should have lower-case ASCII letters, numbers, or dashes.
+ // Should have a length between 3-15
+ String clusterId = clusterContext.getClusterId();
+ String str = clusterId.length() > 10 ? clusterId.substring(0, 10) : clusterId.substring(0, clusterId.length());
+ String group = str.replaceAll("[^a-z0-9-]", "");
+
+ try {
+ ComputeService computeService = getIaasProvider().getComputeService();
+ Template template = getIaasProvider().getTemplate();
+
+ if (template == null) {
+ String msg = "Could not start an instance, jclouds template is null for iaas provider [type]: " +
+ getIaasProvider().getType();
+ log.error(msg);
+ throw new InvalidIaasProviderException(msg);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Cloud Controller is delegating request to start an instance for "
+ + memberContext + " to Jclouds layer.");
+ }
+ // create and start a node
+ Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(group, 1, template);
+ node = nodes.iterator().next();
+ if (log.isDebugEnabled()) {
+ log.debug("Cloud Controller received a response for the request to start "
+ + memberContext + " from Jclouds layer.");
+ }
+
+ if (node == null) {
+ String msg = "Null response received for instance start-up request to Jclouds.\n"
+ + memberContext.toString();
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ } catch (Exception e) {
+ String msg = "Failed to start an instance. " + memberContext.toString() + " Cause: " + e.getMessage();
+ log.error(msg, e);
+ throw new IllegalStateException(msg, e);
+ }
+ return node;
+ }
+
+ public void allocateIpAddress(String clusterId, MemberContext memberContext, Partition partition,
+ String cartridgeType, NodeMetadata node) {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("IP allocation process started for " + memberContext);
+ }
+ String autoAssignIpProp = getIaasProvider().getProperty(CloudControllerConstants.AUTO_ASSIGN_IP_PROPERTY);
+ String preDefinedIp = getIaasProvider().getProperty(CloudControllerConstants.FLOATING_IP_PROPERTY);
+ String publicIp = "";
+ String ip = "";
+
+ // default behavior is autoIpAssign=false
+ if ((autoAssignIpProp == null) || ((autoAssignIpProp != null) && autoAssignIpProp.equals("false"))) {
+
+ // check if floating ip is well defined in cartridge definition
+ if (preDefinedIp != null) {
+ if (CloudControllerServiceUtil.isValidIpAddress(preDefinedIp)) {
+ if (log.isDebugEnabled()) {
+ log.debug("CloudControllerServiceImpl:IpAllocator:preDefinedIp: invoking associatePredefinedAddress" + preDefinedIp);
+ }
+ ip = associatePredefinedAddress(node, preDefinedIp);
+
+ if (ip == null || "".equals(ip) || !preDefinedIp.equals(ip)) {
+ // throw exception and stop instance creation
+ String msg = "Error occurred while allocating predefined floating ip address: " + preDefinedIp +
+ " / allocated ip:" + ip +
+ " - terminating node:" + memberContext.toString();
+ log.error(msg);
+ // terminate instance
+ CloudControllerServiceUtil.terminate(getIaasProvider(),
+ node.getId(), memberContext);
+ throw new CloudControllerException(msg);
+ }
+ } else {
+ String msg = "Invalid floating ip address configured: " + preDefinedIp +
+ " - terminating node:" + memberContext.toString();
+ log.error(msg);
+ // terminate instance
+ CloudControllerServiceUtil.terminate(getIaasProvider(), node.getId(), memberContext);
+ throw new CloudControllerException(msg);
+ }
+
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("CloudControllerServiceImpl:IpAllocator:no (valid) predefined floating ip configured, "
+ + "selecting available one from pool");
+ }
+ // allocate an IP address - manual IP assigning mode
+ ip = associateAddress(node);
+
+ if (ip != null) {
+ memberContext.setAllocatedIpAddress(ip);
+ if (log.isDebugEnabled()) {
+ log.debug("Allocated an ip address: "
+ + memberContext.toString());
+ } else if (log.isInfoEnabled()) {
+ log.info("Allocated ip address [ " + memberContext.getAllocatedIpAddress() +
+ " ] to member with id: " + memberContext.getMemberId());
+ }
+ }
+ }
+
+ if (ip == null) {
+ String msg = "No IP address found. IP allocation failed for " + memberContext;
+ log.error(msg);
+ throw new CloudControllerException(msg);
+ }
+
+ // build the node with the new ip
+ node = NodeMetadataBuilder.fromNodeMetadata(node)
+ .publicAddresses(ImmutableSet.of(ip)).build();
+ }
+
+
+ // public ip
+ if (node.getPublicAddresses() != null &&
+ node.getPublicAddresses().iterator().hasNext()) {
+ ip = node.getPublicAddresses().iterator().next();
+ publicIp = ip;
+ memberContext.setPublicIpAddress(ip);
+ if (log.isDebugEnabled()) {
+ log.debug("Retrieving Public IP Address : " + memberContext.toString());
+ } else if (log.isInfoEnabled()) {
+ log.info("Retrieving Public IP Address: " + memberContext.getPublicIpAddress() +
+ ", member id: " + memberContext.getMemberId());
+ }
+ }
+
+ // private IP
+ if (node.getPrivateAddresses() != null &&
+ node.getPrivateAddresses().iterator().hasNext()) {
+ ip = node.getPrivateAddresses().iterator().next();
+ memberContext.setPrivateIpAddress(ip);
+ if (log.isDebugEnabled()) {
+ log.debug("Retrieving Private IP Address. " + memberContext.toString());
+ } else if (log.isInfoEnabled()) {
+ log.info("Retrieving Private IP Address: " + memberContext.getPrivateIpAddress() +
+ ", member id: " + memberContext.getMemberId());
+ }
+ }
+
+ CloudControllerContext.getInstance().updateMemberContext(memberContext);
+
+ // persist in registry
+ CloudControllerContext.getInstance().persist();
+
+ if (log.isDebugEnabled()) {
+ log.debug("IP allocation process ended for " + memberContext);
+ }
+
+ } catch (Exception e) {
+ String msg = "Error occurred while allocating an ip address. " + memberContext.toString();
+ log.error(msg, e);
+ throw new CloudControllerException(msg, e);
+ }
+ }
+
+ public void terminateInstance(MemberContext memberContext) throws InvalidCartridgeTypeException, InvalidMemberException {
+
+ String memberId = memberContext.getMemberId();
+ String clusterId = memberContext.getClusterId();
+ String partitionId = memberContext.getPartition().getId();
+ String cartridgeType = memberContext.getCartridgeType();
+ String nodeId = memberContext.getNodeId();
+ Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(cartridgeType);
+
+ log.info("Starting to terminate an instance with member id : " + memberId +
+ " in partition id: " + partitionId + " of cluster id: " + clusterId +
+ " and of cartridge type: " + cartridgeType);
+
+ if (cartridge == null) {
+ String msg = "Termination of Member Id: " + memberId + " failed. " +
+ "Cannot find a matching Cartridge for type: " +
+ cartridgeType;
+ log.error(msg);
+ throw new InvalidCartridgeTypeException(msg);
+ }
+
+ // if no matching node id can be found.
+ if (nodeId == null) {
+ String msg = "Termination failed. Cannot find a node id for Member Id: " + memberId;
+
+ // log information
+ CloudControllerServiceUtil.logTermination(memberContext);
+ log.error(msg);
+ throw new InvalidMemberException(msg);
+ }
+
+ IaasProvider iaasProvider = cartridge.getIaasProviderOfPartition(partitionId);
+
+ // terminate it!
+ CloudControllerServiceUtil.terminate(iaasProvider, nodeId, memberContext);
+
+ // log information
+ CloudControllerServiceUtil.logTermination(memberContext);
+ }
+}
[4/4] stratos git commit: Introducing a mock iaas for cloud controller
Posted by im...@apache.org.
Introducing a mock iaas for cloud controller
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/2ec3ff0e
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/2ec3ff0e
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/2ec3ff0e
Branch: refs/heads/mock-iaas
Commit: 2ec3ff0ed41b347627629951eb51924f5ed5c518
Parents: 283d21d
Author: Imesh Gunaratne <im...@apache.org>
Authored: Sun Dec 7 13:27:53 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sun Dec 7 13:27:53 2014 +0530
----------------------------------------------------------------------
.../concurrent/PartitionValidatorCallable.java | 5 +-
.../context/CloudControllerContext.java | 17 +
.../cloud/controller/domain/IaasProvider.java | 6 +-
.../cloud/controller/iaases/AWSEC2Iaas.java | 637 -------------------
.../cloud/controller/iaases/CloudstackIaas.java | 540 ----------------
.../cloud/controller/iaases/DockerIaas.java | 151 -----
.../cloud/controller/iaases/GCEIaas.java | 459 -------------
.../stratos/cloud/controller/iaases/Iaas.java | 135 ++--
.../iaases/JcloudsCloudStackIaas.java | 543 ++++++++++++++++
.../controller/iaases/JcloudsDockerIaas.java | 152 +++++
.../cloud/controller/iaases/JcloudsEC2Iaas.java | 634 ++++++++++++++++++
.../cloud/controller/iaases/JcloudsGCEIaas.java | 456 +++++++++++++
.../cloud/controller/iaases/JcloudsIaas.java | 306 +++++++++
.../controller/iaases/JcloudsIaasUtil.java | 90 +++
.../controller/iaases/JcloudsOpenstackIaas.java | 559 ++++++++++++++++
.../controller/iaases/JcloudsVCloudIaas.java | 261 ++++++++
.../controller/iaases/OpenstackNovaIaas.java | 567 -----------------
.../cloud/controller/iaases/VCloudIaas.java | 262 --------
.../iaases/mock/MockIPAddressPool.java | 99 +++
.../cloud/controller/iaases/mock/MockIaas.java | 176 +++++
.../controller/iaases/mock/MockMember.java | 85 +++
.../iaases/mock/MockMemberContext.java | 68 ++
.../iaases/mock/MockMemberEventPublisher.java | 122 ++++
.../iaases/mock/MockNodeMetadata.java | 143 +++++
.../iaases/mock/MockPartitionValidator.java | 44 ++
.../MockHealthStatisticsNotifier.java | 82 +++
.../MockHealthStatisticsPublisher.java | 89 +++
.../validators/AWSEC2PartitionValidator.java | 10 +-
.../CloudstackPartitionValidator.java | 6 +-
.../validators/DockerPartitionValidator.java | 10 +-
.../OpenstackNovaPartitionValidator.java | 10 +-
.../impl/CloudControllerServiceImpl.java | 47 +-
.../impl/CloudControllerServiceUtil.java | 14 +-
.../services/impl/InstanceCreator.java | 264 ++------
.../services/impl/InstanceTerminator.java | 57 +-
.../controller/util/CloudControllerUtil.java | 66 +-
.../util/ComputeServiceBuilderUtil.java | 12 +-
.../main/resources/conf/cloud-controller.xml | 10 +-
.../modules/distribution/src/bin/stratos.sh | 2 +
.../all/repository/conf/cloud-controller.xml | 8 +-
.../cc/repository/conf/cloud-controller.xml | 6 +-
41 files changed, 4136 insertions(+), 3074 deletions(-)
----------------------------------------------------------------------
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/concurrent/PartitionValidatorCallable.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java
index 0b56eee..1b4a646 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java
@@ -27,6 +27,7 @@ import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderExceptio
import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
import org.apache.stratos.cloud.controller.domain.Cartridge;
import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
import org.apache.stratos.cloud.controller.iaases.Iaas;
import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
@@ -62,9 +63,8 @@ public class PartitionValidatorCallable implements Callable<IaasProvider> {
Iaas iaas = iaasProvider.getIaas();
if (iaas == null) {
-
try {
- iaas = CloudControllerUtil.getIaas(iaasProvider);
+ iaas = CloudControllerServiceUtil.buildIaas(iaasProvider);
} catch (InvalidIaasProviderException e) {
String msg =
"Invalid Partition - " + partition.toString() +
@@ -72,7 +72,6 @@ public class PartitionValidatorCallable implements Callable<IaasProvider> {
log.error(msg, e);
throw new InvalidPartitionException(msg, e);
}
-
}
PartitionValidator validator = iaas.getPartitionValidator();
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/context/CloudControllerContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java
index ff2dc62..56ddd48 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java
@@ -326,6 +326,23 @@ public class CloudControllerContext implements Serializable {
}
}
+ public void updateMemberContext(MemberContext memberContext) {
+ memberIdToMemberContextMap.put(memberContext.getMemberId(), memberContext);
+
+ List<MemberContext> memberContextList;
+ if ((memberContextList = clusterIdToMemberContextListMap.get(memberContext.getClusterId())) == null) {
+ memberContextList = new ArrayList<MemberContext>();
+ }
+ if (memberContextList.contains(memberContext)) {
+ memberContextList.remove(memberContext);
+ }
+ memberContextList.add(memberContext);
+ clusterIdToMemberContextListMap.put(memberContext.getClusterId(), memberContextList);
+ if (log.isDebugEnabled()) {
+ log.debug("Member context updated in the cloud controller context: " + memberContext);
+ }
+ }
+
public void addScheduledFutureJob(String memberId, ScheduledFuture<?> job) {
memberIdToScheduledTaskMap.put(memberId, job);
}
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/domain/IaasProvider.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/IaasProvider.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/IaasProvider.java
index 0f5dd25..36380c8 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/IaasProvider.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/IaasProvider.java
@@ -22,7 +22,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderException;
import org.apache.stratos.cloud.controller.iaases.Iaas;
-import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
+import org.apache.stratos.cloud.controller.iaases.JcloudsIaasUtil;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.Template;
@@ -34,7 +34,7 @@ import java.util.Map;
* This is the basic data structure which holds an IaaS specific details.
* NOTE: If you add a new attribute, please assign it in the constructor too.
*/
-public class IaasProvider implements Serializable{
+public class IaasProvider implements Serializable {
private static final long serialVersionUID = -940288190885166118L;
@@ -217,7 +217,7 @@ public class IaasProvider implements Serializable{
public Iaas getIaas() {
if (iaas == null) {
try {
- iaas = CloudControllerUtil.getIaas(this);
+ iaas = JcloudsIaasUtil.createIaasInstance(this);
} catch (InvalidIaasProviderException e) {
return null;
}
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/AWSEC2Iaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
deleted file mode 100644
index 6519dfb..0000000
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
+++ /dev/null
@@ -1,637 +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 com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-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.exception.InvalidHostException;
-import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
-import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
-import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
-import org.apache.stratos.cloud.controller.domain.IaasProvider;
-import org.apache.stratos.cloud.controller.domain.NetworkInterface;
-import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
-import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
-import org.apache.stratos.cloud.controller.iaases.validators.AWSEC2PartitionValidator;
-import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
-import org.jclouds.aws.ec2.AWSEC2Api;
-import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
-import org.jclouds.aws.ec2.features.AWSKeyPairApi;
-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.domain.Location;
-import org.jclouds.ec2.domain.Attachment;
-import org.jclouds.ec2.domain.AvailabilityZoneInfo;
-import org.jclouds.ec2.domain.KeyPair;
-import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
-import org.jclouds.ec2.domain.Volume;
-import org.jclouds.ec2.features.AvailabilityZoneAndRegionApi;
-import org.jclouds.ec2.features.ElasticBlockStoreApi;
-import org.jclouds.ec2.features.ElasticIPAddressApi;
-import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions;
-import org.jclouds.ec2.options.DetachVolumeOptions;
-
-import java.util.*;
-
-public class AWSEC2Iaas extends Iaas {
-
- public AWSEC2Iaas(IaasProvider iaasProvider) {
- super(iaasProvider);
- }
-
- private static final Log log = LogFactory.getLog(AWSEC2Iaas.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 ";
-
- @Override
- public void buildComputeServiceAndTemplate() {
-
- // builds and sets Compute Service
- ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
- // 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());
-
- if(!(iaasInfo instanceof IaasProvider)) {
- templateBuilder.locationId(iaasInfo.getType());
- }
-
- if(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
- Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
- for(Location location : locations) {
- if(location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) &&
- location.getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
- templateBuilder.locationId(location.getId());
- log.info("ZONE has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
- + " with id: " + location.getId());
- break;
- }
- }
- }
-
- if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
- // set instance type eg: m1.large
- templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
- }
-
- // build the Template
- Template template = templateBuilder.build();
-
- if(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
- if(!template.getLocation().getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
- log.warn("couldn't find assignable ZONE of id :" +
- iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) + " in the IaaS. " +
- "Hence using the default location as " + template.getLocation().getScope().toString() +
- " with the id " + template.getLocation().getId());
- }
- }
-
- // 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?
- boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
- .getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
- 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[] {});
-
- // set EC2 specific options
-
-
- if (iaasInfo.getProperty(CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS) != null) {
- boolean associatePublicIp = Boolean.parseBoolean(iaasInfo.getProperty(
- CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS));
- if(associatePublicIp){
- template.getOptions().as(AWSEC2TemplateOptions.class)
- .associatePublicIpAddress();
- }
- }
-
- if (iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID) != null) {
- template.getOptions().as(AWSEC2TemplateOptions.class)
- .subnetId(iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID));
- }
-
- if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
- template.getOptions().as(AWSEC2TemplateOptions.class)
- .placementGroup(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
- }
-
- // security group names
- if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS) != null) {
- template.getOptions()
- .as(AWSEC2TemplateOptions.class)
- .securityGroups(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS).split(
- CloudControllerConstants.ENTRY_SEPARATOR));
-
- }
-
- // ability to define tags
- if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
- template.getOptions()
- .as(AWSEC2TemplateOptions.class)
- .tags(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.TAGS)
- .split(CloudControllerConstants.ENTRY_SEPARATOR)));
-
- }
-
- // ability to define tags with Key-value pairs
- Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
-
- for (String propertyKey : iaasInfo.getProperties().keySet()){
- if(propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) {
- keyValuePairTagsMap.put(propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()),
- iaasInfo.getProperties().get(propertyKey));
- template.getOptions()
- .as(AWSEC2TemplateOptions.class)
- .userMetadata(keyValuePairTagsMap);
- }
-
- }
-
-
- if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
- template.getOptions()
- .as(AWSEC2TemplateOptions.class)
- .securityGroupIds(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
- .split(CloudControllerConstants.ENTRY_SEPARATOR));
-
- }
-
-
- if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
- template.getOptions().as(AWSEC2TemplateOptions.class)
- .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
- }
-
-
-
- if (iaasInfo.getNetworkInterfaces() != null) {
- List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length);
- for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) {
- networks.add(ni.getNetworkUuid());
- }
- template.getOptions().as(AWSEC2TemplateOptions.class).networks(networks);
- }
-
- // set Template
- iaasInfo.setTemplate(template);
- }
-
- @Override
- public void setDynamicPayload() {
- IaasProvider iaasInfo = getIaasProvider();
- if (iaasInfo.getTemplate() != null && iaasInfo.getPayload() != null) {
-
- iaasInfo.getTemplate().getOptions().as(AWSEC2TemplateOptions.class)
- .userData(iaasInfo.getPayload());
- }
-
- }
-
- @Override
- public synchronized boolean createKeyPairFromPublicKey(String region, String keyPairName,
- String publicKey) {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- String ec2Msg = " ec2. Region: " + region + " - Key Pair Name: ";
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- AWSKeyPairApi keyPairApi = context.unwrapApi(AWSEC2Api.class).getKeyPairApiForRegion(region).get();
-
- KeyPair keyPair = keyPairApi.importKeyPairInRegion(region, keyPairName, publicKey);
-
- if (keyPair != null) {
-
- iaasInfo.getTemplate().getOptions().as(AWSEC2TemplateOptions.class)
- .keyPair(keyPair.getKeyName());
-
- log.info(SUCCESSFUL_LOG_LINE + ec2Msg + keyPair.getKeyName());
- return true;
- }
-
- log.error(FAILED_LOG_LINE + ec2Msg);
-
- return false;
- }
-
- @Override
- public synchronized String associateAddress(NodeMetadata node) {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- ElasticIPAddressApi elasticIPAddressApi = context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
-
- String ip = null;
-
- // first try to find an unassigned IP.
- ArrayList<PublicIpInstanceIdPair> unassignedIps = Lists
- .newArrayList(Iterables.filter(elasticIPAddressApi.describeAddressesInRegion(region, new String[0]),
- new Predicate<PublicIpInstanceIdPair>() {
-
- @Override
- public boolean apply(PublicIpInstanceIdPair arg0) {
- return arg0.getInstanceId() == null;
- }
-
- }));
-
- if (!unassignedIps.isEmpty()) {
- // try to prevent multiple parallel launches from choosing the same
- // ip.
- Collections.shuffle(unassignedIps);
- ip = Iterables.getLast(unassignedIps).getPublicIp();
- }
-
- // if no unassigned IP is available, we'll try to allocate an IP.
- if (ip == null || ip.isEmpty()) {
- try {
- ip = elasticIPAddressApi
- .allocateAddressInRegion(region);
- log.info("Allocated ip [" + ip + "]");
-
- } catch (Exception e) {
- String msg = "Failed to allocate an IP address. All IP addresses are in use.";
- log.error(msg, e);
- throw new CloudControllerException(msg, e);
- }
- }
-
- String id = node.getProviderId();
-
- // wait till the fixed IP address gets assigned - this is needed before
- // we associate a
- // public IP
-
- while (node.getPrivateAddresses() == null) {
- CloudControllerUtil.sleep(1000);
- }
-
- int retries = 0;
- while (retries < 12 && !associatePublicIp(elasticIPAddressApi, region, ip, id)) {
-
- // wait for 5s
- CloudControllerUtil.sleep(5000);
- retries++;
- }
-
- log.debug("Successfully associated an IP address " + ip
- + " for node with id: " + node.getId());
-
- return ip;
-
- }
-
- @Override
- public String associatePredefinedAddress(NodeMetadata node, String ip) {
- return "";
- }
-
- /**
- * @param addressApi
- * @param region
- * @param ip
- * @param id
- */
- private boolean associatePublicIp(ElasticIPAddressApi addressApi, String region,
- String ip, String id) {
- try {
- addressApi.associateAddressInRegion(
- region, ip, id);
- log.info("Successfully associated public IP ");
- return true;
- } catch (Exception e) {
- log.debug("Exception in associating public IP " + e.getMessage());
- return false;
- }
- }
-
- @Override
- public synchronized void releaseAddress(String ip) {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
- ElasticIPAddressApi elasticIPAddressApi = context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
-
- elasticIPAddressApi.disassociateAddressInRegion(
- region, ip);
- elasticIPAddressApi.releaseAddressInRegion(region,
- ip);
- }
-
- @Override
- public boolean isValidRegion(String region) throws InvalidRegionException {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- 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();
- Set<String> regions = context.unwrapApi(AWSEC2Api.class).getConfiguredRegions();
- for (String configuredRegion : regions) {
- if (region.equalsIgnoreCase(configuredRegion)) {
- 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();
-
- if (zone == null || iaasInfo == null) {
- String msg =
- "Zone or IaaSProvider is null: zone: " + zone + " - IaaSProvider: " +
- iaasInfo;
- log.error(msg);
- throw new InvalidZoneException(msg);
- }
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- AvailabilityZoneAndRegionApi zoneRegionApi = context.unwrapApi(AWSEC2Api.class).
- getAvailabilityZoneAndRegionApiForRegion(region).get();
-
- Set<AvailabilityZoneInfo> availabilityZones =
- zoneRegionApi.describeAvailabilityZonesInRegion(region,
- new DescribeAvailabilityZonesOptions[0]);
- for (AvailabilityZoneInfo zoneInfo : availabilityZones) {
- String configuredZone = zoneInfo.getZone();
- if (zone.equalsIgnoreCase(configuredZone)) {
- if (log.isDebugEnabled()) {
- log.debug("Found a matching 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();
-
- // there's no such concept in EC2
- String msg = "Invalid host: " + host +" in the zone: "+zone+ " and of the iaas: "+iaasInfo.getType();
- log.error(msg);
- throw new InvalidHostException(msg);
- }
-
- @Override
- public PartitionValidator getPartitionValidator() {
- return new AWSEC2PartitionValidator();
- }
-
- @Override
- public String createVolume(int sizeGB, String snapshotId) {
- IaasProvider iaasInfo = getIaasProvider();
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
- String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
-
- if(region == null || zone == null) {
- log.fatal("Cannot create a new volume in the [region] : "+region
- +", [zone] : "+zone+" of Iaas : "+iaasInfo);
- return null;
- }
-
- ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
-
- Volume volume;
- if(StringUtils.isEmpty(snapshotId)){
- if(log.isDebugEnabled()){
- log.info("Creating a volume in the zone " + zone);
- }
- volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
- }else{
- if(log.isDebugEnabled()){
- log.info("Creating a volume in the zone " + zone + " from the shanpshot " + snapshotId);
- }
- volume = blockStoreApi.createVolumeFromSnapshotInAvailabilityZone(zone, snapshotId);
- }
-
-
- if (volume == null) {
- log.fatal("Volume creation was unsuccessful. [region] : " + region
- + ", [zone] : " + zone + " of Iaas : " + iaasInfo);
- return null;
- }
-
- log.info("Successfully created a new volume [id]: "+volume.getId()
- +" in [region] : "+region+", [zone] : "+zone+" of Iaas : "+iaasInfo);
- return volume.getId();
- }
-
- @Override
- public String attachVolume(String instanceId, String volumeId, String deviceName) {
- IaasProvider iaasInfo = getIaasProvider();
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
- String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
- String device = deviceName == null ? "/dev/sdh" : deviceName;
-
- if(region == null || zone == null) {
- log.fatal("Cannot attach the volume [id]: "+volumeId+" in the [region] : "+region
- +", [zone] : "+zone+" of Iaas : "+iaasInfo);
- return null;
- }
-
- ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
-
- Volume.Status volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);
-
- if(log.isDebugEnabled()){
- log.debug("Volume " + volumeId + " is in state " + volumeStatus);
- }
-
- while(volumeStatus != Volume.Status.AVAILABLE){
- try {
- // TODO Use a proper mechanism to wait till volume becomes available.
- Thread.sleep(1000);
- volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);
- if(log.isDebugEnabled()){
- log.debug("Volume " + volumeId + " is still NOT in AVAILABLE. Current State=" + volumeStatus);
- }
- } catch (InterruptedException e) {
- // Ignoring the exception
- }
- }
- if(log.isDebugEnabled()){
- log.debug("Volume " + volumeId + " became AVAILABLE");
- }
-
- Attachment attachment = blockStoreApi.attachVolumeInRegion(region, volumeId, instanceId, device);
-
- if (attachment == null) {
- log.fatal("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId
- +" was unsuccessful. [region] : " + region
- + ", [zone] : " + zone + " of Iaas : " + iaasInfo);
- return null;
- }
-
- log.info("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId
- +" was successful [status]: "+attachment.getStatus().value()+". [region] : " + region
- + ", [zone] : " + zone + " of Iaas : " + iaasInfo);
- return attachment.getStatus().value();
- }
-
- private Volume.Status getVolumeStatus(ElasticBlockStoreApi blockStoreApi, String region, String volumeId){
- Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId);
- Iterator<Volume> it = volumeDescriptions.iterator();
- return it.next().getStatus();
- }
-
- @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("Cannot detach the volume [id]: "+volumeId+" from the instance [id]: "+instanceId
- +" of the [region] : "+region
- +" of Iaas : "+iaasInfo);
- return;
- }
-
- ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
-
- Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId);
- Iterator<Volume> it = volumeDescriptions.iterator();
-
- while(it.hasNext()){
- Volume.Status status = it.next().getStatus();
-
- if(status == Volume.Status.AVAILABLE){
- log.warn(String.format("Volume %s is already in AVAILABLE state. Volume seems to be detached somehow", volumeId));
- return;
- }
- }
-
- blockStoreApi.detachVolumeInRegion(region, volumeId, true, DetachVolumeOptions.Builder.fromInstance(instanceId));
-
- log.info("Detachment of Volume [id]: "+volumeId+" from instance [id]: "+instanceId
- +" was successful. [region] : " + region
- + " of Iaas : " + 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("Cannot delete the volume [id]: "+volumeId+" of the [region] : "+region
- +" of Iaas : "+iaasInfo);
- return;
- }
-
- ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
- blockStoreApi.deleteVolumeInRegion(region, volumeId);
-
- log.info("Deletion of Volume [id]: "+volumeId+" was successful. [region] : " + region
- + " of Iaas : " + iaasInfo);
- }
-
- @Override
- /*
- Converts the user defined volume device to Ec2 specific device.
- For example /dev/sdf is converted to /dev/xvdf
- */
- public String getIaasDevice(String device) {
- String[] split = device.split("/");
- String x = split[split.length-1];
- StringBuilder ec2Device = new StringBuilder();
- ec2Device.append("/" + split[1]);
- ec2Device.append("/xvd");
- ec2Device.append(x.charAt(x.length()-1));
- return ec2Device.toString();
- }
-
-
-}
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/CloudstackIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/CloudstackIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/CloudstackIaas.java
deleted file mode 100644
index a67fe8d..0000000
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/CloudstackIaas.java
+++ /dev/null
@@ -1,540 +0,0 @@
-package org.apache.stratos.cloud.controller.iaases;
-
-
-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.exception.InvalidHostException;
-import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
-import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
-import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
-import org.apache.stratos.cloud.controller.domain.IaasProvider;
-import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
-import org.apache.stratos.cloud.controller.iaases.validators.CloudstackPartitionValidator;
-import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
-import org.jclouds.cloudstack.CloudStackApi;
-import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
-import org.jclouds.cloudstack.domain.*;
-import org.jclouds.cloudstack.features.VolumeApi;
-import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
-import org.jclouds.cloudstack.options.ListZonesOptions;
-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.domain.Location;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeoutException;
-
-public class CloudstackIaas extends Iaas {
-
- private static final Log log = LogFactory.getLog(CloudstackIaas.class);
-
- public CloudstackIaas(IaasProvider iaasProvider) {
- super(iaasProvider);
- }
-
- @Override
- public void buildComputeServiceAndTemplate() {
- // builds and sets Compute Service
- ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
- // builds and sets Template
- buildTemplate();
- }
-
- @Override
- public void buildTemplate() {
-
- IaasProvider iaasInfo = getIaasProvider();
-
- //if compute service is not available
- if (iaasInfo.getComputeService() == null) {
- String msg = "Compute service is null for IaaS provider: "
- + iaasInfo.getName();
- log.error(msg);
- throw new CloudControllerException(msg);
- }
-
- //create templateBuilder
- TemplateBuilder templateBuilder = iaasInfo.getComputeService()
- .templateBuilder();
-
- //**SET PROPERTIES TO templateBuilder OBJECT**//
-
- /**
- * PROPERTY - 1
- * set image id specified
- */
- templateBuilder.imageId(iaasInfo.getImage());
-
- /**
- * PROPERTY-2
- * if user has specified a zone in cloud-controller.xml, set the zone into templateBuilder object
- * (user should provide the zone id for this, because zone name is not unique in cloudstack)
- */
- if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
- Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
- for (Location location : locations) {
- if (location.getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
- //if the zone is valid set the zone to templateBuilder Object
- templateBuilder.locationId(location.getId());
- log.info("Zone has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
- + " with id: " + location.getId());
- break;
- }
- }
- }
-
- /**
- * PROPERTY-3
- * if user has specified an instance type in cloud-controller.xml, set the instance type into templateBuilder
- * object.(service offering)
- *Important:Specify the Service Offering type ID. Not the name. Because the name is not unique in cloudstack.
- */
- if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
- templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
- }
-
- //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?
- */
- boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
- .getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
- 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[]{});
-
-
- //**SET CLOUDSTACK SPECIFIC PROPERTIES TO TEMPLATE OBJECT**//
-
- //set security group - If you are using basic zone
- if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
- template.getOptions()
- .as(CloudStackTemplateOptions.class)
- .securityGroupIds(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
- .split(CloudControllerConstants.ENTRY_SEPARATOR)));
- }
-
-
- /**
- * set network ID - If you are using advanced zone
- * in cloudstack sometimes we get unautorized exception if we didn't specify the
- * domain ID and user name
- */
- if (iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS) != null) {
- template.getOptions()
- .as(CloudStackTemplateOptions.class)
- .networks(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS)
- .split(CloudControllerConstants.ENTRY_SEPARATOR)));
- }
-
- //set user name
- if (iaasInfo.getProperty(CloudControllerConstants.USER_NAME) != null) {
- template.getOptions().as(CloudStackTemplateOptions.class)
- .account(iaasInfo.getProperty(CloudControllerConstants.USER_NAME));
- }
- //set domain ID
- if (iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID) != null) {
- template.getOptions().as(CloudStackTemplateOptions.class)
- .domainId(iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID));
- }
-
- /**
- *Set key pair
- * in cloudstack sometimes we get unauthorized exception if we didn't specify the
- * domain ID and user name
- */
- if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
- template.getOptions().as(CloudStackTemplateOptions.class)
- .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
- }
-
- // ability to define tags
- if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
- template.getOptions()
- .as(CloudStackTemplateOptions.class)
- .tags(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.TAGS)
- .split(CloudControllerConstants.ENTRY_SEPARATOR)));
- }
- //set disk offering to the instance
- if (iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING) != null) {
- template.getOptions()
- .as(CloudStackTemplateOptions.class)
- .diskOfferingId(iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING));
- }
-
- // set Template
- iaasInfo.setTemplate(template);
- }
-
- @Override
- public void setDynamicPayload() {
- IaasProvider iaasInfo = getIaasProvider();
- if (iaasInfo.getTemplate() != null && iaasInfo.getPayload() != null) {
- iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
- .userMetadata(convertByteArrayToHashMap(iaasInfo.getPayload()));
- }
- }
-
- /**
- * IMPORTANT
- * In cloudstack we can assign public IPs, if we are using an advanced zone only. If we are using a basic zone
- * we cannot assign public ips.
- * <p/>
- * When we use an advanced zone, a public IP address will get automatically assigned to the vm. So we don't need
- * to find an unallocated IP address and assign that address to the vm. If you are using a basic zone you cannot
- * assign public IPs
- * <p/>
- * So this method will find the IP that has been assigned to the vm and return it.
- */
- @Override
- public String associateAddress(NodeMetadata node) {
-
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
- String ip = null;
-
- // get all allocated IPs
- ListPublicIPAddressesOptions listPublicIPAddressesOptions = new ListPublicIPAddressesOptions();
- listPublicIPAddressesOptions.zoneId(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
-
- Set<PublicIPAddress> publicIPAddresses = cloudStackApi.getAddressApi()
- .listPublicIPAddresses(listPublicIPAddressesOptions);
-
- String id = node.getProviderId(); //vm ID
-
- for (PublicIPAddress publicIPAddress : publicIPAddresses) {
- if (publicIPAddress.getVirtualMachineId().equals(id)) { //check whether this instance has
- // already got an public ip or not
- ip = publicIPAddress.getIPAddress(); //A public ip has been successfully assigned to the vm
- log.info("Successfully associated an IP address " + ip
- + " for node with id: " + node.getId());
- break;
- }
-
- }
-
- if (ip == null || ip.isEmpty()) { //IP has not been successfully assigned to VM(That means there are
- // no more IPs available for the VM)
- String msg = "No address associated for node with id: " + node.getId();
- log.warn(msg);
- throw new CloudControllerException(msg);
- }
-
- return ip;
- }
-
- @Override
- public String associatePredefinedAddress(NodeMetadata node, String ip) {
- return "";
- }
-
- @Override
- public void releaseAddress(String ip) {
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
- cloudStackApi.getAddressApi().disassociateIPAddress(ip);
- }
-
- @Override
- public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
-
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
- SshKeyPair sshKeyPair = cloudStackApi.getSSHKeyPairApi().createSSHKeyPair(keyPairName);
-
- if (sshKeyPair != null) {
-
- iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
- .keyPair(sshKeyPair.getName());
-
- log.info("A key-pair is created successfully - Key Pair Name: " + sshKeyPair.getName());
- return true;
- }
- log.error("Key-pair is unable to create");
- return false;
- }
-
- @Override
- public boolean isValidRegion(String region) throws InvalidRegionException {
-
- IaasProvider iaasInfo = getIaasProvider();
- //no such method in Jclouds cloudstack api
- 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();
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
- ListZonesOptions listZonesOptions = new ListZonesOptions();
- listZonesOptions.available(true);
- Set<Zone> zoneSet = cloudStackApi.getZoneApi().listZones(listZonesOptions);
-
- for (org.jclouds.cloudstack.domain.Zone configuredZone : zoneSet) {
- if (configuredZone.getName().equalsIgnoreCase(zone)) {
- return true;
- }
- }
- String msg = "Invalid zone: " + zone + " in the iaas: " + iaasInfo.getType();
- log.error(msg);
- throw new InvalidZoneException(msg);
- }
-
- @Override
- public boolean isValidHost(String zone, String host) throws InvalidHostException {
-
- IaasProvider iaasInfo = getIaasProvider();
- // there's no such method in jclouds cloustack api
- String msg = "Invalid host: " + host + " in the zone: " + zone + " and of the iaas: " + iaasInfo.getType();
- log.error(msg);
- throw new InvalidHostException(msg);
-
- }
-
- @Override
- public PartitionValidator getPartitionValidator() {
- return new CloudstackPartitionValidator();
- }
-
- @Override
- public String createVolume(int sizeGB, String snapshotId) {
-
- // Snapshot id is not there in IaaS.createVolume() method in stratos 4.0.0
- //todo return volume ID if volume is created
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
- String diskOfferingID = iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
- .getDiskOfferingId();
- if (zone == null && diskOfferingID == null) {
- log.error("Could not create a volume in the , [zone] : " + zone + " of Iaas : " + iaasInfo);
- return null;
- }
-
- VolumeApi volumeApi = context.unwrapApi(CloudStackApi.class).getVolumeApi();
-
- Volume volume;
- if (StringUtils.isEmpty(snapshotId)) {
- if (log.isInfoEnabled()) {
- log.info("Creating a volume in the zone " + zone);
- }
-
- //cloudstack jcloud api does not return a volume object
- volumeApi.createVolumeFromCustomDiskOfferingInZone(null, diskOfferingID, zone, sizeGB);
-
- // volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
- } else {
- if (log.isInfoEnabled()) {
- log.info("Creating a volume in the zone " + zone + " from the snapshot " + snapshotId);
- }
- volumeApi.createVolumeFromSnapshotInZone(null, diskOfferingID, zone);
- }
-
- return null;
- }
-
- @Override
- public String attachVolume(String instanceId, String volumeId, String deviceName) {
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
-
- //get volume
- org.jclouds.cloudstack.domain.Volume volume = cloudStackApi.getVolumeApi().getVolume(volumeId);
-
- //get current volume state
- Volume.State volumeState = volume.getState();
-
- if (log.isDebugEnabled()) {
- log.debug("Volume " + volumeId + " is in state " + volumeState);
- }
-
- //if volume is not available, not allocated or cannot use
- //volume state ALLOCATED means that volume has not been attached to any instance.
-
- //TODO there is an error with logic.
- if (!(volumeState == Volume.State.ALLOCATED || volumeState == Volume.State.CREATING
- || volumeState == Volume.State.READY)) {
- log.error(String.format("Volume %s can not be attached. Volume status is %s", volumeId, volumeState));
- }
-
- //check whether the account of volume and instance is same
- if (!volume.getAccount().equals(cloudStackApi.getVirtualMachineApi()
- .getVirtualMachine(instanceId).getAccount())) {
- log.error(String.format("Volume %s can not be attached. Instance account and Volume account " +
- "are not the same ", volumeId));
- }
-
- boolean volumeBecameAvailable = false, volumeBecameAttached = false;
-
- try {
- if (volumeState == Volume.State.CREATING) {
-
- volumeBecameAvailable = waitForStatus(volumeId, Volume.State.ALLOCATED, 5);
-
- } else if (volumeState == Volume.State.READY) {
- volumeBecameAvailable = true;
- }
-
- } catch (TimeoutException e) {
- log.error("[Volume ID] " + volumeId + "did not become ALLOCATED within expected timeout");
- }
-
- //if volume state is 'ALLOCATED'
- if (volumeBecameAvailable) {
-
- //attach volume into instance
- cloudStackApi.getVolumeApi().attachVolume(volumeId, instanceId);
-
- try {
- volumeBecameAttached = waitForStatus(volumeId, Volume.State.READY, 2);
- } catch (TimeoutException e) {
- log.error("[Volume ID] " + volumeId + "did not become READY within expected timeout");
- }
- }
-
- try {
- // waiting 5seconds till volumes are actually attached.
- Thread.sleep(5000);
- } catch (InterruptedException ignored) {
-
- }
-
- //If volume state is not 'READY'
- 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." +
- " of Iaas : %s", volumeId, instanceId, iaasInfo));
-
- return "Attaching";
-
- }
-
- @Override
- public void detachVolume(String instanceId, String volumeId) {
-
-
- IaasProvider iaasInfo = getIaasProvider();
-
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
-
- if (log.isDebugEnabled()) {
- log.debug(String.format("Starting to detach volume %s from the instance %s", volumeId, instanceId));
- }
-
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
-
- cloudStackApi.getVolumeApi().detachVolume(volumeId);
-
- try {
- //TODO this is true only for newly created volumes
- if (waitForStatus(volumeId, Volume.State.ALLOCATED, 5)) {
- log.info(String.format("Detachment of Volume [id]: %s from instance [id]: %s was successful of Iaas : %s", volumeId, instanceId, iaasInfo));
- }
- } catch (TimeoutException e) {
- log.error(String.format("Detachment of Volume [id]: %s from instance [id]: %s was unsuccessful. [volume Status] : %s", volumeId, instanceId, iaasInfo));
- }
-
- }
-
- @Override
- public void deleteVolume(String volumeId) {
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService()
- .getContext();
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
- cloudStackApi.getVolumeApi().deleteVolume(volumeId);
- log.info("Deletion of Volume [id]: " + volumeId + " was successful. "
- + " of Iaas : " + iaasInfo);
- }
-
- @Override
- public String getIaasDevice(String device) {//todo implement this method(auto generated method)
- return null;
- }
-
- private boolean waitForStatus(String volumeId, Volume.State expectedStatus, int timeoutInMilliseconds) throws TimeoutException {
- int timeout = 1000 * 60 * timeoutInMilliseconds;
- long timout = System.currentTimeMillis() + timeout;
-
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
-
- //get volume
- org.jclouds.cloudstack.domain.Volume volume = cloudStackApi.getVolumeApi().getVolume(volumeId);
-
- Volume.State volumeState = volume.getState();
-
- while (volumeState != expectedStatus) {
- try {
- if (log.isDebugEnabled()) {
- log.debug(String.format("Volume %s is still NOT in %s. Current State=%s", volumeId, expectedStatus, volumeState));
- }
- if (volumeState == Volume.State.FAILED || volumeState == Volume.State.DESTROYED || volumeState == Volume.State.UNRECOGNIZED) {
- log.error("Volume " + volumeId + " is in state" + volumeState);
- return false;
- }
-
- Thread.sleep(1000);
- volumeState = volume.getState();
- 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;
- }
-
- private Map<String, String> convertByteArrayToHashMap(byte[] byteArray) {
-
- Map<String, String> map = new HashMap<String, String>();
-
- String stringFromByteArray = new String(byteArray);
- String[] keyValuePairs = stringFromByteArray.split(",");
-
- for (String keyValuePair : keyValuePairs) {
- String[] keyValue = keyValuePair.split("=");
- if (keyValue.length > 1) {
- map.put(keyValue[0], keyValue[1]);
- }
- }
-
- return map;
- }
-}
\ No newline at end of file
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/DockerIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/DockerIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/DockerIaas.java
deleted file mode 100644
index da2916b..0000000
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/DockerIaas.java
+++ /dev/null
@@ -1,151 +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.logging.Log;
-import org.apache.commons.logging.LogFactory;
-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.util.ComputeServiceBuilderUtil;
-import org.apache.stratos.cloud.controller.domain.IaasProvider;
-import org.apache.stratos.cloud.controller.iaases.validators.DockerPartitionValidator;
-import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-
-import java.util.Set;
-
-/**
- * Docker iaas provider definition.
- */
-public class DockerIaas extends Iaas {
-
- private static final Log log = LogFactory.getLog(AWSEC2Iaas.class);
-
- public DockerIaas(IaasProvider iaasProvider) {
- super(iaasProvider);
- }
-
- @Override
- public void buildComputeServiceAndTemplate() {
- // builds and sets Compute Service
- ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
-
- // builds and sets Template
- buildTemplate();
- }
-
- @Override
- public void setDynamicPayload() {
- log.warn("Not implemented: DockerIaas.setDynamicPayload()");
- }
-
- @Override
- public String associateAddress(NodeMetadata node) {
- log.warn("Not implemented: DockerIaas.associateAddress()");
- return null;
- }
-
- @Override
- public String associatePredefinedAddress(NodeMetadata node, String ip) {
- log.warn("Not implemented: DockerIaas.associatePredefinedAddress()");
- return null;
- }
-
- @Override
- public void releaseAddress(String ip) {
- log.warn("Not implemented: DockerIaas.releaseAddress()");
- }
-
- @Override
- public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
- return false;
- }
-
- @Override
- public boolean isValidRegion(String region) throws InvalidRegionException {
- return true;
- }
-
- @Override
- public boolean isValidZone(String region, String zone) throws InvalidZoneException {
- return true;
- }
-
- @Override
- public boolean isValidHost(String zone, String host) throws InvalidHostException {
- return true;
- }
-
- @Override
- public PartitionValidator getPartitionValidator() {
- return new DockerPartitionValidator();
- }
-
- @Override
- public void buildTemplate() {
- IaasProvider iaasProvider = getIaasProvider();
- ComputeService computeService = iaasProvider.getComputeService();
- Set<? extends Image> images = computeService.listImages();
- Image image = findImage(images, iaasProvider.getImage());
- if(image == null) {
- throw new CloudControllerException(String.format("Docker image not found: %s", iaasProvider.getImage()));
- }
- Template template = computeService.templateBuilder().fromImage(image).build();
- iaasProvider.setTemplate(template);
- }
-
- private Image findImage(Set<? extends Image> images, String name) {
- for(Image image : images) {
- if(image.getDescription().contains(name))
- return image;
- }
- return null;
- }
-
- @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;
- }
-}
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/GCEIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/GCEIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/GCEIaas.java
deleted file mode 100644
index ba186b2..0000000
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/GCEIaas.java
+++ /dev/null
@@ -1,459 +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.*;
-
-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.domain.NetworkInterface;
-import org.apache.stratos.cloud.controller.iaases.validators.GCEPartitionValidator;
-import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator;
-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.jclouds.ContextBuilder;
-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.domain.Location;
-import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
-import org.jclouds.collect.IterableWithMarker;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
-import org.jclouds.googlecomputeengine.features.DiskApi;
-import org.jclouds.googlecomputeengine.features.InstanceApi;
-import org.jclouds.googlecomputeengine.features.RegionApi;
-import org.jclouds.googlecomputeengine.features.ZoneApi;
-import org.jclouds.googlecomputeengine.domain.Disk;
-import org.jclouds.googlecomputeengine.domain.Instance;
-import org.jclouds.googlecomputeengine.domain.Region;
-import org.jclouds.googlecomputeengine.domain.Zone;
-import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.options.AttachDiskOptions;
-import org.jclouds.googlecomputeengine.options.AttachDiskOptions.DiskType;
-
-import com.google.inject.Key;
-import com.google.inject.Injector;
-import com.google.inject.TypeLiteral;
-import com.google.inject.name.Names;
-
-import static org.jclouds.util.Predicates2.retry;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-import com.google.common.base.Predicate;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import com.google.common.util.concurrent.Atomics;
-
-public class GCEIaas extends Iaas {
-
-
- private static final Log log = LogFactory.getLog(GCEIaas.class);
-
- private static final String PROJECTNAME = "projectName";
-
- public GCEIaas(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);
- }
-
- log.info("gce buildTemplate");
-
- TemplateBuilder templateBuilder = iaasInfo.getComputeService()
- .templateBuilder();
-
- // set image id specified
- templateBuilder.imageId(iaasInfo.getImage());
-
- String zone = iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE);
- if(zone != null) {
- Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
- for(Location location : locations) {
- if(location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) &&
- location.getId().equals(zone)) {
- templateBuilder.locationId(location.getId());
- log.info("ZONE has been set as " + zone
- + " with id: " + location.getId());
- break;
- }
- }
- }
-
- if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
- // set instance type eg: m1.large
- templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
- }
-
- // build the Template
- Template template = templateBuilder.build();
-
- if(zone != null) {
- if(!template.getLocation().getId().equals(zone)) {
- log.warn("couldn't find assignable ZONE of id :" + zone +
- " in the IaaS. Hence using the default location as " + template.getLocation().getScope().toString() +
- " with the id " + template.getLocation().getId());
- }
- }
-
- // 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);
-
- if (zone != null) {
- templateBuilder.locationId(zone);
- log.debug("setting location to " + zone);
- }
-
- // ability to define tags with Key-value pairs
- Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
-
- for (String propertyKey : iaasInfo.getProperties().keySet()){
- if(propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) {
- keyValuePairTagsMap.put(propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()),
- iaasInfo.getProperties().get(propertyKey));
- template.getOptions()
- .userMetadata(keyValuePairTagsMap);
- }
- log.info("usermeta data key:"+ propertyKey + " value: " + iaasInfo.getProperties().get(propertyKey));
- }
-
- if (iaasInfo.getNetworkInterfaces() != null) {
- List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length);
- for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) {
- networks.add(ni.getNetworkUuid());
- log.info("using network interface " + ni.getNetworkUuid());
- }
- template.getOptions().as(TemplateOptions.class).networks(networks);
- log.info("using network interface " + networks);
- }
-
- // 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 GCE not found");
- }
- return;
- }
-
- // Payload is a String value
- String payload = new String(iaasInfo.getPayload());
-
- log.info("setDynamicPayload " + payload);
-
- Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
- keyValuePairTagsMap.put("stratos_usermetadata", payload);
- iaasInfo.getTemplate().getOptions().userMetadata(keyValuePairTagsMap);
- }
-
- @Override
- public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
-
- // Not applicable for GCE - Not called by stratos cloud controller as well
- 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) throws InvalidRegionException {
- IaasProvider iaasInfo = getIaasProvider();
-
- if (region == null || iaasInfo == null) {
- String msg = "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " + iaasInfo;
- log.error(msg);
- throw new InvalidRegionException(msg);
- }
-
- GoogleComputeEngineApi api = getGCEApi();
- RegionApi regionApi = api.getRegionApiForProject(iaasInfo.getProperty(PROJECTNAME));
-
- for(IterableWithMarker<Region> page : regionApi.list()) {
- for(Region r : page) {
- if (region.equalsIgnoreCase(r.getName())) {
- 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();
-
- if (zone == null || iaasInfo == null) {
- String msg = "Zone or IaaSProvider is null: region: " + region +
- " zone: " + zone + " - IaaSProvider: " + iaasInfo;
- log.error(msg);
- throw new InvalidZoneException(msg);
- }
-
- GoogleComputeEngineApi api = getGCEApi();
- ZoneApi zoneApi = api.getZoneApiForProject(iaasInfo.getProperty(PROJECTNAME));
-
- for(IterableWithMarker<Zone> page : zoneApi.list()) {
- for(Zone z : page) {
- if (zone.equalsIgnoreCase(z.getName())) {
- log.debug("Found a matching 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();
-
- // Not called by cloud controller
- // there's no such concept in GCE
-
- String msg = "Invalid host: " + host + " in the zone: " + zone + " and of the iaas: " + iaasInfo.getType();
- log.error(msg);
- throw new InvalidHostException(msg);
- }
-
- @Override
- public PartitionValidator getPartitionValidator() {
- return new GCEPartitionValidator();
- }
-
- @Override
- public String createVolume(int sizeGB, String snapshotId) {
- // generate a random diskname
- Random rand = new Random();
- String diskName = "stratos-disk-" + rand.nextInt(100000);
- DiskApi diskApi = getGCEDiskApi();
- String zone = getZone();
-
- log.debug("Creating volume: " + diskName + " in zone: " + zone + " of size: " + sizeGB);
-
- Operation oper = diskApi.createInZone(diskName, sizeGB, zone);
-
- oper = waitGCEOperationDone(oper);
- if (oper.getStatus() != Operation.Status.DONE) {
- log.error("Failed to create volume: " + diskName + " of size: " + sizeGB +
- " in zone: " + zone + " operation: " + oper);
- return null;
- }
-
- return diskName;
- }
-
- @Override
- public String attachVolume(String instanceId, String volumeId, String deviceName) {
- DiskApi diskApi = getGCEDiskApi();
- InstanceApi instApi = getGCEInstanceApi();
- String zone = getZone();
-
- log.debug("Trying to attach volume: " + volumeId + " to instance: " + instanceId +
- " in zone: " + zone + " at devicename: " + deviceName);
-
- Disk disk = diskApi.getInZone(zone, volumeId);
- if (disk == null) {
- log.error("Failed to get volume: " + volumeId + " in zone: " + zone);
- return null;
- }
-
- log.debug("Found volumeId: " + volumeId + " volume: " + disk);
-
- Operation oper = instApi.attachDiskInZone(zone, instanceId,
- new AttachDiskOptions().type(DiskType.PERSISTENT)
- .source(disk.getSelfLink())
- .mode(AttachDiskOptions.DiskMode.READ_WRITE)
- .deviceName(deviceName));
- oper = waitGCEOperationDone(oper);
- if (oper.getStatus() != Operation.Status.DONE) {
- log.error("Failed to attach volume: " + volumeId + " to instance: " + instanceId +
- " in zone: " + zone + " at device: " + deviceName + " operation: " + oper);
- return null;
- }
-
- return volumeId;
- }
-
- @Override
- public void detachVolume(String instanceId, String volumeId) {
- InstanceApi instApi = getGCEInstanceApi();
- String zone = getZone();
- Instance inst = instApi.getInZone(zone, instanceId);
-
- log.debug("Trying to detach volume: " + volumeId + " from instance: " + instanceId +
- " " + inst + " in zone: " + zone);
-
- if (inst == null) {
- log.error("Failed to find instance: " + instanceId + " in zone: " + zone);
- return;
- }
-
- for(Instance.AttachedDisk disk : inst.getDisks()) {
- Instance.PersistentAttachedDisk persistentDisk = (Instance.PersistentAttachedDisk)disk;
-
- log.debug("Found disk - src: " + persistentDisk.getSourceDiskName() +
- " devicename: " + persistentDisk.getDeviceName());
-
- if (persistentDisk.getSourceDiskName().equals(volumeId)) {
- Operation oper = instApi.detachDiskInZone(zone, instanceId, persistentDisk.getDeviceName().get());
- oper = waitGCEOperationDone(oper);
- if (oper.getStatus() != Operation.Status.DONE) {
- log.error("Failed to detach volume: " + volumeId + " to instance: " + instanceId +
- " in zone: " + zone + " at device: " + persistentDisk.getDeviceName() +
- " result operation: " + oper);
- }
- return;
- }
- }
-
- log.error("Cannot find volume: " + volumeId + " in instance: " + instanceId);
- }
-
- @Override
- public void deleteVolume(String volumeId) {
- DiskApi diskApi = getGCEDiskApi();
- String zone = getZone();
-
- log.debug("Deleting volume: " + volumeId + " in zone: " + zone);
-
- Operation oper = diskApi.deleteInZone(zone, volumeId);
-
- oper = waitGCEOperationDone(oper);
- if (oper.getStatus() != Operation.Status.DONE) {
- log.error("Failed to delete volume: " + volumeId + " in zone: " + zone +
- " operation: " + oper);
- }
- }
-
- @Override
- public String getIaasDevice(String device) {
- return device;
- }
-
- private String getZone() {
- IaasProvider iaasInfo = getIaasProvider();
- return iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE);
- }
-
- private GoogleComputeEngineApi getGCEApi() {
- IaasProvider iaasInfo = getIaasProvider();
- ComputeServiceContext context = iaasInfo.getComputeService().getContext();
- GoogleComputeEngineApi api = context.unwrapApi(GoogleComputeEngineApi.class);
-
- return api;
- }
-
- private DiskApi getGCEDiskApi() {
- IaasProvider iaasInfo = getIaasProvider();
- String projectName = iaasInfo.getProperty(PROJECTNAME);
- return getGCEApi().getDiskApiForProject(projectName);
- }
-
- private InstanceApi getGCEInstanceApi() {
- IaasProvider iaasInfo = getIaasProvider();
- String projectName = iaasInfo.getProperty(PROJECTNAME);
- return getGCEApi().getInstanceApiForProject(projectName);
- }
-
- private Operation waitGCEOperationDone(Operation operation) {
- int maxWaitTime = 15; // 15 seconds
- IaasProvider iaasInfo = getIaasProvider();
- Injector injector = ContextBuilder.newBuilder(iaasInfo.getProvider())
- .credentials(iaasInfo.getIdentity(), iaasInfo.getCredential())
- .buildInjector();
- Predicate<AtomicReference<Operation>> zoneOperationDonePredicate =
- injector.getInstance(Key.get(new TypeLiteral<Predicate<AtomicReference<Operation>>>() {
- }, Names.named("zone")));
- AtomicReference<Operation> operationReference = Atomics.newReference(operation);
- retry(zoneOperationDonePredicate, maxWaitTime, 1, SECONDS).apply(operationReference);
-
- return operationReference.get();
- }
-}
-
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/Iaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/Iaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/Iaas.java
index b42f8b9..341d6f1 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/Iaas.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/Iaas.java
@@ -18,155 +18,142 @@
*/
package org.apache.stratos.cloud.controller.iaases;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-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.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.validators.PartitionValidator;
+import org.jclouds.compute.domain.NodeMetadata;
/**
* All IaaSes that are going to support by Cloud Controller, should extend this abstract class.
*/
public abstract class Iaas {
- /**
- * Reference to the corresponding {@link IaasProvider}
- */
- private IaasProvider iaasProvider;
-
- public Iaas(IaasProvider iaasProvider) {
- this.setIaasProvider(iaasProvider);
- }
-
- public IaasProvider getIaasProvider() {
- return iaasProvider;
- }
-
- public void setIaasProvider(IaasProvider iaasProvider) {
- this.iaasProvider = iaasProvider;
- }
-
- /**
- * This should build the {@link ComputeService} object and the {@link Template} object,
- * using the information from {@link IaasProvider} and should set the built
- * {@link ComputeService} object in the {@link IaasProvider#setComputeService(ComputeService)}
- * and also should set the built {@link Template} object in the
- * {@link IaasProvider#setTemplate(Template)}.
- */
- public abstract void buildComputeServiceAndTemplate();
-
/**
- * This method provides a way to set payload that can be obtained from {@link IaasProvider#getPayload()}
- * in the {@link Template} of this IaaS.
+ * Reference to the corresponding {@link IaasProvider}
*/
- public abstract void setDynamicPayload();
-
+ private IaasProvider iaasProvider;
+
+ public Iaas(IaasProvider iaasProvider) {
+ this.setIaasProvider(iaasProvider);
+ }
+
+ public IaasProvider getIaasProvider() {
+ return iaasProvider;
+ }
+
+ public void setIaasProvider(IaasProvider iaasProvider) {
+ this.iaasProvider = iaasProvider;
+ }
+
/**
- * This will obtain an IP address from the allocated list and associate that IP with this node.
- * @param node Node to be associated with an IP.
- * @return associated public IP.
+ * Initialize the iaas object.
*/
- public abstract String associateAddress(NodeMetadata node);
-
+ public abstract void initialize();
+
/**
- * This will obtain a predefined IP address and associate that IP with this node, if ip is already in use allocate ip from pool
- * (through associateAddress())
- * @param node Node to be associated with an IP.
- * @ip preallocated floating Ip
- * @return associated public IP.
+ * Create vm/container instance.
+ *
+ * @param clusterContext
+ * @param memberContext
+ * @return
*/
- public abstract String associatePredefinedAddress(NodeMetadata node, String ip);
-
+ public abstract NodeMetadata createInstance(ClusterContext clusterContext, MemberContext memberContext);
+
/**
* This will deallocate/release the given IP address back to pool.
+ *
* @param ip public IP address to be released.
*/
public abstract void releaseAddress(String ip);
-
- /**
- * This method should create a Key Pair corresponds to a given public key in the respective region having the name given.
- * Also should override the value of the key pair in the {@link Template} of this IaaS.
- * @param region region that the key pair will get created.
- * @param keyPairName name of the key pair. NOTE: Jclouds adds a prefix : <code>jclouds#</code>
- * @param publicKey public key, from which the key pair will be created.
- * @return whether the key pair creation is successful or not.
- */
- public abstract boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey);
-
+
/**
* Validate a given region name against a particular IaaS.
* If a particular IaaS doesn't have a concept called region, it can simply throw {@link InvalidRegionException}.
+ *
* @param region name of the region.
* @return whether the region is valid.
* @throws InvalidRegionException if the region is invalid.
*/
public abstract boolean isValidRegion(String region) throws InvalidRegionException;
-
+
/**
* Validate a given zone name against a particular region in an IaaS.
* If a particular IaaS doesn't have a concept called zone, it can simply throw {@link InvalidZoneException}.
+ *
* @param region region of the IaaS that the zone belongs to.
- * @param zone
+ * @param zone
* @return whether the zone is valid in the given region or not.
* @throws InvalidZoneException if the zone is invalid in a given region.
*/
public abstract boolean isValidZone(String region, String zone) throws InvalidZoneException, InvalidRegionException;
-
+
/**
* Validate a given host id against a particular zone in an IaaS.
* If a particular IaaS doesn't have a concept called hosts, it can simply throw {@link InvalidHostException}.
+ *
* @param zone zone of the IaaS that the host belongs to.
* @param host
* @return whether the host is valid in the given zone or not.
* @throws InvalidHostException if the host is invalid in a given zone.
*/
public abstract boolean isValidHost(String zone, String host) throws InvalidHostException;
-
+
/**
* provides the {@link PartitionValidator} corresponds to this particular IaaS.
+ *
* @return {@link PartitionValidator}
*/
public abstract PartitionValidator getPartitionValidator();
/**
- * Builds only the jclouds {@link Template}
- */
- public abstract void buildTemplate();
-
- /**
* Create a new volume in the respective Iaas.
+ *
* @param sizeGB size of the volume in Giga Bytes.
* @return Id of the created volume.
*/
public abstract String createVolume(int sizeGB, String snapshotId);
-
+
+
/**
* Attach a given volume to an instance at the specified device path.
+ *
* @param instanceId of the instance.
- * @param volumeId volume id of the volume to be attached.
+ * @param volumeId volume id of the volume to be attached.
* @param deviceName name of the device that the volume would bind to.
* @return the status of the attachment.
*/
public abstract String attachVolume(String instanceId, String volumeId, String deviceName);
-
+
/**
* Detach a given volume from the given instance.
+ *
* @param instanceId of the instance.
- * @param volumeId volume id of the volume to be detached.
+ * @param volumeId volume id of the volume to be detached.
*/
public abstract void detachVolume(String instanceId, String volumeId);
-
+
/**
* Delete a given volume.
+ *
* @param volumeId volume id of the volume to be detached.
*/
public abstract void deleteVolume(String volumeId);
/**
- * This returns the device of the volume specified by the user. This is depends on IAAS.
+ * This returns the device of the volume specified by the user. This is depends on IAAS.
* For an instance /dev/sdf maps to /dev/xvdf in EC2.
*/
public abstract String getIaasDevice(String device);
+
+ public abstract void allocateIpAddress(String clusterId, MemberContext memberContext, Partition partition,
+ String cartridgeType, NodeMetadata node);
+
+ /**
+ * This method provides a way to set payload.
+ */
+ public abstract void setDynamicPayload(byte[] payload);
+
+ public abstract void terminateInstance(MemberContext memberContext) throws InvalidCartridgeTypeException, InvalidMemberException;
}
[2/4] stratos git commit: Introducing a mock iaas for cloud controller
Posted by im...@apache.org.
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;
+ }
+}