You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ra...@apache.org on 2015/10/14 13:14:59 UTC

[1/4] stratos git commit: Improvements for mock IaaS. Add payload to mock member context

Repository: stratos
Updated Branches:
  refs/heads/stratos-4.1.x cd18da582 -> bba650ea4


Improvements for mock IaaS. Add payload to mock member context


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/bba650ea
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/bba650ea
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/bba650ea

Branch: refs/heads/stratos-4.1.x
Commit: bba650ea4894cb95f1048728824b59646fa20150
Parents: 4f02149
Author: Akila Perera <ra...@gmail.com>
Authored: Wed Oct 14 16:25:58 2015 +0530
Committer: Akila Perera <ra...@gmail.com>
Committed: Wed Oct 14 16:43:04 2015 +0530

----------------------------------------------------------------------
 .../org.apache.stratos.cloud.controller/pom.xml |  1 +
 .../cloud/controller/iaases/mock/MockIaas.java  | 67 ++++++++++-----
 .../status/InstanceStatusTopicReceiver.java     | 45 +++++++---
 .../stratos/mock/iaas/api/MockIaasApi.java      | 15 ++--
 .../mock/iaas/client/MockIaasApiClient.java     | 28 +++++-
 components/org.apache.stratos.mock.iaas/pom.xml |  3 +-
 .../mock/iaas/domain/MockInstanceContext.java   | 15 +++-
 .../mock/iaas/domain/MockInstanceMetadata.java  | 16 +++-
 .../iaas/services/impl/MockIaasServiceImpl.java | 90 +++++++++++---------
 .../mock/iaas/services/impl/MockInstance.java   | 90 ++++++++++----------
 10 files changed, 247 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.cloud.controller/pom.xml
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/pom.xml b/components/org.apache.stratos.cloud.controller/pom.xml
index e5ca7da..9bae032 100644
--- a/components/org.apache.stratos.cloud.controller/pom.xml
+++ b/components/org.apache.stratos.cloud.controller/pom.xml
@@ -54,6 +54,7 @@
                         </Private-Package>
                         <Import-Package>
                             !org.apache.stratos.cloud.controller.*,
+                            org.apache.stratos.mock.iaas.*,
                             org.apache.commons.*,
                             org.wso2.carbon.utils.*,
                             org.apache.stratos.common.*; version="${project.version}",

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/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
index fb92d27..f774afc 100644
--- 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
@@ -20,6 +20,8 @@
 package org.apache.stratos.cloud.controller.iaases.mock;
 
 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.MemberContext;
 import org.apache.stratos.cloud.controller.domain.Partition;
