diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java index 15d2ef0306..66fca96493 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java @@ -202,6 +202,11 @@ public class Messages { public static final String COULD_NOT_BIND_OPTIONAL_SERVICE_TO_APP = "Could not bind optional service \"{0}\" to application \"{1}\""; public static final String COULD_NOT_UNBIND_OPTIONAL_SERVICE_TO_APP = "Could not unbind optional service \"{0}\" to application \"{1}\""; public static final String COULD_NOT_CREATE_OPTIONAL_SERVICE = "Could not create optional service \"{0}\""; + public static final String COULD_NOT_UPDATE_TAGS_OF_OPTIONAL_SERVICE = "Could not update tags of optional service \"{0}\" : {1}"; + public static final String COULD_NOT_UPDATE_METADATA_OF_OPTIONAL_SERVICE = "Could not update metadata of optional service \"{0}\" : {1}"; + public static final String COULD_NOT_UPDATE_PARAMETERS_OPTIONAL_SERVICE = "Could not update parameters of optional service \"{0}\" : {1}"; + public static final String COULD_NOT_UPDATE_PLAN_OPTIONAL_SERVICE = "Could not update plan of optional service \"{0}\" : {1}"; + public static final String COULD_NOT_UPDATE_SYSLOG_DRAIN_URL_OPTIONAL_SERVICE = "Could not update syslog drain url of optional service \"{0}\" : {1}"; public static final String COULD_NOT_GET_SERVICE_KEYS_FOR_OPTIONAL_SERVICE = "Could not get service keys for optional service \"{0}\""; public static final String DEFAULT_FAILED_OPERATION_DESCRIPTION = "The service broker returned an error with no description!"; public static final String ERROR_DURING_CLEAN_UP_0 = "Error during clean-up: {0}"; diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateServiceStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateServiceStep.java index 29044ab487..ce682ca3ca 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateServiceStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateServiceStep.java @@ -19,9 +19,7 @@ import org.springframework.util.Assert; import com.sap.cloudfoundry.client.facade.CloudControllerClient; -import com.sap.cloudfoundry.client.facade.CloudControllerException; import com.sap.cloudfoundry.client.facade.CloudOperationException; -import com.sap.cloudfoundry.client.facade.CloudServiceBrokerException; import com.sap.cloudfoundry.client.facade.domain.CloudServiceInstance; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; @@ -44,7 +42,12 @@ protected OperationExecutionState executeOperation(ProcessContext context, Cloud if (operationExecutionState.isPresent()) { return operationExecutionState.get(); } - processServiceCreationFailure(context, serviceInstance, e); + String exceptionDescription = MessageFormat.format(Messages.COULD_NOT_CREATE_OPTIONAL_SERVICE, serviceInstance.getName()); + CloudOperationException cloudOperationException = new CloudOperationException(e.getStatusCode(), + e.getStatusText(), + exceptionDescription); + + processServiceActionFailure(context, serviceInstance, cloudOperationException); } return OperationExecutionState.FINISHED; } @@ -74,21 +77,6 @@ private void setServiceGuid(ProcessContext context, CloudServiceInstanceExtended new DynamicResolvableParametersContextUpdater(context).updateServiceGuid(serviceInstance); } - private void processServiceCreationFailure(ProcessContext context, CloudServiceInstanceExtended serviceInstance, - CloudOperationException e) { - if (!serviceInstance.isOptional()) { - String detailedDescription = MessageFormat.format(Messages.ERROR_CREATING_SERVICE, serviceInstance.getName(), - serviceInstance.getLabel(), serviceInstance.getPlan(), e.getDescription()); - if (e.getStatusCode() == HttpStatus.BAD_GATEWAY) { - context.setVariable(Variables.SERVICE_OFFERING, serviceInstance.getLabel()); - throw new CloudServiceBrokerException(e.getStatusCode(), e.getStatusText(), detailedDescription); - } - throw new CloudControllerException(e.getStatusCode(), e.getStatusText(), detailedDescription); - } - getStepLogger().warn(MessageFormat.format(Messages.COULD_NOT_CREATE_OPTIONAL_SERVICE, serviceInstance.getName()), e, - ExceptionMessageTailMapper.map(configuration, CloudComponents.SERVICE_BROKERS, serviceInstance.getLabel())); - } - private Optional getServiceInstanceStateIfCreated(CloudControllerClient controllerClient, CloudServiceInstanceExtended serviceInstance, CloudOperationException e) { diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ServiceStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ServiceStep.java index 4137efd0da..a5bef54afd 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ServiceStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ServiceStep.java @@ -6,6 +6,8 @@ import javax.inject.Inject; +import com.sap.cloudfoundry.client.facade.CloudControllerException; +import com.sap.cloudfoundry.client.facade.CloudServiceBrokerException; import org.cloudfoundry.multiapps.common.util.JsonUtil; import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; import org.cloudfoundry.multiapps.controller.core.util.OperationExecutionState; @@ -17,6 +19,7 @@ import com.sap.cloudfoundry.client.facade.CloudControllerClient; import com.sap.cloudfoundry.client.facade.CloudOperationException; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; +import org.springframework.http.HttpStatus; public abstract class ServiceStep extends AsyncFlowableStep { @@ -61,6 +64,20 @@ private OperationExecutionState executeOperationAndHandleExceptions(ProcessConte protected abstract OperationExecutionState executeOperation(ProcessContext context, CloudControllerClient controllerClient, CloudServiceInstanceExtended service); + protected void processServiceActionFailure(ProcessContext context, CloudServiceInstanceExtended serviceInstance, + CloudOperationException e) { + if (!serviceInstance.isOptional()) { + String detailedDescription = MessageFormat.format(Messages.ERROR_CREATING_SERVICE, serviceInstance.getName(), + serviceInstance.getLabel(), serviceInstance.getPlan(), e.getDescription()); + if (e.getStatusCode() == HttpStatus.BAD_GATEWAY) { + context.setVariable(Variables.SERVICE_OFFERING, serviceInstance.getLabel()); + throw new CloudServiceBrokerException(e.getStatusCode(), e.getStatusText(), detailedDescription); + } + throw new CloudControllerException(e.getStatusCode(), e.getStatusText(), detailedDescription); + } + getStepLogger().warn(e.getDescription()); + } + protected abstract ServiceOperation.Type getOperationType(); protected ServiceOperationGetter getServiceOperationGetter() { diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStep.java index fd1eb21c3b..c00c5c2de1 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStep.java @@ -1,5 +1,6 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import java.text.MessageFormat; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -13,6 +14,7 @@ import org.springframework.context.annotation.Scope; import com.sap.cloudfoundry.client.facade.CloudControllerClient; +import com.sap.cloudfoundry.client.facade.CloudOperationException; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; @Named("updateServiceMetadataStep") @@ -24,10 +26,21 @@ protected OperationExecutionState executeOperation(ProcessContext context, Cloud CloudServiceInstanceExtended service) { getStepLogger().debug(Messages.UPDATING_METADATA_OF_SERVICE_INSTANCE_0, service.getName(), service.getResourceName()); - UUID serviceGuid = client.getRequiredServiceInstanceGuid(service.getName()); - client.updateServiceInstanceMetadata(serviceGuid, service.getV3Metadata()); + try { + UUID serviceGuid = client.getRequiredServiceInstanceGuid(service.getName()); + client.updateServiceInstanceMetadata(serviceGuid, service.getV3Metadata()); + getStepLogger().debug(Messages.UPDATING_METADATA_OF_SERVICE_INSTANCE_0_DONE, service.getName()); + } catch (CloudOperationException e) { + String exceptionDescription = MessageFormat.format(Messages.COULD_NOT_UPDATE_METADATA_OF_OPTIONAL_SERVICE, service.getName(), + e.getDescription()); + CloudOperationException cloudOperationException = new CloudOperationException(e.getStatusCode(), + e.getStatusText(), + exceptionDescription); + + processServiceActionFailure(context, service, cloudOperationException); + return OperationExecutionState.FINISHED; + } - getStepLogger().debug(Messages.UPDATING_METADATA_OF_SERVICE_INSTANCE_0_DONE, service.getName()); return OperationExecutionState.EXECUTING; } diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceParametersStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceParametersStep.java index 1d1fd8eebf..75b3259ec7 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceParametersStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceParametersStep.java @@ -1,5 +1,6 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import java.text.MessageFormat; import java.util.Collections; import java.util.List; @@ -12,6 +13,7 @@ import org.springframework.context.annotation.Scope; import com.sap.cloudfoundry.client.facade.CloudControllerClient; +import com.sap.cloudfoundry.client.facade.CloudOperationException; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; @Named("updateServiceParametersStep") @@ -27,9 +29,19 @@ protected OperationExecutionState executeOperation(ProcessContext context, Cloud } getStepLogger().info(Messages.UPDATING_SERVICE, service.getName()); - client.updateServiceParameters(service.getName(), service.getCredentials()); - - getStepLogger().debug(Messages.SERVICE_UPDATED, service.getName()); + try { + client.updateServiceParameters(service.getName(), service.getCredentials()); + getStepLogger().debug(Messages.SERVICE_UPDATED, service.getName()); + } catch (CloudOperationException e) { + String exceptionDescription = MessageFormat.format(Messages.COULD_NOT_UPDATE_PARAMETERS_OPTIONAL_SERVICE, service.getName(), + e.getDescription()); + CloudOperationException cloudOperationException = new CloudOperationException(e.getStatusCode(), + e.getStatusText(), + exceptionDescription); + + processServiceActionFailure(context, service, cloudOperationException); + return OperationExecutionState.FINISHED; + } return OperationExecutionState.EXECUTING; } diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServicePlanStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServicePlanStep.java index 3c8a2a50c4..fcf5f3f730 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServicePlanStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServicePlanStep.java @@ -1,5 +1,6 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import java.text.MessageFormat; import java.util.Collections; import java.util.List; @@ -12,6 +13,7 @@ import org.springframework.context.annotation.Scope; import com.sap.cloudfoundry.client.facade.CloudControllerClient; +import com.sap.cloudfoundry.client.facade.CloudOperationException; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; @Named("updateServicePlanStep") @@ -27,9 +29,20 @@ protected OperationExecutionState executeOperation(ProcessContext context, Cloud } getStepLogger().debug(Messages.UPDATING_SERVICE_0_WITH_PLAN_1, service.getName(), service.getPlan()); - client.updateServicePlan(service.getName(), service.getPlan()); + try { + client.updateServicePlan(service.getName(), service.getPlan()); + getStepLogger().debug(Messages.SERVICE_PLAN_FOR_SERVICE_0_UPDATED, service.getName()); + } catch (CloudOperationException e) { + String exceptionDescription = MessageFormat.format(Messages.COULD_NOT_UPDATE_PLAN_OPTIONAL_SERVICE, service.getName(), + e.getDescription()); + CloudOperationException cloudOperationException = new CloudOperationException(e.getStatusCode(), + e.getStatusText(), + exceptionDescription); + + processServiceActionFailure(context, service, cloudOperationException); + return OperationExecutionState.FINISHED; + } - getStepLogger().debug(Messages.SERVICE_PLAN_FOR_SERVICE_0_UPDATED, service.getName()); return OperationExecutionState.EXECUTING; } diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStep.java index 5fd0baf63f..409de8521b 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStep.java @@ -1,5 +1,6 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import java.text.MessageFormat; import java.util.Collections; import java.util.List; @@ -12,6 +13,7 @@ import org.springframework.context.annotation.Scope; import com.sap.cloudfoundry.client.facade.CloudControllerClient; +import com.sap.cloudfoundry.client.facade.CloudOperationException; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation.Type; @@ -28,9 +30,20 @@ protected OperationExecutionState executeOperation(ProcessContext context, Cloud } getStepLogger().info(Messages.UPDATING_SERVICE_SYSLOG_URL, service.getName()); - client.updateServiceSyslogDrainUrl(service.getName(), service.getSyslogDrainUrl()); + try { + client.updateServiceSyslogDrainUrl(service.getName(), service.getSyslogDrainUrl()); + getStepLogger().debug(Messages.SERVICE_SYSLOG_URL_UPDATED, service.getName()); + } catch (CloudOperationException e) { + String exceptionDescription = MessageFormat.format(Messages.COULD_NOT_UPDATE_SYSLOG_DRAIN_URL_OPTIONAL_SERVICE, + service.getName(), e.getDescription()); + CloudOperationException cloudOperationException = new CloudOperationException(e.getStatusCode(), + e.getStatusText(), + exceptionDescription); + + processServiceActionFailure(context, service, cloudOperationException); + return OperationExecutionState.FINISHED; + } - getStepLogger().debug(Messages.SERVICE_SYSLOG_URL_UPDATED, service.getName()); return OperationExecutionState.EXECUTING; } diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceTagsStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceTagsStep.java index 7505e1662a..308e471490 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceTagsStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceTagsStep.java @@ -1,5 +1,6 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import java.text.MessageFormat; import java.util.Collections; import java.util.List; @@ -12,6 +13,7 @@ import org.springframework.context.annotation.Scope; import com.sap.cloudfoundry.client.facade.CloudControllerClient; +import com.sap.cloudfoundry.client.facade.CloudOperationException; import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; @Named("updateServiceTagsStep") @@ -27,9 +29,20 @@ protected OperationExecutionState executeOperation(ProcessContext context, Cloud } getStepLogger().info(Messages.UPDATING_SERVICE_TAGS, service.getName()); - client.updateServiceTags(service.getName(), service.getTags()); + try { + client.updateServiceTags(service.getName(), service.getTags()); + getStepLogger().debug(Messages.SERVICE_TAGS_UPDATED, service.getName()); + } catch (CloudOperationException e) { + String exceptionDescription = MessageFormat.format(Messages.COULD_NOT_UPDATE_TAGS_OF_OPTIONAL_SERVICE, service.getName(), + e.getDescription()); + CloudOperationException cloudOperationException = new CloudOperationException(e.getStatusCode(), + e.getStatusText(), + exceptionDescription); + + processServiceActionFailure(context, service, cloudOperationException); + return OperationExecutionState.FINISHED; + } - getStepLogger().debug(Messages.SERVICE_TAGS_UPDATED, service.getName()); return OperationExecutionState.EXECUTING; } diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/SyncFlowableStepTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/SyncFlowableStepTest.java index 01c7caf212..9faa137435 100644 --- a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/SyncFlowableStepTest.java +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/SyncFlowableStepTest.java @@ -1,13 +1,21 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import static java.lang.Boolean.TRUE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; import java.util.Collections; import java.util.List; +import java.util.UUID; +import com.sap.cloudfoundry.client.facade.CloudOperationException; +import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudMetadata; +import org.cloudfoundry.client.v3.Metadata; import org.cloudfoundry.multiapps.common.test.Tester; +import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; +import org.cloudfoundry.multiapps.controller.client.lib.domain.ImmutableCloudServiceInstanceExtended; import org.cloudfoundry.multiapps.controller.core.cf.CloudControllerClientProvider; import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration; import org.cloudfoundry.multiapps.controller.persistence.services.FileService; @@ -37,6 +45,7 @@ import org.slf4j.LoggerFactory; import com.sap.cloudfoundry.client.facade.CloudControllerClient; +import org.springframework.http.HttpStatus; public abstract class SyncFlowableStepTest { @@ -48,6 +57,12 @@ public abstract class SyncFlowableStepTest { protected static final String SPACE_GUID = "spaceGuid"; protected final String TEST_CORRELATION_ID = "test"; protected final String TEST_TASK_ID = "testTask"; + protected final String RETRY_STEP_EXECUTION_STATUS = "RETRY"; + protected final String DONE_STEP_EXECUTION_STATUS = "DONE"; + protected static final String SERVICE_NAME = "test-service"; + private static final String METADATA_LABEL = "test-label"; + private static final String METADATA_LABEL_VALUE = "test-label-value"; + private static final String SYSLOG_DRAIN_URL = "test-syslog-url"; protected final Tester tester = Tester.forClass(getClass()); @@ -137,6 +152,32 @@ private ExecutionQuery createExecutionQueryMock() { return mockExecutionQuery; } + protected void assertExecutionStepStatus(String executionStepStatus) { + assertEquals(executionStepStatus, getExecutionStatus()); + } + + protected void prepareServiceToProcess(CloudServiceInstanceExtended serviceToProcess) { + context.setVariable(Variables.SERVICE_TO_PROCESS, serviceToProcess); + } + + protected void prepareClient(CloudServiceInstanceExtended serviceToProcess) { + when(client.getRequiredServiceInstanceGuid(SERVICE_NAME)).thenReturn(serviceToProcess.getGuid()); + } + + protected CloudServiceInstanceExtended buildServiceToProcess(boolean isOptional) { + return ImmutableCloudServiceInstanceExtended.builder() + .name(SERVICE_NAME) + .metadata(ImmutableCloudMetadata.builder() + .guid(UUID.randomUUID()) + .build()) + .syslogDrainUrl(SYSLOG_DRAIN_URL) + .v3Metadata(Metadata.builder() + .label(METADATA_LABEL, METADATA_LABEL_VALUE) + .build()) + .isOptional(isOptional) + .build(); + } + protected void assertStepFinishedSuccessfully() { assertEquals(StepPhase.DONE.toString(), getExecutionStatus()); } diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStepTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStepTest.java index 5147ec08ce..1178192605 100644 --- a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStepTest.java +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceMetadataStepTest.java @@ -1,27 +1,26 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import java.util.UUID; - -import org.cloudfoundry.client.v3.Metadata; +import org.cloudfoundry.multiapps.common.SLException; import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; -import org.cloudfoundry.multiapps.controller.client.lib.domain.ImmutableCloudServiceInstanceExtended; -import org.cloudfoundry.multiapps.controller.process.variables.Variables; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.HttpStatus; -import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudMetadata; +import com.sap.cloudfoundry.client.facade.CloudOperationException; +import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; class UpdateServiceMetadataStepTest extends SyncFlowableStepTest { - private static final String SERVICE_NAME = "test-service"; - private static final String METADATA_LABEL = "test-label"; - private static final String METADATA_LABEL_VALUE = "test-label-value"; - @Test void testUpdateServiceMetadata() { - CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(); + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); prepareServiceToProcess(serviceToProcess); prepareClient(serviceToProcess); @@ -32,24 +31,60 @@ void testUpdateServiceMetadata() { serviceToProcess.getV3Metadata()); } - private CloudServiceInstanceExtended buildServiceToProcess() { - return ImmutableCloudServiceInstanceExtended.builder() - .name(SERVICE_NAME) - .metadata(ImmutableCloudMetadata.builder() - .guid(UUID.randomUUID()) - .build()) - .v3Metadata(Metadata.builder() - .label(METADATA_LABEL, METADATA_LABEL_VALUE) - .build()) - .build(); + @Test + void testExceptionIsThrownOnMandatoryServiceMetadataUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceMetadataUpdate(HttpStatus.BAD_GATEWAY); + + assertThrows(SLException.class, () -> step.execute(execution)); } - private void prepareServiceToProcess(CloudServiceInstanceExtended serviceToProcess) { - context.setVariable(Variables.SERVICE_TO_PROCESS, serviceToProcess); + @Test + void testExceptionIsThrownOnMandatoryServiceMetadataUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceMetadataUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + assertThrows(SLException.class, () -> step.execute(execution)); + assertExecutionStepStatus(RETRY_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServiceMetadataUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceMetadataUpdate(HttpStatus.BAD_GATEWAY); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServiceMetadataUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceMetadataUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testOperationType() { + assertEquals(ServiceOperation.Type.UPDATE, step.getOperationType()); } - private void prepareClient(CloudServiceInstanceExtended serviceToProcess) { - when(client.getRequiredServiceInstanceGuid(SERVICE_NAME)).thenReturn(serviceToProcess.getGuid()); + private void throwExceptionOnServiceMetadataUpdate(HttpStatus httpStatus) { + Mockito.doThrow(new CloudOperationException(httpStatus, "Error occurred")) + .when(client) + .updateServiceInstanceMetadata(any(), any()); } @Override diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceParametersStepTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceParametersStepTest.java new file mode 100644 index 0000000000..3f2e15e1af --- /dev/null +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceParametersStepTest.java @@ -0,0 +1,92 @@ +package org.cloudfoundry.multiapps.controller.process.steps; + +import com.sap.cloudfoundry.client.facade.CloudOperationException; +import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; +import org.cloudfoundry.multiapps.common.SLException; +import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.HttpStatus; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + +class UpdateServiceParametersStepTest extends SyncFlowableStepTest { + + @Test + void testUpdateServiceParameters() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + + step.execute(execution); + + verify(client).updateServiceParameters(serviceToProcess.getName(), + serviceToProcess.getCredentials()); + } + + @Test + void testExceptionIsThrownOnMandatoryServiceParametersUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceParametersUpdate(HttpStatus.BAD_GATEWAY); + + assertThrows(SLException.class, () -> step.execute(execution)); + } + + @Test + void testExceptionIsThrownOnMandatoryServiceParametersUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceParametersUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + assertThrows(SLException.class, () -> step.execute(execution)); + assertExecutionStepStatus(RETRY_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServiceParametersUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceParametersUpdate(HttpStatus.BAD_GATEWAY); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServiceParametersUpdateInterServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceParametersUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testOperationType() { + assertEquals(ServiceOperation.Type.UPDATE, step.getOperationType()); + } + + private void throwExceptionOnServiceParametersUpdate(HttpStatus httpStatus) { + Mockito.doThrow(new CloudOperationException(httpStatus, "Error occurred")) + .when(client) + .updateServiceParameters(any(), any()); + } + + @Override + protected UpdateServiceParametersStep createStep() { + return new UpdateServiceParametersStep(); + } +} diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServicePlanStepTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServicePlanStepTest.java new file mode 100644 index 0000000000..c49d2a22bb --- /dev/null +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServicePlanStepTest.java @@ -0,0 +1,92 @@ +package org.cloudfoundry.multiapps.controller.process.steps; + +import com.sap.cloudfoundry.client.facade.CloudOperationException; +import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; +import org.cloudfoundry.multiapps.common.SLException; +import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.HttpStatus; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + +class UpdateServicePlanStepTest extends SyncFlowableStepTest { + + @Test + void testUpdateServicePlan() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + + step.execute(execution); + + verify(client).updateServicePlan(serviceToProcess.getName(), + serviceToProcess.getPlan()); + } + + @Test + void testExceptionIsThrownOnMandatoryServicePlanUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServicePlanUpdate(HttpStatus.BAD_GATEWAY); + + assertThrows(SLException.class, () -> step.execute(execution)); + } + + @Test + void testExceptionIsThrownOnMandatoryServicePlanUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServicePlanUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + assertThrows(SLException.class, () -> step.execute(execution)); + assertExecutionStepStatus(RETRY_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServicePlanUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServicePlanUpdate(HttpStatus.BAD_GATEWAY); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServicePlanUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServicePlanUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testOperationType() { + assertEquals(ServiceOperation.Type.UPDATE, step.getOperationType()); + } + + private void throwExceptionOnServicePlanUpdate(HttpStatus httpStatus) { + Mockito.doThrow(new CloudOperationException(httpStatus, "Error occurred")) + .when(client) + .updateServicePlan(any(), any()); + } + + @Override + protected UpdateServicePlanStep createStep() { + return new UpdateServicePlanStep(); + } +} diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStepTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStepTest.java index faa0688199..5270953547 100644 --- a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStepTest.java +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceSyslogDrainUrlStepTest.java @@ -1,26 +1,35 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.UUID; +import com.sap.cloudfoundry.client.facade.CloudOperationException; +import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; +import org.cloudfoundry.multiapps.common.SLException; import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; import org.cloudfoundry.multiapps.controller.client.lib.domain.ImmutableCloudServiceInstanceExtended; import org.cloudfoundry.multiapps.controller.process.variables.Variables; import org.junit.jupiter.api.Test; import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudMetadata; +import org.mockito.Mockito; +import org.springframework.http.HttpStatus; class UpdateServiceSyslogDrainUrlStepTest extends SyncFlowableStepTest { - private static final String SERVICE_NAME = "service-name"; private static final String SYSLOG_DRAIN_URL = "test-syslog-url"; @Test void testUpdateServiceSyslogDrainUrl() { - CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(); + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); prepareServiceToProcess(serviceToProcess); prepareClient(serviceToProcess); step.execute(execution); @@ -36,37 +45,74 @@ void testSkipParametersUpdate() { verify(client, never()).updateServiceSyslogDrainUrl(SERVICE_NAME, SYSLOG_DRAIN_URL); } - private void prepareClient(CloudServiceInstanceExtended serviceToProcess) { - when(client.getRequiredServiceInstanceGuid(SERVICE_NAME)).thenReturn(serviceToProcess.getGuid()); + @Test + void testExceptionIsThrownOnMandatoryServiceSyslogDrainUrlUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceSyslogDrainUrlUpdate(HttpStatus.BAD_GATEWAY); + + assertThrows(SLException.class, () -> step.execute(execution)); + assertExecutionStepStatus(RETRY_STEP_EXECUTION_STATUS); } - private void prepareServiceToProcess(CloudServiceInstanceExtended serviceToProcess) { - context.setVariable(Variables.SERVICE_TO_PROCESS, serviceToProcess); + @Test + void testExceptionIsThrownOnMandatoryServiceSyslogDrainUrlUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceSyslogDrainUrlUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + assertThrows(SLException.class, () -> step.execute(execution)); + assertExecutionStepStatus(RETRY_STEP_EXECUTION_STATUS); } - private CloudServiceInstanceExtended buildServiceToProcess() { - return ImmutableCloudServiceInstanceExtended.builder() - .name(SERVICE_NAME) - .metadata(buildCloudMetadata()) - .syslogDrainUrl(SYSLOG_DRAIN_URL) - .build(); + @Test + void testExceptionIsNotThrownOnOptionalServiceSyslogDrainUrlUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceSyslogDrainUrlUpdate(HttpStatus.BAD_GATEWAY); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServiceSyslogDrainUrlUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceSyslogDrainUrlUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testOperationType() { + assertEquals(ServiceOperation.Type.UPDATE, step.getOperationType()); + } + + private void throwExceptionOnServiceSyslogDrainUrlUpdate(HttpStatus httpStatus) { + Mockito.doThrow(new CloudOperationException(httpStatus, "Error occurred")) + .when(client) + .updateServiceSyslogDrainUrl(any(), any()); } private CloudServiceInstanceExtended buildServiceWithSkipUpdate() { return ImmutableCloudServiceInstanceExtended.builder() - .metadata(buildCloudMetadata()) + .metadata(ImmutableCloudMetadata.builder() + .guid(UUID.randomUUID()) + .build()) .name(SERVICE_NAME) .syslogDrainUrl(SYSLOG_DRAIN_URL) .shouldSkipSyslogUrlUpdate(true) .build(); } - private ImmutableCloudMetadata buildCloudMetadata() { - return ImmutableCloudMetadata.builder() - .guid(UUID.randomUUID()) - .build(); - } - @Override protected UpdateServiceSyslogDrainUrlStep createStep() { return new UpdateServiceSyslogDrainUrlStep(); diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceTagsStepTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceTagsStepTest.java new file mode 100644 index 0000000000..f06ed1897c --- /dev/null +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/UpdateServiceTagsStepTest.java @@ -0,0 +1,92 @@ +package org.cloudfoundry.multiapps.controller.process.steps; + +import com.sap.cloudfoundry.client.facade.CloudOperationException; +import com.sap.cloudfoundry.client.facade.domain.ServiceOperation; +import org.cloudfoundry.multiapps.common.SLException; +import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.HttpStatus; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + +class UpdateServiceTagsStepTest extends SyncFlowableStepTest { + + @Test + void testUpdateServiceTags() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + + step.execute(execution); + + verify(client).updateServiceTags(serviceToProcess.getName(), + serviceToProcess.getTags()); + } + + @Test + void testExceptionIsThrownOnMandatoryServiceTagsUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceTagsUpdate(HttpStatus.BAD_GATEWAY); + + assertThrows(SLException.class, () -> step.execute(execution)); + } + + @Test + void testExceptionIsThrownOnMandatoryServiceTagsUpdateInternalServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(FALSE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceTagsUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + assertThrows(SLException.class, () -> step.execute(execution)); + assertExecutionStepStatus(RETRY_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServiceTagsUpdateBadGateway() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceTagsUpdate(HttpStatus.BAD_GATEWAY); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testExceptionIsNotThrownOnOptionalServiceTagsUpdateInterServerError() { + CloudServiceInstanceExtended serviceToProcess = buildServiceToProcess(TRUE); + prepareServiceToProcess(serviceToProcess); + prepareClient(serviceToProcess); + throwExceptionOnServiceTagsUpdate(HttpStatus.INTERNAL_SERVER_ERROR); + + step.execute(execution); + + assertExecutionStepStatus(DONE_STEP_EXECUTION_STATUS); + } + + @Test + void testOperationType() { + assertEquals(ServiceOperation.Type.UPDATE, step.getOperationType()); + } + + private void throwExceptionOnServiceTagsUpdate(HttpStatus httpStatus) { + Mockito.doThrow(new CloudOperationException(httpStatus, "Error occurred")) + .when(client) + .updateServiceTags(any(), any()); + } + + @Override + protected UpdateServiceTagsStep createStep() { + return new UpdateServiceTagsStep(); + } +}