From 142965d73141b0c15b7a13fcf6d960ba1239c1a1 Mon Sep 17 00:00:00 2001 From: David Kopp Date: Wed, 2 Oct 2019 16:00:12 +0200 Subject: [PATCH 1/3] Add unit test to check status of undeployed service instance --- .../ust/mico/core/MicoStatusServiceTest.java | 73 +++++++++++++++++-- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java b/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java index 710299858..2378f961c 100644 --- a/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java +++ b/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java @@ -579,21 +579,30 @@ public void getServiceStatus() throws Exception { .setExternalIp("192.168.2.112") .setPort(8080))); - given(micoKubernetesClient.getPodsCreatedByDeploymentOfMicoServiceInstance(any(MicoServiceDeploymentInfo.class))).willReturn(podList.getItems()); + given(micoKubernetesClient.getPodsCreatedByDeploymentOfMicoServiceInstance(eq(micoServiceDeploymentInfo))) + .willReturn(podList.getItems()); Deployment deployment = new DeploymentBuilder() .withNewMetadata().withName("deployment1").endMetadata() .withNewSpec().withReplicas(podList.getItems().size()).endSpec() .withNewStatus().withAvailableReplicas(podList.getItems().size()).endStatus() .build(); - given(micoKubernetesClient.getDeploymentOfMicoServiceInstance(any(MicoServiceDeploymentInfo.class))).willReturn(Optional.of(deployment)); - given(micoKubernetesClient.getInterfaceByNameOfMicoServiceInstance(any(MicoServiceDeploymentInfo.class), anyString())).willReturn(Optional.ofNullable(kubernetesService)); + given(micoKubernetesClient.getDeploymentOfMicoServiceInstance(eq(micoServiceDeploymentInfo))) + .willReturn(Optional.of(deployment)); + given(micoKubernetesClient.getInterfaceByNameOfMicoServiceInstance( + eq(micoServiceDeploymentInfo), eq(micoServiceInterface.getServiceInterfaceName()))) + .willReturn(Optional.ofNullable(kubernetesService)); given(micoKubernetesClient.isApplicationDeployed(otherMicoApplication)).willReturn(true); - given(micoKubernetesClient.getApplicationDeploymentStatus(otherMicoApplication)).willReturn(new MicoApplicationDeploymentStatus(MicoApplicationDeploymentStatus.Value.DEPLOYED)); - given(applicationRepository.findByShortNameAndVersion(SHORT_NAME, VERSION)).willReturn(Optional.of(micoApplication)); - given(applicationRepository.findAllByUsedServiceInstance(INSTANCE_ID)).willReturn(CollectionUtils.listOf(otherMicoApplication)); + given(micoKubernetesClient.getApplicationDeploymentStatus(otherMicoApplication)) + .willReturn(new MicoApplicationDeploymentStatus(MicoApplicationDeploymentStatus.Value.DEPLOYED)); + given(applicationRepository.findByShortNameAndVersion(micoApplication.getShortName(), micoApplication.getVersion())) + .willReturn(Optional.of(micoApplication)); + given(applicationRepository.findAllByUsedServiceInstance(micoServiceDeploymentInfo.getInstanceId())) + .willReturn(CollectionUtils.listOf(otherMicoApplication)); given(prometheusConfig.getUri()).willReturn("http://localhost:9090/api/v1/query"); - given(serviceInterfaceRepository.findByServiceAndName(micoService.getShortName(), micoService.getVersion(), SERVICE_INTERFACE_NAME)).willReturn(Optional.of(micoServiceInterface)); + given(serviceInterfaceRepository.findByServiceAndName( + micoService.getShortName(), micoService.getVersion(), micoServiceInterface.getServiceInterfaceName())) + .willReturn(Optional.of(micoServiceInterface)); given(micoKubernetesClient.getPublicIpOfKubernetesService(kubernetesService.getMetadata().getName(), kubernetesService.getMetadata().getNamespace())).willReturn(Optional.of("192.168.2.112")); @@ -620,6 +629,56 @@ public void getServiceStatus() throws Exception { assertEquals(micoServiceStatus, micoStatusService.getServiceInstanceStatus(micoServiceDeploymentInfo)); } + @Test + public void getServiceStatusOfUndeployedInstance() throws Exception { + MicoServiceStatusResponseDTO micoServiceStatus = new MicoServiceStatusResponseDTO(); + micoServiceStatus + .setName(micoService.getName()) + .setShortName(micoService.getShortName()) + .setVersion(micoService.getVersion()) + .setInstanceId(micoServiceDeploymentInfo.getInstanceId()) + .setAvailableReplicas(0) + .setRequestedReplicas(0) + .setOtherApplicationsUsingThisServiceInstance(CollectionUtils.listOf()) + .setNodeMetrics(CollectionUtils.listOf()) + // Add four pods (on two different nodes) + .setPodsInformation(CollectionUtils.listOf()) + .setErrorMessages(CollectionUtils.listOf( + new MicoMessageResponseDTO() + .setContent("No deployment of MicoService '" + micoService.getShortName() + "' '" + micoService.getVersion() + + "' with instance ID '" + micoServiceDeploymentInfo.getInstanceId() + "' is available.") + .setType(Type.ERROR) + )) + .setInterfacesInformation(CollectionUtils.listOf()); + + given(micoKubernetesClient.getPodsCreatedByDeploymentOfMicoServiceInstance(eq(micoServiceDeploymentInfo))) + .willReturn(new ArrayList<>()); + given(micoKubernetesClient.getDeploymentOfMicoServiceInstance(eq(micoServiceDeploymentInfo))) + .willReturn(Optional.empty()); + given(micoKubernetesClient.getInterfaceByNameOfMicoServiceInstance( + eq(micoServiceDeploymentInfo), eq(micoServiceInterface.getServiceInterfaceName()))) + .willReturn(Optional.empty()); + given(micoKubernetesClient.isApplicationDeployed(otherMicoApplication)).willReturn(false); + given(micoKubernetesClient.getApplicationDeploymentStatus(otherMicoApplication)) + .willReturn(new MicoApplicationDeploymentStatus(MicoApplicationDeploymentStatus.Value.UNDEPLOYED)); + given(applicationRepository.findByShortNameAndVersion(micoApplication.getShortName(), micoApplication.getVersion())) + .willReturn(Optional.of(micoApplication)); + given(applicationRepository.findAllByUsedServiceInstance(micoServiceDeploymentInfo.getInstanceId())) + .willReturn(CollectionUtils.listOf(otherMicoApplication)); + + given(prometheusConfig.getUri()).willReturn("http://localhost:9090/api/v1/query"); + given(serviceInterfaceRepository.findByServiceAndName( + micoService.getShortName(), micoService.getVersion(), micoServiceInterface.getServiceInterfaceName())) + .willReturn(Optional.of(micoServiceInterface)); + + given(micoKubernetesClient.getPublicIpOfKubernetesService(kubernetesService.getMetadata().getName(), + kubernetesService.getMetadata().getNamespace())).willReturn(Optional.empty()); + given(micoKubernetesClient.getPublicPortsOfKubernetesService(kubernetesService.getMetadata().getName(), + kubernetesService.getMetadata().getNamespace())).willReturn(new ArrayList<>()); + + assertEquals(micoServiceStatus, micoStatusService.getServiceInstanceStatus(micoServiceDeploymentInfo)); + } + @Test public void getServiceInterfaceStatus() throws Exception { From 26162c09bff82dedf4c4902fb21154582023f39f Mon Sep 17 00:00:00 2001 From: David Kopp Date: Wed, 2 Oct 2019 18:56:08 +0200 Subject: [PATCH 2/3] Fix only including service instance status if it is relevant --- .../status/MicoServiceStatusResponseDTO.java | 2 +- .../mico/core/service/MicoStatusService.java | 23 +++++++---- .../ust/mico/core/MicoStatusServiceTest.java | 41 +++++++------------ .../core/ServiceResourceIntegrationTests.java | 16 +++++--- .../github/ust/mico/core/TestConstants.java | 1 + 5 files changed, 43 insertions(+), 40 deletions(-) diff --git a/mico-core/src/main/java/io/github/ust/mico/core/dto/response/status/MicoServiceStatusResponseDTO.java b/mico-core/src/main/java/io/github/ust/mico/core/dto/response/status/MicoServiceStatusResponseDTO.java index 9224eaa29..711649f14 100644 --- a/mico-core/src/main/java/io/github/ust/mico/core/dto/response/status/MicoServiceStatusResponseDTO.java +++ b/mico-core/src/main/java/io/github/ust/mico/core/dto/response/status/MicoServiceStatusResponseDTO.java @@ -146,7 +146,7 @@ public class MicoServiceStatusResponseDTO { @ApiModelProperty(extensions = {@Extension( name = CustomOpenApiExtentionsPlugin.X_MICO_CUSTOM_EXTENSION, properties = { - @ExtensionProperty(name = "title", value = "Other Applications Using This Service Instance"), + @ExtensionProperty(name = "title", value = "Applications Using This Service Instance"), @ExtensionProperty(name = "x-order", value = "70"), @ExtensionProperty(name = "description", value = "List of MicoApplicationDTOs " + "representing all applications that share the MicoService instance.") diff --git a/mico-core/src/main/java/io/github/ust/mico/core/service/MicoStatusService.java b/mico-core/src/main/java/io/github/ust/mico/core/service/MicoStatusService.java index dd60f7302..b6faebaf3 100644 --- a/mico-core/src/main/java/io/github/ust/mico/core/service/MicoStatusService.java +++ b/mico-core/src/main/java/io/github/ust/mico/core/service/MicoStatusService.java @@ -125,14 +125,23 @@ public List getServiceStatus(MicoService micoServi List responseDTOList = new ArrayList<>(); for (MicoServiceDeploymentInfo serviceDeploymentInfo : serviceDeploymentInfos) { MicoServiceStatusResponseDTO serviceInstanceStatus = getServiceInstanceStatus(serviceDeploymentInfo); - responseDTOList.add(serviceInstanceStatus); + // Add the instance only to the list if it's considered to be relevant for the service status: + // Either it must be requested to be deployed (requested replicas > 0) + // or it must be currently deployed (available replicas > 0). + if (serviceInstanceStatus.getRequestedReplicas() > 0 || serviceInstanceStatus.getAvailableReplicas() > 0) { + responseDTOList.add(serviceInstanceStatus); + } else { + log.debug("MicoService '{}' '{}' with instance ID '{}' is considered to be not relevant for the status response." + + "There are no requested or available replicas.", + micoService.getShortName(), micoService.getVersion(), serviceDeploymentInfo.getInstanceId()); + } } return responseDTOList; } /** - * Get status information for a single {@link MicoServiceDeploymentInfo}: # available replicas, # requested replicas, pod metrics - * (CPU load, memory usage). + * Get status information for a single {@link MicoServiceDeploymentInfo} if it is deployed: + * # available replicas, # requested replicas, pod metrics (CPU load, memory usage). * * @param serviceDeploymentInfo the {@link MicoServiceDeploymentInfo}. * @return the {@link MicoServiceStatusResponseDTO} which contains status information @@ -168,10 +177,10 @@ public MicoServiceStatusResponseDTO getServiceInstanceStatus(MicoServiceDeployme serviceStatus.setAvailableReplicas(0); } } else { - message = "No deployment of MicoService '" + micoService.getShortName() + "' '" + micoService.getVersion() + - "' with instance ID '" + instanceId + "' is available."; - log.warn(message); - MicoMessage errorMessage = MicoMessage.error(message); + message = "MicoService '" + micoService.getShortName() + "' '" + micoService.getVersion() + + "' with instance ID '" + instanceId + "' is not deployed."; + log.debug(message); + MicoMessage errorMessage = MicoMessage.info(message); return serviceStatus.setErrorMessages(CollectionUtils.listOf(new MicoMessageResponseDTO(errorMessage))); } diff --git a/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java b/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java index 2378f961c..87ff7461b 100644 --- a/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java +++ b/mico-core/src/test/java/io/github/ust/mico/core/MicoStatusServiceTest.java @@ -32,6 +32,7 @@ import io.github.ust.mico.core.model.*; import io.github.ust.mico.core.model.MicoMessage.Type; import io.github.ust.mico.core.persistence.MicoApplicationRepository; +import io.github.ust.mico.core.persistence.MicoServiceDeploymentInfoRepository; import io.github.ust.mico.core.persistence.MicoServiceInterfaceRepository; import io.github.ust.mico.core.persistence.MicoServiceRepository; import io.github.ust.mico.core.service.MicoKubernetesClient; @@ -79,6 +80,8 @@ public class MicoStatusServiceTest { private MicoServiceRepository serviceRepository; @MockBean private MicoServiceInterfaceRepository serviceInterfaceRepository; + @MockBean + private MicoServiceDeploymentInfoRepository serviceDeploymentInfoRepository; @Autowired private MicoStatusService micoStatusService; @@ -487,9 +490,9 @@ public void getApplicationStatusWithMissingDeployment() { .setName(micoApplication.getServices().get(0).getName()) .setInstanceId(micoApplication.getServiceDeploymentInfos().get(0).getInstanceId()) .setErrorMessages(CollectionUtils - .listOf(new MicoMessageResponseDTO().setContent("No deployment of MicoService '" + micoService.getShortName() + .listOf(new MicoMessageResponseDTO().setContent("MicoService '" + micoService.getShortName() + "' '" + micoService.getVersion() + "' with instance ID '" + micoServiceDeploymentInfo.getInstanceId() - + "' is available.").setType(Type.ERROR))))); + + "' is not deployed.").setType(Type.INFO))))); given(micoKubernetesClient.getDeploymentOfMicoServiceInstance(any(MicoServiceDeploymentInfo.class))).willReturn(Optional.empty()); given(micoKubernetesClient.getInterfaceByNameOfMicoServiceInstance(any(MicoServiceDeploymentInfo.class), anyString())).willReturn(Optional.ofNullable(kubernetesService)); given(micoKubernetesClient.getPodsCreatedByDeploymentOfMicoServiceInstance(any(MicoServiceDeploymentInfo.class))).willReturn(podListWithOnePod.getItems()); @@ -513,8 +516,8 @@ private ResponseEntity getPrometheusResponseEntity(int value) { @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void getServiceStatus() throws Exception { - MicoServiceStatusResponseDTO micoServiceStatus = new MicoServiceStatusResponseDTO(); - micoServiceStatus + List micoServiceStatusList = new ArrayList<>(); + MicoServiceStatusResponseDTO micoServiceStatusResponseDTO = new MicoServiceStatusResponseDTO() .setName(micoService.getName()) .setShortName(micoService.getShortName()) .setVersion(micoService.getVersion()) @@ -578,7 +581,10 @@ public void getServiceStatus() throws Exception { .setExternalIpIsAvailable(true) .setExternalIp("192.168.2.112") .setPort(8080))); + micoServiceStatusList.add(micoServiceStatusResponseDTO); + given(serviceDeploymentInfoRepository.findAllByService(micoService.getShortName(), micoService.getVersion())) + .willReturn(CollectionUtils.listOf(micoServiceDeploymentInfo)); given(micoKubernetesClient.getPodsCreatedByDeploymentOfMicoServiceInstance(eq(micoServiceDeploymentInfo))) .willReturn(podList.getItems()); Deployment deployment = new DeploymentBuilder() @@ -626,31 +632,12 @@ public void getServiceStatus() throws Exception { .willReturn(responseEntityCpuLoadPod3) .willReturn(responseEntityMemoryUsagePod4) .willReturn(responseEntityCpuLoadPod4); - assertEquals(micoServiceStatus, micoStatusService.getServiceInstanceStatus(micoServiceDeploymentInfo)); + + assertEquals(micoServiceStatusList, micoStatusService.getServiceStatus(micoService)); } @Test - public void getServiceStatusOfUndeployedInstance() throws Exception { - MicoServiceStatusResponseDTO micoServiceStatus = new MicoServiceStatusResponseDTO(); - micoServiceStatus - .setName(micoService.getName()) - .setShortName(micoService.getShortName()) - .setVersion(micoService.getVersion()) - .setInstanceId(micoServiceDeploymentInfo.getInstanceId()) - .setAvailableReplicas(0) - .setRequestedReplicas(0) - .setOtherApplicationsUsingThisServiceInstance(CollectionUtils.listOf()) - .setNodeMetrics(CollectionUtils.listOf()) - // Add four pods (on two different nodes) - .setPodsInformation(CollectionUtils.listOf()) - .setErrorMessages(CollectionUtils.listOf( - new MicoMessageResponseDTO() - .setContent("No deployment of MicoService '" + micoService.getShortName() + "' '" + micoService.getVersion() - + "' with instance ID '" + micoServiceDeploymentInfo.getInstanceId() + "' is available.") - .setType(Type.ERROR) - )) - .setInterfacesInformation(CollectionUtils.listOf()); - + public void getServiceStatusWithInstanceThatIsNotDeployed() throws Exception { given(micoKubernetesClient.getPodsCreatedByDeploymentOfMicoServiceInstance(eq(micoServiceDeploymentInfo))) .willReturn(new ArrayList<>()); given(micoKubernetesClient.getDeploymentOfMicoServiceInstance(eq(micoServiceDeploymentInfo))) @@ -676,7 +663,7 @@ public void getServiceStatusOfUndeployedInstance() throws Exception { given(micoKubernetesClient.getPublicPortsOfKubernetesService(kubernetesService.getMetadata().getName(), kubernetesService.getMetadata().getNamespace())).willReturn(new ArrayList<>()); - assertEquals(micoServiceStatus, micoStatusService.getServiceInstanceStatus(micoServiceDeploymentInfo)); + assertEquals("Expected there is no instance included", 0, micoStatusService.getServiceStatus(micoService).size()); } @Test diff --git a/mico-core/src/test/java/io/github/ust/mico/core/ServiceResourceIntegrationTests.java b/mico-core/src/test/java/io/github/ust/mico/core/ServiceResourceIntegrationTests.java index 8b3bca58f..dae3bea83 100644 --- a/mico-core/src/test/java/io/github/ust/mico/core/ServiceResourceIntegrationTests.java +++ b/mico-core/src/test/java/io/github/ust/mico/core/ServiceResourceIntegrationTests.java @@ -222,6 +222,9 @@ public void getStatusListOfService() throws Exception { MicoServiceDeploymentInfo micoServiceDeploymentInfo2 = new MicoServiceDeploymentInfo() .setService(micoService) .setInstanceId(INSTANCE_ID_2); + MicoServiceDeploymentInfo micoServiceDeploymentInfo3 = new MicoServiceDeploymentInfo() + .setService(micoService) + .setInstanceId(INSTANCE_ID_3); String nodeName = "testNode"; String podPhase = "Running"; @@ -254,7 +257,7 @@ public void getStatusListOfService() throws Exception { .setCpuLoad(cpuLoadPod2) .setMemoryUsage(memoryUsagePod2)); - MicoServiceStatusResponseDTO micoServiceStatus1 = new MicoServiceStatusResponseDTO() + MicoServiceStatusResponseDTO micoServiceInstanceStatus1 = new MicoServiceStatusResponseDTO() .setVersion(micoService.getVersion()) .setName(micoService.getName()) .setShortName(micoService.getShortName()) @@ -269,7 +272,7 @@ public void getStatusListOfService() throws Exception { .setInterfacesInformation(CollectionUtils.listOf(new MicoServiceInterfaceStatusResponseDTO().setName(SERVICE_INTERFACE_NAME))) .setPodsInformation(Collections.singletonList(kubernetesPodInfo1)); - MicoServiceStatusResponseDTO micoServiceStatus2 = new MicoServiceStatusResponseDTO() + MicoServiceStatusResponseDTO micoServiceInstanceStatus2 = new MicoServiceStatusResponseDTO() .setVersion(micoService.getVersion()) .setName(micoService.getName()) .setShortName(micoService.getShortName()) @@ -284,10 +287,13 @@ public void getStatusListOfService() throws Exception { .setInterfacesInformation(CollectionUtils.listOf(new MicoServiceInterfaceStatusResponseDTO().setName(SERVICE_INTERFACE_NAME))) .setPodsInformation(Collections.singletonList(kubernetesPodInfo2)); - given(micoStatusService.getServiceStatus(micoService)).willReturn(CollectionUtils.listOf(micoServiceStatus1, micoServiceStatus2)); + // MicoService instance 3 ist not deployed, therefore the status should not be part of the list. + given(micoStatusService.getServiceStatus(micoService)) + .willReturn(CollectionUtils.listOf(micoServiceInstanceStatus1, micoServiceInstanceStatus2)); given(serviceDeploymentInfoRepository.findAllByService(micoService.getShortName(), micoService.getVersion())) - .willReturn(CollectionUtils.listOf(micoServiceDeploymentInfo1, micoServiceDeploymentInfo2)); - given(serviceRepository.findByShortNameAndVersion(micoService.getShortName(), micoService.getVersion())).willReturn(Optional.of(micoService)); + .willReturn(CollectionUtils.listOf(micoServiceDeploymentInfo1, micoServiceDeploymentInfo2, micoServiceDeploymentInfo3)); + given(serviceRepository.findByShortNameAndVersion(micoService.getShortName(), micoService.getVersion())) + .willReturn(Optional.of(micoService)); mvc.perform(get(BASE_PATH + "/" + SHORT_NAME + "/" + VERSION + "/status")) .andDo(print()) diff --git a/mico-core/src/test/java/io/github/ust/mico/core/TestConstants.java b/mico-core/src/test/java/io/github/ust/mico/core/TestConstants.java index 8817ea2e3..435980ae7 100644 --- a/mico-core/src/test/java/io/github/ust/mico/core/TestConstants.java +++ b/mico-core/src/test/java/io/github/ust/mico/core/TestConstants.java @@ -91,6 +91,7 @@ class TestConstants { static final String INSTANCE_ID = "instance-id"; static final String INSTANCE_ID_1 = "instance-id-1"; static final String INSTANCE_ID_2 = "instance-id-2"; + static final String INSTANCE_ID_3 = "instance-id-3"; static final String INPUT_TOPIC = "input-topic"; static final String INPUT_TOPIC_1 = "input-topic-1"; From efea809852bded2fd26c14799268e4d16f06f618 Mon Sep 17 00:00:00 2001 From: David Kopp Date: Wed, 2 Oct 2019 19:12:27 +0200 Subject: [PATCH 3/3] Update JavaDoc --- .../java/io/github/ust/mico/core/service/MicoStatusService.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mico-core/java/io/github/ust/mico/core/service/MicoStatusService.rst b/docs/mico-core/java/io/github/ust/mico/core/service/MicoStatusService.rst index d27b2d9b7..7bb814d92 100644 --- a/docs/mico-core/java/io/github/ust/mico/core/service/MicoStatusService.rst +++ b/docs/mico-core/java/io/github/ust/mico/core/service/MicoStatusService.rst @@ -90,7 +90,7 @@ getServiceInstanceStatus .. java:method:: public MicoServiceStatusResponseDTO getServiceInstanceStatus(MicoServiceDeploymentInfo serviceDeploymentInfo) :outertype: MicoStatusService - Get status information for a single \ :java:ref:`MicoServiceDeploymentInfo`\ : # available replicas, # requested replicas, pod metrics (CPU load, memory usage). + Get status information for a single \ :java:ref:`MicoServiceDeploymentInfo`\ if it is deployed: # available replicas, # requested replicas, pod metrics (CPU load, memory usage). :param serviceDeploymentInfo: the \ :java:ref:`MicoServiceDeploymentInfo`\ . :return: the \ :java:ref:`MicoServiceStatusResponseDTO`\ which contains status information for a specific instance of a \ :java:ref:`MicoService`\ .