Adding Kubernetes services to topology/cluster and introducing access URLs
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterContext.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterContext.java
index dd5f43e..f786626 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterContext.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterContext.java
@@ -18,12 +18,12 @@
  */
 package org.apache.stratos.cloud.controller.domain;
 
-import java.io.Serializable;
-import java.util.List;
-
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.stratos.common.Properties;
-import org.apache.stratos.kubernetes.client.model.Service;
+import org.apache.stratos.messaging.domain.topology.KubernetesService;
+
+import java.io.Serializable;
+import java.util.List;
 
 /**
  * Holds runtime data of a Cluster.
@@ -45,7 +45,7 @@
     // timeout in milliseconds - this would be the per member time that CC waits before forcefully terminate instances on an unregistration.
     private long timeoutInMillis;
     private Properties properties;
-    private List<Service> kubernetesServices;
+    private List<KubernetesService> kubernetesServices;
     private String kubernetesClusterId;
 
     public ClusterContext(String applicationId, String cartridgeType, String clusterId, String payload, String hostName,
@@ -116,11 +116,11 @@
 		this.properties = properties;
 	}
 
-    public List<Service> getKubernetesServices() {
+    public List<KubernetesService> getKubernetesServices() {
         return kubernetesServices;
     }
 
-    public void setKubernetesServices(List<Service> kubernetesServices) {
+    public void setKubernetesServices(List<KubernetesService> kubernetesServices) {
         this.kubernetesServices = kubernetesServices;
     }
 
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java
index 9c7ad08..bc483bd 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java
@@ -44,6 +44,7 @@
 import org.apache.stratos.kubernetes.client.model.Labels;
 import org.apache.stratos.kubernetes.client.model.Pod;
 import org.apache.stratos.kubernetes.client.model.Service;
+import org.apache.stratos.messaging.domain.topology.KubernetesService;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -214,8 +215,9 @@
             createReplicationController(clusterContext, memberContext, kubernetesApi);
 
             // Create proxy services for port mappings
-            List<Service> services = createProxyServices(clusterContext, kubClusterContext, kubernetesApi);
-            clusterContext.setKubernetesServices(services);
+            List<KubernetesService> kubernetesServices = createKubernetesServices(kubernetesApi, clusterContext,
+                    kubClusterContext);
+            clusterContext.setKubernetesServices(kubernetesServices);
             CloudControllerContext.getInstance().updateClusterContext(clusterContext);
 
             // Wait for pod status to be changed to running
@@ -229,7 +231,7 @@
             MemberContext newMemberContext = createNewMemberContext(memberContext, pod, kubernetesCluster);
             CloudControllerContext.getInstance().addMemberContext(newMemberContext);
 
-            // persist in registry
+            // Persist in registry
             CloudControllerContext.getInstance().persist();
             log.info(String.format("Container started successfully: [cluster-id] %s [member-id] %s",
                     newMemberContext.getClusterId(), newMemberContext.getMemberId()));
@@ -408,18 +410,17 @@
     }
 
     /**
-     * Create proxy services for the cluster and add them to the cluster context.
+     * Creates and returns proxy services for the cluster.
      *
+     * @param kubernetesApi
      * @param clusterContext
      * @param kubernetesClusterContext
-     * @param kubernetesApi
      * @return
      * @throws KubernetesClientException
      */
-    private List<Service> createProxyServices(ClusterContext clusterContext,
-                                              KubernetesClusterContext kubernetesClusterContext,
-                                              KubernetesApiClient kubernetesApi) throws KubernetesClientException {
-        List<Service> services = new ArrayList<Service>();
+    private List<KubernetesService> createKubernetesServices(KubernetesApiClient kubernetesApi, ClusterContext clusterContext,
+                                                             KubernetesClusterContext kubernetesClusterContext) throws KubernetesClientException {
+        List<KubernetesService> kubernetesServices = new ArrayList<KubernetesService>();
 
         String clusterId = clusterContext.getClusterId();
         Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(clusterContext.getCartridgeType());
@@ -453,7 +454,15 @@
             }
 
             Service service = kubernetesApi.getService(serviceId);
-            services.add(service);
+
+            KubernetesService kubernetesService = new KubernetesService();
+            kubernetesService.setId(service.getId());
+            kubernetesService.setPortalIP(service.getPortalIP());
+            kubernetesService.setPublicIPs(service.getPublicIPs());
+            kubernetesService.setProtocol(portMapping.getProtocol());
+            kubernetesService.setPort(service.getPort());
+            kubernetesService.setContainerPort(portMapping.getPort());
+            kubernetesServices.add(kubernetesService);
 
             if (log.isInfoEnabled()) {
                 log.info(String.format("Kubernetes service successfully created: [cluster-id] %s [service-id] %s " +
@@ -461,7 +470,7 @@
                         serviceId, portMapping.getProtocol(), servicePort, portMapping.getPort()));
             }
         }
