http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/KubernetesIaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/KubernetesIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/KubernetesIaas.java index 2b824dc..bdb36cc 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/KubernetesIaas.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/KubernetesIaas.java @@ -19,7 +19,6 @@ package org.apache.stratos.cloud.controller.iaases; -import org.apache.commons.collections.ListUtils; import org.apache.commons.lang.NotImplementedException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -27,9 +26,7 @@ import org.apache.stratos.cloud.controller.concurrent.ScheduledThreadExecutor; import org.apache.stratos.cloud.controller.context.CloudControllerContext; import org.apache.stratos.cloud.controller.domain.*; import org.apache.stratos.cloud.controller.exception.*; -import org.apache.stratos.cloud.controller.functions.ContainerClusterContextToKubernetesService; import org.apache.stratos.cloud.controller.functions.ContainerClusterContextToReplicationController; -import org.apache.stratos.cloud.controller.functions.PodToMemberContext; import org.apache.stratos.cloud.controller.iaases.validators.KubernetesPartitionValidator; import org.apache.stratos.cloud.controller.iaases.validators.PartitionValidator; import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil; @@ -41,13 +38,9 @@ import org.apache.stratos.common.kubernetes.KubernetesGroup; import org.apache.stratos.common.kubernetes.PortRange; import org.apache.stratos.kubernetes.client.KubernetesApiClient; import org.apache.stratos.kubernetes.client.exceptions.KubernetesClientException; -import org.apache.stratos.kubernetes.client.model.Label; -import org.apache.stratos.kubernetes.client.model.Pod; -import org.apache.stratos.kubernetes.client.model.ReplicationController; -import org.apache.stratos.kubernetes.client.model.Service; +import org.apache.stratos.kubernetes.client.model.*; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.concurrent.locks.Lock; @@ -57,6 +50,7 @@ import java.util.concurrent.locks.Lock; public class KubernetesIaas extends Iaas { private static final Log log = LogFactory.getLog(KubernetesIaas.class); + private static final long POD_CREATION_TIMEOUT = 60000; // 1 min private PartitionValidator partitionValidator; @@ -71,9 +65,8 @@ public class KubernetesIaas extends Iaas { } @Override - public MemberContext createInstance(MemberContext memberContext) throws CartridgeNotFoundException { - memberContext = startContainer(memberContext); - return memberContext; + public MemberContext startInstance(MemberContext memberContext) throws CartridgeNotFoundException { + return startContainer(memberContext); } @Override @@ -83,17 +76,20 @@ public class KubernetesIaas extends Iaas { @Override public boolean isValidRegion(String region) throws InvalidRegionException { - return false; + // No regions in kubernetes cluster + return true; } @Override public boolean isValidZone(String region, String zone) throws InvalidZoneException, InvalidRegionException { - return false; + // No zones in kubernetes cluster + return true; } @Override public boolean isValidHost(String zone, String host) throws InvalidHostException { - return false; + // No zones in kubernetes cluster + return true; } @Override @@ -133,12 +129,13 @@ public class KubernetesIaas extends Iaas { @Override public void setDynamicPayload(byte[] payload) { - + // Payload is passed via environment } @Override - public void terminateInstance(MemberContext memberContext) throws InvalidCartridgeTypeException, InvalidMemberException { - + public void terminateInstance(MemberContext memberContext) throws InvalidCartridgeTypeException, + InvalidMemberException, MemberTerminationFailedException { + terminateContainer(memberContext.getMemberId()); } public MemberContext startContainer(MemberContext memberContext) @@ -154,22 +151,25 @@ public class KubernetesIaas extends Iaas { // Validate cluster id String clusterId = memberContext.getClusterId(); - handleNullObject(clusterId, "Could not start containers, cluster id is null in member context."); + String memberId = memberContext.getMemberId(); + handleNullObject(clusterId, "Could not start containers, cluster id is null in member context"); // Validate cluster context ClusterContext clusterContext = CloudControllerContext.getInstance().getClusterContext(clusterId); handleNullObject(clusterContext, "Could not start containers, cluster context not found: [cluster-id] " - + clusterId); + + clusterId + " [member-id] " + memberId); // Validate partition Partition partition = memberContext.getPartition(); - handleNullObject(partition, "Could not start containers, partition not found in member context."); + handleNullObject(partition, "Could not start containers, partition not found in member context: " + + "[cluster-id] " + clusterId + " [member-id] " + memberId); // Validate cartridge String cartridgeType = clusterContext.getCartridgeType(); Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(cartridgeType); if (cartridge == null) { - String msg = "Could not start containers, cartridge not found: [cartridge-type] " + cartridgeType; + String msg = "Could not start containers, cartridge not found: [cartridge-type] " + cartridgeType + " " + + "[cluster-id] " + clusterId + " [member-id] " + memberId; log.error(msg); throw new CartridgeNotFoundException(msg); } @@ -179,123 +179,83 @@ public class KubernetesIaas extends Iaas { partition.getProperties(), partition.toString()); - KubernetesGroup kubernetesGroup = - CloudControllerContext.getInstance().getKubernetesGroup(kubernetesClusterId); + KubernetesGroup kubernetesGroup = CloudControllerContext.getInstance(). + getKubernetesGroup(kubernetesClusterId); handleNullObject(kubernetesGroup, "Could not start container, kubernetes group not found: " + - "[kubernetes-cluster-id] " + kubernetesClusterId); + "[kubernetes-cluster-id] " + kubernetesClusterId + " [cluster-id] " + clusterId + + " [member-id] " + memberId); + // Prepare kubernetes context String kubernetesMasterIp = kubernetesGroup.getKubernetesMaster().getHostIpAddress(); PortRange kubernetesPortRange = kubernetesGroup.getPortRange(); - - // optional String kubernetesMasterPort = CloudControllerUtil.getProperty( kubernetesGroup.getKubernetesMaster().getProperties(), StratosConstants.KUBERNETES_MASTER_PORT, StratosConstants.KUBERNETES_MASTER_DEFAULT_PORT); - KubernetesClusterContext kubClusterContext = getKubernetesClusterContext(kubernetesClusterId, - kubernetesMasterIp, kubernetesMasterPort, kubernetesPortRange.getLower(), kubernetesPortRange.getUpper()); - KubernetesApiClient kubernetesApi = kubClusterContext.getKubApi(); - - - // first let's create a replication controller. - ContainerClusterContextToReplicationController controllerFunction = new ContainerClusterContextToReplicationController(); - ReplicationController controller = controllerFunction.apply(memberContext); - if (log.isDebugEnabled()) { - log.debug("Cloud Controller is delegating request to start a replication controller " + controller + - " for " + memberContext + " to Kubernetes layer."); - } - kubernetesApi.createReplicationController(controller); - - if (log.isDebugEnabled()) { - log.debug("Cloud Controller successfully started the controller " - + controller + " via Kubernetes layer."); - } + kubernetesMasterIp, kubernetesMasterPort, kubernetesPortRange.getLower(), + kubernetesPortRange.getUpper()); - // secondly let's create a kubernetes service proxy to load balance these containers - ContainerClusterContextToKubernetesService serviceFunction = new ContainerClusterContextToKubernetesService(); - Service service = serviceFunction.apply(memberContext); + // Get kubernetes API + KubernetesApiClient kubernetesApi = kubClusterContext.getKubApi(); - if(kubernetesApi.getService(service.getId()) == null) { - if (log.isDebugEnabled()) { - log.debug("Delegating request to start a kubernetes service " + service + - " for member " + memberContext.getMemberId()); - } - kubernetesApi.createService(service); - } + // Create replication controller + createReplicationController(memberContext, clusterId, kubernetesApi); - // set host port and update - Property allocatedServiceHostPortProp = new Property(); - allocatedServiceHostPortProp.setName(StratosConstants.ALLOCATED_SERVICE_HOST_PORT); - allocatedServiceHostPortProp.setValue(String.valueOf(service.getPort())); - clusterContext.getProperties().addProperty(allocatedServiceHostPortProp); - CloudControllerContext.getInstance().addClusterContext(clusterContext); + // Create proxy services for port mappings + List<Service> services = createProxyServices(clusterContext, kubClusterContext, kubernetesApi); - if (log.isDebugEnabled()) { - log.debug("Successfully started the kubernetes service: " - + controller); - } - - // create a label query - Label label = new Label(); - label.setName(clusterId); - // execute the label query - Pod[] newlyCreatedPods = new Pod[0]; - int expectedCount = 1; - - for (int i = 0; i < expectedCount; i++) { - newlyCreatedPods = kubernetesApi.queryPods(new Label[]{label}); + // Wait for pod to be created + Pod[] pods = waitForPodToBeCreated(memberContext, kubernetesApi); + if (pods.length != 1) { if (log.isDebugEnabled()) { - log.debug("Pods Count: " + newlyCreatedPods.length + " for cluster: " + clusterId); - } - if (newlyCreatedPods.length == expectedCount) { - break; - } - Thread.sleep(10000); - } - - if (newlyCreatedPods.length == 0) { - if (log.isDebugEnabled()) { - log.debug(String.format("Pods are not created for cluster : %s, hence deleting the service", clusterId)); + log.debug(String.format("Pod did not create within %d sec, hence deleting the service: " + + "[cluster-id] %s [member-id] %s", ((int)POD_CREATION_TIMEOUT/1000), clusterId, memberId)); } terminateContainers(clusterId); return null; } - + Pod pod = pods[0]; if (log.isDebugEnabled()) { - log.debug(String.format("Pods created : %s for cluster : %s", newlyCreatedPods.length, clusterId)); + log.debug(String.format("Pod created: [cluster-id] %s [member-id] %s [pod-id] %s", + clusterId, memberId, pod.getId())); } - List<MemberContext> memberContexts = new ArrayList<MemberContext>(); - - PodToMemberContext podToMemberContextFunc = new PodToMemberContext(); - // generate Member Contexts - for (Pod pod : newlyCreatedPods) { - MemberContext context = podToMemberContextFunc.apply(pod); - context.setCartridgeType(cartridgeType); - context.setClusterId(clusterId); - - context.setProperties(CloudControllerUtil.addProperty(context.getProperties(), - StratosConstants.ALLOCATED_SERVICE_HOST_PORT, - String.valueOf(service.getPort()))); - - CloudControllerContext.getInstance().addMemberContext(context); - - // wait till Pod status turns to running and send member spawned. - ScheduledThreadExecutor exec = ScheduledThreadExecutor.getInstance(); - if (log.isDebugEnabled()) { - log.debug("Cloud Controller is starting the instance start up thread."); - } - CloudControllerContext.getInstance().addScheduledFutureJob(context.getMemberId(), - exec.schedule(new PodActivationWatcher(pod.getId(), context, kubernetesApi), 5000)); - memberContexts.add(context); + // Create member context + MemberContext newMemberContext = new MemberContext(); + newMemberContext.setCartridgeType(cartridgeType); + newMemberContext.setClusterId(clusterId); + newMemberContext.setMemberId(memberContext.getMemberId()); + newMemberContext.setClusterInstanceId(memberContext.getClusterInstanceId()); + newMemberContext.setInitTime(memberContext.getInitTime()); + newMemberContext.setNetworkPartitionId(memberContext.getNetworkPartitionId()); + newMemberContext.setPartition(memberContext.getPartition()); + newMemberContext.setInitTime(System.currentTimeMillis()); + newMemberContext.setInstanceId(pod.getId()); + newMemberContext.setPrivateIpAddress(pod.getCurrentState().getHostIP()); + newMemberContext.setPublicIpAddress(pod.getCurrentState().getHostIP()); + newMemberContext.setProperties(memberContext.getProperties()); + + Property servicesProperty = new Property(); + servicesProperty.setName(StratosConstants.KUBERNETES_SERVICES); + servicesProperty.setValue(services); + newMemberContext.getProperties().addProperty(servicesProperty); + + CloudControllerContext.getInstance().addMemberContext(newMemberContext); + + // wait till pod status turns to running and send member spawned. + ScheduledThreadExecutor exec = ScheduledThreadExecutor.getInstance(); + if (log.isDebugEnabled()) { + log.debug("Cloud Controller is starting the instance start up thread."); } + CloudControllerContext.getInstance().addScheduledFutureJob(newMemberContext.getMemberId(), + exec.schedule(new PodActivationWatcher(pod.getId(), newMemberContext, kubernetesApi), 5000)); // persist in registry CloudControllerContext.getInstance().persist(); + log.info("Container started successfully: [cluster-id] " + clusterId + " [member-id] " + + memberContext.getMemberId()); - log.info("Kubernetes entities are successfully starting up: " + memberContexts); - - return memberContext; + return newMemberContext; } catch (Exception e) { String msg = "Could not start container: " + memberContext.toString() + " Cause: " + e.getMessage(); log.error(msg, e); @@ -308,26 +268,106 @@ public class KubernetesIaas extends Iaas { } } - public void unregisterDockerService(String clusterId) - throws UnregisteredClusterException { - Lock lock = null; - try { - lock = CloudControllerContext.getInstance().acquireClusterContextWriteLock(); - // terminate all kubernetes units - try { - terminateContainers(clusterId); - } catch (InvalidClusterException e) { - String msg = "Docker instance termination fails for cluster: " + clusterId; - log.error(msg, e); - throw new UnregisteredClusterException(msg, e); + private Pod[] waitForPodToBeCreated(MemberContext memberContext, KubernetesApiClient kubernetesApi) throws KubernetesClientException, InterruptedException { + Labels labels = new Labels(); + labels.setName(memberContext.getMemberId()); + Pod[] pods = new Pod[0]; + long startTime = System.currentTimeMillis(); + while (pods.length == 1) { + pods = kubernetesApi.queryPods(new Labels[]{labels}); + if (log.isDebugEnabled()) { + log.debug("Member pod: [member-id] " + memberContext.getMemberId() + " [count] " + pods.length); } - // send cluster removal notifications and update the state - //onClusterRemoval(clusterId); - } finally { - if (lock != null) { - CloudControllerContext.getInstance().releaseWriteLock(lock); + if ((System.currentTimeMillis() - startTime) > POD_CREATION_TIMEOUT) { + break; + } + Thread.sleep(5000); + } + return pods; + } + + /** + * Create new replication controller for the cluster and generate environment variables using member context. + * @param memberContext + * @param clusterId + * @param kubernetesApi + * @throws KubernetesClientException + */ + private ReplicationController createReplicationController(MemberContext memberContext, String clusterId, KubernetesApiClient kubernetesApi) throws KubernetesClientException { + if (log.isDebugEnabled()) { + log.debug("Creating kubernetes replication controller: [cluster-id] " + clusterId); + } + ContainerClusterContextToReplicationController controllerFunction = new ContainerClusterContextToReplicationController(); + ReplicationController replicationController = controllerFunction.apply(memberContext); + kubernetesApi.createReplicationController(replicationController); + if (log.isDebugEnabled()) { + log.debug("Kubernetes replication controller successfully created: [cluster-id] " + clusterId); + } + return replicationController; + } + + /** + * Create proxy services for the cluster + * @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>(); + + String clusterId = clusterContext.getClusterId(); + Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(clusterContext.getCartridgeType()); + if(cartridge == null) { + String message = "Could not create kubernetes services, cartridge not found: [cartridge-type] " + + clusterContext.getCartridgeType(); + log.error(message); + throw new RuntimeException(message); + } + List<PortMapping> portMappings = cartridge.getPortMappings(); + for(PortMapping portMapping : portMappings) { + if (log.isInfoEnabled()) { + log.info(String.format("Creating kubernetes service: [cluster-id] %s [protocol] %s [port] %s ", + clusterId, portMapping.getProtocol(), portMapping.getPort())); + } + + Service service = new Service(); + service.setId(prepareKubernetesServiceId(clusterId, portMapping)); + service.setApiVersion("v1beta1"); + service.setKind("Service"); + int nextServicePort = kubernetesClusterContext.getNextServicePort(); + if(nextServicePort == -1) { + throw new RuntimeException("Service port not found"); + } + service.setPort(nextServicePort); + Selector selector = new Selector(); + selector.setName(clusterId); + service.setSelector(selector); + + kubernetesApi.createService(service); + services.add(service); + + if (log.isInfoEnabled()) { + log.info(String.format("Kubernetes service successfully created: [cluster-id] %s [protocol] %s " + + "[port] %s [proxy-port] %s", clusterId, portMapping.getProtocol(), + portMapping.getPort(), service.getPort())); } } + // Set service port and update + Property servicePortProperty = new Property(); + servicePortProperty.setName(StratosConstants.KUBERNETES_SERVICES); + servicePortProperty.setValue(services); + clusterContext.getProperties().addProperty(servicePortProperty); + CloudControllerContext.getInstance().addClusterContext(clusterContext); + + return services; + } + + private String prepareKubernetesServiceId(String clusterId, PortMapping portMapping) { + return String.format("%s-%s-%s", clusterId, portMapping.getProtocol(), portMapping.getPort()); } public MemberContext[] terminateContainers(String clusterId) @@ -336,86 +376,50 @@ public class KubernetesIaas extends Iaas { try { lock = CloudControllerContext.getInstance().acquireMemberContextWriteLock(); - ClusterContext ctxt = CloudControllerContext.getInstance().getClusterContext(clusterId); - handleNullObject(ctxt, "Kubernetes units temrination failed. Invalid cluster id. " + clusterId); + ClusterContext clusterContext = CloudControllerContext.getInstance().getClusterContext(clusterId); + handleNullObject(clusterContext, "Could not terminate containers, cluster not found: [cluster-id] " + clusterId); - String kubernetesClusterId = CloudControllerUtil.getProperty(ctxt.getProperties(), + String kubernetesClusterId = CloudControllerUtil.getProperty(clusterContext.getProperties(), StratosConstants.KUBERNETES_CLUSTER_ID); - handleNullObject(kubernetesClusterId, "Kubernetes units termination failed. Cannot find '" + - StratosConstants.KUBERNETES_CLUSTER_ID + "'. " + ctxt); + handleNullObject(kubernetesClusterId, "Could not terminate containers, kubernetes cluster id not found: " + + "[cluster-id] " + clusterId); KubernetesClusterContext kubClusterContext = CloudControllerContext.getInstance().getKubernetesClusterContext(kubernetesClusterId); - handleNullObject(kubClusterContext, "Kubernetes units termination failed. Cannot find a matching Kubernetes Cluster for cluster id: " - + kubernetesClusterId); + handleNullObject(kubClusterContext, "Could not terminate containers, kubernetes cluster not found: " + + "[kubernetes-cluster-id] " + kubernetesClusterId); KubernetesApiClient kubApi = kubClusterContext.getKubApi(); - // delete the service - try { - kubApi.deleteService(CloudControllerUtil.getCompatibleId(clusterId)); - } catch (KubernetesClientException e) { - // we're not going to throw this error, but proceed with other deletions - log.error("Failed to delete Kubernetes service with id: " + clusterId, e); - } - // set replicas=0 for the replication controller - try { - kubApi.updateReplicationController(clusterId, 0); - } catch (KubernetesClientException e) { - // we're not going to throw this error, but proceed with other deletions - log.error("Failed to update Kubernetes Controller with id: " + clusterId, e); - } - - // delete pods forcefully - try { - // create a label query - Label l = new Label(); - l.setName(clusterId); - // execute the label query - Pod[] pods = kubApi.queryPods(new Label[]{l}); - - for (Pod pod : pods) { + // Remove the services + Property servicesProperty = clusterContext.getProperties().getProperty(StratosConstants.KUBERNETES_SERVICES); + if (servicesProperty != null) { + List<Service> services = (List<Service>) servicesProperty.getValue(); + for (Service service : services) { try { - // delete pods forcefully - kubApi.deletePod(pod.getId()); - } catch (KubernetesClientException ignore) { - // we can't do nothing here - log.warn(String.format("Failed to delete Pod [%s] forcefully!", pod.getId())); + kubApi.deleteService(service.getId()); + int allocatedPort = service.getPort(); + kubClusterContext.deallocatePort(allocatedPort); + } catch (KubernetesClientException e) { + log.error("Could not remove kubernetes service: [cluster-id] " + clusterId, e); } } - } catch (KubernetesClientException e) { - // we're not going to throw this error, but proceed with other deletions - log.error("Failed to delete pods forcefully for cluster: " + clusterId, e); } - // delete the replication controller. - try { - kubApi.deleteReplicationController(clusterId); - } catch (KubernetesClientException e) { - String msg = "Failed to delete Kubernetes Controller with id: " + clusterId; - log.error(msg, e); - throw new InvalidClusterException(msg, e); - } - - String allocatedPort = CloudControllerUtil.getProperty(ctxt.getProperties(), - StratosConstants.ALLOCATED_SERVICE_HOST_PORT); - - if (allocatedPort != null) { - kubClusterContext.deallocateHostPort(Integer - .parseInt(allocatedPort)); - } else { - log.warn("Host port dealloacation failed due to a missing property: " - + StratosConstants.ALLOCATED_SERVICE_HOST_PORT); - } - - List<MemberContext> membersToBeRemoved = CloudControllerContext.getInstance().getMemberContextsOfClusterId(clusterId); - - for (MemberContext memberContext : membersToBeRemoved) { - CloudControllerServiceUtil.executeMemberTerminationPostProcess(memberContext); + List<MemberContext> memberContextsRemoved = new ArrayList<MemberContext>(); + List<MemberContext> memberContexts = CloudControllerContext.getInstance().getMemberContextsOfClusterId(clusterId); + for(MemberContext memberContext : memberContexts) { + try { + MemberContext memberContextRemoved = terminateContainer(memberContext.getMemberId()); + memberContextsRemoved.add(memberContextRemoved); + } catch (MemberTerminationFailedException e) { + String message = "Could not terminate container: [member-id] " + memberContext.getMemberId(); + log.error(message); + } } // persist CloudControllerContext.getInstance().persist(); - return membersToBeRemoved.toArray(new MemberContext[0]); + return memberContextsRemoved.toArray(new MemberContext[memberContextsRemoved.size()]); } finally { if (lock != null) { CloudControllerContext.getInstance().releaseWriteLock(lock); @@ -423,184 +427,66 @@ public class KubernetesIaas extends Iaas { } } - public MemberContext[] updateContainers(String clusterId, int containerCount) - throws CartridgeNotFoundException { + /** + * Terminate a container by member id + * @param memberId + * @return + * @throws MemberTerminationFailedException + */ + public MemberContext terminateContainer(String memberId) throws MemberTerminationFailedException { Lock lock = null; try { lock = CloudControllerContext.getInstance().acquireMemberContextWriteLock(); + handleNullObject(memberId, "Could not terminate container, member id is null"); - if (log.isDebugEnabled()) { - log.debug("CloudControllerServiceImpl:updateContainers for cluster : " + clusterId); - } + MemberContext memberContext = CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId); + handleNullObject(memberContext, "Could not terminate container, member context not found: [member-id] " + memberId); + + String clusterId = memberContext.getClusterId(); + handleNullObject(clusterId, "Could not terminate container, cluster id is null: [member-id] " + memberId); ClusterContext clusterContext = CloudControllerContext.getInstance().getClusterContext(clusterId); - handleNullObject(clusterContext, "Container update failed. Invalid cluster id. " + clusterId); + handleNullObject(clusterContext, String.format("Could not terminate container, cluster context not found: " + + "[cluster-id] %s [member-id] %s", clusterId, memberId)); - String cartridgeType = clusterContext.getCartridgeType(); - Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(cartridgeType); + String kubernetesClusterId = CloudControllerUtil.getProperty(clusterContext.getProperties(), + StratosConstants.KUBERNETES_CLUSTER_ID); + handleNullObject(kubernetesClusterId, String.format("Could not terminate container, kubernetes cluster " + + "context id is null: [cluster-id] %s [member-id] %s", clusterId, memberId)); - if (cartridge == null) { - String msg = "Container update failed. No matching Cartridge found [type] " + cartridgeType - + ". [cluster id] " + clusterId; - log.error(msg); - throw new CartridgeNotFoundException(msg); - } + KubernetesClusterContext kubernetesClusterContext = CloudControllerContext.getInstance().getKubernetesClusterContext(kubernetesClusterId); + handleNullObject(kubernetesClusterContext, String.format("Could not terminate container, kubernetes cluster " + + "context not found: [cluster-id] %s [member-id] %s", clusterId, memberId)); + KubernetesApiClient kubApi = kubernetesClusterContext.getKubApi(); + // Remove the pod forcefully try { - String kubernetesClusterId = readProperty(StratosConstants.KUBERNETES_CLUSTER_ID, - clusterContext.getProperties(), clusterContext.toString()); - KubernetesClusterContext kubClusterContext = - CloudControllerContext.getInstance().getKubernetesClusterContext(kubernetesClusterId); - - if (kubClusterContext == null) { - String msg = "Instance startup failed. No matching Kubernetes context found for [id] " + - kubernetesClusterId + " [cluster id] " + clusterId; - log.error(msg); - throw new CartridgeNotFoundException(msg); - } - - KubernetesApiClient kubApi = kubClusterContext.getKubApi(); - // create a label query - Label label = new Label(); - label.setName(clusterId); - - // get the current pods - useful when scale down - Pod[] pods = kubApi.queryPods(new Label[]{label}); - - // update the replication controller - cluster id = replication controller id - if (log.isDebugEnabled()) { - log.debug("Cloud Controller is delegating request to update a replication controller " + clusterId + - " to Kubernetes layer."); - } - - kubApi.updateReplicationController(clusterId, containerCount); - - if (log.isDebugEnabled()) { - log.debug("Cloud Controller successfully updated the controller " - + clusterId + " via Kubernetes layer."); - } - + Labels l = new Labels(); + l.setName(memberId); // execute the label query - Pod[] selectedPods = new Pod[0]; - - // wait replicas*5s time in the worst case ; best case = 0s - for (int i = 0; i < (containerCount * pods.length + 1); i++) { - selectedPods = kubApi.queryPods(new Label[]{label}); - - if (log.isDebugEnabled()) { - log.debug("Pods count: " + selectedPods.length + " for cluster: " + clusterId); - } - if (selectedPods.length == containerCount) { - break; - } - Thread.sleep(10000); - } - - if (log.isDebugEnabled()) { - - log.debug(String.format("Pods created : %s for cluster : %s", selectedPods.length, clusterId)); - } - - List<MemberContext> memberContexts = new ArrayList<MemberContext>(); - - PodToMemberContext podToMemberContextFunc = new PodToMemberContext(); - // generate Member Contexts - for (Pod pod : selectedPods) { - MemberContext context; - // if member context does not exist -> a new member (scale up) - if ((context = CloudControllerContext.getInstance().getMemberContextOfMemberId(pod.getId())) == null) { - - context = podToMemberContextFunc.apply(pod); - context.setCartridgeType(cartridgeType); - context.setClusterId(clusterId); - - context.setProperties(CloudControllerUtil.addProperty(context - .getProperties(), StratosConstants.ALLOCATED_SERVICE_HOST_PORT, - CloudControllerUtil.getProperty(clusterContext.getProperties(), - StratosConstants.ALLOCATED_SERVICE_HOST_PORT))); - - // wait till Pod status turns to running and send member spawned. - ScheduledThreadExecutor exec = ScheduledThreadExecutor.getInstance(); - if (log.isDebugEnabled()) { - log.debug("Cloud Controller is starting the instance start up thread."); - } - CloudControllerContext.getInstance().addScheduledFutureJob(context.getMemberId(), exec.schedule(new PodActivationWatcher(pod.getId(), context, kubApi), 5000)); - - memberContexts.add(context); - - } - // publish data - // TODO -// CartridgeInstanceDataPublisher.publish(context.getMemberId(), null, null, context.getClusterId(), cartridgeType, MemberStatus.Created.toString(), node); - - } - - if (memberContexts.isEmpty()) { - // terminated members - @SuppressWarnings("unchecked") - List<Pod> difference = ListUtils.subtract(Arrays.asList(pods), Arrays.asList(selectedPods)); - for (Pod pod : difference) { - if (pod != null) { - MemberContext context = CloudControllerContext.getInstance().getMemberContextOfMemberId(pod.getId()); - CloudControllerServiceUtil.executeMemberTerminationPostProcess(context); - memberContexts.add(context); - } + Pod[] pods = kubApi.queryPods(new Labels[]{l}); + for (Pod pod : pods) { + try { + // delete pods forcefully + kubApi.deletePod(pod.getId()); + } catch (KubernetesClientException ignore) { + // we can't do nothing here + log.warn(String.format("Could not delete pod: [pod-id] %s", pod.getId())); } } - - - // persist in registry - CloudControllerContext.getInstance().persist(); - - log.info("Kubernetes entities are successfully starting up. " + memberContexts); - return memberContexts.toArray(new MemberContext[0]); - - } catch (Exception e) { - String msg = "Failed to update containers belong to cluster " + clusterId + ". Cause: " + e.getMessage(); - log.error(msg, e); - throw new IllegalStateException(msg, e); - } - } finally { - if (lock != null) { - CloudControllerContext.getInstance().releaseWriteLock(lock); + } catch (KubernetesClientException e) { + // we're not going to throw this error, but proceed with other deletions + log.error("Could not delete pods of cluster: [cluster-id] " + clusterId, e); } - } - } - - public MemberContext terminateContainer(String memberId) throws MemberTerminationFailedException { - Lock lock = null; - try { - lock = CloudControllerContext.getInstance().acquireMemberContextWriteLock(); - handleNullObject(memberId, "Failed to terminate member. Invalid Member id. [member-id] " + memberId); - MemberContext memberContext = CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId); - handleNullObject(memberContext, "Failed to terminate member. Member id not found. [member-id] " + memberId); - - String clusterId = memberContext.getClusterId(); - handleNullObject(clusterId, "Failed to terminate member. Cluster id is null. [member-id] " + memberId); - - ClusterContext ctxt = CloudControllerContext.getInstance().getClusterContext(clusterId); - handleNullObject(ctxt, String.format("Failed to terminate member [member-id] %s. Invalid cluster id %s ", memberId, clusterId)); - - String kubernetesClusterId = CloudControllerUtil.getProperty(ctxt.getProperties(), - StratosConstants.KUBERNETES_CLUSTER_ID); - - handleNullObject(kubernetesClusterId, String.format("Failed to terminate member [member-id] %s. Cannot find '" + - StratosConstants.KUBERNETES_CLUSTER_ID + "' in [cluster context] %s ", memberId, ctxt)); - KubernetesClusterContext kubClusterContext = CloudControllerContext.getInstance().getKubernetesClusterContext(kubernetesClusterId); - handleNullObject(kubClusterContext, String.format("Failed to terminate member [member-id] %s. Cannot find a matching Kubernetes Cluster in [cluster context] %s ", memberId, ctxt)); - KubernetesApiClient kubApi = kubClusterContext.getKubApi(); - // delete the Pod + // Remove the replication controller try { - // member id = pod id - kubApi.deletePod(memberId); + kubApi.deleteReplicationController(memberContext.getMemberId()); MemberContext memberToBeRemoved = CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId); CloudControllerServiceUtil.executeMemberTerminationPostProcess(memberToBeRemoved); - return memberToBeRemoved; - } catch (KubernetesClientException e) { - String msg = String.format("Failed to terminate member: [member-id] %s", memberId); + String msg = String.format("Failed to terminate member: [cluster-id] %s [member-id] %s", clusterId, memberId); log.error(msg, e); throw new MemberTerminationFailedException(msg, e); } @@ -614,30 +500,21 @@ public class KubernetesIaas extends Iaas { private KubernetesClusterContext getKubernetesClusterContext(String kubernetesClusterId, String kubernetesMasterIp, String kubernetesMasterPort, int upperPort, int lowerPort) { - KubernetesClusterContext origCtxt = - CloudControllerContext.getInstance().getKubernetesClusterContext(kubernetesClusterId); - KubernetesClusterContext newCtxt = - new KubernetesClusterContext(kubernetesClusterId, kubernetesMasterIp, - kubernetesMasterPort, upperPort, lowerPort); - - if (origCtxt == null) { - CloudControllerContext.getInstance().addKubernetesClusterContext(newCtxt); - return newCtxt; + KubernetesClusterContext kubernetesClusterContext = CloudControllerContext.getInstance(). + getKubernetesClusterContext(kubernetesClusterId); + if (kubernetesClusterContext != null) { + return kubernetesClusterContext; } - if (!origCtxt.equals(newCtxt)) { - // if for some reason master IP etc. have changed - newCtxt.setAvailableHostPorts(origCtxt.getAvailableHostPorts()); - CloudControllerContext.getInstance().addKubernetesClusterContext(newCtxt); - return newCtxt; - } else { - return origCtxt; - } + kubernetesClusterContext = new KubernetesClusterContext(kubernetesClusterId, kubernetesMasterIp, + kubernetesMasterPort, lowerPort, upperPort); + CloudControllerContext.getInstance().addKubernetesClusterContext(kubernetesClusterContext); + return kubernetesClusterContext; } private String readProperty(String property, org.apache.stratos.common.Properties properties, String object) { String propVal = CloudControllerUtil.getProperty(properties, property); - handleNullObject(propVal, "Property validation failed. Cannot find property: '" + property + " in " + object); + handleNullObject(propVal, "Property validation failed. Could not find property: '" + property + " in " + object); return propVal; }
http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/MockIaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/MockIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/MockIaas.java index d4956d4..0c86ad2 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/MockIaas.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/MockIaas.java @@ -40,7 +40,7 @@ public class MockIaas extends Iaas { } @Override - public MemberContext createInstance(MemberContext memberContext) { + public MemberContext startInstance(MemberContext memberContext) { return MockIaasService.getInstance().createInstance(memberContext); } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/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 6220f24..400428a 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 @@ -155,7 +155,6 @@ public class TopologyBuilder { try { Topology topology = TopologyManager.getTopology(); - for (Cluster cluster : appClusters) { Service service = topology.getService(cluster.getServiceName()); if (service == null) { @@ -168,13 +167,10 @@ public class TopologyBuilder { } TopologyManager.updateTopology(topology); - } finally { TopologyManager.releaseWriteLock(); } - TopologyEventPublisher.sendApplicationClustersCreated(appId, appClusters); - } public static void handleApplicationClustersRemoved(String appId, Set<ClusterDataHolder> clusterData) { @@ -397,7 +393,8 @@ public class TopologyBuilder { // adding the new member to the cluster after it is successfully started // in IaaS. Topology topology = TopologyManager.getTopology(); - Service service = topology.getService(memberContext.getCartridgeType()); + + Service service = topology.getService(memberContext.getCartridgeType()); String clusterId = memberContext.getClusterId(); Cluster cluster = service.getCluster(clusterId); String memberId = memberContext.getMemberId(); @@ -436,7 +433,7 @@ public class TopologyBuilder { if(cluster.isKubernetesCluster()){ // Update port mappings with generated service proxy port // TODO: Need to properly fix with the latest Kubernetes version - String serviceHostPortStr = CloudControllerUtil.getProperty(memberContext.getProperties(), StratosConstants.ALLOCATED_SERVICE_HOST_PORT); + String serviceHostPortStr = CloudControllerUtil.getProperty(memberContext.getProperties(), StratosConstants.KUBERNETES_SERVICES); if(StringUtils.isEmpty(serviceHostPortStr)) { log.warn("Kubernetes service host port not found for member: [member-id] " + memberId); } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/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 e67b26c..a5d78eb 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 @@ -383,7 +383,7 @@ public class CloudControllerServiceImpl implements CloudControllerService { org.apache.stratos.common.Properties properties = memberContext.getProperties(); if (properties != null) { for (Property prop : properties.getProperties()) { - addToPayload(payload, prop.getName(), prop.getValue()); + addToPayload(payload, prop.getName(), String.valueOf(prop.getValue())); } } } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java index 01059ec..415b3a7 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/InstanceCreator.java @@ -29,7 +29,6 @@ import org.apache.stratos.cloud.controller.iaases.Iaas; import org.apache.stratos.cloud.controller.messaging.publisher.StatisticsDataPublisher; import org.apache.stratos.cloud.controller.messaging.topology.TopologyBuilder; import org.apache.stratos.messaging.domain.topology.MemberStatus; -import org.jclouds.compute.domain.NodeMetadata; import java.util.concurrent.locks.Lock; @@ -98,7 +97,7 @@ public class InstanceCreator implements Runnable { } private MemberContext createInstance(Iaas iaas, MemberContext memberContext) throws CartridgeNotFoundException { - memberContext = iaas.createInstance(memberContext); + memberContext = iaas.startInstance(memberContext); // Validate node id String instanceId = memberContext.getInstanceId(); http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java index 8dc6164..b2af060 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java @@ -111,7 +111,7 @@ public class CloudControllerUtil { org.apache.stratos.common.Properties props = config.getProperties(); if (props != null) { for (Property prop : props.getProperties()) { - cartridge.addProperty(prop.getName(), prop.getValue()); + cartridge.addProperty(prop.getName(), String.valueOf(prop.getValue())); } } @@ -178,7 +178,7 @@ public class CloudControllerUtil { org.apache.stratos.common.Properties props1 = iaasConfig.getProperties(); if (props1 != null) { for (Property prop : props1.getProperties()) { - iaasProvider.addProperty(prop.getName(), prop.getValue()); + iaasProvider.addProperty(prop.getName(), String.valueOf(prop.getValue())); } } @@ -261,7 +261,7 @@ public class CloudControllerUtil { public static String getProperty(Properties properties, String key, String defaultValue) { if (key != null && properties != null) { for (Iterator<Entry<Object, Object>> iterator = properties.entrySet().iterator(); iterator.hasNext();) { - Entry<Object, Object> type = (Entry<Object, Object>) iterator.next(); + Entry<Object, Object> type = iterator.next(); String propName = type.getKey().toString(); String propValue = type.getValue().toString(); if (key.equals(propName)) { http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Properties.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Properties.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Properties.java index 638daba..9dcf5b2 100644 --- a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Properties.java +++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Properties.java @@ -54,6 +54,15 @@ public class Properties implements Serializable { } } + public Property getProperty(String name) { + for(Property property : properties) { + if(property.getName().equals(name)) { + return property; + } + } + return null; + } + public void setProperties(Property[] properties) { this.properties = new ArrayList<Property>(); Collections.addAll(this.properties, properties.clone()); http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Property.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Property.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Property.java index 7ac6b02..4e50252 100644 --- a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Property.java +++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/Property.java @@ -28,7 +28,7 @@ public class Property implements Serializable, Cloneable { private static final long serialVersionUID = -2191782657999410197L; private String name; - private String value; + private Object value; public Property() { } @@ -46,11 +46,11 @@ public class Property implements Serializable, Cloneable { this.name = name; } - public String getValue() { + public Object getValue() { return value; } - public void setValue(String value) { + public void setValue(Object value) { this.value = value; } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/constants/StratosConstants.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/constants/StratosConstants.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/constants/StratosConstants.java index d6bf002..7583f89 100644 --- a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/constants/StratosConstants.java +++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/constants/StratosConstants.java @@ -154,7 +154,7 @@ public class StratosConstants { public static final String KUBERNETES_MIN_REPLICAS = "KUBERNETES_REPLICAS_MIN"; public static final String KUBERNETES_MAX_REPLICAS = "KUBERNETES_REPLICAS_MAX"; public static final String KUBERNETES_PORT_RANGE = "KUBERNETES_PORT_RANGE"; - public static final String ALLOCATED_SERVICE_HOST_PORT = "ALLOCATED_SERVICE_HOST_PORT"; + public static final String KUBERNETES_SERVICES = "KUBERNETES_SERVICES"; //drools related constants public static final String DROOLS_DIR_NAME = "drools"; http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java index f075b8e..beec22f 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java @@ -267,78 +267,80 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { } @Override - public void updateReplicationController(String controllerId, int replicas) + public void updateReplicationController(ReplicationController replicationController) throws KubernetesClientException { - // gets the current controller - ReplicationController controller = getReplicationController(controllerId); - try { - // update the number of replicas - controller.getDesiredState().setReplicas(replicas); - GsonBuilder gsonBuilder = new GsonBuilder(); Gson gson = gsonBuilder.create(); - String content = gson.toJson(controller); + String content = gson.toJson(replicationController); if (log.isDebugEnabled()) { - log.debug("UpdateReplicationController Request Body : " + log.debug("Update kubernetes replication controller request body: " + content); } - URI uri = new URIBuilder(baseURL+"replicationControllers/"+controllerId).build(); + URI uri = new URIBuilder(baseURL+"replicationControllers/"+replicationController.getId()).build(); KubernetesResponse res = restClient.doPut(uri, content); - handleNullResponse("Replication Controller ["+controllerId+"] update failed.", res); + handleNullResponse("Could not update kubernetes replication controller: [replication-controller-id] " + + replicationController.getId(), res); if (res.getStatusCode() != HttpStatus.SC_ACCEPTED && res.getStatusCode() != HttpStatus.SC_OK) { - String msg = "Replication Controller [" + controller - + "] update failed. Error: " - + res.getReason(); - log.error(msg); - throw new KubernetesClientException(msg); + String message = "Could not update kubernetes replication controller: [replication-controller-id] " + + replicationController.getId() + ": " + res.getReason(); + log.error(message); + throw new KubernetesClientException(message); } } catch (KubernetesClientException e) { + String message = "Could not update kubernetes replication controller: [replication-controller-id] " + + replicationController.getId(); + log.error(message, e); throw e; } catch (Exception e) { - String msg = "Error while updating Replication Controller: " - + controller; - log.error(msg, e); - throw new KubernetesClientException(msg, e); - + String message = "Could not update kubernetes replication controller: [replication-controller-id] " + + replicationController.getId(); + log.error(message, e); + throw new KubernetesClientException(message, e); } } @Override - public void deleteReplicationController(String controllerId) + public void deleteReplicationController(String replicationControllerId) throws KubernetesClientException { try { - URI uri = new URIBuilder(baseURL+"replicationControllers/"+controllerId).build(); + URI uri = new URIBuilder(baseURL+"replicationControllers/"+ replicationControllerId).build(); KubernetesResponse res = restClient.doDelete(uri); - handleNullResponse("Replication Controller ["+controllerId+"] deletion failed.", res); + handleNullResponse("Could not delete kubernetes replication controller: [replication-controller-id] " + + replicationControllerId, res); if (res.getStatusCode() == HttpStatus.SC_NOT_FOUND) { - String msg = "Replication Controller ["+controllerId+"] doesn't exist."; - log.error(msg); - throw new KubernetesClientException(msg); + String message = "Replication controller does not exist: [replicateion-controller-id] " + + replicationControllerId; + log.error(message); + throw new KubernetesClientException(message); } if (res.getStatusCode() != HttpStatus.SC_ACCEPTED && res.getStatusCode() != HttpStatus.SC_OK) { - String msg = "Replication Controller ["+controllerId+"] deletion failed. Error: "+ - res.getReason(); - log.error(msg); - throw new KubernetesClientException(msg); + String message = "Could not delete kubernetes replication controller: [replication-controller-id] " + + replicationControllerId + ": " + res.getReason(); + log.error(message); + throw new KubernetesClientException(message); } } catch (KubernetesClientException e) { + String message = "Could not delete kubernetes replication controller: [replication-controller-id] " + + replicationControllerId; + log.error(message, e); throw e; } catch (Exception e) { - String msg = "Error while deleting Replication Controller with Controller ID: "+controllerId; - log.error(msg, e); - throw new KubernetesClientException(msg, e); + String message = "Could not delete kubernetes replication controller: [replication-controller-id] " + + replicationControllerId; + log.error(message, e); + throw new KubernetesClientException(message, e); } } @@ -440,7 +442,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { throws KubernetesClientException { try { - URI uri = new URIBuilder(baseURL+"services/"+serviceId).build(); + URI uri = new URIBuilder(baseURL + "services/" + serviceId).build(); KubernetesResponse res = restClient.doDelete(uri); handleNullResponse("Service ["+serviceId+"] deletion failed.", res); @@ -469,10 +471,10 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { } @Override - public Pod[] queryPods(Label[] label) throws KubernetesClientException { + public Pod[] queryPods(Labels[] labels) throws KubernetesClientException { try { - String labelQuery = getLabelQuery(label); + String labelQuery = getLabelQuery(labels); URI uri = new URIBuilder(baseURL + "pods").addParameter("labels", labelQuery).build(); KubernetesResponse response = restClient.doGet(uri); @@ -497,9 +499,9 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { } } - private String getLabelQuery(Label[] label) { + private String getLabelQuery(Labels[] labels) { String query = ""; - for (Label l : label) { + for (Labels l : labels) { query = query.concat("name="+l.getName()+","); } return query.endsWith(",") ? query.substring(0, query.length()-1) : query; http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java index aab4f52..72eda49 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java @@ -45,11 +45,11 @@ public interface KubernetesAPIClientInterface { /** * Run a label query and retrieve a sub set of Pods. - * @param label of labels for the label query + * @param labels of labels for the label query * @return Pods selected Pods by executing the label query. * @throws KubernetesClientException */ - public Pod[] queryPods(Label[] label) throws KubernetesClientException; + public Pod[] queryPods(Labels[] labels) throws KubernetesClientException; /** * Create a new Pod @@ -84,25 +84,24 @@ public interface KubernetesAPIClientInterface { /** * Create a new Replication Controller - * @param controller controller to be created + * @param replicationController replication controller to be created * @throws KubernetesClientException */ - public void createReplicationController(ReplicationController controller) throws KubernetesClientException; + public void createReplicationController(ReplicationController replicationController) throws KubernetesClientException; /** * Update a Replication Controller (update the number of replicas). - * @param controllerId id of the controller to be updated - * @param replicas update the replicas count of the current controller. + * @param replicationController replication controller to be updated * @throws KubernetesClientException */ - public void updateReplicationController(String controllerId, int replicas) throws KubernetesClientException; + public void updateReplicationController(ReplicationController replicationController) throws KubernetesClientException; /** * Delete a Replication Controller. - * @param controllerId controller id controller id to be deleted. + * @param replicationControllerId controller id controller id to be deleted. * @throws KubernetesClientException */ - public void deleteReplicationController(String controllerId) throws KubernetesClientException; + public void deleteReplicationController(String replicationControllerId) throws KubernetesClientException; /* Services API */ http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Container.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Container.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Container.java index d0187ee..2496523 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Container.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Container.java @@ -37,45 +37,59 @@ public class Container { public String getName() { return name; } + public void setName(String name) { this.name = name; } + public String getImage() { return image; } + public void setImage(String image) { this.image = image; } + public String getWorkingDir() { return workingDir; } + public void setWorkingDir(String workingDir) { this.workingDir = workingDir; } + public String[] getCommand() { return command; } + public void setCommand(String[] command) { this.command = ArrayUtils.clone(command); } + public VolumeMount[] getVolumeMounts() { return volumeMounts; } + public void setVolumeMounts(VolumeMount[] volumeMounts) { this.volumeMounts = ArrayUtils.clone(volumeMounts); } + public Port[] getPorts() { return ports; } + public void setPorts(Port[] ports) { this.ports = ArrayUtils.clone(ports); } + public EnvironmentVariable[] getEnv() { return env; } + public void setEnv(EnvironmentVariable[] env) { this.env = ArrayUtils.clone(env); } + @Override public String toString() { return "Container [name=" + name + ", image=" + image + ", workingDir=" @@ -84,6 +98,4 @@ public class Container { + ", ports=" + Arrays.toString(ports) + ", env=" + Arrays.toString(env) + "]"; } - - } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/EnvironmentVariable.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/EnvironmentVariable.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/EnvironmentVariable.java index 7c9644a..4fb9ab7 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/EnvironmentVariable.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/EnvironmentVariable.java @@ -42,6 +42,4 @@ public class EnvironmentVariable { public String toString() { return "EnvironmentVariable [name=" + name + ", value=" + value + "]"; } - - } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Label.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Label.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Label.java deleted file mode 100644 index 873e882..0000000 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Label.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.stratos.kubernetes.client.model; - -public class Label { - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public String toString() { - return "Label [name=" + name + "]"; - } - -} http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Labels.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Labels.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Labels.java new file mode 100644 index 0000000..dfcf082 --- /dev/null +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Labels.java @@ -0,0 +1,42 @@ +/* + * + * 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.kubernetes.client.model; + +/** + * Labels can contain a list of key/value pairs. Currently we are only using one key/value pair: name/value. + */ +public class Labels { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Label [name=" + name + "]"; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Manifest.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Manifest.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Manifest.java index eef33a4..c4c850e 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Manifest.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Manifest.java @@ -20,7 +20,9 @@ */ package org.apache.stratos.kubernetes.client.model; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.apache.commons.lang3.ArrayUtils; @@ -33,38 +35,51 @@ public class Manifest { private String version; private String id; - private Container[] containers; - private Volume[] volumes; - + private List<Container> containers; + private List<Volume> volumes; + + public Manifest() { + containers = new ArrayList<Container>(); + volumes = new ArrayList<Volume>(); + } + public String getVersion() { return version; } + public void setVersion(String version) { this.version = version; } + public String getId() { return id; } + public void setId(String id) { this.id = id; } - public Container[] getContainers() { + + public List<Container> getContainers() { return containers; } - public void setContainers(Container[] containers) { - this.containers = ArrayUtils.clone(containers); + + public void addContainer(Container container) { + containers.add(container); } - public Volume[] getVolumes() { + + public List<Volume> getVolumes() { return volumes; } - public void setVolumes(Volume[] volumes) { - this.volumes = ArrayUtils.clone(volumes); + + public void addVolume(Volume volume) { + volumes.add(volume); } + @Override public String toString() { return "Manifest [version=" + version + ", id=" + id + ", containers=" - + Arrays.toString(containers) + ", volumes=" - + Arrays.toString(volumes) + "]"; + + containers + ", volumes=" + + volumes + "]"; } } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Pod.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Pod.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Pod.java index 49334d4..a875105 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Pod.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Pod.java @@ -41,80 +41,104 @@ public class Pod { private String status; private String message; private String code; - private Label labels; + private Labels labels; public String getKind() { return kind; } + public void setKind(String kind) { this.kind = kind; } + public String getId() { return id; } + public void setId(String id) { this.id = id; } + public String getCreationTimestamp() { return creationTimestamp; } + public void setCreationTimestamp(String creationTimestamp) { this.creationTimestamp = creationTimestamp; } + public String getSelfLink() { return selfLink; } + public void setSelfLink(String selfLink) { this.selfLink = selfLink; } + public State getDesiredState() { return desiredState; } - public void setDesiredState(State desiredState) { + + public void setState(State desiredState) { this.desiredState = desiredState; } + public State getCurrentState() { return currentState; } + public void setCurrentState(State currentState) { this.currentState = currentState; } + public String getResourceVersion() { return resourceVersion; } + public void setResourceVersion(String resourceVersion) { this.resourceVersion = resourceVersion; } + public String getApiVersion() { return apiVersion; } + public void setApiVersion(String apiVersion) { this.apiVersion = apiVersion; } - public Label getLabels() { + + public Labels getLabels() { return labels; } - public void setLabels(Label labels) { + + public void setLabels(Labels labels) { this.labels = labels; } + public String getStatus() { return status; } + public void setStatus(String status) { this.status = status; } + public String getMessage() { return message; } + public void setMessage(String message) { this.message = message; } + public String getCode() { return code; } + public void setCode(String code) { this.code = code; } + @Override public String toString() { return "Pod [kind=" + kind + ", id=" + id + ", creationTimestamp=" @@ -148,6 +172,4 @@ public class Pod { return false; return true; } - - } http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/ReplicationController.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/ReplicationController.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/ReplicationController.java index 2f1d822..a8a757e 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/ReplicationController.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/ReplicationController.java @@ -21,6 +21,8 @@ package org.apache.stratos.kubernetes.client.model; import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; +import java.util.List; /** * @@ -35,42 +37,53 @@ public class ReplicationController { private String creationTimestamp; private String selfLink; private String apiVersion; - private Label labels; + private Labels labels; private State desiredState; - + public String getKind() { return kind; } + public void setKind(String kind) { this.kind = kind; } + public String getId() { return id; } + public void setId(String id) { this.id = id; } + public String getCreationTimestamp() { return creationTimestamp; } + public void setCreationTimestamp(String creationTimestamp) { this.creationTimestamp = creationTimestamp; } + public String getSelfLink() { return selfLink; } + public void setSelfLink(String selfLink) { this.selfLink = selfLink; } - public Label getLabels() { + + public Labels getLabels() { return labels; } - public void setLabels(Label labels) { + + public void setLabels(Labels labels) { this.labels = labels; } + public State getDesiredState() { return desiredState; } + public void setDesiredState(State desiredState) { this.desiredState = desiredState; } @@ -78,15 +91,19 @@ public class ReplicationController { public String getApiVersion() { return apiVersion; } + public void setApiVersion(String apiVersion) { this.apiVersion = apiVersion; } + public int getResourceVersion() { return resourceVersion; } + public void setResourceVersion(int resourceVersion) { this.resourceVersion = resourceVersion; } + @Override public String toString() { return "ReplicationController [kind=" + kind + ", id=" + id http://git-wip-us.apache.org/repos/asf/stratos/blob/405ff36d/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/model/Service.java ---------------------------------------------------------------------- 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 0950d1f..9cc904e 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 @@ -41,81 +41,102 @@ public class Service { private String containerPort; private Selector selector; private String apiVersion; - private Label labels; + private Labels labels; private String[] publicIPs; public String getKind() { return kind; } + public void setKind(String kind) { this.kind = kind; } + public String getId() { return id; } + public void setId(String id) { this.id = id; } + public String getCreationTimestamp() { return creationTimestamp; } + public void setCreationTimestamp(String creationTimestamp) { this.creationTimestamp = creationTimestamp; } + public String getSelfLink() { return selfLink; } + public void setSelfLink(String selfLink) { this.selfLink = selfLink; } + public String getApiVersion() { return apiVersion; } + public void setApiVersion(String apiVersion) { this.apiVersion = apiVersion; } - public Label getLabels() { + + public Labels getLabels() { return labels; } - public void setLabels(Label labels) { + + public void setLabels(Labels labels) { this.labels = labels; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } + public int getPort() { return port; } + public void setPort(int port) { this.port = port; } + public String getContainerPort() { return containerPort; } + public void setContainerPort(String containerPort) { this.containerPort = containerPort; } + public Selector getSelector() { return selector; } + public void setSelector(Selector selector) { this.selector = selector; } + public String[] getPublicIPs() { return publicIPs; } + public void setPublicIPs(String[] publicIPs) { this.publicIPs = publicIPs; } - @Override + + @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) + "]"; } - }
