Repository: stratos Updated Branches: refs/heads/master bb6e10298 -> b7667b18b
Fixing kubernetes service port duplication issue when multiple applications are deployed Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/b7667b18 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/b7667b18 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/b7667b18 Branch: refs/heads/master Commit: b7667b18b5129f2a55763ece7b51448f26dfa501 Parents: bb6e102 Author: Imesh Gunaratne <[email protected]> Authored: Tue Jun 23 23:13:15 2015 +0530 Committer: Imesh Gunaratne <[email protected]> Committed: Tue Jun 23 23:13:41 2015 +0530 ---------------------------------------------------------------------- .../context/CloudControllerContext.java | 69 ++++++++++++- .../controller/domain/ClusterPortMapping.java | 78 ++++++++++++++ .../cloud/controller/domain/PortMapping.java | 21 +--- .../iaases/kubernetes/KubernetesIaas.java | 103 +++++++++++++------ .../messaging/topology/TopologyBuilder.java | 33 +++++- .../impl/CloudControllerServiceImpl.java | 20 ++-- .../rest/endpoint/api/StratosApiV41Utils.java | 7 ++ 7 files changed, 262 insertions(+), 69 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/b7667b18/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java index 5292255..626f3c8 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/context/CloudControllerContext.java @@ -62,6 +62,9 @@ public class CloudControllerContext implements Serializable { private static final String CC_CARTRIDGE_TYPE_TO_CARTRIDGES_MAP = "CC_CARTRIDGE_TYPE_TO_CARTRIDGES_MAP"; private static final String CC_SERVICE_GROUP_NAME_TO_SERVICE_GROUP_MAP = "CC_SERVICE_GROUP_NAME_TO_SERVICE_GROUP_MAP"; private static final String CC_NETWORK_PARTITION_ID_TO_NETWORK_PARTITION_MAP = "CC_NETWORK_PARTITION_ID_TO_NETWORK_PARTITION_MAP"; + private static final String CC_PARTITION_TO_IAAS_PROVIDER_BY_CARTRIDGE_MAP = "CC_PARTITION_TO_IAAS_PROVIDER_BY_CARTRIDGE_MAP"; + private static final String CC_CARTRIDGE_TYPE_TO_IAAS_PROVIDER_MAP = "CC_CARTRIDGE_TYPE_TO_IAAS_PROVIDER_MAP"; + private static final String CC_APPLICATION_ID_TO_CLUSTER_ID_TO_PORT_MAPPING_MAP = "CC_APPLICATION_ID_TO_CLUSTER_ID_TO_PORT_MAPPING_MAP"; private static final String CC_CLUSTER_CTX_WRITE_LOCK = "CC_CLUSTER_CTX_WRITE_LOCK"; private static final String CC_MEMBER_CTX_WRITE_LOCK = "CC_MEMBER_CTX_WRITE_LOCK"; @@ -71,8 +74,6 @@ public class CloudControllerContext implements Serializable { private static final String CC_CARTRIDGES_WRITE_LOCK = "CC_CARTRIDGES_WRITE_LOCK"; private static final String CC_SERVICE_GROUPS_WRITE_LOCK = "CC_SERVICE_GROUPS_WRITE_LOCK"; - private static final String CC_PARTITION_TO_IAAS_PROVIDER_BY_CARTRIDGE_MAP = "CC_PARTITION_TO_IAAS_PROVIDER_BY_CARTRIDGE_MAP"; - private static final String CC_CARTRIDGE_TYPE_TO_IAAS_PROVIDER_MAP = "CC_CARTRIDGE_TYPE_TO_IAAS_PROVIDER_MAP"; private static volatile CloudControllerContext instance; private final transient DistributedObjectProvider distributedObjectProvider; @@ -163,6 +164,12 @@ public class CloudControllerContext implements Serializable { */ private Map<String, List<IaasProvider>> cartridgeTypeToIaasProviders; + /** + * Key - Application id + * Value - Cluster port mappings against application id, cluster id + */ + private Map<String, Map<String, List<ClusterPortMapping>>> applicationIdToClusterIdToPortMappings; + private String streamId; private boolean isPublisherRunning; private boolean isTopologySyncRunning; @@ -194,6 +201,8 @@ public class CloudControllerContext implements Serializable { networkPartitionIDToNetworkPartitionMap = distributedObjectProvider.getMap(CC_NETWORK_PARTITION_ID_TO_NETWORK_PARTITION_MAP); partitionToIaasProviderByCartridge = distributedObjectProvider.getMap(CC_PARTITION_TO_IAAS_PROVIDER_BY_CARTRIDGE_MAP); cartridgeTypeToIaasProviders = distributedObjectProvider.getMap(CC_CARTRIDGE_TYPE_TO_IAAS_PROVIDER_MAP); + applicationIdToClusterIdToPortMappings = distributedObjectProvider.getMap(CC_APPLICATION_ID_TO_CLUSTER_ID_TO_PORT_MAPPING_MAP); + // Update context from the registry updateContextFromRegistry(); } @@ -712,6 +721,8 @@ public class CloudControllerContext implements Serializable { partitionToIaasProviderByCartridge); copyMap(serializedObj.cartridgeTypeToIaasProviders, cartridgeTypeToIaasProviders); + copyMap(serializedObj.applicationIdToClusterIdToPortMappings, + applicationIdToClusterIdToPortMappings); if (log.isDebugEnabled()) { log.debug("Cloud controller context is read from the registry"); @@ -834,4 +845,58 @@ public class CloudControllerContext implements Serializable { List<IaasProvider> iaasProviderList = cartridgeTypeToIaasProviders.get(cartridgeType); return iaasProviderList; } + + /** + * Add a cluster port mapping. + * @param portMapping + */ + public void addClusterPortMapping(ClusterPortMapping portMapping) { + String applicationId = portMapping.getApplicationId(); + String clusterId = portMapping.getClusterId(); + + List<ClusterPortMapping> portMappings = null; + Map<String, List<ClusterPortMapping>> clusterIdToPortMappings = + applicationIdToClusterIdToPortMappings.get(applicationId); + + if(clusterIdToPortMappings == null) { + clusterIdToPortMappings = new HashMap<String, List<ClusterPortMapping>>(); + applicationIdToClusterIdToPortMappings.put(applicationId, clusterIdToPortMappings); + } else { + portMappings = clusterIdToPortMappings.get(portMapping.getClusterId()); + } + if(portMappings == null) { + portMappings = new ArrayList<ClusterPortMapping>(); + clusterIdToPortMappings.put(clusterId, portMappings); + } + + if(!portMappings.contains(portMapping)) { + portMappings.add(portMapping); + } + } + + /** + * Get cluster port mappings of an application cluster. + * @param applicationId + * @param clusterId + * @return + */ + public List<ClusterPortMapping> getClusterPortMappings(String applicationId, String clusterId) { + Map<String, List<ClusterPortMapping>> clusterIdToPortMappings = + applicationIdToClusterIdToPortMappings.get(applicationId); + + if(clusterIdToPortMappings != null) { + return clusterIdToPortMappings.get(clusterId); + } + return null; + } + + /** + * Remove all the cluster port mappings of the given application. + * @param applicationId + */ + public void removeClusterPortMappings(String applicationId) { + if(applicationIdToClusterIdToPortMappings.containsKey(applicationId)) { + applicationIdToClusterIdToPortMappings.remove(applicationId); + } + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/b7667b18/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterPortMapping.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterPortMapping.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterPortMapping.java new file mode 100644 index 0000000..e816459 --- /dev/null +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/ClusterPortMapping.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.cloud.controller.domain; + +import java.io.Serializable; + +/** + * Cluster port mappings keep track of the generated kubernetes service ports for each + * port mapping defined in the corresponding cartridge. + */ +public class ClusterPortMapping extends PortMapping implements Serializable { + + private static final long serialVersionUID = -5387564414633460306L; + + private String applicationId; + private String clusterId; + private boolean kubernetes; + private int kubernetesServicePort; + + public ClusterPortMapping() { + } + + public ClusterPortMapping(String applicationId, String clusterId, String name, String protocol, int port, int proxyPort) { + super(protocol, port, proxyPort); + super.setName(name); + + this.applicationId = applicationId; + this.clusterId = clusterId; + } + + public String getApplicationId() { + return applicationId; + } + + public String getClusterId() { + return clusterId; + } + + public int getKubernetesServicePort() { + return kubernetesServicePort; + } + + public void setKubernetesServicePort(int kubernetesServicePort) { + this.kubernetesServicePort = kubernetesServicePort; + kubernetes = true; + } + + public boolean isKubernetes() { + return kubernetes; + } + + @Override + public boolean equals(Object obj) { + ClusterPortMapping portMappingObj = (ClusterPortMapping) obj; + return this.getName().equals(portMappingObj.getName()); + } + + public String toString() { + return "[application-id] " + getApplicationId() + " [cluster-id] " + getClusterId() + ", " + + super.toString() + " [kubernetes-service-port] "+ getKubernetesServicePort(); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/b7667b18/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/PortMapping.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/PortMapping.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/PortMapping.java index 81c91a4..b33eb97 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/PortMapping.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/PortMapping.java @@ -28,8 +28,6 @@ public class PortMapping implements Serializable { private String protocol; private int port; private int proxyPort; - private int kubernetesServicePort; - private boolean isKubernetesServicePortMapping; public PortMapping() { } @@ -73,23 +71,6 @@ public class PortMapping implements Serializable { } public String toString() { - - return "Protocol: " + protocol + ", Port: " + port + ", Proxy Port: " + proxyPort; - } - - public void setKubernetesServicePort(int kubernetesServicePort) { - this.kubernetesServicePort = kubernetesServicePort; - } - - public int getKubernetesServicePort() { - return kubernetesServicePort; - } - - public boolean isKubernetesServicePortMapping() { - return isKubernetesServicePortMapping; - } - - public void setKubernetesServicePortMapping(boolean isKubernetesServicePortMapping) { - this.isKubernetesServicePortMapping = isKubernetesServicePortMapping; + return "[protocol] " + protocol + " [port] " + port + " [proxy-port] " + proxyPort; } } http://git-wip-us.apache.org/repos/asf/stratos/blob/b7667b18/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java ---------------------------------------------------------------------- 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 423eb23..faeed2c 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 @@ -47,6 +47,7 @@ import org.apache.stratos.messaging.domain.topology.KubernetesService; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.concurrent.locks.Lock; @@ -214,7 +215,8 @@ public class KubernetesIaas extends Iaas { kubernetesPortRange.getLower()); // Generate kubernetes service ports and update port mappings in cartridge - generateKubernetesServicePorts(kubernetesClusterContext, clusterContext.getClusterId(), cartridge); + generateKubernetesServicePorts(clusterContext.getApplicationId(), clusterContext.getClusterId(), + kubernetesClusterContext, cartridge); // Create kubernetes services for port mappings KubernetesApiClient kubernetesApi = kubernetesClusterContext.getKubApi(); @@ -493,11 +495,14 @@ public class KubernetesIaas extends Iaas { log.debug(String.format("Minion private IPs: %s", minionPrivateIPList)); } - if (cartridge.getPortMappings() != null) { - for (PortMapping portMapping : Arrays.asList(cartridge.getPortMappings())) { + Collection<ClusterPortMapping> clusterPortMappings = CloudControllerContext.getInstance() + .getClusterPortMappings(clusterContext.getApplicationId(), clusterId); + + if (clusterPortMappings != null) { + for (ClusterPortMapping clusterPortMapping : clusterPortMappings) { // Skip if already created - int containerPort = portMapping.getPort(); + int containerPort = clusterPortMapping.getPort(); if (kubernetesServiceExist(kubernetesServices, containerPort)) { continue; } @@ -505,19 +510,18 @@ public class KubernetesIaas extends Iaas { // Find next service sequence no long serviceSeqNo = kubernetesClusterContext.getServiceSeqNo().incrementAndGet(); String serviceId = KubernetesIaasUtil.fixSpecialCharacters("service" + "-" + (serviceSeqNo)); - String serviceLabel = KubernetesIaasUtil.fixSpecialCharacters(clusterId); if (log.isInfoEnabled()) { log.info(String.format("Creating kubernetes service: [cluster] %s [service] %s " + "[protocol] %s [service-port] %d [container-port] %s", clusterId, - serviceId, portMapping.getProtocol(), portMapping.getKubernetesServicePort(), - containerPort)); + serviceId, clusterPortMapping.getProtocol(), + clusterPortMapping.getKubernetesServicePort(), containerPort)); } // Create kubernetes service for port mapping - int servicePort = portMapping.getKubernetesServicePort(); - String containerPortName = KubernetesIaasUtil.preparePortNameFromPortMapping(portMapping); + int servicePort = clusterPortMapping.getKubernetesServicePort(); + String containerPortName = KubernetesIaasUtil.preparePortNameFromPortMapping(clusterPortMapping); try { // Services need to use minions private IP addresses for creating iptable rules @@ -541,7 +545,7 @@ public class KubernetesIaas extends Iaas { // Expose minions public IP addresses as they need to be accessed by external networks String[] minionPublicIPArray = minionPublicIPList.toArray(new String[minionPublicIPList.size()]); kubernetesService.setPublicIPs(minionPublicIPArray); - kubernetesService.setProtocol(portMapping.getProtocol()); + kubernetesService.setProtocol(clusterPortMapping.getProtocol()); kubernetesService.setPort(service.getSpec().getPorts().get(0).getPort()); kubernetesService.setContainerPort(containerPort); kubernetesServices.add(kubernetesService); @@ -549,7 +553,7 @@ public class KubernetesIaas extends Iaas { if (log.isInfoEnabled()) { log.info(String.format("Kubernetes service successfully created: [cluster] %s [service] %s " + "[protocol] %s [service-port] %d [container-port] %s", clusterId, - serviceId, portMapping.getProtocol(), servicePort, containerPort)); + serviceId, clusterPortMapping.getProtocol(), servicePort, containerPort)); } } } @@ -575,46 +579,79 @@ public class KubernetesIaas extends Iaas { * @param clusterId * @param cartridge */ - private void generateKubernetesServicePorts(KubernetesClusterContext kubernetesClusterContext, String clusterId, + private void generateKubernetesServicePorts(String applicationId, String clusterId, + KubernetesClusterContext kubernetesClusterContext, Cartridge cartridge) { + synchronized (KubernetesIaas.class) { if (cartridge != null) { + StringBuilder portMappingStrBuilder = new StringBuilder(); for (PortMapping portMapping : Arrays.asList(cartridge.getPortMappings())) { - if (portMapping.getKubernetesServicePort() == 0) { - int nextServicePort = kubernetesClusterContext.getNextServicePort(); - if (nextServicePort == -1) { - throw new RuntimeException(String.format("Could not generate service port: [cluster-id] %s " + - "[port] %d", clusterId, portMapping.getPort())); - } - portMapping.setKubernetesServicePort(nextServicePort); - portMapping.setKubernetesServicePortMapping(true); - // Add port mappings to payload - if (portMappingStrBuilder.toString().length() > 0) { - portMappingStrBuilder.append(";"); - } - portMappingStrBuilder.append(String.format("NAME:%s|PROTOCOL:%s|PORT:%d|PROXY_PORT:%d", - portMapping.getName(), portMapping.getProtocol(), - portMapping.getKubernetesServicePort(), portMapping.getProxyPort())); + int nextServicePort = kubernetesClusterContext.getNextServicePort(); + if (nextServicePort == -1) { + throw new RuntimeException(String.format("Could not generate service port: [cluster-id] %s " + + "[port] %d", clusterId, portMapping.getPort())); + } - if (log.isInfoEnabled()) { - log.info(String.format("Kubernetes service port generated: [cluster-id] %s [port] %d " + - "[service-port] %d", clusterId, portMapping.getPort(), nextServicePort)); - } + Collection<ClusterPortMapping> clusterPortMappings = + CloudControllerContext.getInstance().getClusterPortMappings(applicationId, clusterId); + if(clusterPortMappings == null) { + throw new CloudControllerException(String.format("Cluster port mappings not found: " + + "[application-id] %s [cluster-id] %s", applicationId, clusterId)); + } + + ClusterPortMapping clusterPortMapping = findClusterPortMapping(clusterPortMappings, portMapping); + if(clusterPortMappings == null) { + throw new CloudControllerException(String.format("Cluster port mapping not found: " + + "[application-id] %s [cluster-id] %s [transport] %s", applicationId, clusterId, + portMapping.getName())); + } + + clusterPortMapping.setKubernetesServicePort(nextServicePort); + + // Add port mappings to payload + if (portMappingStrBuilder.toString().length() > 0) { + portMappingStrBuilder.append(";"); + } + portMappingStrBuilder.append(String.format("NAME:%s|PROTOCOL:%s|PORT:%d|PROXY_PORT:%d", + clusterPortMapping.getName(), clusterPortMapping.getProtocol(), + clusterPortMapping.getKubernetesServicePort(), clusterPortMapping.getProxyPort())); + + if (log.isInfoEnabled()) { + log.info(String.format("Kubernetes service port generated: [application-id] %s " + + "[cluster-id] %s [port] %d [service-port] %d", + applicationId, clusterId, clusterPortMapping.getPort(), + clusterPortMapping.getKubernetesServicePort())); } } NameValuePair nameValuePair = new NameValuePair(PORT_MAPPINGS, portMappingStrBuilder.toString()); payload.add(nameValuePair); - // Persist service ports added to port mappings - CloudControllerContext.getInstance().updateKubernetesClusterContext(kubernetesClusterContext); + // Persist service ports added to cluster port mappings CloudControllerContext.getInstance().persist(); } } } + + /** + * Find cluster port mapping that corresponds to cartridge port mapping. + * @param clusterPortMappings + * @param portMapping + * @return + */ + private ClusterPortMapping findClusterPortMapping(Collection<ClusterPortMapping> clusterPortMappings, PortMapping portMapping) { + for(ClusterPortMapping clusterPortMapping : clusterPortMappings) { + if(clusterPortMapping.getName().equals(portMapping.getName())) { + return clusterPortMapping; + } + } + return null; + } + /** * Terminate all the containers belong to a cluster by cluster id. * http://git-wip-us.apache.org/repos/asf/stratos/blob/b7667b18/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java ---------------------------------------------------------------------- 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 4a78a6e..cfa7732 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 @@ -21,10 +21,8 @@ package org.apache.stratos.cloud.controller.messaging.topology; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.cloud.controller.context.CloudControllerContext; -import org.apache.stratos.cloud.controller.domain.Cartridge; -import org.apache.stratos.cloud.controller.domain.ClusterContext; -import org.apache.stratos.cloud.controller.domain.MemberContext; -import org.apache.stratos.cloud.controller.domain.PortMapping; +import org.apache.stratos.cloud.controller.domain.*; +import org.apache.stratos.cloud.controller.exception.CloudControllerException; import org.apache.stratos.cloud.controller.exception.InvalidCartridgeTypeException; import org.apache.stratos.cloud.controller.exception.InvalidMemberException; import org.apache.stratos.cloud.controller.messaging.publisher.TopologyEventPublisher; @@ -193,11 +191,32 @@ public class TopologyBuilder { log.info("Application Cluster " + cluster.getClusterId() + " created in CC topology"); } } - TopologyManager.updateTopology(topology); } finally { TopologyManager.releaseWriteLock(); } + + log.debug("Creating cluster port mappings: [appication-id] " + appId); + for(Cluster cluster : appClusters) { + String cartridgeType = cluster.getServiceName(); + Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(cartridgeType); + if(cartridge == null) { + throw new CloudControllerException("Cartridge not found: [cartridge-type] " + cartridgeType); + } + + for(PortMapping portMapping : cartridge.getPortMappings()) { + ClusterPortMapping clusterPortMapping = new ClusterPortMapping(appId, + cluster.getClusterId(), portMapping.getName(), portMapping.getProtocol(), portMapping.getPort(), + portMapping.getProxyPort()); + CloudControllerContext.getInstance().addClusterPortMapping(clusterPortMapping); + log.debug("Cluster port mapping created: " + clusterPortMapping.toString()); + } + } + + // Persist cluster port mappings + CloudControllerContext.getInstance().persist(); + + // Send application clusters created event TopologyEventPublisher.sendApplicationClustersCreated(appId, appClusters); } @@ -235,6 +254,10 @@ public class TopologyBuilder { TopologyManager.releaseWriteLock(); } + // Remove cluster port mappings of application + CloudControllerContext.getInstance().removeClusterPortMappings(appId); + CloudControllerContext.getInstance().persist(); + TopologyEventPublisher.sendApplicationClustersRemoved(appId, clusterData); } http://git-wip-us.apache.org/repos/asf/stratos/blob/b7667b18/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java index dab9f29..4d51cc1 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 @@ -1050,23 +1050,25 @@ public class CloudControllerServiceImpl implements CloudControllerService { Map<String, List<String>> accessUrls = new HashMap<String, List<String>>(); for (ApplicationClusterContext appClusterCtxt : appClustersContexts) { + String clusterId = appClusterCtxt.getClusterId(); if (appClusterCtxt.isLbCluster()) { String[] dependencyClusterIDs = appClusterCtxt.getDependencyClusterIds(); if (dependencyClusterIDs != null) { for (int i = 0; i < dependencyClusterIDs.length; i++) { - Cartridge cartridge = CloudControllerContext.getInstance().getCartridge( - appClusterCtxt.getCartridgeType()); + List<String> accessUrlPerCluster = new ArrayList(); - List<PortMapping> portMappings = Arrays.asList(cartridge.getPortMappings()); - for (PortMapping portMap : portMappings) { + Collection<ClusterPortMapping> clusterPortMappings = + CloudControllerContext.getInstance().getClusterPortMappings(appId, clusterId); + + for (ClusterPortMapping clusterPortMapping : clusterPortMappings) { try { - if (portMap.isKubernetesServicePortMapping()) { - URL accessUrl = new URL(portMap.getProtocol(), appClusterCtxt.getHostName(), - portMap.getKubernetesServicePort(), ""); + if (clusterPortMapping.isKubernetes()) { + URL accessUrl = new URL(clusterPortMapping.getProtocol(), appClusterCtxt.getHostName(), + clusterPortMapping.getKubernetesServicePort(), ""); accessUrlPerCluster.add(accessUrl.toString()); } else { - URL accessUrl = new URL(portMap.getProtocol(), appClusterCtxt.getHostName(), - portMap.getProxyPort(), ""); + URL accessUrl = new URL(clusterPortMapping.getProtocol(), appClusterCtxt.getHostName(), + clusterPortMapping.getProxyPort(), ""); accessUrlPerCluster.add(accessUrl.toString()); } } catch (MalformedURLException e) { http://git-wip-us.apache.org/repos/asf/stratos/blob/b7667b18/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java ---------------------------------------------------------------------- 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 2211ef3..1a80bc2 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 @@ -127,6 +127,13 @@ public class StratosApiV41Utils { cartridgeBean.getType())); } + for(PortMappingBean portMapping : cartridgeBean.getPortMapping()) { + if(StringUtils.isBlank(portMapping.getName())) { + throw new RestAPIException(String.format("A name is required for each port mapping: " + + "[cartridge] %s", cartridgeBean.getType())); + } + } + Cartridge cartridgeConfig = createCartridgeConfig(cartridgeBean); CloudControllerServiceClient cloudControllerServiceClient = CloudControllerServiceClient.getInstance(); cloudControllerServiceClient.addCartridge(cartridgeConfig);