@@ -30,23 +32,30 @@ import org.apache.stratos.mock.iaas.client.MockIaasApiClient;
 import org.apache.stratos.mock.iaas.domain.MockInstanceContext;
 import org.apache.stratos.mock.iaas.domain.MockInstanceMetadata;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Mock IaaS client for invoking mock IaaS service.
  */
 public class MockIaas extends Iaas {
-
+    private static final Log log = LogFactory.getLog(MockIaas.class);
     private MockIaasApiClient apiClient;
     private PartitionValidator partitionValidator;
+    private Map<String, String> payloadMap;
+    private static final String PAYLOAD_PARAMETER_SEPARATOR = ",";
+    private static final String PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR = "=";
 
     public MockIaas(IaasProvider iaasProvider) {
         super(iaasProvider);
         String endpoint = iaasProvider.getProperty("api.endpoint");
         if (StringUtils.isBlank(endpoint)) {
-            throw new CloudControllerException("api.endpoint property not found in mock iaas provider in" +
-                    "cloud-controller.xml file");
+            throw new CloudControllerException(
+                    "api.endpoint property not found in mock iaas provider in" + "cloud-controller.xml file");
         }
         apiClient = new MockIaasApiClient(endpoint);
         partitionValidator = new MockIaasPartitionValidator();
+        payloadMap = new HashMap<>();
     }
 
     @Override
@@ -54,17 +63,13 @@ public class MockIaas extends Iaas {
     }
 
     @Override
-    public MemberContext startInstance(MemberContext memberContext, byte[] payload) {
-        MockInstanceContext mockInstanceContext = new MockInstanceContext(
-                memberContext.getApplicationId(),
-                memberContext.getCartridgeType(),
-                memberContext.getClusterId(),
-                memberContext.getMemberId(),
-                memberContext.getClusterInstanceId(),
-                memberContext.getNetworkPartitionId(),
-                memberContext.getPartition().getId()
-        );
-        setDynamicPayload(payload);
+    public MemberContext startInstance(MemberContext memberContext, byte[] payloadByteArray) {
+        MockInstanceContext mockInstanceContext = new MockInstanceContext(memberContext.getApplicationId(),
+                memberContext.getCartridgeType(), memberContext.getClusterId(), memberContext.getMemberId(),
+                memberContext.getClusterInstanceId(), memberContext.getNetworkPartitionId(),
+                memberContext.getPartition().getId());
+        setDynamicPayload(payloadByteArray);
+        mockInstanceContext.setPayload(new String(payloadByteArray));
         MockInstanceMetadata mockInstanceMetadata = apiClient.startInstance(mockInstanceContext);
         memberContext.setInstanceId(mockInstanceMetadata.getInstanceId());
         return memberContext;
@@ -124,19 +129,43 @@ public class MockIaas extends Iaas {
             memberContext.setDefaultPrivateIP(mockInstanceMetadata.getDefaultPrivateIp());
             memberContext.setDefaultPublicIP(mockInstanceMetadata.getDefaultPublicIp());
 
-            String[] privateIPs = new String[]{mockInstanceMetadata.getDefaultPrivateIp()};
-            String[] publicIPs = new String[]{mockInstanceMetadata.getDefaultPublicIp()};
+            String[] privateIPs = new String[] { mockInstanceMetadata.getDefaultPrivateIp() };
+            String[] publicIPs = new String[] { mockInstanceMetadata.getDefaultPublicIp() };
             memberContext.setPrivateIPs(privateIPs);
             memberContext.setPublicIPs(publicIPs);
         }
     }
 
     @Override
-    public void setDynamicPayload(byte[] payload) {
+    public void setDynamicPayload(byte[] payloadByteArray) {
+        // Clear existing payloadMap parameters
+        payloadMap.clear();
+
+        if (payloadByteArray != null) {
+            String payloadString = new String(payloadByteArray);
+            String[] parameterArray = payloadString.split(PAYLOAD_PARAMETER_SEPARATOR);
+            if (parameterArray.length > 0) {
+                for (String parameter : parameterArray) {
+                    if (parameter != null) {
+                        String[] nameValueArray = parameter.split(PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR, 2);
+                        if ((nameValueArray.length == 2)) {
+                            payloadMap.put(nameValueArray[0], nameValueArray[1]);
+                        }
+                    }
+                }
+                if (log.isDebugEnabled()) {
+                    log.debug("Dynamic payloadMap is set: " + payloadMap.values());
+                }
+            }
+        }
     }
 
     @Override
-    public void terminateInstance(MemberContext memberContext) throws InvalidCartridgeTypeException, InvalidMemberException {
-        apiClient.terminateInstance(memberContext.getInstanceId());
+    public void terminateInstance(MemberContext memberContext)
+            throws InvalidCartridgeTypeException, InvalidMemberException {
+        boolean terminated = apiClient.terminateInstance(memberContext.getInstanceId());
+        if (terminated) {
+            log.info("Mock instance terminated via MockIaaSApiClient [member-id] " + memberContext.getMemberId());
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/receiver/instance/status/InstanceStatusTopicReceiver.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/receiver/instance/status/InstanceStatusTopicReceiver.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/receiver/instance/status/InstanceStatusTopicReceiver.java
index 2d8a275..e212fea 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/receiver/instance/status/InstanceStatusTopicReceiver.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/receiver/instance/status/InstanceStatusTopicReceiver.java
@@ -66,10 +66,15 @@ public class InstanceStatusTopicReceiver {
         statusEventReceiver.addEventListener(new InstanceActivatedEventListener() {
             @Override
             protected void onEvent(Event event) {
+                InstanceActivatedEvent instanceActivatedEvent = (InstanceActivatedEvent) event;
+                if (log.isDebugEnabled()) {
+                    log.debug(String.format("Handling InstanceActivatedEvent for [member-id] %s",
+                            instanceActivatedEvent.getMemberId()));
+                }
                 try {
-                    TopologyBuilder.handleMemberActivated((InstanceActivatedEvent) event);
-                } catch (RegistryException e) {
-                    log.error("Could not persist data in registry data store", e);
+                    TopologyBuilder.handleMemberActivated(instanceActivatedEvent);
+                } catch (Exception e) {
+                    log.error("Failed to process InstanceActivatedEvent", e);
                 }
             }
         });
@@ -77,18 +82,33 @@ public class InstanceStatusTopicReceiver {
         statusEventReceiver.addEventListener(new InstanceStartedEventListener() {
             @Override
             protected void onEvent(Event event) {
-                TopologyBuilder.handleMemberStarted((InstanceStartedEvent) event);
+                InstanceStartedEvent instanceStartedEvent = (InstanceStartedEvent) event;
+                if (log.isDebugEnabled()) {
+                    log.debug(String.format("Handling InstanceStartedEvent for [member-id] %s",
+                            instanceStartedEvent.getMemberId()));
+                }
+                try {
+                    TopologyBuilder.handleMemberStarted(instanceStartedEvent);
+                } catch (Exception e) {
+                    log.error(String.format("Failed to process InstanceStartedEvent for [member-id] %s",
+                            instanceStartedEvent.getMemberId()), e);
+                }
             }
         });
 
         statusEventReceiver.addEventListener(new InstanceReadyToShutdownEventListener() {
             @Override
             protected void onEvent(Event event) {
+                InstanceReadyToShutdownEvent instanceReadyToShutdownEvent = (InstanceReadyToShutdownEvent) event;
+                if (log.isDebugEnabled()) {
+                    log.debug(String.format("Handling InstanceReadyToShutdownEvent for [member-id] %s",
+                            instanceReadyToShutdownEvent.getMemberId()));
+                }
                 try {
-                    TopologyBuilder.handleMemberReadyToShutdown((InstanceReadyToShutdownEvent) event);
+                    TopologyBuilder.handleMemberReadyToShutdown(instanceReadyToShutdownEvent);
                 } catch (Exception e) {
-                    String error = "Failed to process the instance status event message";
-                    log.error(error, e);
+                    log.error(String.format("Failed to process InstanceReadyToShutdownEvent for [member-id] %s",
+                            instanceReadyToShutdownEvent.getMemberId()), e);
                 }
             }
         });
@@ -96,11 +116,16 @@ public class InstanceStatusTopicReceiver {
         statusEventReceiver.addEventListener(new InstanceMaintenanceListener() {
             @Override
             protected void onEvent(Event event) {
+                InstanceMaintenanceModeEvent instanceMaintenanceModeEvent = (InstanceMaintenanceModeEvent) event;
+                if (log.isDebugEnabled()) {
+                    log.debug(String.format("Handling InstanceMaintenanceModeEvent for [member-id] %s",
+                            instanceMaintenanceModeEvent.getMemberId()));
+                }
                 try {
-                    TopologyBuilder.handleMemberMaintenance((InstanceMaintenanceModeEvent) event);
+                    TopologyBuilder.handleMemberMaintenance(instanceMaintenanceModeEvent);
                 } catch (Exception e) {
-                    String error = "Failed to process the instance status event message";
-                    log.error(error, e);
+                    log.error(String.format("Failed to process InstanceMaintenanceModeEvent for [member-id] %s",
+                            instanceMaintenanceModeEvent.getMemberId()), e);
                 }
             }
         });

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.mock.iaas.api/src/main/java/org/apache/stratos/mock/iaas/api/MockIaasApi.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mock.iaas.api/src/main/java/org/apache/stratos/mock/iaas/api/MockIaasApi.java b/components/org.apache.stratos.mock.iaas.api/src/main/java/org/apache/stratos/mock/iaas/api/MockIaasApi.java
index 51adad8..d3ff5d1 100644
--- a/components/org.apache.stratos.mock.iaas.api/src/main/java/org/apache/stratos/mock/iaas/api/MockIaasApi.java
+++ b/components/org.apache.stratos.mock.iaas.api/src/main/java/org/apache/stratos/mock/iaas/api/MockIaasApi.java
@@ -54,6 +54,11 @@ public class MockIaasApi {
     @Consumes("application/json")
     @Produces("application/json")
     public Response startInstance(MockInstanceContext mockInstanceContext) throws MockIaasApiException {
+        if (mockInstanceContext == null) {
+            String msg = "Mock instance context is null";
+            log.error(msg);
+            throw new MockIaasApiException(msg);
+        }
         try {
             // Validate mock iaas service
             validateMockIaasService();
@@ -81,8 +86,8 @@ public class MockIaasApi {
             log.debug(String.format("Get mock instances"));
 
             List<MockInstanceMetadata> mockInstanceMetadataList = getMockIaasService().getInstances();
-            MockInstanceMetadata[] mockInstanceMetadataArray = mockInstanceMetadataList.toArray(
-                    new MockInstanceMetadata[mockInstanceMetadataList.size()]);
+            MockInstanceMetadata[] mockInstanceMetadataArray = mockInstanceMetadataList
+                    .toArray(new MockInstanceMetadata[mockInstanceMetadataList.size()]);
             return Response.ok(mockInstanceMetadataArray).build();
         } catch (Exception e) {
             String message = "Could not get mock instances";
@@ -130,9 +135,9 @@ public class MockIaasApi {
                 return Response.status(Response.Status.NOT_FOUND).build();
             }
             mockInstanceMetadata = getMockIaasService().allocateIpAddress(instanceId);
-            log.info(String.format("IP addresses allocated: [instance-id] %s [default-private-ip] %s " +
-                            "[default-public-ip] %s", instanceId, mockInstanceMetadata.getDefaultPrivateIp(),
-                    mockInstanceMetadata.getDefaultPublicIp()));
+            log.info(String.format(
+                    "IP addresses allocated: [instance-id] %s [default-private-ip] %s " + "[default-public-ip] %s",
+                    instanceId, mockInstanceMetadata.getDefaultPrivateIp(), mockInstanceMetadata.getDefaultPublicIp()));
             return Response.ok(mockInstanceMetadata).build();
         } catch (Exception e) {
             String message = String.format("Could not allocate ip address: [instance-id] %s", instanceId);

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.mock.iaas.client/src/main/java/org/apache/stratos/mock/iaas/client/MockIaasApiClient.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mock.iaas.client/src/main/java/org/apache/stratos/mock/iaas/client/MockIaasApiClient.java b/components/org.apache.stratos.mock.iaas.client/src/main/java/org/apache/stratos/mock/iaas/client/MockIaasApiClient.java
index 47bbd17..1ec00e6 100644
--- a/components/org.apache.stratos.mock.iaas.client/src/main/java/org/apache/stratos/mock/iaas/client/MockIaasApiClient.java
+++ b/components/org.apache.stratos.mock.iaas.client/src/main/java/org/apache/stratos/mock/iaas/client/MockIaasApiClient.java
@@ -58,6 +58,9 @@ public class MockIaasApiClient {
             }
             URI uri = new URIBuilder(endpoint + INSTANCES_CONTEXT).build();
             HttpResponse response = restClient.doPost(uri, content);
+            if (log.isDebugEnabled()) {
+                log.debug("Mock start instance call response: " + response.getContent());
+            }
             if (response != null) {
                 if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                     return gson.fromJson(response.getContent(), MockInstanceMetadata.class);
@@ -84,7 +87,7 @@ public class MockIaasApiClient {
             HttpResponse response = restClient.doDelete(uri);
             if (response != null) {
                 if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
-                    return false;
+                    return true;
                 } else {
                     GsonBuilder gsonBuilder = new GsonBuilder();
                     Gson gson = gsonBuilder.create();
@@ -127,4 +130,27 @@ public class MockIaasApiClient {
             throw new RuntimeException(message, e);
         }
     }
+
+    public MockInstanceMetadata getInstance(String instanceId) {
+        try {
+            GsonBuilder gsonBuilder = new GsonBuilder();
+            Gson gson = gsonBuilder.create();
+            URI uri = new URIBuilder(endpoint + INSTANCES_CONTEXT + instanceId).build();
+            HttpResponse response = restClient.doGet(uri);
+            if (response != null) {
+                if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
+                    return gson.fromJson(response.getContent(), MockInstanceMetadata.class);
+                } else {
+                    ErrorResponse errorResponse = gson.fromJson(response.getContent(), ErrorResponse.class);
+                    if (errorResponse != null) {
+                        throw new RuntimeException(errorResponse.getErrorMessage());
+                    }
+                }
+            }
+            throw new RuntimeException("An unknown error occurred");
+        } catch (Exception e) {
+            String message = "Could not start mock instance";
+            throw new RuntimeException(message, e);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.mock.iaas/pom.xml
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mock.iaas/pom.xml b/components/org.apache.stratos.mock.iaas/pom.xml
index b0e4798..7df2cc3 100644
--- a/components/org.apache.stratos.mock.iaas/pom.xml
+++ b/components/org.apache.stratos.mock.iaas/pom.xml
@@ -81,6 +81,7 @@
                             org.apache.stratos.mock.iaas.internal;
                         </Private-Package>
                         <Import-Package>
+                            org.apache.stratos.common.*,
                             *;resolution:=optional
                         </Import-Package>
                         <DynamicImport-Package>*</DynamicImport-Package>
@@ -89,4 +90,4 @@
             </plugin>
         </plugins>
     </build>
-</project>
\ No newline at end of file
+</project>

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceContext.java b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceContext.java
index 582ea43..7f992bd 100644
--- a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceContext.java
+++ b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceContext.java
@@ -19,8 +19,12 @@
 
 package org.apache.stratos.mock.iaas.domain;
 
+import org.apache.stratos.messaging.adapters.MapAdapter;
+
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.io.Serializable;
+import java.util.Map;
 
 /**
  * Mock member context.
@@ -40,12 +44,13 @@ public class MockInstanceContext implements Serializable {
     private String defaultPrivateIP;
     private String defaultPublicIP;
     private String instanceId;
+    private String payload;
 
     public MockInstanceContext() {
     }
 
     public MockInstanceContext(String applicationId, String serviceName, String clusterId, String memberId,
-                               String clusterInstanceId, String networkPartitionId, String partitionId) {
+            String clusterInstanceId, String networkPartitionId, String partitionId) {
         this.setApplicationId(applicationId);
         this.setServiceName(serviceName);
         this.setClusterId(clusterId);
@@ -138,4 +143,12 @@ public class MockInstanceContext implements Serializable {
     public void setInstanceId(String instanceId) {
         this.instanceId = instanceId;
     }
+
+    public String getPayload() {
+        return payload;
+    }
+
+    public void setPayload(String payload) {
+        this.payload = payload;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceMetadata.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceMetadata.java b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceMetadata.java
index 1b67650..480d7e3 100644
--- a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceMetadata.java
+++ b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/domain/MockInstanceMetadata.java
@@ -19,20 +19,23 @@
 
 package org.apache.stratos.mock.iaas.domain;
 
+import org.apache.stratos.messaging.adapters.MapAdapter;
+
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.io.Serializable;
+import java.util.Map;
 
 /**
  * Mock instance metadata.
  */
 @XmlRootElement(name = "mockInstanceMetadata")
 public class MockInstanceMetadata implements Serializable {
-
     private static final long serialVersionUID = -1323605022799409426L;
-
     private String instanceId;
     private String defaultPrivateIp;
     private String defaultPublicIp;
+    private String payload;
 
     public MockInstanceMetadata() {
     }
@@ -41,6 +44,7 @@ public class MockInstanceMetadata implements Serializable {
         this.instanceId = mockInstanceContext.getInstanceId();
         this.defaultPrivateIp = mockInstanceContext.getDefaultPrivateIP();
         this.defaultPublicIp = mockInstanceContext.getDefaultPublicIP();
+        this.payload = mockInstanceContext.getPayload();
     }
 
     public String getInstanceId() {
@@ -66,4 +70,12 @@ public class MockInstanceMetadata implements Serializable {
     public void setDefaultPublicIp(String defaultPublicIp) {
         this.defaultPublicIp = defaultPublicIp;
     }
+
+    public String getPayload() {
+        return payload;
+    }
+
+    public void setPayload(String payload) {
+        this.payload = payload;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockIaasServiceImpl.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockIaasServiceImpl.java b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockIaasServiceImpl.java
index 4d2ff12..2090199 100644
--- a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockIaasServiceImpl.java
+++ b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockIaasServiceImpl.java
@@ -42,7 +42,6 @@ import java.util.concurrent.ExecutorService;
 /**
  * Mock IaaS service implementation. This is a singleton class that simulates a standard Infrastructure as a Service
  * platform by creating mock instances and managing their lifecycle states.
- * <p/>
  * How does this work:
  * - Mock IaaS starts a Mock Member thread or each instance created
  * - A sample private IP and a public IP will be assigned to the instance
@@ -54,9 +53,8 @@ public class MockIaasServiceImpl implements MockIaasService {
 
     private static final Log log = LogFactory.getLog(MockIaasServiceImpl.class);
 
-    private static final ExecutorService mockMemberExecutorService =
-            StratosThreadPool.getExecutorService(MockConstants.MOCK_MEMBER_THREAD_POOL,
-                    MockConstants.MOCK_MEMBER_THREAD_POOL_SIZE);
+    private static final ExecutorService mockMemberExecutorService = StratosThreadPool
+            .getExecutorService(MockConstants.MOCK_MEMBER_THREAD_POOL, MockConstants.MOCK_MEMBER_THREAD_POOL_SIZE);
     private static volatile MockIaasServiceImpl instance;
 
     private PersistenceManager persistenceManager;
@@ -68,8 +66,8 @@ public class MockIaasServiceImpl implements MockIaasService {
      */
     public MockIaasServiceImpl() {
         try {
-            String persistenceManagerTypeStr = System.getProperty(MockConstants.PERSISTENCE_MANAGER_TYPE,
-                    PersistenceManagerType.Registry.toString());
+            String persistenceManagerTypeStr = System
+                    .getProperty(MockConstants.PERSISTENCE_MANAGER_TYPE, PersistenceManagerType.Registry.toString());
             PersistenceManagerType persistenceManagerType = PersistenceManagerType.valueOf(persistenceManagerTypeStr);
             persistenceManager = PersistenceManagerFactory.getPersistenceManager(persistenceManagerType);
             mockIaasServiceUtil = new MockIaasServiceUtil(persistenceManager);
@@ -95,30 +93,35 @@ public class MockIaasServiceImpl implements MockIaasService {
      */
     @Override
     public MockInstanceMetadata startInstance(MockInstanceContext mockInstanceContext) throws MockIaasException {
-        synchronized (MockIaasServiceImpl.class) {
-
-            if (mockInstanceContext == null) {
-                throw new MockIaasException("Mock instance context is null");
-            }
-
-            // Generate instance id
-            String instanceId = mockInstanceContext.getMemberId();
-            mockInstanceContext.setInstanceId(instanceId);
+        if (mockInstanceContext == null) {
+            throw new MockIaasException("Mock instance context is null");
+        }
+        try {
+            synchronized (MockIaasServiceImpl.class) {
+                // Generate instance id
+                String instanceId = mockInstanceContext.getMemberId();
+                mockInstanceContext.setInstanceId(instanceId);
 
-            MockInstance mockInstance = new MockInstance(mockInstanceContext);
-            instanceIdToMockInstanceMap.put(instanceId, mockInstance);
-            mockMemberExecutorService.submit(mockInstance);
+                MockInstance mockInstance = new MockInstance(mockInstanceContext);
+                instanceIdToMockInstanceMap.put(instanceId, mockInstance);
+                mockMemberExecutorService.submit(mockInstance);
 
-            // Persist changes
-            mockIaasServiceUtil.persistInRegistry((ConcurrentHashMap<String, MockInstance>) instanceIdToMockInstanceMap);
+                // Persist changes
+                mockIaasServiceUtil
+                        .persistInRegistry((ConcurrentHashMap<String, MockInstance>) instanceIdToMockInstanceMap);
 
-            String serviceName = mockInstanceContext.getServiceName();
-            MockHealthStatisticsGenerator.getInstance().scheduleStatisticsUpdaterTasks(serviceName);
+                String serviceName = mockInstanceContext.getServiceName();
+                MockHealthStatisticsGenerator.getInstance().scheduleStatisticsUpdaterTasks(serviceName);
 
-            // Simulate instance creation time
-            sleep(2000);
+                // Simulate instance creation time
+                sleep(2000);
 
-            return new MockInstanceMetadata(mockInstanceContext);
+                return new MockInstanceMetadata(mockInstanceContext);
+            }
+        } catch (Exception e) {
+            String msg = "Could not start mock instance: " + mockInstanceContext.getMemberId();
+            log.error(msg, e);
+            throw new MockIaasException(msg, e);
         }
     }
 
@@ -158,7 +161,8 @@ public class MockIaasServiceImpl implements MockIaasService {
     @Override
     public MockInstanceMetadata getInstance(String instanceId) {
         if (instanceIdToMockInstanceMap.containsKey(instanceId)) {
-            MockInstanceContext mockInstanceContext = instanceIdToMockInstanceMap.get(instanceId).getMockInstanceContext();
+            MockInstanceContext mockInstanceContext = instanceIdToMockInstanceMap.get(instanceId)
+                    .getMockInstanceContext();
             return new MockInstanceMetadata(mockInstanceContext);
         }
         return null;
@@ -193,25 +197,31 @@ public class MockIaasServiceImpl implements MockIaasService {
      */
     @Override
     public void terminateInstance(String instanceId) {
-        synchronized (MockIaasServiceImpl.class) {
-            log.info(String.format("Terminating instance: [instance-id] %s", instanceId));
+        try {
+            synchronized (MockIaasServiceImpl.class) {
+                log.info(String.format("Terminating instance: [instance-id] %s", instanceId));
 
-            MockInstance mockInstance = instanceIdToMockInstanceMap.get(instanceId);
-            if (mockInstance != null) {
-                String serviceName = mockInstance.getMockInstanceContext().getServiceName();
+                MockInstance mockInstance = instanceIdToMockInstanceMap.get(instanceId);
+                if (mockInstance != null) {
+                    String serviceName = mockInstance.getMockInstanceContext().getServiceName();
 
-                mockInstance.terminate();
-                instanceIdToMockInstanceMap.remove(instanceId);
-                mockIaasServiceUtil.persistInRegistry((ConcurrentHashMap<String, MockInstance>) instanceIdToMockInstanceMap);
+                    mockInstance.terminate();
+                    instanceIdToMockInstanceMap.remove(instanceId);
+                    mockIaasServiceUtil
+                            .persistInRegistry((ConcurrentHashMap<String, MockInstance>) instanceIdToMockInstanceMap);
 
-                if (getMemberCount(serviceName) == 0) {
-                    MockHealthStatisticsGenerator.getInstance().stopStatisticsUpdaterTasks(serviceName);
-                }
+                    if (getMemberCount(serviceName) == 0) {
+                        MockHealthStatisticsGenerator.getInstance().stopStatisticsUpdaterTasks(serviceName);
+                    }
 
-                log.info(String.format("Instance terminated successfully: [instance-id] %s", instanceId));
-            } else {
-                log.warn(String.format("Instance not found: [instance-id] %s", instanceId));
+                    log.info(String.format("Instance terminated successfully: [instance-id] %s", instanceId));
+                } else {
+                    log.warn(String.format("Instance not found: [instance-id] %s", instanceId));
+                }
             }
+        } catch (Exception e) {
+            String msg = "Could not terminate mock instance: " + instanceId;
+            log.error(msg, e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/bba650ea/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockInstance.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockInstance.java b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockInstance.java
index 9f03698..a8f3bcc 100644
--- a/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockInstance.java
+++ b/components/org.apache.stratos.mock.iaas/src/main/java/org/apache/stratos/mock/iaas/services/impl/MockInstance.java
@@ -21,6 +21,7 @@ package org.apache.stratos.mock.iaas.services.impl;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.common.domain.NameValuePair;
 import org.apache.stratos.common.threading.StratosThreadPool;
 import org.apache.stratos.messaging.event.Event;
 import org.apache.stratos.messaging.event.instance.notifier.InstanceCleanupClusterEvent;
@@ -33,62 +34,49 @@ import org.apache.stratos.mock.iaas.event.publisher.MockMemberEventPublisher;
 import org.apache.stratos.mock.iaas.statistics.publisher.MockHealthStatisticsNotifier;
 
 import java.io.Serializable;
+import java.util.Properties;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * Mock member definition.
+ * Mock member instance definition.
  */
 public class MockInstance implements Runnable, Serializable {
-
     private static final Log log = LogFactory.getLog(MockInstance.class);
-    private static final ExecutorService eventListenerExecutorService =
-            StratosThreadPool.getExecutorService("mock.iaas.event.listener.thread.pool", 20);
-    private static final ScheduledExecutorService healthStatNotifierExecutorService =
-            StratosThreadPool.getScheduledExecutorService("mock.iaas.health.statistics.notifier.thread.pool", 20);
     private static final int HEALTH_STAT_INTERVAL = 15; // 15 seconds
-
-    private final MockInstanceContext mockMemberContext;
-    private boolean terminated;
+    private final MockInstanceContext mockInstanceContext;
     private transient ScheduledFuture<?> healthStatNotifierScheduledFuture;
     private transient InstanceNotifierEventReceiver instanceNotifierEventReceiver;
-
-    public MockInstance(MockInstanceContext mockMemberContext) {
-        this.mockMemberContext = mockMemberContext;
+    private static final ExecutorService eventListenerExecutorService = StratosThreadPool
+            .getExecutorService("mock.iaas.event.listener.thread.pool", 20);
+    private static final ScheduledExecutorService healthStatNotifierExecutorService = StratosThreadPool
+            .getScheduledExecutorService("mock.iaas.health.statistics.notifier.thread.pool", 20);
+    AtomicBoolean hasGracefullyShutdown = new AtomicBoolean(false);
+
+    public MockInstance(MockInstanceContext mockInstanceContext) {
+        this.mockInstanceContext = mockInstanceContext;
     }
 
     @Override
     public void run() {
         if (log.isInfoEnabled()) {
-            log.info(String.format("Mock member started: [member-id] %s", mockMemberContext.getMemberId()));
+            log.info(String.format("Mock member started: [member-id] %s", mockInstanceContext.getMemberId()));
         }
-
         sleep(5000);
-        MockMemberEventPublisher.publishInstanceStartedEvent(mockMemberContext);
-
+        MockMemberEventPublisher.publishInstanceStartedEvent(mockInstanceContext);
         sleep(5000);
-        MockMemberEventPublisher.publishInstanceActivatedEvent(mockMemberContext);
-
+        MockMemberEventPublisher.publishInstanceActivatedEvent(mockInstanceContext);
         startInstanceNotifierReceiver();
         startHealthStatisticsPublisher();
-
-        while (!terminated) {
-            sleep(1000);
-        }
-
-        stopInstanceNotifierReceiver();
-        stopHealthStatisticsPublisher();
-
-        if (log.isInfoEnabled()) {
-            log.info(String.format("Mock member terminated: [member-id] %s", mockMemberContext.getMemberId()));
-        }
     }
 
     private void startInstanceNotifierReceiver() {
         if (log.isDebugEnabled()) {
-            log.debug("Starting instance notifier event message receiver");
+            log.debug("Starting instance notifier event message receiver for mock member [member-id] "
+                            + mockInstanceContext.getMemberId());
         }
 
         instanceNotifierEventReceiver = new InstanceNotifierEventReceiver();
@@ -96,9 +84,9 @@ public class MockInstance implements Runnable, Serializable {
             @Override
             protected void onEvent(Event event) {
                 InstanceCleanupClusterEvent instanceCleanupClusterEvent = (InstanceCleanupClusterEvent) event;
-                if (mockMemberContext.getClusterId().equals(instanceCleanupClusterEvent.getClusterId()) &&
-                        mockMemberContext.getClusterInstanceId().equals(
-                                instanceCleanupClusterEvent.getClusterInstanceId())) {
+                if (mockInstanceContext.getClusterId().equals(instanceCleanupClusterEvent.getClusterId())
+                        && mockInstanceContext.getClusterInstanceId()
+                        .equals(instanceCleanupClusterEvent.getClusterInstanceId())) {
                     handleMemberTermination();
                 }
             }
@@ -108,7 +96,7 @@ public class MockInstance implements Runnable, Serializable {
             @Override
             protected void onEvent(Event event) {
                 InstanceCleanupMemberEvent instanceCleanupMemberEvent = (InstanceCleanupMemberEvent) event;
-                if (mockMemberContext.getMemberId().equals(instanceCleanupMemberEvent.getMemberId())) {
+                if (mockInstanceContext.getMemberId().equals(instanceCleanupMemberEvent.getMemberId())) {
                     handleMemberTermination();
                 }
             }
@@ -127,21 +115,32 @@ public class MockInstance implements Runnable, Serializable {
     }
 
     private void handleMemberTermination() {
-        MockMemberEventPublisher.publishMaintenanceModeEvent(mockMemberContext);
-        sleep(2000);
-        MockMemberEventPublisher.publishInstanceReadyToShutdownEvent(mockMemberContext);
+        if (!hasGracefullyShutdown.get()) {
+            MockMemberEventPublisher.publishMaintenanceModeEvent(mockInstanceContext);
+            sleep(5000);
+            MockMemberEventPublisher.publishInstanceReadyToShutdownEvent(mockInstanceContext);
+            hasGracefullyShutdown.set(true);
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug(String.format("Mock instance is already gracefully shutdown [member-id] %s",
+                        mockInstanceContext.getMemberId()));
+            }
+        }
     }
 
     private void startHealthStatisticsPublisher() {
         if (log.isDebugEnabled()) {
-            log.debug(String.format("Starting health statistics notifier: [member-id] %s", mockMemberContext.getMemberId()));
+            log.debug(String.format("Starting health statistics notifier: [member-id] %s",
+                    mockInstanceContext.getMemberId()));
         }
 
-        healthStatNotifierScheduledFuture = healthStatNotifierExecutorService.scheduleAtFixedRate(new MockHealthStatisticsNotifier(mockMemberContext),
-                0, HEALTH_STAT_INTERVAL, TimeUnit.SECONDS);
+        healthStatNotifierScheduledFuture = healthStatNotifierExecutorService
+                .scheduleAtFixedRate(new MockHealthStatisticsNotifier(mockInstanceContext), 0, HEALTH_STAT_INTERVAL,
+                        TimeUnit.SECONDS);
 
         if (log.isDebugEnabled()) {
-            log.debug(String.format("Health statistics notifier started: [member-id] %s", mockMemberContext.getMemberId()));
+            log.debug(String.format("Health statistics notifier started: [member-id] %s",
+                    mockInstanceContext.getMemberId()));
         }
     }
 
@@ -161,15 +160,18 @@ public class MockInstance implements Runnable, Serializable {
         try {
             Thread.sleep(time);
         } catch (InterruptedException ignore) {
-            terminate();
         }
     }
 
     public MockInstanceContext getMockInstanceContext() {
-        return mockMemberContext;
+        return mockInstanceContext;
     }
 
     public void terminate() {
-        terminated = true;
+        stopInstanceNotifierReceiver();
+        stopHealthStatisticsPublisher();
+        if (log.isInfoEnabled()) {
+            log.info(String.format("Mock member terminated: [member-id] %s", mockInstanceContext.getMemberId()));
+        }
     }
 }


[4/4] stratos git commit: Removing metadata service features from as, cc p2 profiles and removing metadata client features from all p2 profiles since it is not being used

Posted by ra...@apache.org.
Removing metadata service features from as, cc p2 profiles and removing metadata client features from all p2 profiles since it is not being used


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/ade33aa7
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/ade33aa7
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/ade33aa7

Branch: refs/heads/stratos-4.1.x
Commit: ade33aa7cf8ec5ab07ebbab70371d57749b7f3a2
Parents: cd18da5
Author: Akila Perera <ra...@gmail.com>
Authored: Tue Oct 13 13:01:08 2015 +0530
Committer: Akila Perera <ra...@gmail.com>
Committed: Wed Oct 14 16:43:04 2015 +0530

----------------------------------------------------------------------
 .../org.apache.stratos.autoscaler/pom.xml       |  7 +----
 .../org.apache.stratos.cloud.controller/pom.xml |  7 +----
 .../apache/stratos/metadata/service/Utils.java  | 18 +++++--------
 products/stratos/modules/p2-profile-gen/pom.xml | 27 +-------------------
 4 files changed, 9 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/ade33aa7/components/org.apache.stratos.autoscaler/pom.xml
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/pom.xml b/components/org.apache.stratos.autoscaler/pom.xml
index 150e380..026cc0e 100644
--- a/components/org.apache.stratos.autoscaler/pom.xml
+++ b/components/org.apache.stratos.autoscaler/pom.xml
@@ -164,11 +164,6 @@
             <version>${carbon.kernel.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.stratos</groupId>
-            <artifactId>org.apache.stratos.metadata.client</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
             <groupId>org.wso2.carbon</groupId>
             <artifactId>org.wso2.carbon.identity.oauth</artifactId>
             <version>4.2.3</version>
@@ -250,4 +245,4 @@
             </resource>
         </resources>
     </build>
-</project>
\ No newline at end of file
+</project>

http://git-wip-us.apache.org/repos/asf/stratos/blob/ade33aa7/components/org.apache.stratos.cloud.controller/pom.xml
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/pom.xml b/components/org.apache.stratos.cloud.controller/pom.xml
index 62165b5..e5ca7da 100644
--- a/components/org.apache.stratos.cloud.controller/pom.xml
+++ b/components/org.apache.stratos.cloud.controller/pom.xml
@@ -138,11 +138,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.stratos</groupId>
-            <artifactId>org.apache.stratos.metadata.client</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.stratos</groupId>
             <artifactId>org.apache.stratos.mock.iaas.client</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -229,4 +224,4 @@
             <version>${jclouds.version}</version>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>

http://git-wip-us.apache.org/repos/asf/stratos/blob/ade33aa7/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/Utils.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/Utils.java b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/Utils.java
index f7b5491..b56ea91 100644
--- a/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/Utils.java
+++ b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/Utils.java
@@ -21,24 +21,18 @@ package org.apache.stratos.metadata.service;
 public class Utils {
 
     public static String buildMessage(int errorCode, String errorMessage) {
-        String jsonResponse =
-                "{\"Error\":{" + " \"errorCode\": \" " + errorCode + "\"," +
-                        " \"errorMessage\": \" " + errorMessage + "\"" + "}" + "}";
-        return jsonResponse;
+        return "{\"Error\":{" + " \"errorCode\": \" " + errorCode + "\"," +
+                " \"errorMessage\": \" " + errorMessage + "\"" + "}" + "}";
     }
 
     public static String buildMessage(String errorMessage) {
-        String jsonResponse =
-                "{\"Error\":{" + " \"errorCode\": \" " + -1234 + "\"," +
-                        " \"errorMessage\": \" " + errorMessage + "\"" + "}" + "}";
-        return jsonResponse;
+        return "{\"Error\":{" + " \"errorCode\": \" " + -1234 + "\"," +
+                " \"errorMessage\": \" " + errorMessage + "\"" + "}" + "}";
     }
 
     public static String buildAuthenticationSuccessMessage(String jSessionId) {
-        String jsonResponse =
-                "{\"Success\":{" + " \"sessionId\": \"" + jSessionId + "\"" + "}" +
-                        "}";
-        return jsonResponse;
+        return "{\"Success\":{" + " \"sessionId\": \"" + jSessionId + "\"" + "}" +
+                "}";
     }
 
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/ade33aa7/products/stratos/modules/p2-profile-gen/pom.xml
----------------------------------------------------------------------
diff --git a/products/stratos/modules/p2-profile-gen/pom.xml b/products/stratos/modules/p2-profile-gen/pom.xml
index 51d9abb..1834fc7 100644
--- a/products/stratos/modules/p2-profile-gen/pom.xml
+++ b/products/stratos/modules/p2-profile-gen/pom.xml
@@ -815,14 +815,6 @@
                                     <version>${carbon.platform.patch.version.4.2.1}</version>
                                 </feature>
                                 <feature>
-                                    <id>org.apache.stratos.metadata.service.feature.group</id>
-                                    <version>${project.version}</version>
-                                </feature>
-                                <feature>
-                                    <id>org.apache.stratos.metadata.client.feature.group</id>
-                                    <version>${project.version}</version>
-                                </feature>
-                                <feature>
                                     <id>org.apache.stratos.common.feature.group</id>
                                     <version>${project.version}</version>
                                 </feature>
@@ -905,14 +897,6 @@
                                     <id>org.wso2.carbon.event.server.feature.group</id>
                                     <version>${carbon.platform.patch.version.4.2.1}</version>
                                 </feature>
-                                <feature>
-                                    <id>org.apache.stratos.metadata.service.feature.group</id>
-                                    <version>${project.version}</version>
-                                </feature>
-                                <feature>
-                                    <id>org.apache.stratos.metadata.client.feature.group</id>
-                                    <version>${project.version}</version>
-                                </feature>
                             </features>
                         </configuration>
                     </execution>
@@ -1178,10 +1162,6 @@
 
                                 <!-- Stratos features -->
                                 <feature>
-                                    <id>org.apache.stratos.metadata.client.feature.group</id>
-                                    <version>${project.version}</version>
-                                </feature>
-                                <feature>
                                     <id>org.apache.stratos.custom.handlers.feature.group</id>
                                     <version>${project.version}</version>
                                 </feature>
@@ -1221,15 +1201,10 @@
                                     <id>org.apache.stratos.common.feature.group</id>
                                     <version>${project.version}</version>
                                 </feature>
-                                <!-- Mock IaaS features -->
                                 <feature>
                                     <id>org.apache.stratos.mock.iaas.api.feature.group</id>
                                     <version>${project.version}</version>
                                 </feature>
-                                <feature>
-                                    <id>org.apache.stratos.metadata.service.feature.group</id>
-                                    <version>${project.version}</version>
-                                </feature>
                             </features>
                         </configuration>
                     </execution>
@@ -1257,4 +1232,4 @@
             </plugin>
         </plugins>
     </build>
-</project>
\ No newline at end of file
+</project>


[2/4] stratos git commit: Fix STRATOS-1585: Threads can override resource paths in metadata api registry

Posted by ra...@apache.org.
Fix STRATOS-1585: Threads can override resource paths in metadata api registry


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/4b8d439b
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/4b8d439b
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/4b8d439b

Branch: refs/heads/stratos-4.1.x
Commit: 4b8d439b34097715f9cddfab4948f4c14e472653
Parents: ade33aa
Author: Akila Perera <ra...@gmail.com>
Authored: Wed Oct 14 16:23:23 2015 +0530
Committer: Akila Perera <ra...@gmail.com>
Committed: Wed Oct 14 16:43:04 2015 +0530

----------------------------------------------------------------------
 .../service/MetadataTopologyEventReceiver.java  |  95 ++++++++
 .../metadata/service/api/MetadataApi.java       |  56 +++--
 .../service/registry/MetadataApiRegistry.java   | 223 +++++++++++--------
 3 files changed, 255 insertions(+), 119 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/4b8d439b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/MetadataTopologyEventReceiver.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/MetadataTopologyEventReceiver.java b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/MetadataTopologyEventReceiver.java
new file mode 100644
index 0000000..f483995
--- /dev/null
+++ b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/MetadataTopologyEventReceiver.java
@@ -0,0 +1,95 @@
+/*
+ * 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.metadata.service;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.common.concurrent.locks.ReadWriteLock;
+import org.apache.stratos.common.threading.StratosThreadPool;
+import org.apache.stratos.messaging.event.Event;
+import org.apache.stratos.messaging.event.application.ApplicationCreatedEvent;
+import org.apache.stratos.messaging.event.application.ApplicationDeletedEvent;
+import org.apache.stratos.messaging.event.topology.ApplicationClustersCreatedEvent;
+import org.apache.stratos.messaging.event.topology.ApplicationClustersRemovedEvent;
+import org.apache.stratos.messaging.listener.application.ApplicationCreatedEventListener;
+import org.apache.stratos.messaging.listener.application.ApplicationDeletedEventListener;
+import org.apache.stratos.messaging.listener.topology.ApplicationClustersCreatedEventListener;
+import org.apache.stratos.messaging.listener.topology.ApplicationClustersRemovedEventListener;
+import org.apache.stratos.messaging.message.receiver.topology.TopologyEventReceiver;
+import org.apache.stratos.metadata.service.registry.MetadataApiRegistry;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Topology receiver class for metadata service
+ */
+public class MetadataTopologyEventReceiver {
+    private static final Log log = LogFactory.getLog(MetadataTopologyEventReceiver.class);
+
+    private TopologyEventReceiver topologyEventReceiver;
+    private ExecutorService executorService;
+    public static final String METADATA_SERVICE_THREAD_POOL_ID = "metadata.service.thread.pool.";
+
+    public MetadataTopologyEventReceiver() {
+        this.topologyEventReceiver = new TopologyEventReceiver();
+        executorService = StratosThreadPool.getExecutorService(METADATA_SERVICE_THREAD_POOL_ID, 10);
+        addEventListeners();
+    }
+
+    private void addEventListeners() {
+        topologyEventReceiver.addEventListener(new ApplicationClustersCreatedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                ApplicationClustersCreatedEvent appClustersCreatedEvent = (ApplicationClustersCreatedEvent) event;
+                String applicationId = appClustersCreatedEvent.getAppId();
+                MetadataApiRegistry.getApplicationIdToReadWriteLockMap()
+                        .put(applicationId, new ReadWriteLock(METADATA_SERVICE_THREAD_POOL_ID.concat(applicationId)));
+            }
+        });
+
+        topologyEventReceiver.addEventListener(new ApplicationClustersRemovedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                ApplicationClustersRemovedEvent appClustersRemovedEvent = (ApplicationClustersRemovedEvent) event;
+                String applicationId = appClustersRemovedEvent.getAppId();
+                MetadataApiRegistry.getApplicationIdToReadWriteLockMap().remove(applicationId);
+            }
+        });
+    }
+
+    public void execute() {
+        topologyEventReceiver.setExecutorService(getExecutorService());
+        topologyEventReceiver.execute();
+
+        if (log.isInfoEnabled()) {
+            log.info("Metadata service topology receiver started.");
+        }
+    }
+
+    public void terminate() {
+        topologyEventReceiver.terminate();
+        if (log.isInfoEnabled()) {
+            log.info("Metadata service topology receiver stopped.");
+        }
+    }
+
+    public ExecutorService getExecutorService() {
+        return executorService;
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4b8d439b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/api/MetadataApi.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/api/MetadataApi.java b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/api/MetadataApi.java
index 712bcaa..53174e0 100644
--- a/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/api/MetadataApi.java
+++ b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/api/MetadataApi.java
@@ -44,7 +44,13 @@ public class MetadataApi {
      * Meta data admin configuration loading
      */
     public MetadataApi() {
-        registry = new MetadataApiRegistry();
+        try {
+            registry = new MetadataApiRegistry();
+        } catch (Exception e) {
+            String msg = "Could not initialize Metadata API";
+            log.error(msg, e);
+            throw new RuntimeException(msg);
+        }
     }
 
     @GET
@@ -57,8 +63,7 @@ public class MetadataApi {
         List<Property> properties;
         Property[] propertiesArr = null;
         try {
-            properties = registry
-                    .getApplicationProperties(applicationId);
+            properties = registry.getApplicationProperties(applicationId);
             if (properties != null) {
                 propertiesArr = new Property[properties.size()];
                 propertiesArr = properties.toArray(propertiesArr);
@@ -83,13 +88,12 @@ public class MetadataApi {
     @Produces("application/json")
     @Consumes("application/json")
     public Response getClusterProperties(@PathParam("application_id") String applicationId,
-                                         @PathParam("cluster_id") String clusterId) throws RestAPIException {
+            @PathParam("cluster_id") String clusterId) throws RestAPIException {
 
         List<Property> properties;
         Property[] propertiesArr = null;
         try {
-            properties = registry
-                    .getClusterProperties(applicationId, clusterId);
+            properties = registry.getClusterProperties(applicationId, clusterId);
             if (properties != null) {
                 propertiesArr = new Property[properties.size()];
                 propertiesArr = properties.toArray(propertiesArr);
@@ -114,11 +118,9 @@ public class MetadataApi {
     @Produces("application/json")
     @Consumes("application/json")
     public Response getApplicationProperty(@PathParam("application_id") String applicationId,
-                                           @PathParam("property_name") String propertyName)
-            throws RestAPIException {
+            @PathParam("property_name") String propertyName) throws RestAPIException {
         List<Property> properties;
 
-
         Property property = null;
         try {
             properties = registry.getApplicationProperties(applicationId);
@@ -151,8 +153,8 @@ public class MetadataApi {
     @Produces("application/json")
     @Consumes("application/json")
     public Response getClusterProperty(@PathParam("application_id") String applicationId,
-                                       @PathParam("cluster_id") String clusterId,
-                                       @PathParam("property_name") String propertyName) throws RestAPIException {
+            @PathParam("cluster_id") String clusterId, @PathParam("property_name") String propertyName)
+            throws RestAPIException {
         List<Property> properties;
 
         Property property = null;
@@ -186,8 +188,7 @@ public class MetadataApi {
     @Path("applications/{application_id}/properties")
     @Produces("application/json")
     @Consumes("application/json")
-    public Response addPropertyToApplication(@PathParam("application_id") String applicationId,
-                                               Property property)
+    public Response addPropertyToApplication(@PathParam("application_id") String applicationId, Property property)
             throws RestAPIException {
         URI url = uriInfo.getAbsolutePathBuilder().path(applicationId).build();
 
@@ -206,8 +207,7 @@ public class MetadataApi {
     @Produces("application/json")
     @Consumes("application/json")
     public Response addPropertyToCluster(@PathParam("application_id") String applicationId,
-                                         @PathParam("cluster_id") String clusterId, Property property)
-            throws RestAPIException {
+            @PathParam("cluster_id") String clusterId, Property property) throws RestAPIException {
         URI url = uriInfo.getAbsolutePathBuilder().path(applicationId + "/" + clusterId).build();
 
         try {
@@ -230,9 +230,7 @@ public class MetadataApi {
         try {
             boolean deleted = registry.deleteApplicationProperties(applicationId);
             if (!deleted) {
-                log.warn(String.format(
-                        "No metadata is associated with given appId %s",
-                        applicationId));
+                log.warn(String.format("No metadata is associated with given appId %s", applicationId));
             }
         } catch (RegistryException e) {
             String msg = "Resource attached with appId could not be deleted [application-id] " + applicationId;
@@ -247,18 +245,16 @@ public class MetadataApi {
     @Produces("application/json")
     @Consumes("application/json")
     public Response deleteApplicationProperty(@PathParam("application_id") String applicationId,
-                                              @PathParam("property_name") String propertyName)
-            throws RestAPIException {
+            @PathParam("property_name") String propertyName) throws RestAPIException {
 
         try {
             boolean deleted = registry.removePropertyFromApplication(applicationId, propertyName);
             if (!deleted) {
-                log.warn(String.format(
-                        "No metadata is associated with given appId %s",
-                        applicationId));
+                log.warn(String.format("No metadata is associated with given appId %s", applicationId));
             }
         } catch (RegistryException e) {
-            String msg = String.format("[application-id] %s [property-name] deletion failed ", applicationId, propertyName);
+            String msg = String
+                    .format("[application-id] %s [property-name] %s deletion failed ", applicationId, propertyName);
             log.error(msg, e);
             throw new RestAPIException(msg, e);
         }
@@ -270,20 +266,18 @@ public class MetadataApi {
     @Produces("application/json")
     @Consumes("application/json")
     public Response deleteApplicationPropertyValue(@PathParam("application_id") String applicationId,
-                                                   @PathParam("property_name") String propertyName,
-                                                   @PathParam("value") String propertyValue)
+            @PathParam("property_name") String propertyName, @PathParam("value") String propertyValue)
             throws RestAPIException {
 
         try {
             boolean deleted = registry.removePropertyValueFromApplication(applicationId, propertyName, propertyValue);
             if (!deleted) {
-                log.warn(String.format(
-                        "No metadata is associated with given [application-id] %s",
-                        applicationId));
+                log.warn(String.format("No metadata is associated with given [application-id] %s", applicationId));
             }
         } catch (RegistryException e) {
-            String msg = String.format("[application-id] %s [property-name] %s [value] %s deletion failed" +
-                    applicationId, propertyName, propertyValue);
+            String msg = String
+                    .format("[application-id] %s [property-name] %s [value] %s deletion failed" + applicationId,
+                            propertyName, propertyValue);
             log.error(msg, e);
             throw new RestAPIException(msg, e);
         }

http://git-wip-us.apache.org/repos/asf/stratos/blob/4b8d439b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/registry/MetadataApiRegistry.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/registry/MetadataApiRegistry.java b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/registry/MetadataApiRegistry.java
index abd3f4b..f6b1ee4 100644
--- a/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/registry/MetadataApiRegistry.java
+++ b/components/org.apache.stratos.metadata.service/src/main/java/org/apache/stratos/metadata/service/registry/MetadataApiRegistry.java
@@ -21,6 +21,8 @@ package org.apache.stratos.metadata.service.registry;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.common.concurrent.locks.ReadWriteLock;
+import org.apache.stratos.metadata.service.MetadataTopologyEventReceiver;
 import org.apache.stratos.metadata.service.definition.Property;
 import org.wso2.carbon.context.PrivilegedCarbonContext;
 import org.wso2.carbon.registry.core.Registry;
@@ -33,7 +35,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.core.Context;
 import java.util.*;
 
-
 /**
  * Carbon registry implementation
  */
@@ -44,8 +45,12 @@ public class MetadataApiRegistry implements DataStore {
     private static Log log = LogFactory.getLog(MetadataApiRegistry.class);
     @Context
     HttpServletRequest httpServletRequest;
+    private static final Map<String, ReadWriteLock> applicationIdToReadWriteLockMap = new HashMap<>();
+    private MetadataTopologyEventReceiver metadataTopologyEventReceiver;
 
     public MetadataApiRegistry() {
+        metadataTopologyEventReceiver = new MetadataTopologyEventReceiver();
+        metadataTopologyEventReceiver.execute();
     }
 
     public List<Property> getApplicationProperties(String applicationName) throws RegistryException {
@@ -90,7 +95,6 @@ public class MetadataApiRegistry implements DataStore {
         Registry tempRegistry = getRegistry();
         String resourcePath = mainResource + applicationName + "/" + clusterId;
 
-
         if (!tempRegistry.resourceExists(resourcePath)) {
             return null;
         }
@@ -123,7 +127,7 @@ public class MetadataApiRegistry implements DataStore {
     public void addPropertyToApplication(String applicationId, Property property) throws RegistryException {
         Registry registry = getRegistry();
         String resourcePath = mainResource + applicationId;
-
+        acquireWriteLock(applicationId);
         try {
             // We are using only super tenant registry to persist
             PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
@@ -135,7 +139,7 @@ public class MetadataApiRegistry implements DataStore {
             } else {
                 nodeResource = registry.newCollection();
                 if (log.isDebugEnabled()) {
-                    log.debug("Registry resource is create at path for application: " + nodeResource.getPath());
+                    log.debug("Registry resource created for application: " + applicationId);
                 }
             }
 
@@ -143,34 +147,39 @@ public class MetadataApiRegistry implements DataStore {
             for (String value : property.getValues()) {
                 if (!propertyValueExist(nodeResource, property.getKey(), value)) {
                     updated = true;
-                    log.info(String.format("Registry property is added: [resource-path] %s " +
-                                    "[Property Name] %s [Property Value] %s",
-                            resourcePath, property.getKey(), value));
+                    if (log.isDebugEnabled()) {
+                        log.debug(String.format("Registry property is added: [resource-path] %s "
+                                        + "[Property Name] %s [Property Value] %s", resourcePath, property.getKey(),
+                                value));
+                    }
                     nodeResource.addProperty(property.getKey(), value);
                 } else {
-                    log.info(String.format("Property value already exist property=%s value=%s", property.getKey(), value));
+                    if (log.isDebugEnabled()) {
+                        log.debug(String.format("Property value already exist property=%s value=%s", property.getKey(),
+                                value));
+                    }
                 }
             }
-
             if (updated) {
                 registry.put(resourcePath, nodeResource);
+                if (log.isDebugEnabled()) {
+                    log.debug(String.format(
+                            "Registry property is persisted: [resource-path] %s [Property Name] %s [Property Values] "
+                                    + "%s", resourcePath, property.getKey(), Arrays.asList(property.getValues())));
+                }
             }
-            //registry.commitTransaction();
         } catch (Exception e) {
             String msg = "Failed to persist properties in registry: " + resourcePath;
-            //registry.rollbackTransaction();
             log.error(msg, e);
             throw new RegistryException(msg, e);
+        } finally {
+            releaseWriteLock(applicationId);
         }
     }
 
     private boolean propertyValueExist(Resource nodeResource, String key, String value) {
         List<String> properties = nodeResource.getPropertyValues(key);
-        if (properties == null) {
-            return false;
-        } else {
-            return properties.contains(value);
-        }
+        return properties != null && properties.contains(value);
 
     }
 
@@ -178,14 +187,12 @@ public class MetadataApiRegistry implements DataStore {
             throws RegistryException {
         Registry registry = getRegistry();
         String resourcePath = mainResource + applicationId;
-
-        // We are using only super tenant registry to persist
-        PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
-        ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
-        ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
-
+        acquireWriteLock(applicationId);
         try {
-            registry.beginTransaction();
+            // We are using only super tenant registry to persist
+            PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+            ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
+            ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
             Resource nodeResource;
             if (registry.resourceExists(resourcePath)) {
                 nodeResource = registry.get(resourcePath);
@@ -195,20 +202,13 @@ public class MetadataApiRegistry implements DataStore {
             }
             nodeResource.removePropertyValue(propertyName, valueToRemove);
             registry.put(resourcePath, nodeResource);
-            registry.commitTransaction();
-
-            log.info(String.format("Application %s property %s value %s is removed from metadata ",
-                    applicationId, propertyName, valueToRemove));
+            log.info(String.format("Application %s property %s value %s is removed from metadata ", applicationId,
+                    propertyName, valueToRemove));
             return true;
-        }catch (Exception e){
-            try {
-                registry.rollbackTransaction();
-            } catch (RegistryException e1) {
-                if (log.isErrorEnabled()) {
-                    log.error("Could not rollback transaction", e1);
-                }
-            }
+        } catch (Exception e) {
             throw new RegistryException("Could not remove registry resource: [resource-path] " + resourcePath, e);
+        } finally {
+            releaseWriteLock(applicationId);
         }
     }
 
@@ -220,30 +220,33 @@ public class MetadataApiRegistry implements DataStore {
      * @param property
      * @throws RegistryException
      */
-    public void addPropertyToCluster(String applicationId, String clusterId, Property property) throws RegistryException {
+    public void addPropertyToCluster(String applicationId, String clusterId, Property property)
+            throws RegistryException {
         Registry registry = getRegistry();
         String resourcePath = mainResource + applicationId + "/" + clusterId;
-
-        // We are using only super tenant registry to persist
-        PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
-        ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
-        ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
-
-        Resource nodeResource = null;
-        if (registry.resourceExists(resourcePath)) {
-            nodeResource = registry.get(resourcePath);
-        } else {
-            nodeResource = registry.newResource();
-            if (log.isDebugEnabled()) {
-                log.debug("Registry resource is create at path for cluster" + nodeResource.getPath() + " for cluster");
+        acquireWriteLock(applicationId);
+        try {
+            // We are using only super tenant registry to persist
+            PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+            ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
+            ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+            Resource nodeResource = null;
+            if (registry.resourceExists(resourcePath)) {
+                nodeResource = registry.get(resourcePath);
+            } else {
+                nodeResource = registry.newResource();
+                if (log.isDebugEnabled()) {
+                    log.debug("Registry resource created for cluster" + clusterId);
+                }
             }
+            nodeResource.setProperty(property.getKey(), Arrays.asList(property.getValues()));
+            registry.put(resourcePath, nodeResource);
+            log.info(String.format(
+                    "Registry property is persisted: [resource-path] %s [Property Name] %s [Property Values] %s",
+                    resourcePath, property.getKey(), Arrays.asList(property.getValues())));
+        } finally {
+            releaseWriteLock(applicationId);
         }
-
-        nodeResource.setProperty(property.getKey(), Arrays.asList(property.getValues()));
-        registry.put(resourcePath, nodeResource);
-
-        log.info(String.format("Registry property is persisted: [resource-path] %s [Property Name] %s [Property Values] %s",
-                resourcePath, property.getKey(), Arrays.asList(property.getValues())));
     }
 
     private UserRegistry getRegistry() throws RegistryException {
@@ -262,31 +265,24 @@ public class MetadataApiRegistry implements DataStore {
         if (StringUtils.isBlank(applicationId)) {
             throw new IllegalArgumentException("Application ID can not be null");
         }
-
-        // We are using only super tenant registry to persist
-        PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
-        ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
-        ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
         Registry registry = getRegistry();
         String resourcePath = mainResource + applicationId;
+        acquireWriteLock(applicationId);
         try {
-            registry.beginTransaction();
+            // We are using only super tenant registry to persist
+            PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+            ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
+            ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
             if (registry.resourceExists(resourcePath)) {
                 registry.delete(resourcePath);
                 log.info(String.format("Application [application-id ] properties removed from registry %s",
                         applicationId));
             }
-            registry.commitTransaction();
             return true;
-        }catch (Exception e){
-            try {
-                registry.rollbackTransaction();
-            } catch (RegistryException e1) {
-                if (log.isErrorEnabled()) {
-                    log.error("Could not rollback transaction", e1);
-                }
-            }
+        } catch (Exception e) {
             throw new RegistryException("Could not remove registry resource: [resource-path] " + resourcePath, e);
+        } finally {
+            releaseWriteLock(applicationId);
         }
     }
 
@@ -294,30 +290,81 @@ public class MetadataApiRegistry implements DataStore {
             throws org.wso2.carbon.registry.api.RegistryException {
         Registry registry = getRegistry();
         String resourcePath = mainResource + applicationId;
-        // We are using only super tenant registry to persist
-        PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
-        ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
-        ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
-
+        acquireWriteLock(applicationId);
         Resource nodeResource;
-        if (registry.resourceExists(resourcePath)) {
-            nodeResource = registry.get(resourcePath);
-            if (nodeResource.getProperty(propertyName) == null) {
-                log.info(String.format("[application-id] %s does not have a property [property-name] %s ", applicationId,
-                        propertyName));
-                return false;
+        try {
+            // We are using only super tenant registry to persist
+            PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+            ctx.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
+            ctx.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+            if (registry.resourceExists(resourcePath)) {
+                nodeResource = registry.get(resourcePath);
+                if (nodeResource.getProperty(propertyName) == null) {
+                    log.info(String.format("[application-id] %s does not have a property [property-name] %s ",
+                            applicationId, propertyName));
+                    return false;
+                } else {
+                    nodeResource.removeProperty(propertyName);
+                    registry.put(resourcePath, nodeResource);
+                }
             } else {
-                nodeResource.removeProperty(propertyName);
-                registry.put(resourcePath, nodeResource);
+                log.error("Registry resource not not found at " + resourcePath);
+                return false;
             }
+
+            log.info(String.format("Application [application-id] %s property [property-name] %s removed from Registry ",
+                    applicationId, propertyName));
+            return true;
+        } finally {
+            releaseWriteLock(applicationId);
+        }
+    }
+
+    public void acquireReadLock(String applicationId) {
+        if (applicationIdToReadWriteLockMap.get(applicationId) == null) {
+            throw new RuntimeException(
+                    String.format("Invalid application [application-id] %s not found. Failed to acquire read lock.",
+                            applicationId));
         } else {
-            log.error("Registry resource not not found at " + resourcePath);
-            return false;
+            applicationIdToReadWriteLockMap.get(applicationId).acquireReadLock();
         }
+    }
 
-        log.info(String.format("Application [application-id] %s property [property-name] %s removed from Registry ",
-                applicationId, propertyName));
-        return true;
+    public void acquireWriteLock(String applicationId) {
+        if (applicationIdToReadWriteLockMap.get(applicationId) == null) {
+            throw new RuntimeException(
+                    String.format("Invalid application [application-id] %s not found. Failed to acquire write lock.",
+                            applicationId));
+        } else {
+            applicationIdToReadWriteLockMap.get(applicationId).acquireWriteLock();
+        }
     }
 
+    public void releaseReadLock(String applicationId) {
+        if (applicationIdToReadWriteLockMap.get(applicationId) == null) {
+            throw new RuntimeException(
+                    String.format("Invalid application [application-id] %s not found. Failed to release read lock.",
+                            applicationId));
+        } else {
+            applicationIdToReadWriteLockMap.get(applicationId).releaseReadLock();
+        }
+    }
+
+    public void releaseWriteLock(String applicationId) {
+        if (applicationIdToReadWriteLockMap.get(applicationId) == null) {
+            throw new RuntimeException(
+                    String.format("Invalid application [application-id] %s not found. Failed to release write lock.",
+                            applicationId));
+        } else {
+            applicationIdToReadWriteLockMap.get(applicationId).releaseWriteLock();
+        }
+    }
+
+    public static Map<String, ReadWriteLock> getApplicationIdToReadWriteLockMap() {
+        return applicationIdToReadWriteLockMap;
+    }
+
+    public void stopTopologyReceiver() {
+        metadataTopologyEventReceiver.terminate();
+    }
 }


[3/4] stratos git commit: Integration test for metadata service

Posted by ra...@apache.org.
Integration test for metadata service


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/4f021496
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/4f021496
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/4f021496

Branch: refs/heads/stratos-4.1.x
Commit: 4f021496f6bf25628f2128edf44da04e75527b89
Parents: 4b8d439
Author: Akila Perera <ra...@gmail.com>
Authored: Wed Oct 14 16:25:00 2015 +0530
Committer: Akila Perera <ra...@gmail.com>
Committed: Wed Oct 14 16:43:04 2015 +0530

----------------------------------------------------------------------
 .../modules/integration/test-common/pom.xml     |   7 +-
 .../integration/common/RestConstants.java       |   1 +
 .../integration/common/TopologyHandler.java     | 115 ++++----
 .../common/rest/IntegrationMockClient.java      |   3 +-
 .../integration/common/rest/RestClient.java     | 272 ++++++++++++++-----
 .../tests/StratosIntegrationTest.java           |  26 +-
 .../SampleApplicationStartupTestCase.java       |  66 ++++-
 .../src/test/resources/common/log4j.properties  |   5 +-
 .../src/test/resources/test-suite-smoke.xml     |   2 +-
 9 files changed, 345 insertions(+), 152 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-common/pom.xml
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-common/pom.xml b/products/stratos/modules/integration/test-common/pom.xml
index df26f50..6822a32 100755
--- a/products/stratos/modules/integration/test-common/pom.xml
+++ b/products/stratos/modules/integration/test-common/pom.xml
@@ -114,6 +114,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.stratos</groupId>
+            <artifactId>org.apache.stratos.metadata.client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.stratos</groupId>
             <artifactId>org.apache.stratos.mock.iaas.client</artifactId>
             <version>${project.version}</version>
             <scope>compile</scope>
@@ -123,4 +128,4 @@
             <artifactId>org.jacoco.agent</artifactId>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/RestConstants.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/RestConstants.java b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/RestConstants.java
index f3577bc..1778bb9 100644
--- a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/RestConstants.java
+++ b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/RestConstants.java
@@ -21,6 +21,7 @@ package org.apache.stratos.integration.common;
  */
 public class RestConstants {
     public static final String API = "api";
+    public static final String METADATA_API = "/metadata/api";
     public static final String AUTOSCALING_POLICIES = "/" + API + "/autoscalingPolicies";
     public static final String USERS = "/" + API + "/users";
     public static final String TENANTS = "/" + API + "/tenants";

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/TopologyHandler.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/TopologyHandler.java b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/TopologyHandler.java
index 2144b12..721a5c6 100644
--- a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/TopologyHandler.java
+++ b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/TopologyHandler.java
@@ -21,7 +21,6 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.stratos.autoscaler.stub.pojo.ApplicationContext;
 import org.apache.stratos.common.client.AutoscalerServiceClient;
 import org.apache.stratos.common.threading.StratosThreadPool;
-import org.apache.stratos.integration.common.rest.IntegrationMockClient;
 import org.apache.stratos.messaging.domain.application.*;
 import org.apache.stratos.messaging.domain.instance.ClusterInstance;
 import org.apache.stratos.messaging.domain.instance.GroupInstance;
@@ -38,12 +37,10 @@ import org.apache.stratos.messaging.message.receiver.application.ApplicationMana
 import org.apache.stratos.messaging.message.receiver.application.ApplicationsEventReceiver;
 import org.apache.stratos.messaging.message.receiver.topology.TopologyEventReceiver;
 import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
+import org.apache.stratos.mock.iaas.client.MockIaasApiClient;
 
 import java.rmi.RemoteException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 
@@ -90,7 +87,6 @@ public class TopologyHandler {
         return topologyHandler;
     }
 
-
     /**
      * Initialize application event receiver
      */
@@ -124,8 +120,7 @@ public class TopologyHandler {
         while (!applicationTopologyInitialized) {
             try {
                 Thread.sleep(1000);
-            }
-            catch (InterruptedException ignore) {
+            } catch (InterruptedException ignore) {
             }
             applicationTopologyInitialized = ApplicationManager.getApplications().isInitialized();
             if ((System.currentTimeMillis() - startTime) > APPLICATION_TOPOLOGY_TIMEOUT) {
@@ -145,8 +140,7 @@ public class TopologyHandler {
         while (!topologyInitialized) {
             try {
                 Thread.sleep(1000);
-            }
-            catch (InterruptedException ignore) {
+            } catch (InterruptedException ignore) {
             }
             topologyInitialized = TopologyManager.getTopology().isInitialized();
             if ((System.currentTimeMillis() - startTime) > APPLICATION_TOPOLOGY_TIMEOUT) {
@@ -167,8 +161,7 @@ public class TopologyHandler {
         while (!((application != null) && (application.getStatus() == status))) {
             try {
                 Thread.sleep(1000);
-            }
-            catch (InterruptedException ignore) {
+            } catch (InterruptedException ignore) {
             }
             application = ApplicationManager.getApplications().getApplication(applicationName);
             if ((System.currentTimeMillis() - startTime) > APPLICATION_ACTIVATION_TIMEOUT) {
@@ -188,8 +181,7 @@ public class TopologyHandler {
      */
     public void assertGroupActivation(String applicationName) {
         Application application = ApplicationManager.getApplications().getApplication(applicationName);
-        assertNotNull(String.format("Application is not found: [application-id] %s",
-                applicationName), application);
+        assertNotNull(String.format("Application is not found: [application-id] %s", applicationName), application);
 
         Collection<Group> groups = application.getAllGroupsRecursively();
         for (Group group : groups) {
@@ -204,24 +196,23 @@ public class TopologyHandler {
      */
     public void assertClusterActivation(String applicationName) {
         Application application = ApplicationManager.getApplications().getApplication(applicationName);
-        assertNotNull(String.format("Application is not found: [application-id] %s",
-                applicationName), application);
+        assertNotNull(String.format("Application is not found: [application-id] %s", applicationName), application);
 
         Set<ClusterDataHolder> clusterDataHolderSet = application.getClusterDataRecursively();
         for (ClusterDataHolder clusterDataHolder : clusterDataHolderSet) {
             String serviceName = clusterDataHolder.getServiceType();
             String clusterId = clusterDataHolder.getClusterId();
             Service service = TopologyManager.getTopology().getService(serviceName);
-            assertNotNull(String.format("Service is not found: [application-id] %s [service] %s",
-                    applicationName, serviceName), service);
+            assertNotNull(String.format("Service is not found: [application-id] %s [service] %s", applicationName,
+                    serviceName), service);
 
             Cluster cluster = service.getCluster(clusterId);
             assertNotNull(String.format("Cluster is not found: [application-id] %s [service] %s [cluster-id] %s",
                     applicationName, serviceName, clusterId), cluster);
             for (Member member : cluster.getMembers()) {
-                log.info(String.format("Member [member-id] %s found in cluster instance [cluster-instance] %s of " +
-                        "cluster [cluster-id] %s", member
-                        .getMemberId(), member.getClusterInstanceId(), member.getClusterId()));
+                log.info(String.format("Member [member-id] %s found in cluster instance [cluster-instance] %s of "
+                                + "cluster [cluster-id] %s", member.getMemberId(), member.getClusterInstanceId(),
+                        member.getClusterId()));
             }
             boolean clusterActive = false;
             int activeInstances;
@@ -259,8 +250,8 @@ public class TopologyHandler {
             if (cartridgeName.equals(serviceName)) {
                 String clusterId = clusterDataHolder.getClusterId();
                 Service service = TopologyManager.getTopology().getService(serviceName);
-                assertNotNull(String.format("Service is not found: [application-id] %s [service] %s",
-                        applicationName, serviceName), service);
+                assertNotNull(String.format("Service is not found: [application-id] %s [service] %s", applicationName,
+                        serviceName), service);
 
                 Cluster cluster = service.getCluster(clusterId);
                 assertNotNull(String.format("Cluster is not found: [application-id] %s [service] %s [cluster-id] %s",
@@ -282,7 +273,7 @@ public class TopologyHandler {
      * @param memberId
      * @param mockIaasApiClient
      */
-    public void terminateMemberInMockIaas(String memberId, IntegrationMockClient mockIaasApiClient) {
+    public void terminateMemberInMockIaas(String memberId, MockIaasApiClient mockIaasApiClient) {
         boolean memberTerminated = false;
         memberTerminated = mockIaasApiClient.terminateInstance(memberId);
         assertTrue(String.format("Member [member-id] %s couldn't be terminated from the mock IaaS", memberId),
@@ -309,8 +300,7 @@ public class TopologyHandler {
             }
             try {
                 Thread.sleep(1000);
-            }
-            catch (InterruptedException e) {
+            } catch (InterruptedException e) {
                 log.error("Could not sleep", e);
             }
         }
@@ -322,16 +312,15 @@ public class TopologyHandler {
         long startTime = System.currentTimeMillis();
 
         Application application = ApplicationManager.getApplications().getApplication(applicationName);
-        assertNotNull(String.format("Application is not found: [application-id] %s",
-                applicationName), application);
+        assertNotNull(String.format("Application is not found: [application-id] %s", applicationName), application);
 
         Set<ClusterDataHolder> clusterDataHolderSet = application.getClusterDataRecursively();
         for (ClusterDataHolder clusterDataHolder : clusterDataHolderSet) {
             String serviceName = clusterDataHolder.getServiceType();
             String clusterId = clusterDataHolder.getClusterId();
             Service service = TopologyManager.getTopology().getService(serviceName);
-            assertNotNull(String.format("Service is not found: [application-id] %s [service] %s",
-                    applicationName, serviceName), service);
+            assertNotNull(String.format("Service is not found: [application-id] %s [service] %s", applicationName,
+                    serviceName), service);
 
             Cluster cluster = service.getCluster(clusterId);
             assertNotNull(String.format("Cluster is not found: [application-id] %s [service] %s [cluster-id] %s",
@@ -352,12 +341,12 @@ public class TopologyHandler {
                 while (!clusterActive) {
                     try {
                         Thread.sleep(1000);
-                    }
-                    catch (InterruptedException ignore) {
+                    } catch (InterruptedException ignore) {
                     }
                     service = TopologyManager.getTopology().getService(serviceName);
-                    assertNotNull(String.format("Service is not found: [application-id] %s [service] %s",
-                            applicationName, serviceName), service);
+                    assertNotNull(
+                            String.format("Service is not found: [application-id] %s [service] %s", applicationName,
+                                    serviceName), service);
 
                     cluster = service.getCluster(clusterId);
                     activeInstances = 0;
@@ -385,7 +374,6 @@ public class TopologyHandler {
 
     }
 
-
     /**
      * Assert application activation
      *
@@ -397,22 +385,19 @@ public class TopologyHandler {
         ApplicationContext applicationContext = null;
         try {
             applicationContext = AutoscalerServiceClient.getInstance().getApplication(applicationName);
-        }
-        catch (RemoteException e) {
+        } catch (RemoteException e) {
             log.error("Error while getting the application context for [application] " + applicationName);
         }
-        while (((application != null) && application.getInstanceContextCount() > 0) ||
-                (applicationContext == null || applicationContext.getStatus().equals(APPLICATION_STATUS_UNDEPLOYING))) {
+        while (((application != null) && application.getInstanceContextCount() > 0) || (applicationContext == null
+                || applicationContext.getStatus().equals(APPLICATION_STATUS_UNDEPLOYING))) {
             try {
                 Thread.sleep(1000);
-            }
-            catch (InterruptedException ignore) {
+            } catch (InterruptedException ignore) {
             }
             application = ApplicationManager.getApplications().getApplication(applicationName);
             try {
                 applicationContext = AutoscalerServiceClient.getInstance().getApplication(applicationName);
-            }
-            catch (RemoteException e) {
+            } catch (RemoteException e) {
                 log.error("Error while getting the application context for [application] " + applicationName);
             }
             if ((System.currentTimeMillis() - startTime) > APPLICATION_UNDEPLOYMENT_TIMEOUT) {
@@ -421,14 +406,13 @@ public class TopologyHandler {
             }
         }
 
-        assertNotNull(String.format("Application is not found: [application-id] %s",
-                applicationName), application);
-        assertNotNull(String.format("Application Context is not found: [application-id] %s",
-                applicationName), applicationContext);
+        assertNotNull(String.format("Application is not found: [application-id] %s", applicationName), application);
+        assertNotNull(String.format("Application Context is not found: [application-id] %s", applicationName),
+                applicationContext);
 
         //Force undeployment after the graceful deployment
-        if (application.getInstanceContextCount() > 0 ||
-                applicationContext.getStatus().equals(APPLICATION_STATUS_UNDEPLOYING)) {
+        if (application.getInstanceContextCount() > 0 || applicationContext.getStatus()
+                .equals(APPLICATION_STATUS_UNDEPLOYING)) {
             return false;
         }
         assertEquals(
@@ -450,8 +434,7 @@ public class TopologyHandler {
             while (group.getInstanceContextCount() != count) {
                 try {
                     Thread.sleep(1000);
-                }
-                catch (InterruptedException ignore) {
+                } catch (InterruptedException ignore) {
                 }
                 if ((System.currentTimeMillis() - startTime) > APPLICATION_ACTIVATION_TIMEOUT) {
                     log.error("Group instance min count check failed within timeout period");
@@ -462,8 +445,7 @@ public class TopologyHandler {
                 while (!instance.getStatus().equals(GroupStatus.Active)) {
                     try {
                         Thread.sleep(1000);
-                    }
-                    catch (InterruptedException ignore) {
+                    } catch (InterruptedException ignore) {
                     }
                     if ((System.currentTimeMillis() - startTime) > APPLICATION_ACTIVATION_TIMEOUT) {
                         log.error("Application did not activate within timeout period");
@@ -498,7 +480,6 @@ public class TopologyHandler {
             }
         });
 
-
         topologyEventReceiver.addEventListener(new ClusterInstanceCreatedEventListener() {
             @Override
             protected void onEvent(Event event) {
@@ -545,7 +526,6 @@ public class TopologyHandler {
             }
         });
 
-
     }
 
     private void addApplicationEventListeners() {
@@ -626,7 +606,6 @@ public class TopologyHandler {
         return dataHolder.getClusterId();
     }
 
-
     public void removeMembersFromMaps(String applicationId) {
         for (Map.Entry<String, Long> entry : getActivateddMembers().entrySet()) {
             if (entry.getKey().contains(applicationId)) {
@@ -680,4 +659,28 @@ public class TopologyHandler {
     public void setActivateddMembers(Map<String, Long> activateddMembers) {
         this.activateddMembers = activateddMembers;
     }
+
+    public List<Member> getMembersForApplication(String applicationId) {
+        Application application = ApplicationManager.getApplications().getApplication(applicationId);
+        assertNotNull(String.format("Application is not found: [application-id] %s", applicationId), application);
+        Set<ClusterDataHolder> clusterDataHolderSet = application.getClusterDataRecursively();
+        List<Member> memberList = new ArrayList<>();
+        for (ClusterDataHolder clusterDataHolder : clusterDataHolderSet) {
+            String serviceName = clusterDataHolder.getServiceType();
+            String clusterId = clusterDataHolder.getClusterId();
+            Service service = TopologyManager.getTopology().getService(serviceName);
+            assertNotNull(
+                    String.format("Service is not found: [application-id] %s [service] %s", applicationId, serviceName),
+                    service);
+            Cluster cluster = service.getCluster(clusterId);
+            assertNotNull(String.format("Cluster is not found: [application-id] %s [service] %s [cluster-id] %s",
+                    applicationId, serviceName, clusterId), cluster);
+            for (ClusterInstance instance : cluster.getInstanceIdToInstanceContextMap().values()) {
+                for (Member member : cluster.getMembers()) {
+                    memberList.add(member);
+                }
+            }
+        }
+        return memberList;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/IntegrationMockClient.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/IntegrationMockClient.java b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/IntegrationMockClient.java
index 73090bd..8ce3311 100644
--- a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/IntegrationMockClient.java
+++ b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/IntegrationMockClient.java
@@ -66,7 +66,8 @@ public class IntegrationMockClient extends MockIaasApiClient {
                 } else {
                     GsonBuilder gsonBuilder = new GsonBuilder();
                     Gson gson = gsonBuilder.create();
-                    org.apache.stratos.mock.iaas.domain.ErrorResponse errorResponse = gson.fromJson(response.getContent(), org.apache.stratos.mock.iaas.domain.ErrorResponse.class);
+                    org.apache.stratos.mock.iaas.domain.ErrorResponse errorResponse = gson
+                            .fromJson(response.getContent(), org.apache.stratos.mock.iaas.domain.ErrorResponse.class);
                     if (errorResponse != null) {
                         throw new RuntimeException(errorResponse.getErrorMessage());
                     }

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/RestClient.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/RestClient.java b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/RestClient.java
index e438a9e..fca36a1 100644
--- a/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/RestClient.java
+++ b/products/stratos/modules/integration/test-common/src/main/java/org/apache/stratos/integration/common/rest/RestClient.java
@@ -16,49 +16,62 @@
 
 package org.apache.stratos.integration.common.rest;
 
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonParser;
+import com.google.gson.*;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.*;
 import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLContextBuilder;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.HttpClients;
 import org.apache.http.impl.conn.PoolingClientConnectionManager;
+import org.apache.stratos.integration.common.RestConstants;
+import org.apache.stratos.metadata.client.beans.PropertyBean;
+import org.apache.stratos.metadata.client.exception.RestClientException;
+import org.apache.stratos.metadata.client.rest.HTTPConnectionManager;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.lang.reflect.Type;
 import java.net.URI;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
 
 /**
  * Rest client to handle rest requests
  */
 public class RestClient {
     private static final Log log = LogFactory.getLog(RestClient.class);
-    private DefaultHttpClient httpClient;
+    private HttpClient httpClient;
     private String endPoint;
+    private String securedEndpoint;
     private String userName;
     private String password;
-
-    public RestClient() {
-        PoolingClientConnectionManager cm = new PoolingClientConnectionManager();
-        // Increase max total connection to 200
-        cm.setMaxTotal(200);
-        // Increase default max connection per route to 50
-        cm.setDefaultMaxPerRoute(50);
-
-        httpClient = new DefaultHttpClient(cm);
-        httpClient = (DefaultHttpClient) WebClientWrapper.wrapClient(httpClient);
+    private GsonBuilder gsonBuilder = new GsonBuilder();
+    private Gson gson = gsonBuilder.create();
+
+    public RestClient() throws Exception {
+        SSLContextBuilder builder = new SSLContextBuilder();
+        SSLConnectionSocketFactory sslConnectionFactory;
+        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
+        sslConnectionFactory = new SSLConnectionSocketFactory(builder.build());
+        this.httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionFactory)
+                .setConnectionManager(HTTPConnectionManager.getInstance().getHttpConnectionManager()).build();
     }
 
-    public RestClient(String endPoint, String userName, String password) {
+    public RestClient(String endPoint, String securedEndpoint, String userName, String password) throws Exception {
         this();
         this.endPoint = endPoint;
+        this.securedEndpoint = securedEndpoint;
         this.userName = userName;
         this.password = password;
     }
@@ -80,13 +93,12 @@ public class RestClient {
             postRequest.setEntity(input);
 
             String userPass = getUsernamePassword();
-            String basicAuth =
-                    "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userPass.getBytes("UTF-8"));
+            String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter
+                    .printBase64Binary(userPass.getBytes("UTF-8"));
             postRequest.addHeader("Authorization", basicAuth);
 
             return httpClient.execute(postRequest, new HttpResponseHandler());
-        }
-        finally {
+        } finally {
             releaseConnection(postRequest);
         }
     }
@@ -105,13 +117,12 @@ public class RestClient {
             getRequest = new HttpGet(resourcePath);
             getRequest.addHeader("Content-Type", "application/json");
             String userPass = getUsernamePassword();
-            String basicAuth =
-                    "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userPass.getBytes("UTF-8"));
+            String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter
+                    .printBase64Binary(userPass.getBytes("UTF-8"));
             getRequest.addHeader("Authorization", basicAuth);
 
             return httpClient.execute(getRequest, new HttpResponseHandler());
-        }
-        finally {
+        } finally {
             releaseConnection(getRequest);
         }
     }
@@ -122,12 +133,11 @@ public class RestClient {
             httpDelete = new HttpDelete(resourcePath);
             httpDelete.addHeader("Content-Type", "application/json");
             String userPass = getUsernamePassword();
-            String basicAuth =
-                    "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userPass.getBytes("UTF-8"));
+            String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter
+                    .printBase64Binary(userPass.getBytes("UTF-8"));
             httpDelete.addHeader("Authorization", basicAuth);
             return httpClient.execute(httpDelete, new HttpResponseHandler());
-        }
-        finally {
+        } finally {
             releaseConnection(httpDelete);
         }
     }
@@ -142,12 +152,11 @@ public class RestClient {
             input.setContentType("application/json");
             putRequest.setEntity(input);
             String userPass = getUsernamePassword();
-            String basicAuth =
-                    "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userPass.getBytes("UTF-8"));
+            String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter
+                    .printBase64Binary(userPass.getBytes("UTF-8"));
             putRequest.addHeader("Authorization", basicAuth);
             return httpClient.execute(putRequest, new HttpResponseHandler());
-        }
-        finally {
+        } finally {
             releaseConnection(putRequest);
         }
     }
@@ -167,12 +176,7 @@ public class RestClient {
             if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                 return true;
             } else {
-                GsonBuilder gsonBuilder = new GsonBuilder();
-                Gson gson = gsonBuilder.create();
-                ErrorResponse errorResponse = gson.fromJson(response.getContent(), ErrorResponse.class);
-                if (errorResponse != null) {
-                    throw new RuntimeException(errorResponse.getErrorMessage());
-                }
+                throw new RuntimeException(response.getContent());
             }
         }
         throw new Exception("Null response received. Could not add entity [entity name] " + entityName);
@@ -186,12 +190,7 @@ public class RestClient {
             if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                 return true;
             } else {
-                GsonBuilder gsonBuilder = new GsonBuilder();
-                Gson gson = gsonBuilder.create();
-                ErrorResponse errorResponse = gson.fromJson(response.getContent(), ErrorResponse.class);
-                if (errorResponse != null) {
-                    throw new RuntimeException(errorResponse.getErrorMessage());
-                }
+                throw new RuntimeException(response.getContent());
             }
         }
         throw new Exception("Null response received. Could not deploy entity [entity name] " + entityName);
@@ -205,34 +204,23 @@ public class RestClient {
             if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                 return true;
             } else {
-                GsonBuilder gsonBuilder = new GsonBuilder();
-                Gson gson = gsonBuilder.create();
-                ErrorResponse errorResponse = gson.fromJson(response.getContent(), ErrorResponse.class);
-                if (errorResponse != null) {
-                    throw new RuntimeException(errorResponse.getErrorMessage());
-                }
+                throw new RuntimeException(response.getContent());
             }
         }
         throw new Exception("Null response received. Could not undeploy entity [entity name] " + entityName);
     }
 
-    public Object getEntity(String resourcePath, String identifier, Class responseJsonClass,
-                            String entityName) throws Exception {
+    public Object getEntity(String resourcePath, String identifier, Class responseJsonClass, String entityName)
+            throws Exception {
         URI uri = new URIBuilder(this.endPoint + resourcePath + "/" + identifier).build();
         HttpResponse response = doGet(uri);
-        GsonBuilder gsonBuilder = new GsonBuilder();
-        Gson gson = gsonBuilder.create();
         if (response != null) {
             if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                 return gson.fromJson(response.getContent(), responseJsonClass);
             } else if (response.getStatusCode() == 404) {
                 return null;
             } else {
-                ErrorResponse errorResponse = gson.fromJson(response.getContent(),
-                        ErrorResponse.class);
-                if (errorResponse != null) {
-                    throw new RuntimeException(errorResponse.getErrorMessage());
-                }
+                throw new RuntimeException(response.getContent());
             }
         }
         throw new Exception("Null response received. Could not get entity [entity name] " + entityName);
@@ -241,19 +229,13 @@ public class RestClient {
     public Object listEntity(String resourcePath, Type type, String entityName) throws Exception {
         URI uri = new URIBuilder(this.endPoint + resourcePath).build();
         HttpResponse response = doGet(uri);
-        GsonBuilder gsonBuilder = new GsonBuilder();
-        Gson gson = gsonBuilder.create();
         if (response != null) {
             if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                 return gson.fromJson(response.getContent(), type);
             } else if (response.getStatusCode() == 404) {
                 return null;
             } else {
-                ErrorResponse errorResponse = gson.fromJson(response.getContent(),
-                        ErrorResponse.class);
-                if (errorResponse != null) {
-                    throw new RuntimeException(errorResponse.getErrorMessage());
-                }
+                throw new RuntimeException(response.getContent());
             }
         }
         throw new Exception("Null response received. Could not get entity [entity name] " + entityName);
@@ -266,10 +248,7 @@ public class RestClient {
             if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                 return true;
             } else {
-                GsonBuilder gsonBuilder = new GsonBuilder();
-                Gson gson = gsonBuilder.create();
-                ErrorResponse errorResponse = gson.fromJson(response.getContent(),
-                        ErrorResponse.class);
+                ErrorResponse errorResponse = gson.fromJson(response.getContent(), ErrorResponse.class);
                 log.error("Error response while removing entity [identifier] " + identifier + ", [entity name] " +
                         entityName + ", [error] " + errorResponse.getErrorMessage() + ", [error code] " + errorResponse
                         .getErrorCode());
@@ -288,10 +267,7 @@ public class RestClient {
             if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
                 return true;
             } else {
-                GsonBuilder gsonBuilder = new GsonBuilder();
-                Gson gson = gsonBuilder.create();
-                ErrorResponse errorResponse = gson.fromJson(response.getContent(),
-                        ErrorResponse.class);
+                ErrorResponse errorResponse = gson.fromJson(response.getContent(), ErrorResponse.class);
                 if (errorResponse != null) {
                     throw new RuntimeException(errorResponse.getErrorMessage());
                 }
@@ -300,6 +276,152 @@ public class RestClient {
         throw new Exception("Null response received. Could not update entity [entity name] " + entityName);
     }
 
+    public boolean addPropertyToApplication(String appId, String propertyKey, String propertyValue, String accessToken)
+            throws Exception {
+        URI uri = new URIBuilder(
+                this.securedEndpoint + RestConstants.METADATA_API + "/applications/" + appId + "/properties").build();
+        log.info("Metadata endpoint resource: " + uri.toString());
+        PropertyBean property = new PropertyBean(propertyKey, propertyValue);
+        HttpResponse response;
+        HttpPost postRequest = null;
+        String requestBody = gson.toJson(property, PropertyBean.class);
+        try {
+            postRequest = new HttpPost(uri);
+            StringEntity input = new StringEntity(requestBody);
+            input.setContentType("application/json");
+            postRequest.setEntity(input);
+            String bearerAuth = "Bearer " + accessToken;
+            postRequest.addHeader("Authorization", bearerAuth);
+            response = httpClient.execute(postRequest, new HttpResponseHandler());
+        } finally {
+            releaseConnection(postRequest);
+        }
+
+        if (response != null) {
+            if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
+                return true;
+            } else {
+                throw new RuntimeException(response.getContent());
+            }
+        }
+        throw new Exception("Null response received. Could not add property to application: " + appId);
+    }
+
+    public boolean addPropertyToCluster(String appId, String clusterId, String propertyKey, String propertyValue,
+            String accessToken) throws Exception {
+        URI uri = new URIBuilder(
+                this.securedEndpoint + RestConstants.METADATA_API + "/applications/" + appId + "/clusters/" + clusterId
+                        + "/properties").build();
+        PropertyBean property = new PropertyBean(propertyKey, propertyValue);
+        HttpResponse response;
+        HttpPost postRequest = null;
+        String requestBody = gson.toJson(property);
+        try {
+            postRequest = new HttpPost(uri);
+            StringEntity input = new StringEntity(requestBody);
+            input.setContentType("application/json");
+            postRequest.setEntity(input);
+            String bearerAuth = "Bearer " + accessToken;
+            postRequest.addHeader("Authorization", bearerAuth);
+            response = httpClient.execute(postRequest, new HttpResponseHandler());
+        } finally {
+            releaseConnection(postRequest);
+        }
+
+        if (response != null) {
+            if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
+                return true;
+            } else {
+                throw new RuntimeException(response.getContent());
+            }
+        }
+        throw new Exception("Null response received. Could not add property to cluster: " + clusterId);
+    }
+
+    public PropertyBean getClusterProperty(String appId, String clusterId, String propertyName, String accessToken)
+            throws Exception {
+        URI uri = new URIBuilder(
+                this.securedEndpoint + RestConstants.METADATA_API + "/applications/" + appId + "/cluster/" + clusterId
+                        + "/properties/" + propertyName).build();
+        HttpResponse response;
+        HttpGet getRequest = null;
+        try {
+            getRequest = new HttpGet(uri);
+            getRequest.addHeader("Content-Type", "application/json");
+            String bearerAuth = "Bearer " + accessToken;
+            getRequest.addHeader("Authorization", bearerAuth);
+            response = httpClient.execute(getRequest, new HttpResponseHandler());
+        } finally {
+            releaseConnection(getRequest);
+        }
+        Gson gson = new GsonBuilder().registerTypeAdapter(List.class, new JsonSerializer<List<?>>() {
+            @Override
+            public JsonElement serialize(List<?> list, Type t, JsonSerializationContext jsc) {
+                if (list.size() == 1) {
+                    // Don't put single element lists in a json array
+                    return new Gson().toJsonTree(list.get(0));
+                } else {
+                    return new Gson().toJsonTree(list);
+                }
+            }
+        }).create();
+        return gson.fromJson(response.getContent(), PropertyBean.class);
+    }
+
+    public PropertyBean getApplicationProperty(String appId, String propertyName, String accessToken) throws Exception {
+        URI uri = new URIBuilder(
+                this.securedEndpoint + RestConstants.METADATA_API + "/applications/" + appId + "/properties/"
+                        + propertyName).build();
+        HttpResponse response;
+        HttpGet getRequest = null;
+        try {
+            getRequest = new HttpGet(uri);
+            getRequest.addHeader("Content-Type", "application/json");
+            String bearerAuth = "Bearer " + accessToken;
+            getRequest.addHeader("Authorization", bearerAuth);
+            response = httpClient.execute(getRequest, new HttpResponseHandler());
+        } finally {
+            releaseConnection(getRequest);
+        }
+        Gson gson = new GsonBuilder().registerTypeAdapter(List.class, new JsonSerializer<List<?>>() {
+            @Override
+            public JsonElement serialize(List<?> list, Type t, JsonSerializationContext jsc) {
+                if (list.size() == 1) {
+                    // Don't put single element lists in a json array
+                    return new Gson().toJsonTree(list.get(0));
+                } else {
+                    return new Gson().toJsonTree(list);
+                }
+            }
+        }).create();
+        return gson.fromJson(response.getContent(), PropertyBean.class);
+    }
+
+    public boolean deleteApplicationProperties(String appId, String accessToken) throws Exception {
+        URI uri = new URIBuilder(
+                this.securedEndpoint + RestConstants.METADATA_API + "/applications/" + appId + "/properties").build();
+        HttpResponse response;
+        HttpDelete httpDelete = null;
+        try {
+            httpDelete = new HttpDelete(uri);
+            httpDelete.addHeader("Content-Type", "application/json");
+            String bearerAuth = "Bearer " + accessToken;
+            httpDelete.addHeader("Authorization", bearerAuth);
+            response = httpClient.execute(httpDelete, new HttpResponseHandler());
+        } finally {
+            releaseConnection(httpDelete);
+        }
+
+        if (response != null) {
+            if ((response.getStatusCode() >= 200) && (response.getStatusCode() < 300)) {
+                return true;
+            } else {
+                throw new RuntimeException(response.getContent());
+            }
+        }
+        throw new Exception("Null response received. Could not delete properties for application: " + appId);
+    }
+
     /**
      * Get the json string from the artifacts directory
      *
@@ -333,4 +455,4 @@ public class RestClient {
     private String getUsernamePassword() {
         return this.userName + ":" + this.password;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/StratosIntegrationTest.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/StratosIntegrationTest.java b/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/StratosIntegrationTest.java
index 0f90dcb..2836f93 100644
--- a/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/StratosIntegrationTest.java
+++ b/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/StratosIntegrationTest.java
@@ -18,9 +18,10 @@ package org.apache.stratos.integration.tests;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.integration.common.TopologyHandler;
 import org.apache.stratos.integration.common.extensions.StratosServerExtension;
-import org.apache.stratos.integration.common.rest.IntegrationMockClient;
 import org.apache.stratos.integration.common.rest.RestClient;
+import org.apache.stratos.mock.iaas.client.MockIaasApiClient;
 import org.wso2.carbon.automation.engine.context.AutomationContext;
 import org.wso2.carbon.automation.engine.context.TestUserMode;
 
@@ -30,26 +31,29 @@ public class StratosIntegrationTest {
     protected String adminUsername;
     protected String adminPassword;
     protected String stratosBackendURL;
+    protected String stratosSecuredBackendURL;
     protected RestClient restClient;
-    protected IntegrationMockClient mockIaasApiClient;
+    protected MockIaasApiClient mockIaasApiClient;
     public static final int GLOBAL_TEST_TIMEOUT = 5 * 60 * 1000; // 5 mins
     public static final int APPLICATION_TEST_TIMEOUT = 20 * 60 * 1000; // 20 mins
 
     public StratosIntegrationTest() {
         try {
             stratosAutomationCtx = new AutomationContext("STRATOS", "stratos-001", TestUserMode.SUPER_TENANT_ADMIN);
-            adminUsername = stratosAutomationCtx.getConfigurationValue
-                    ("/automation/userManagement/superTenant/tenant/admin/user/userName");
-            adminPassword = stratosAutomationCtx.getConfigurationValue
-                    ("/automation/userManagement/superTenant/tenant/admin/user/password");
+            adminUsername = stratosAutomationCtx
+                    .getConfigurationValue("/automation/userManagement/superTenant/tenant/admin/user/userName");
+            adminPassword = stratosAutomationCtx
+                    .getConfigurationValue("/automation/userManagement/superTenant/tenant/admin/user/password");
 
             // Do not rely on automation context for context URLs since ports are dynamically picked
             stratosBackendURL = StratosServerExtension.getStratosTestServerManager().getWebAppURL();
-            restClient = new RestClient(stratosBackendURL, adminUsername, adminPassword);
-            mockIaasApiClient = new IntegrationMockClient(stratosBackendURL + "/mock-iaas/api");
-        }
-        catch (Exception e) {
+            stratosSecuredBackendURL = StratosServerExtension.getStratosTestServerManager().getWebAppURLHttps();
+            restClient = new RestClient(stratosBackendURL, stratosSecuredBackendURL, adminUsername, adminPassword);
+            mockIaasApiClient = new MockIaasApiClient(stratosBackendURL + "/mock-iaas/api");
+            // initialize topology handler before running the tests
+            TopologyHandler.getInstance();
+        } catch (Exception e) {
             throw new RuntimeException("Could not initialize StratosIntegrationTest", e);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/application/SampleApplicationStartupTestCase.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/application/SampleApplicationStartupTestCase.java b/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/application/SampleApplicationStartupTestCase.java
index bc99bc9..1890287 100644
--- a/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/application/SampleApplicationStartupTestCase.java
+++ b/products/stratos/modules/integration/test-integration/src/test/java/org/apache/stratos/integration/tests/application/SampleApplicationStartupTestCase.java
@@ -19,6 +19,9 @@
 
 package org.apache.stratos.integration.tests.application;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.stratos.common.beans.application.ApplicationBean;
@@ -28,11 +31,17 @@ import org.apache.stratos.integration.common.TopologyHandler;
 import org.apache.stratos.integration.tests.StratosIntegrationTest;
 import org.apache.stratos.messaging.domain.application.ApplicationStatus;
 import org.apache.stratos.messaging.domain.topology.Member;
+import org.apache.stratos.metadata.client.beans.PropertyBean;
+import org.apache.stratos.mock.iaas.domain.MockInstanceMetadata;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
@@ -44,6 +53,12 @@ import static org.testng.AssertJUnit.assertTrue;
 public class SampleApplicationStartupTestCase extends StratosIntegrationTest {
     private static final Log log = LogFactory.getLog(SampleApplicationStartupTestCase.class);
     private static final String RESOURCES_PATH = "/sample-application-startup-test";
+    private static final String PAYLOAD_PARAMETER_SEPARATOR = ",";
+    private static final String PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR = "=";
+    private static final String PAYLOAD_PARAMETER_TOKEN_KEY = "TOKEN";
+    private static final String PAYLOAD_PARAMETER_APPLICATION_ID_KEY = "APPLICATION_ID";
+    private GsonBuilder gsonBuilder = new GsonBuilder();
+    private Gson gson = gsonBuilder.create();
 
     @Test(timeOut = APPLICATION_TEST_TIMEOUT,
           description = "Application startup, activation and faulty member " + "detection",
@@ -140,6 +155,47 @@ public class SampleApplicationStartupTestCase extends StratosIntegrationTest {
         log.info("Waiting for cluster status to become ACTIVE...");
         topologyHandler.assertClusterActivation(bean.getApplicationId());
 
+        List<Member> memberList = topologyHandler.getMembersForApplication(bean.getApplicationId());
+        Assert.assertTrue(memberList.size() > 1,
+                String.format("Active member list for application %s is empty", bean.getApplicationId()));
+        MockInstanceMetadata mockInstanceMetadata = mockIaasApiClient.getInstance(memberList.get(0).getMemberId());
+        String payloadString = mockInstanceMetadata.getPayload();
+        log.info("Mock instance payload properties: " + payloadString);
+
+        Properties payloadProperties = new Properties();
+        String[] parameterArray = payloadString.split(PAYLOAD_PARAMETER_SEPARATOR);
+        for (String parameter : parameterArray) {
+            if (parameter != null) {
+                String[] nameValueArray = parameter.split(PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR, 2);
+                if ((nameValueArray.length == 2)) {
+                    payloadProperties.put(nameValueArray[0], nameValueArray[1]);
+                }
+            }
+        }
+
+        String key = "mykey";
+        String val1 = "myval1";
+        String val2 = "myval2";
+        String accessToken = payloadProperties.getProperty(PAYLOAD_PARAMETER_TOKEN_KEY);
+        String appId = payloadProperties.getProperty(PAYLOAD_PARAMETER_APPLICATION_ID_KEY);
+        assertNotNull(accessToken, "Access token is null in member payload");
+
+        log.info("Trying to add metadata for application:" + appId + ", with accessToken: " + accessToken);
+        boolean hasProperty1Added = restClient.addPropertyToApplication(appId, key, val1, accessToken);
+        Assert.assertTrue(hasProperty1Added, "Could not add metadata property1 to application: " + appId);
+
+        boolean hasProperty2Added = restClient.addPropertyToApplication(appId, key, val2, accessToken);
+        Assert.assertTrue(hasProperty2Added, "Could not add metadata property2 to application: " + appId);
+
+        PropertyBean propertyBean = restClient.getApplicationProperty(appId, key, accessToken);
+        log.info("Retrieved metadata property: " + gson.toJson(propertyBean));
+        Assert.assertTrue(propertyBean != null && propertyBean.getValues().length > 0, "Empty property list");
+        boolean hasPropertiesAdded = ArrayUtils.contains(propertyBean.getValues(), val1) && ArrayUtils
+                .contains(propertyBean.getValues(), val2);
+
+        Assert.assertTrue(hasPropertiesAdded, "Metadata properties retrieved are not correct");
+        log.info("Metadata test completed successfully");
+
         log.info("Terminating members in [cluster id] c1-sample-application-startup-test in mock IaaS directly to "
                 + "simulate faulty members...");
         Map<String, Member> memberMap = TopologyHandler.getInstance()
@@ -207,17 +263,15 @@ public class SampleApplicationStartupTestCase extends StratosIntegrationTest {
                 RestConstants.AUTOSCALING_POLICIES_NAME);
         assertTrue(removedAuto);
 
-        log.info(
-                "Removing the deployment policy [deployment policy id] "
-                        + "deployment-policy-sample-application-startup-test");
+        log.info("Removing the deployment policy [deployment policy id] "
+                + "deployment-policy-sample-application-startup-test");
         boolean removedDep = restClient
                 .removeEntity(RestConstants.DEPLOYMENT_POLICIES, "deployment-policy-sample-application-startup-test",
                         RestConstants.DEPLOYMENT_POLICIES_NAME);
         assertTrue(removedDep);
 
-        log.info(
-                "Removing the network partition [network partition id] "
-                        + "network-partition-sample-application-startup-test");
+        log.info("Removing the network partition [network partition id] "
+                + "network-partition-sample-application-startup-test");
         boolean removedNet = restClient
                 .removeEntity(RestConstants.NETWORK_PARTITIONS, "network-partition-sample-application-startup-test",
                         RestConstants.NETWORK_PARTITIONS_NAME);

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-integration/src/test/resources/common/log4j.properties
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-integration/src/test/resources/common/log4j.properties b/products/stratos/modules/integration/test-integration/src/test/resources/common/log4j.properties
index fb0da79..6fc6f45 100644
--- a/products/stratos/modules/integration/test-integration/src/test/resources/common/log4j.properties
+++ b/products/stratos/modules/integration/test-integration/src/test/resources/common/log4j.properties
@@ -59,7 +59,10 @@ log4j.logger.org.apache.stratos.cloud.controller=DEBUG
 log4j.logger.org.wso2.andes.client=ERROR
 # Autoscaler rule logs
 log4j.logger.org.apache.stratos.autoscaler.rule.RuleLog=DEBUG
-org.apache.stratos.cloud.controller.messaging.topology.TopologyManager=INFO
+log4j.logger.org.apache.stratos.cloud.controller.messaging.topology.TopologyManager=INFO
+log4j.logger.org.apache.stratos.mock.iaas.client=DEBUG
+log4j.logger.org.apache.stratos.mock.iaas.services=DEBUG
+log4j.logger.org.apache.stratos.metadata.service=DEBUG
 
 # Apache jclouds
 #log4j.logger.jclouds.wire=DEBUG

http://git-wip-us.apache.org/repos/asf/stratos/blob/4f021496/products/stratos/modules/integration/test-integration/src/test/resources/test-suite-smoke.xml
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/test-integration/src/test/resources/test-suite-smoke.xml b/products/stratos/modules/integration/test-integration/src/test/resources/test-suite-smoke.xml
index bc44369..0f388d7 100644
--- a/products/stratos/modules/integration/test-integration/src/test/resources/test-suite-smoke.xml
+++ b/products/stratos/modules/integration/test-integration/src/test/resources/test-suite-smoke.xml
@@ -42,4 +42,4 @@
             <package name="org.apache.stratos.integration.tests.*"/>
         </packages>
     </test>
-</suite>
\ No newline at end of file
+</suite>