-        return services;
+        return kubernetesServices;
     }
 
     private void updateKubernetesServicePorts(KubernetesClusterContext kubernetesClusterContext, String clusterId,
@@ -519,13 +528,13 @@
 
             KubernetesApiClient kubApi = kubClusterContext.getKubApi();
 
-            // Remove the services
-            List<Service> services = clusterContext.getKubernetesServices();
-            if (services != null) {
-                for (Service service : services) {
+            // Remove kubernetes services
+            List<KubernetesService> kubernetesServices = clusterContext.getKubernetesServices();
+            if (kubernetesServices != null) {
+                for (KubernetesService kubernetesService : kubernetesServices) {
                     try {
-                        kubApi.deleteService(service.getId());
-                        int allocatedPort = service.getPort();
+                        kubApi.deleteService(kubernetesService.getId());
+                        int allocatedPort = kubernetesService.getPort();
                         kubClusterContext.deallocatePort(allocatedPort);
                     } catch (KubernetesClientException e) {
                         log.error("Could not remove kubernetes service: [cluster-id] " + clusterId, e);
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/internal/CloudControllerServiceComponent.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/internal/CloudControllerServiceComponent.java
index 6894bb4..70c0ee7 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/internal/CloudControllerServiceComponent.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/internal/CloudControllerServiceComponent.java
@@ -103,6 +103,8 @@
             } else {
                 executeCoordinatorTasks();
             }
+
+            log.info("Cloud controller service component activated");
 		} catch (Exception e) {
 			log.error("Could not activate cloud controller service component", e);
         }
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java
index 6a539a8..f0762fa 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java
@@ -405,43 +405,6 @@
 			member.setStatus(MemberStatus.Created);
 			member.setLbClusterId(lbClusterId);
 			member.setProperties(CloudControllerUtil.toJavaUtilProperties(memberContext.getProperties()));
-            try {
-
-                Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(service.getServiceName());
-                List<PortMapping> portMappings = cartridge.getPortMappings();
-                Port port;
-                if(cluster.isKubernetesCluster()){
-                    // Update port mappings with generated service proxy port
-                    ClusterContext clusterContext = CloudControllerContext.getInstance().getClusterContext(clusterId);
-                    if(clusterContext == null) {
-                        log.warn("Cluster context not found, could not add member ports: [cluster-id] " + clusterId);
-                    } else {
-                        List<org.apache.stratos.kubernetes.client.model.Service> services =
-                                clusterContext.getKubernetesServices();
-                        if(services == null) {
-                            log.warn("Kubernetes services not found in cluster context, could not add member ports: " +
-                                    "[cluster-id] " + clusterId);
-                        } else {
-                            // Adding ports to the member
-                            for (PortMapping portMapping : portMappings) {
-                                port = new Port(portMapping.getProtocol(),
-                                        findServicePort(clusterId, services, portMapping), portMapping.getProxyPort());
-                                member.addPort(port);
-                            }
-                        }
-                    }
-
-                } else {
-                    // Adding ports to the member
-                    for (PortMapping portMapping : portMappings) {
-                        port = new Port(portMapping.getProtocol(), portMapping.getPort(), portMapping.getProxyPort());
-                        member.addPort(port);
-                    }
-                }
-
-            } catch (Exception e) {
-                log.error("Could not update member port-map: [member-id] " + memberId, e);
-            }
 			cluster.addMember(member);
 			TopologyManager.updateTopology(topology);
 		} finally {
@@ -517,12 +480,11 @@
         }
     }
 
-    private static int findServicePort(String clusterId,
-                                       List<org.apache.stratos.kubernetes.client.model.Service> services,
-                                       PortMapping portMapping) {
-        for(org.apache.stratos.kubernetes.client.model.Service service : services) {
-            if(service.getContainerPort().equals(portMapping.getPort())) {
-                return service.getPort();
+    private static int findKubernetesServicePort(String clusterId, List<KubernetesService> kubernetesServices,
+                                                 PortMapping portMapping) {
+        for(KubernetesService kubernetesService : kubernetesServices) {
+            if(kubernetesService.getProtocol().equals(portMapping.getProtocol())) {
+                return kubernetesService.getPort();
             }
         }
         throw new RuntimeException("Kubernetes service port not found: [cluster-id] " + clusterId + " [port] "
@@ -530,53 +492,60 @@
     }
 
     public static void handleMemberStarted(InstanceStartedEvent instanceStartedEvent) {
-        Topology topology = TopologyManager.getTopology();
-        Service service = topology.getService(instanceStartedEvent.getServiceName());
-        if (service == null) {
-        	log.warn(String.format("Service %s does not exist",
-                    instanceStartedEvent.getServiceName()));
-        	return;
-        }
-        if (!service.clusterExists(instanceStartedEvent.getClusterId())) {
-        	log.warn(String.format("Cluster %s does not exist in service %s",
-                    instanceStartedEvent.getClusterId(),
-                    instanceStartedEvent.getServiceName()));
-        	return;
-        }
-
-        Member member = service.getCluster(instanceStartedEvent.getClusterId()).
-                getMember(instanceStartedEvent.getMemberId());
-        if (member == null) {
-        	log.warn(String.format("Member %s does not exist",
-                    instanceStartedEvent.getMemberId()));
-        	return;
-        }
-
         try {
-            TopologyManager.acquireWriteLock();
-            // try update lifecycle state
-            if (!member.isStateTransitionValid(MemberStatus.Starting)) {
-                log.error("Invalid State Transition from " + member.getStatus() + " to " +
-                        MemberStatus.Starting);
-                return;
-            } else {
-                member.setStatus(MemberStatus.Starting);
-                log.info("member started event adding status started");
-
-                TopologyManager.updateTopology(topology);
-                //memberStartedEvent.
-                TopologyEventPublisher.sendMemberStartedEvent(instanceStartedEvent);
-                //publishing data
-                StatisticsDataPublisher.publish(instanceStartedEvent.getMemberId(),
-                        instanceStartedEvent.getPartitionId(),
-                        instanceStartedEvent.getNetworkPartitionId(),
-                        instanceStartedEvent.getClusterId(),
-                        instanceStartedEvent.getServiceName(),
-                        MemberStatus.Starting.toString(),
-                        null);
+            Topology topology = TopologyManager.getTopology();
+            Service service = topology.getService(instanceStartedEvent.getServiceName());
+            if (service == null) {
+        	    log.warn(String.format("Service %s does not exist",
+                        instanceStartedEvent.getServiceName()));
+        	    return;
             }
-        } finally {
-            TopologyManager.releaseWriteLock();
+            if (!service.clusterExists(instanceStartedEvent.getClusterId())) {
+                log.warn(String.format("Cluster %s does not exist in service %s",
+                        instanceStartedEvent.getClusterId(),
+                        instanceStartedEvent.getServiceName()));
+                return;
+            }
+
+            Cluster cluster = service.getCluster(instanceStartedEvent.getClusterId());
+            Member member = cluster.getMember(instanceStartedEvent.getMemberId());
+            if (member == null) {
+                log.warn(String.format("Member %s does not exist",
+                        instanceStartedEvent.getMemberId()));
+                return;
+            }
+
+            try {
+                TopologyManager.acquireWriteLock();
+                // try update lifecycle state
+                if (!member.isStateTransitionValid(MemberStatus.Starting)) {
+                    log.error("Invalid State Transition from " + member.getStatus() + " to " +
+                            MemberStatus.Starting);
+                    return;
+                } else {
+                    member.setStatus(MemberStatus.Starting);
+                    log.info("member started event adding status started");
+
+                    TopologyManager.updateTopology(topology);
+                    //memberStartedEvent.
+                    TopologyEventPublisher.sendMemberStartedEvent(instanceStartedEvent);
+                    //publishing data
+                    StatisticsDataPublisher.publish(instanceStartedEvent.getMemberId(),
+                            instanceStartedEvent.getPartitionId(),
+                            instanceStartedEvent.getNetworkPartitionId(),
+                            instanceStartedEvent.getClusterId(),
+                            instanceStartedEvent.getServiceName(),
+                            MemberStatus.Starting.toString(),
+                            null);
+                }
+            } finally {
+                TopologyManager.releaseWriteLock();
+            }
+        } catch (Exception e) {
+            String message = String.format("Could not handle member started event: [application-id] %s " +
+                    "[service-name] %s [member-id] %s", instanceStartedEvent.getApplicationId(),
+                    instanceStartedEvent.getServiceName(), instanceStartedEvent.getMemberId());
+            log.warn(message, e);
         }
     }
 
@@ -597,7 +566,6 @@
         }
 
         Member member = cluster.getMember(instanceActivatedEvent.getMemberId());
-
         if (member == null) {
         	log.warn(String.format("Member %s does not exist",
                     instanceActivatedEvent.getMemberId()));
@@ -619,32 +587,52 @@
             TopologyManager.acquireWriteLock();
             // try update lifecycle state
             if (!member.isStateTransitionValid(MemberStatus.Active)) {
-                log.error("Invalid State Transition from " + member.getStatus() + " to " +
-                        MemberStatus.Active);
+                log.error("Invalid state transition from [" + member.getStatus() + "] to [" + MemberStatus.Active + "]");
                 return;
             } else {
                 member.setStatus(MemberStatus.Active);
-                log.info("member started event adding status activated");
-                Cartridge cartridge = CloudControllerContext.getInstance().
-                        getCartridge(instanceActivatedEvent.getServiceName());
 
-                List<PortMapping> portMappings = cartridge.getPortMappings();
-                Port port;
-                //adding ports to the event
-                for (PortMapping portMapping : portMappings) {
-                    port = new Port(portMapping.getProtocol(), portMapping.getPort(), portMapping.getProxyPort());
-                    member.addPort(port);
-                    memberActivatedEvent.addPort(port);
+                // Set member ports
+                try {
+                    Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(service.getServiceName());
+                    if (cartridge == null) {
+                        throw new RuntimeException(String.format("Cartridge not found: [cartridge-type] %s",
+                                service.getServiceName()));
+                    }
+
+                    Port port; int portValue;
+                    List<PortMapping> portMappings = cartridge.getPortMappings();
+                    String clusterId = cluster.getClusterId();
+                    ClusterContext clusterContext = CloudControllerContext.getInstance().getClusterContext(clusterId);
+                    List<KubernetesService> kubernetesServices = clusterContext.getKubernetesServices();
+
+                    for (PortMapping portMapping : portMappings) {
+                        if(kubernetesServices != null) {
+                            portValue = findKubernetesServicePort(clusterId, kubernetesServices, portMapping);
+                        } else {
+                            portValue = portMapping.getPort();
+                        }
+                        port = new Port(portMapping.getProtocol(), portValue, portMapping.getProxyPort());
+                        member.addPort(port);
+                        memberActivatedEvent.addPort(port);
+                    }
+                } catch (Exception e) {
+                    String message = String.format("Could not add member ports: [service-name] %s [member-id] %s",
+                            memberActivatedEvent.getServiceName(), memberActivatedEvent.getMemberId());
+                    log.error(message, e);
                 }
 
+                // Set member ip addresses
                 memberActivatedEvent.setDefaultPrivateIP(member.getDefaultPrivateIP());
                 memberActivatedEvent.setMemberPrivateIPs(member.getMemberPrivateIPs());
                 memberActivatedEvent.setDefaultPublicIP(member.getDefaultPublicIP());
                 memberActivatedEvent.setMemberPublicIPs(member.getMemberPublicIPs());
                 TopologyManager.updateTopology(topology);
 
+                // Publish member activated event
                 TopologyEventPublisher.sendMemberActivatedEvent(memberActivatedEvent);
-                //publishing data
+
+                // Publish statistics data
                 StatisticsDataPublisher.publish(memberActivatedEvent.getMemberId(),
                         memberActivatedEvent.getPartitionId(),
                         memberActivatedEvent.getNetworkPartitionId(),
@@ -656,7 +644,6 @@
         } finally {
             TopologyManager.releaseWriteLock();
         }
-
     }
 
     public static void handleMemberReadyToShutdown(InstanceReadyToShutdownEvent instanceReadyToShutdownEvent)
@@ -830,37 +817,48 @@
         }
     }
 
-    public static void handleClusterActivatedEvent(ClusterStatusClusterActivatedEvent clusterActivatedEvent) {
+    public static void handleClusterActivatedEvent(ClusterStatusClusterActivatedEvent clusterStatusClusterActivatedEvent) {
 
         Topology topology = TopologyManager.getTopology();
-        Service service = topology.getService(clusterActivatedEvent.getServiceName());
+        Service service = topology.getService(clusterStatusClusterActivatedEvent.getServiceName());
         //update the status of the cluster
         if (service == null) {
             log.warn(String.format("Service %s does not exist",
-                    clusterActivatedEvent.getServiceName()));
+                    clusterStatusClusterActivatedEvent.getServiceName()));
             return;
         }
 
-        Cluster cluster = service.getCluster(clusterActivatedEvent.getClusterId());
+        Cluster cluster = service.getCluster(clusterStatusClusterActivatedEvent.getClusterId());
         if (cluster == null) {
             log.warn(String.format("Cluster %s does not exist",
-                    clusterActivatedEvent.getClusterId()));
+                    clusterStatusClusterActivatedEvent.getClusterId()));
             return;
         }
 
-        ClusterInstanceActivatedEvent clusterActivatedEvent1 =
+        String clusterId = cluster.getClusterId();
+        ClusterContext clusterContext = CloudControllerContext.getInstance().getClusterContext(clusterId);
+        if (clusterContext == null) {
+            log.warn("Cluster context not found: [cluster-id] " + clusterId);
+            return;
+        }
+
+        ClusterInstanceActivatedEvent clusterInstanceActivatedEvent =
                 new ClusterInstanceActivatedEvent(
-                        clusterActivatedEvent.getAppId(),
-                        clusterActivatedEvent.getServiceName(),
-                        clusterActivatedEvent.getClusterId(),
-                        clusterActivatedEvent.getInstanceId());
+                        clusterStatusClusterActivatedEvent.getAppId(),
+                        clusterStatusClusterActivatedEvent.getServiceName(),
+                        clusterStatusClusterActivatedEvent.getClusterId(),
+                        clusterStatusClusterActivatedEvent.getInstanceId());
         try {
             TopologyManager.acquireWriteLock();
-            ClusterInstance context = cluster.getInstanceContexts(clusterActivatedEvent.getInstanceId());
+            List<KubernetesService> kubernetesServices = clusterContext.getKubernetesServices();
+            cluster.setKubernetesServices(kubernetesServices);
+            clusterInstanceActivatedEvent.setKubernetesServices(kubernetesServices);
+
+            ClusterInstance context = cluster.getInstanceContexts(clusterStatusClusterActivatedEvent.getInstanceId());
             if (context == null) {
-                log.warn("Cluster Instance Context is not found for [cluster] " +
-                        clusterActivatedEvent.getClusterId() + " [instance-id] " +
-                        clusterActivatedEvent.getInstanceId());
+                log.warn("Cluster instance context is not found for [cluster] " +
+                        clusterStatusClusterActivatedEvent.getClusterId() + " [instance-id] " +
+                        clusterStatusClusterActivatedEvent.getInstanceId());
                 return;
             }
             ClusterStatus status = ClusterStatus.Active;
@@ -868,12 +866,12 @@
                 context.setStatus(status);
                 log.info("Cluster activated adding status started for " + cluster.getClusterId());
                 TopologyManager.updateTopology(topology);
-                //publishing data
-                TopologyEventPublisher.sendClusterActivatedEvent(clusterActivatedEvent1);
+                // publish event
+                TopologyEventPublisher.sendClusterActivatedEvent(clusterInstanceActivatedEvent);
             } else {
                 log.error(String.format("Cluster state transition is not valid: [cluster-id] %s " +
                                 " [instance-id] %s [current-status] %s [status-requested] %s",
-                        clusterActivatedEvent.getClusterId(), clusterActivatedEvent.getInstanceId(),
+                        clusterStatusClusterActivatedEvent.getClusterId(), clusterStatusClusterActivatedEvent.getInstanceId(),
                         context.getStatus(), status));
                 return;
             }
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
index 44f1f51..d58c326 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
@@ -1087,7 +1087,7 @@
 
                 CloudControllerContext.getInstance().addClusterContext(clusterContext);
 
-	            Cartridge cartridge=CloudControllerContext.getInstance().getCartridge(clusterContext.getCartridgeType());
+	            Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(clusterContext.getCartridgeType());
 
                 // Create cluster object
                 Cluster cluster = new Cluster(appClusterCtxt.getCartridgeType(), appClusterCtxt.getClusterId(),
diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/beans/kubernetes/KubernetesServiceBean.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/beans/kubernetes/KubernetesServiceBean.java
new file mode 100644
index 0000000..a7d967d
--- /dev/null
+++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/beans/kubernetes/KubernetesServiceBean.java
@@ -0,0 +1,84 @@
+/*
+ * 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.common.beans.kubernetes;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Kubernetes service bean.
+ */
+@XmlRootElement
+public class KubernetesServiceBean {
+
+    private String id;
+    private String[] publicIPs;
+    private String portalIP;
+    private String protocol;
+    private int port;
+    private int containerPort;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String[] getPublicIPs() {
+        return publicIPs;
+    }
+
+    public void setPublicIPs(String[] publicIPs) {
+        this.publicIPs = publicIPs;
+    }
+
+    public String getPortalIP() {
+        return portalIP;
+    }
+
+    public void setPortalIP(String portalIP) {
+        this.portalIP = portalIP;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public void setContainerPort(int containerPort) {
+        this.containerPort = containerPort;
+    }
+
+    public int getContainerPort() {
+        return containerPort;
+    }
+}
diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/beans/topology/ClusterInstanceBean.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/beans/topology/ClusterInstanceBean.java
index 91d719c..a0e85b6 100644
--- a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/beans/topology/ClusterInstanceBean.java
+++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/beans/topology/ClusterInstanceBean.java
@@ -18,6 +18,8 @@
  */
 package org.apache.stratos.common.beans.topology;
 
+import org.apache.stratos.common.beans.kubernetes.KubernetesServiceBean;
+
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
 import java.util.List;
@@ -35,8 +37,9 @@
     private String tenantRange;
     private List<String> hostNames;
 	private List<String> accessUrls;
+    private List<KubernetesServiceBean> kubernetesServices;
 
-	public String getStatus() {
+    public String getStatus() {
 		return status;
 	}
 
@@ -103,7 +106,8 @@
     @Override
     public String toString() {
         return "Cluster [serviceName=" + getServiceName() + ", clusterId=" + getClusterId() + ", member=" + getMember()
-                + ", tenantRange=" + getTenantRange() + ", hostNames=" + getHostNames();
+                + ", tenantRange=" + getTenantRange() + ", hostNames=" + getHostNames() + ", accessURLs=" +
+                getAccessUrls() + ", kubernetesServices=" + getKubernetesServices();
     }
 
     public String getParentInstanceId() {
@@ -121,4 +125,12 @@
 	public void setAccessUrls(List<String> accessUrls) {
 		this.accessUrls = accessUrls;
 	}
+
+    public void setKubernetesServices(List<KubernetesServiceBean> kubernetesServices) {
+        this.kubernetesServices = kubernetesServices;
+    }
+
+    public List<KubernetesServiceBean> getKubernetesServices() {
+        return kubernetesServices;
+    }
 }
diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Service.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Service.java
index 6a65a55..7480edf 100644
--- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Service.java
+++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Service.java
@@ -20,11 +20,10 @@
  */
 package org.apache.stratos.kubernetes.client.model;
 
+import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
 import java.util.Arrays;
 
-import javax.xml.bind.annotation.XmlRootElement;
-
 /**
  * https://github.com/GoogleCloudPlatform/kubernetes/blob/master/api/doc/service-schema.json
  *
@@ -46,6 +45,7 @@
 	private String apiVersion;
 	private Labels labels;
 	private String[] publicIPs;
+    private String portalIP;
 	
 	public String getKind() {
 		return kind;
@@ -135,11 +135,19 @@
 	    this.publicIPs = publicIPs;
 	}
 
-	@Override
+    public String getPortalIP() {
+        return portalIP;
+    }
+
+    public void setPortalIP(String portalIP) {
+        this.portalIP = portalIP;
+    }
+
+    @Override
     public String toString() {
         return "Service [kind=" + kind + ", id=" + id + ", creationTimestamp=" + creationTimestamp + ", selfLink="
                 + selfLink + ", name=" + name + ", port=" + port + ", containerPort=" + containerPort + ", selector="
                 + selector + ", apiVersion=" + apiVersion + ", labels=" + labels + ", publicIPs="
-                + Arrays.toString(publicIPs) + "]";
+                + Arrays.toString(publicIPs) + "portalIP=" + portalIP + "]";
     }
 }
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Cluster.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Cluster.java
index 5c41a3a..427ccfa 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Cluster.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Cluster.java
@@ -46,7 +46,7 @@
     private List<String> hostNames;
     private String tenantRange;
     private boolean isLbCluster;
-    private boolean isKubernetesCluster; // TODO fix properly with an Enum
+    private boolean isKubernetesCluster;
     // Key: Member.memberId
     @XmlJavaTypeAdapter(MapAdapter.class)
     private Map<String, Member> memberMap;
@@ -54,15 +54,14 @@
     //private ClusterStatus status;
 
     private String appId;
-
     private String parentId;
-
     private String loadBalanceAlgorithmName;
     @XmlJavaTypeAdapter(MapAdapter.class)
     private Properties properties;
     private Map<String, ClusterInstance> instanceIdToInstanceContextMap;
     //private LifeCycleStateManager<ClusterStatus> clusterStateManager;
 	private List<String> accessUrls;
+    private List<KubernetesService> kubernetesServices;
 
     public Cluster(Cluster cluster) {
         this.serviceName = cluster.getServiceName();
@@ -70,7 +69,6 @@
         this.deploymentPolicyName = cluster.getDeploymentPolicyName();
         this.autoscalePolicyName = cluster.getAutoscalePolicyName();
         this.appId = cluster.getAppId();
-        this.setKubernetesCluster(cluster.isKubernetesCluster());
         this.setHostNames(cluster.getHostNames());
         this.memberMap = cluster.getMemberMap();
         this.setInstanceIdToInstanceContextMap(cluster.getInstanceIdToInstanceContextMap());
@@ -79,6 +77,9 @@
         this.parentId = cluster.getParentId();
         this.tenantRange = cluster.getTenantRange();
         this.setLbCluster(cluster.isLbCluster());
+        this.setKubernetesCluster(cluster.isKubernetesCluster());
+        this.accessUrls = cluster.getAccessUrls();
+        this.kubernetesServices = cluster.getKubernetesServices();
     }
     
     public Cluster(String serviceName, String clusterId, String deploymentPolicyName,
@@ -91,9 +92,8 @@
         this.memberMap = new HashMap<String, Member>();
         this.appId = appId;
         this.setInstanceIdToInstanceContextMap(new HashMap<String, ClusterInstance>());
-        //this.clusterStateManager = new LifeCycleStateManager<ClusterStatus>(ClusterStatus.Created, clusterId);
-        // temporary; should be removed
-        //this.status = ClusterStatus.Created;
+        this.accessUrls = new ArrayList<String>();
+        this.kubernetesServices = new ArrayList<KubernetesService>();
     }
 
     public String getServiceName() {
@@ -182,9 +182,9 @@
 		return isKubernetesCluster;
 	}
 
-	public void setKubernetesCluster(boolean isKubernetesCluster) {
-		this.isKubernetesCluster = isKubernetesCluster;
-	}
+    public void setKubernetesCluster(boolean isKubernetesCluster) {
+        this.isKubernetesCluster = isKubernetesCluster;
+    }
 
     /**
      * Check whether a given tenant id is in tenant range of the cluster.
@@ -305,12 +305,6 @@
         return clusterId.hashCode();
     }
 
-    public String toString () {
-
-        return " [ Cluster Id: " + clusterId + ", Service Name: " + serviceName + ", Autoscale Policy Name: "
-                + autoscalePolicyName + ", Deployment Policy Name: " + deploymentPolicyName +
-                ", Tenant Range: " + tenantRange + ", Is a Kubernetes Cluster: " + isKubernetesCluster + " ] ";
-    }
     public String getAppId() {
         return appId;
     }
@@ -346,12 +340,32 @@
 	public void setAccessUrls(List<String> accessUrls) {
 		this.accessUrls = accessUrls;
 	}
-	//    public ClusterStatus getTempStatus() {
-//        return status;
-//    }
-//
-//    public void setTempStatus(ClusterStatus status) {
-//        this.status = status;
-//    }
+
+    public void addAccessUrl(String accessUrl) {
+        if(accessUrls == null) {
+            accessUrls = new ArrayList<String>();
+        }
+        if(!accessUrls.contains(accessUrl)) {
+            accessUrls.add(accessUrl);
+        }
+    }
+
+    public List<KubernetesService> getKubernetesServices() {
+        return kubernetesServices;
+    }
+
+    public void setKubernetesServices(List<KubernetesService> kubernetesServices) {
+        this.kubernetesServices = kubernetesServices;
+        setKubernetesCluster((kubernetesServices != null) && (kubernetesServices.size() > 0));
+    }
+
+    @Override
+    public String toString() {
+        return String.format("[serviceName=%s, clusterId=%s, autoscalePolicyName=%s, deploymentPolicyName=%s, " +
+                        "hostNames=%s, tenantRange=%s, loadBalanceAlgorithmName=%s, appId=%s, parentId=%s, " +
+                        "accessUrls=%s, kubernetesServices=%s]", serviceName, clusterId, autoscalePolicyName,
+                deploymentPolicyName, hostNames, tenantRange,loadBalanceAlgorithmName, appId, parentId,
+                accessUrls, kubernetesServices );
+    }
 }
 
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/KubernetesService.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/KubernetesService.java
new file mode 100644
index 0000000..fc02179
--- /dev/null
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/KubernetesService.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.stratos.messaging.domain.topology;
+
+import java.io.Serializable;
+
+/**
+ * Kubernetes service definition.
+ */
+public class KubernetesService implements Serializable {
+
+    private static final long serialVersionUID = -2329017659002353186L;
+
+    private String id;
+    private String[] publicIPs;
+    private String portalIP;
+    private String protocol;
+    private int port;
+    private int containerPort;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String[] getPublicIPs() {
+        return publicIPs;
+    }
+
+    public void setPublicIPs(String[] publicIPs) {
+        this.publicIPs = publicIPs;
+    }
+
+    public String getPortalIP() {
+        return portalIP;
+    }
+
+    public void setPortalIP(String portalIP) {
+        this.portalIP = portalIP;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public void setContainerPort(int containerPort) {
+        this.containerPort = containerPort;
+    }
+
+    public int getContainerPort() {
+        return containerPort;
+    }
+}
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ClusterInstanceActivatedEvent.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ClusterInstanceActivatedEvent.java
index 34b304f..7b02f9f 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ClusterInstanceActivatedEvent.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ClusterInstanceActivatedEvent.java
@@ -18,9 +18,11 @@
  */
 package org.apache.stratos.messaging.event.topology;
 
-import org.apache.stratos.messaging.domain.topology.ClusterStatus;
+import org.apache.stratos.messaging.domain.topology.KubernetesService;
 import org.apache.stratos.messaging.event.Event;
 
+import java.util.List;
+
 /**
  * Cluster activated event will be sent by Autoscaler
  */
@@ -30,6 +32,7 @@
     private final String clusterId;
     private String appId;
     private String instanceId;
+    private List<KubernetesService> kubernetesServices;
 
     public ClusterInstanceActivatedEvent(String appId, String serviceName, String clusterId, String instanceId) {
         this.serviceName = serviceName;
@@ -60,4 +63,11 @@
         return instanceId;
     }
 
+    public List<KubernetesService> getKubernetesServices() {
+        return kubernetesServices;
+    }
+
+    public void setKubernetesServices(List<KubernetesService> kubernetesServices) {
+        this.kubernetesServices = kubernetesServices;
+    }
 }
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ClusterInstanceActivatedProcessor.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ClusterInstanceActivatedProcessor.java
index c53fc4c..bb0d1e1 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ClusterInstanceActivatedProcessor.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ClusterInstanceActivatedProcessor.java
@@ -21,10 +21,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.stratos.messaging.domain.instance.ClusterInstance;
-import org.apache.stratos.messaging.domain.topology.Cluster;
-import org.apache.stratos.messaging.domain.topology.ClusterStatus;
-import org.apache.stratos.messaging.domain.topology.Service;
-import org.apache.stratos.messaging.domain.topology.Topology;
+import org.apache.stratos.messaging.domain.topology.*;
 import org.apache.stratos.messaging.event.topology.ClusterInstanceActivatedEvent;
 import org.apache.stratos.messaging.message.filter.topology.TopologyClusterFilter;
 import org.apache.stratos.messaging.message.filter.topology.TopologyServiceFilter;
@@ -32,6 +29,9 @@
 import org.apache.stratos.messaging.message.processor.topology.updater.TopologyUpdater;
 import org.apache.stratos.messaging.util.MessagingUtil;
 
+import java.net.URL;
+import java.util.List;
+
 /**
  * This processor will act upon the cluster activated event
  */
@@ -59,12 +59,13 @@
             ClusterInstanceActivatedEvent event = (ClusterInstanceActivatedEvent) MessagingUtil.
                     jsonToObject(message, ClusterInstanceActivatedEvent.class);
 
-            TopologyUpdater.acquireWriteLockForCluster(event.getServiceName(), event.getClusterId());
+            String clusterId = event.getClusterId();
+            TopologyUpdater.acquireWriteLockForCluster(event.getServiceName(), clusterId);
             try {
                 return doProcess(event, topology);
 
             } finally {
-                TopologyUpdater.releaseWriteLockForCluster(event.getServiceName(), event.getClusterId());
+                TopologyUpdater.releaseWriteLockForCluster(event.getServiceName(), clusterId);
             }
 
         } else {
@@ -120,19 +121,37 @@
             }
         } else {
             // Apply changes to the topology
+            List<KubernetesService> kubernetesServices = event.getKubernetesServices();
+            if(kubernetesServices != null) {
+                // Set kubernetes services
+                cluster.setKubernetesServices(kubernetesServices);
+                try {
+                    // Generate access URLs for kubernetes services
+                    for (KubernetesService kubernetesService : kubernetesServices) {
+                        String[] publicIPs = kubernetesService.getPublicIPs();
+                        if((publicIPs != null) && (publicIPs.length > 0)) {
+                            URL accessURL = new URL(kubernetesService.getProtocol(), publicIPs[0],
+                                    kubernetesService.getPort(), "");
+                            cluster.addAccessUrl(accessURL.toString());
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("Could not create access URLs for Kubernetes services");
+                }
+            }
+
             ClusterInstance context = cluster.getInstanceContexts(event.getInstanceId());
             if(context == null) {
-                log.warn("Cluster Instance Context is not found for [cluster] " +
+                log.warn("Cluster instance context is not found for [cluster] " +
                         event.getClusterId() + " [instance-id] " +
                         event.getInstanceId());
                 return false;
             }
             ClusterStatus status = ClusterStatus.Active;
             if (!context.isStateTransitionValid(status)) {
-                log.error("Invalid State Transition from " + context.getStatus() + " to " + status);
+                log.error("Invalid state transition from " + context.getStatus() + " to " + status);
             }
             context.setStatus(status);
-
         }
 
         // Notify event listeners
diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java
index 623f8b7..fd7a7e9 100644
--- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java
+++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java
@@ -715,8 +715,7 @@
     @Consumes("application/json")
     @AuthorizationAction("/permission/protected/manage/getApplicationRuntime")
     public Response getApplicationRuntime(@PathParam("applicationId") String applicationId) throws RestAPIException {
-        ApplicationInfoBean applicationRuntime = StratosApiV41Utils.
-                getApplicationRuntime(applicationId);
+        ApplicationInfoBean applicationRuntime = StratosApiV41Utils.getApplicationRuntime(applicationId);
         if (applicationRuntime == null) {
             return Response.status(Response.Status.NOT_FOUND).build();
         } else {
diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java
index ca04768..694c4c7 100644
--- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java
+++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java
@@ -34,7 +34,6 @@
 import org.apache.stratos.cloud.controller.stub.domain.CartridgeInfo;
 import org.apache.stratos.cloud.controller.stub.domain.Persistence;
 import org.apache.stratos.cloud.controller.stub.domain.Volume;
-import org.apache.stratos.common.beans.ErrorResponseBean;
 import org.apache.stratos.common.beans.PropertyBean;
 import org.apache.stratos.common.beans.application.ApplicationBean;
 import org.apache.stratos.common.beans.application.GroupBean;
@@ -1244,10 +1243,10 @@
                 String serviceType = clusterDataHolder.getServiceType();
                 try {
                     TopologyManager.acquireReadLockForCluster(serviceType, clusterId);
-                    Cluster topLevelCluster = TopologyManager.getTopology().getService(serviceType).getCluster(clusterId);
+                    Cluster cluster = TopologyManager.getTopology().getService(serviceType).getCluster(clusterId);
                     applicationInstanceBean.getClusterInstances().add(ObjectConverter.
                             convertClusterToClusterInstanceBean(applicationInstanceBean.getInstanceId(),
-                                    topLevelCluster, entry.getKey()));
+                                    cluster, entry.getKey()));
 	            } finally {
 		            TopologyManager.releaseReadLockForCluster(serviceType, clusterId);
 	            }
diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/util/converter/ObjectConverter.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/util/converter/ObjectConverter.java
index f192914..240f1a4 100644
--- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/util/converter/ObjectConverter.java
+++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/util/converter/ObjectConverter.java
@@ -37,10 +37,7 @@
 import org.apache.stratos.common.beans.application.signup.ApplicationSignUpBean;
 import org.apache.stratos.common.beans.artifact.repository.ArtifactRepositoryBean;
 import org.apache.stratos.common.beans.cartridge.*;
-import org.apache.stratos.common.beans.kubernetes.KubernetesClusterBean;
-import org.apache.stratos.common.beans.kubernetes.KubernetesHostBean;
-import org.apache.stratos.common.beans.kubernetes.KubernetesMasterBean;
-import org.apache.stratos.common.beans.kubernetes.PortRangeBean;
+import org.apache.stratos.common.beans.kubernetes.*;
 import org.apache.stratos.common.beans.partition.ChildLevelNetworkPartitionBean;
 import org.apache.stratos.common.beans.partition.ChildLevelPartitionBean;
 import org.apache.stratos.common.beans.partition.NetworkPartitionBean;
@@ -60,6 +57,7 @@
 import org.apache.stratos.messaging.domain.instance.ClusterInstance;
 import org.apache.stratos.messaging.domain.instance.GroupInstance;
 import org.apache.stratos.messaging.domain.topology.Cluster;
+import org.apache.stratos.messaging.domain.topology.KubernetesService;
 import org.apache.stratos.rest.endpoint.exception.ServiceGroupDefinitionException;
 import org.wso2.carbon.stratos.common.beans.TenantInfoBean;
 
@@ -698,9 +696,31 @@
         for (String hostname : cluster.getHostNames()) {
             clusterInstanceBean.getHostNames().add(hostname);
         }
+        clusterInstanceBean.setKubernetesServices(convertKubernetesServiceToKubernetesServiceBean(
+                cluster.getKubernetesServices()));
         return clusterInstanceBean;
     }
 
+    private static List<KubernetesServiceBean> convertKubernetesServiceToKubernetesServiceBean(
+            List<KubernetesService> kubernetesServices) {
+        List<KubernetesServiceBean> kubernetesServiceBeans = new ArrayList<KubernetesServiceBean>();
+        if(kubernetesServices != null) {
+            for (KubernetesService kubernetesService : kubernetesServices) {
+
+                KubernetesServiceBean kubernetesServiceBean = new KubernetesServiceBean();
+                kubernetesServiceBean.setId(kubernetesService.getId());
+                kubernetesServiceBean.setPublicIPs(kubernetesService.getPublicIPs());
+                kubernetesServiceBean.setPortalIP(kubernetesService.getPortalIP());
+                kubernetesServiceBean.setProtocol(kubernetesService.getProtocol());
+                kubernetesServiceBean.setPort(kubernetesService.getPort());
+                kubernetesServiceBean.setContainerPort(kubernetesService.getContainerPort());
+
+                kubernetesServiceBeans.add(kubernetesServiceBean);
+            }
+        }
+        return kubernetesServiceBeans;
+    }
+
     private static org.apache.stratos.autoscaler.stub.deployment.partition.Partition[] convertToCCPartitionPojos
             (List<PartitionBean> partitionList) {
 
@@ -1386,7 +1406,6 @@
         applicationBean.setTenantDomain(application.getTenantDomain());
         applicationBean.setTenantAdminUsername(application.getTenantAdminUserName());
         applicationBean.setApplicationInstances(convertApplicationInstancesToApplicationInstances(application));
-	   // applicationBean.setAccessURL(createApplicationAccessUrl(application));
         return applicationBean;
     }
 
diff --git a/components/org.apache.stratos.rest.endpoint/src/main/webapp/api/WEB-INF/cxf-servlet.xml b/components/org.apache.stratos.rest.endpoint/src/main/webapp/api/WEB-INF/cxf-servlet.xml
index d1004a6..3ec0d44 100644
--- a/components/org.apache.stratos.rest.endpoint/src/main/webapp/api/WEB-INF/cxf-servlet.xml
+++ b/components/org.apache.stratos.rest.endpoint/src/main/webapp/api/WEB-INF/cxf-servlet.xml
@@ -133,6 +133,8 @@
                 <value>clusterInstances</value>
                 <value>applicationInstances</value>
                 <value>accessUrls</value>
+                <value>kubernetesServices</value>
+                <value>publicIPs</value>
             </list>
         </property>
     </bean>