diff --git a/multiapps-controller-api/src/main/resources/mtarest.yaml b/multiapps-controller-api/src/main/resources/mtarest.yaml index 2fa76ac907..bbc4cb40ec 100644 --- a/multiapps-controller-api/src/main/resources/mtarest.yaml +++ b/multiapps-controller-api/src/main/resources/mtarest.yaml @@ -37,127 +37,6 @@ paths: $ref: "#/definitions/Info" security: - oauth2: [] - /api/v1/spaces/{spaceGuid}/files: - get: - summary: "" - description: "Retrieves all Multi-Target Application files " - operationId: "getMtaFiles" - produces: - - "application/json" - parameters: - - name: "spaceGuid" - in: "path" - description: "GUID of space with mtas" - required: true - type: "string" - - name: "namespace" - in: "query" - description: "Filter mtas by namespace" - required: false - type: "string" - responses: - 200: - description: "OK" - schema: - type: "array" - items: - $ref: "#/definitions/FileMetadata" - security: - - oauth2: [] - post: - summary: "" - description: "Uploads a Multi Target Application archive or an Extension Descriptor " - operationId: "uploadMtaFile" - consumes: - - "multipart/form-data" - produces: - - "application/json" - parameters: - - name: "spaceGuid" - in: "path" - description: "GUID of space you wish to deploy in" - required: true - type: "string" - - name: "namespace" - in: "query" - description: "file namespace" - required: false - type: "string" - responses: - 200: - description: "successful operation" - schema: - $ref: "#/definitions/FileMetadata" - 201: - description: "Created" - schema: - $ref: "#/definitions/FileMetadata" - security: - - oauth2: [] - /api/v1/spaces/{spaceGuid}/files/async: - post: - summary: "" - description: "Uploads a Multi Target Application archive or an Extension Descriptor\ - \ from a remote endpoint" - operationId: "startUploadFromUrl" - consumes: - - "application/json" - parameters: - - name: "spaceGuid" - in: "path" - description: "GUID of space you wish to deploy in" - required: true - type: "string" - - name: "namespace" - in: "query" - description: "file namespace" - required: false - type: "string" - - in: "body" - name: "body" - description: "URL reference to a remote file" - required: false - schema: - $ref: "#/definitions/FileUrl" - responses: - 202: - description: "Accepted" - security: - - oauth2: [] - /api/v1/spaces/{spaceGuid}/files/jobs/{jobId}: - get: - summary: "" - description: "Gets the status of an async upload job" - operationId: "getAsyncUploadJob" - produces: - - "application/json" - parameters: - - name: "spaceGuid" - in: "path" - description: "GUID of space you wish to deploy in" - required: true - type: "string" - - name: "namespace" - in: "query" - description: "file namespace" - required: false - type: "string" - - name: "jobId" - in: "path" - description: "ID of the upload job" - required: true - type: "string" - responses: - 200: - description: "OK" - schema: - $ref: "#/definitions/AsyncUploadResult" - 201: - description: "Created" - schema: - $ref: "#/definitions/AsyncUploadResult" - security: - - oauth2: [] /api/v1/spaces/{spaceGuid}/mtas: get: summary: "" @@ -403,66 +282,6 @@ securityDefinitions: flow: "password" scopes: {} definitions: - AsyncUploadResult: - type: "object" - properties: - status: - type: "string" - readOnly: true - enum: - - "RUNNING" - - "FINISHED" - - "ERROR" - bytes_processed: - type: "integer" - format: "int64" - readOnly: true - error: - type: "string" - readOnly: true - file: - readOnly: true - $ref: "#/definitions/FileMetadata" - mta_id: - type: "string" - readOnly: true - client_actions: - type: "array" - readOnly: true - items: - type: "string" - enum: - - "RETRY_UPLOAD" - FileMetadata: - type: "object" - properties: - id: - type: "string" - readOnly: true - name: - type: "string" - readOnly: true - size: - type: "integer" - readOnly: true - digest: - type: "string" - readOnly: true - digestAlgorithm: - type: "string" - readOnly: true - space: - type: "string" - readOnly: true - namespace: - type: "string" - readOnly: true - FileUrl: - type: "object" - properties: - file_url: - type: "string" - readOnly: true Info: type: "object" properties: diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java index 5d99deb953..8cbf45decb 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Messages.java @@ -179,7 +179,7 @@ public final class Messages { public static final String THREAD_MONITOR_CACHE_TIMEOUT = "Flowable thread monitor cache timeout: {0} seconds"; public static final String SPACE_DEVELOPERS_CACHE_TIME_IN_SECONDS = "Cache for list of space developers per SpaceGUID: {0} seconds"; public static final String APP_SHUTDOWN_REQUEST = "Application with id:\"{0}\", instance id:\"{1}\", instance index:\"{2}\", is requested to shutdown. Timeout to wait before shutdown of Flowable job executor:\"{3}\" seconds."; - public static final String APP_SHUTDOWNED = "Application with id:\"{0}\", instance id:\"{1}\", instance index:\"{2}\", is shutdowned. Timeout to wait before shutdown of Flowable job executor:\"{3}\" seconds."; + public static final String APP_SUCCESSFULLY_SHUTDOWN = "Application with id:\"{0}\", instance id:\"{1}\", instance index:\"{2}\", is shutdown. Timeout to wait before shutdown of Flowable job executor:\"{3}\" seconds."; public static final String APP_SHUTDOWN_STATUS_MONITOR = "Monitor shutdown status of application with id:\"{0}\", instance id:\"{1}\", instance index:\"{2}\". Status:\"{3}\"."; public static final String CONTROLLER_CLIENT_SSL_HANDSHAKE_TIMEOUT_IN_SECONDS = "Controller client SSL handshake timeout in seconds: {0}"; public static final String CONTROLLER_CLIENT_CONNECT_TIMEOUT_IN_SECONDS = "Controller client connect timeout in seconds: {0}"; diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminer.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminer.java index 7e0b54d0e5..d191580212 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminer.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminer.java @@ -10,7 +10,7 @@ public AppSuffixDeterminer(boolean keepOriginalNamesAfterDeploy, boolean isAfter this.isAfterResumePhase = isAfterResumePhase; } - public boolean shouldAppendApplicationSuffix() { + public boolean shouldAppendIdleSuffix() { return keepOriginalNamesAfterDeploy && isAfterResumePhase; } } diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/ApplicationCloudModelBuilder.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/ApplicationCloudModelBuilder.java index 2910e5e4e7..0abebaf7c6 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/ApplicationCloudModelBuilder.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/ApplicationCloudModelBuilder.java @@ -152,7 +152,7 @@ private DeployedMtaApplication findDeployedApplication(String moduleName, Deploy private String getApplicationName(Module module) { String applicationName = NameUtil.getApplicationName(module); - if (appSuffixDeterminer.shouldAppendApplicationSuffix()) { + if (appSuffixDeterminer.shouldAppendIdleSuffix()) { applicationName += BlueGreenApplicationNameSuffix.IDLE.asSuffix(); } return applicationName; diff --git a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminerTest.java b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminerTest.java index bce9c48cb8..ea99048ff4 100644 --- a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminerTest.java +++ b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/detect/AppSuffixDeterminerTest.java @@ -1,18 +1,18 @@ package org.cloudfoundry.multiapps.controller.core.cf.detect; -import static org.junit.jupiter.api.Assertions.assertEquals; - import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; + class AppSuffixDeterminerTest { static Stream testAppSuffixDeterminer() { return Stream.of( - //@formatter:off + //@formatter:off // (1) Keep original app names is not set and the process is not after resume phase Arguments.of(false, false, false), // (2) Keep original app names is set but the process is not after resume phase @@ -29,6 +29,6 @@ static Stream testAppSuffixDeterminer() { @MethodSource void testAppSuffixDeterminer(boolean keepOriginalNamesAfterDeploy, boolean isAfterResumePhase, boolean shouldAppendApplicationSuffix) { AppSuffixDeterminer appSuffixDeterminer = new AppSuffixDeterminer(keepOriginalNamesAfterDeploy, isAfterResumePhase); - assertEquals(shouldAppendApplicationSuffix, appSuffixDeterminer.shouldAppendApplicationSuffix()); + assertEquals(shouldAppendApplicationSuffix, appSuffixDeterminer.shouldAppendIdleSuffix()); } } 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 a2f1261b98..0fd9fdc598 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 @@ -161,7 +161,6 @@ public class Messages { public static final String ERROR_MONITORING_OPERATIONS_OVER_SERVICES = "Error monitoring operations over services"; public static final String ERROR_DELETING_REMAINING_FILE_PARTS = "Error deleting remaining file parts"; public static final String ERROR_DETECTING_APPLICATIONS_TO_RENAME = "Error detecting applications to rename"; - public static final String ERROR_RENAMING_NEW_APPLICATIONS = "Error renaming new applications"; public static final String ERROR_MONITORING_CREATION_OR_UPDATE_OF_SERVICES = "Error monitoring creation or update of services"; public static final String ERROR_MONITORING_DELETION_OF_SERVICES = "Error monitoring deletion of services"; public static final String SERVICE_IS_ALREADY_DELETED = "Service \"{0}\" is already deleted"; diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateAppStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateAppStep.java index cb190b0b61..59d79bc17b 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateAppStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateAppStep.java @@ -18,6 +18,7 @@ import org.cloudfoundry.multiapps.controller.client.facade.CloudControllerClient; import org.cloudfoundry.multiapps.controller.client.facade.CloudCredentials; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; +import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableCloudApplication; import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableStaging; import org.cloudfoundry.multiapps.controller.client.facade.domain.Staging; import org.cloudfoundry.multiapps.controller.client.facade.dto.ApplicationToCreateDto; @@ -28,8 +29,11 @@ import org.cloudfoundry.multiapps.controller.core.cf.clients.AppBoundServiceInstanceNamesGetter; import org.cloudfoundry.multiapps.controller.core.cf.clients.WebClientFactory; import org.cloudfoundry.multiapps.controller.core.helpers.ApplicationFileDigestDetector; +import org.cloudfoundry.multiapps.controller.core.model.BlueGreenApplicationNameSuffix; import org.cloudfoundry.multiapps.controller.core.security.token.TokenService; import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration; +import org.cloudfoundry.multiapps.controller.persistence.model.ConfigurationSubscription; +import org.cloudfoundry.multiapps.controller.persistence.services.ConfigurationSubscriptionService; import org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException; import org.cloudfoundry.multiapps.controller.process.Messages; import org.cloudfoundry.multiapps.controller.process.util.ApplicationAttributeUpdater; @@ -59,6 +63,8 @@ public class CreateOrUpdateAppStep extends SyncFlowableStep { private WebClientFactory webClientFactory; @Inject private ApplicationConfiguration configuration; + @Inject + private ConfigurationSubscriptionService subscriptionService; @Override protected StepPhase executeStep(ProcessContext context) throws FileStorageException { @@ -95,7 +101,9 @@ protected AppBoundServiceInstanceNamesGetter getAppBoundServiceInstanceNamesGett return new AppBoundServiceInstanceNamesGetter(configuration, webClientFactory, credentials, correlationId); } - private StepFlowHandler createStepFlowHandler(ProcessContext context, CloudControllerClient client, CloudApplicationExtended app, + private StepFlowHandler createStepFlowHandler(ProcessContext context, + CloudControllerClient client, + CloudApplicationExtended app, CloudApplication existingApp) { if (existingApp == null) { return new CreateAppFlowHandler(context, client, app); @@ -213,7 +221,9 @@ private class UpdateAppFlowHandler extends StepFlowHandler { final CloudApplication existingApp; - public UpdateAppFlowHandler(ProcessContext context, CloudControllerClient client, CloudApplicationExtended app, + public UpdateAppFlowHandler(ProcessContext context, + CloudControllerClient client, + CloudApplicationExtended app, CloudApplication existingApp) { super(context, client, app); this.existingApp = existingApp; @@ -231,7 +241,9 @@ public void handleApplicationAttributes() { reportApplicationUpdateStatus(app, arePropertiesChanged); context.setVariable(Variables.VCAP_APP_PROPERTIES_CHANGED, arePropertiesChanged); + updateApplicationEnvironment(); + updateApplicationName(); } private void updateApplicationEnvironment() { @@ -279,6 +291,31 @@ private UpdateStrategy getEnvUpdateStrategy() { .shouldKeepExistingEnv() ? UpdateStrategy.MERGE : UpdateStrategy.REPLACE; } + public void updateApplicationName() { + boolean processIsBlueGreenWithIdleSuffix = StepsUtil.getAppSuffixDeterminer(context) + .shouldAppendIdleSuffix(); + if (!processIsBlueGreenWithIdleSuffix) { + return; + } + + String oldName = existingApp.getName(); + String newName = BlueGreenApplicationNameSuffix.removeSuffix(oldName); + if (oldName.equals(newName)) { + getStepLogger().info(Messages.THE_DETECTED_APPLICATION_HAS_THE_SAME_NAME_AS_THE_NEW_ONE); + return; + } + + getStepLogger().info(Messages.RENAMING_APPLICATION_0_TO_1, oldName, newName); + client.rename(oldName, newName); + + context.setVariable(Variables.EXISTING_APP, ImmutableCloudApplication.copyOf(existingApp) + .withName(newName)); + context.setVariable(Variables.APP_TO_PROCESS, ImmutableCloudApplicationExtended.copyOf(app) + .withName(newName)); + + updateConfigurationSubscribers(oldName, newName); + } + @Override public void handleApplicationServices() { if (context.getVariable(Variables.SHOULD_SKIP_SERVICE_REBINDING)) { @@ -298,6 +335,40 @@ public void printStepEndMessage() { getStepLogger().debug(Messages.APP_UPDATED, app.getName()); } + private void updateConfigurationSubscribers(String oldAppName, String newAppName) { + String mtaId = context.getVariable(Variables.MTA_ID); + String spaceGuid = context.getVariable(Variables.SPACE_GUID); + + List subscriptions = subscriptionService.createQuery() + .mtaId(mtaId) + .spaceId(spaceGuid) + .list(); + for (ConfigurationSubscription subscription : subscriptions) { + if (oldAppName.equals(subscription.getAppName())) { + getStepLogger().debug(Messages.UPDATING_CONFIGURATION_SUBSCRIPTION_0_WITH_NAME_1, subscription.getAppName(), + newAppName); + updateConfigurationSubscription(subscription, newAppName); + } + } + } + + private void updateConfigurationSubscription(ConfigurationSubscription subscription, String newAppName) { + ConfigurationSubscription newSubscription = createNewSubscription(subscription, newAppName); + subscriptionService.update(subscription, newSubscription); + } + + private ConfigurationSubscription createNewSubscription(ConfigurationSubscription subscription, String newAppName) { + return new ConfigurationSubscription(subscription.getId(), + subscription.getMtaId(), + subscription.getSpaceId(), + newAppName, + subscription.getFilter(), + subscription.getModuleDto(), + subscription.getResourceDto(), + subscription.getModuleId(), + subscription.getResourceId()); + } + private List getMtaAndExistingServices() { var serviceNamesGetter = getAppBoundServiceInstanceNamesGetter(context); return Stream.of(app.getServices(), serviceNamesGetter.getServiceInstanceNamesBoundToApp(existingApp.getGuid())) diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/RemoveNewApplicationsSuffixStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/RemoveNewApplicationsSuffixStep.java deleted file mode 100644 index aee843d5d3..0000000000 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/RemoveNewApplicationsSuffixStep.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.cloudfoundry.multiapps.controller.process.steps; - -import java.util.List; - -import jakarta.inject.Inject; -import jakarta.inject.Named; -import org.cloudfoundry.multiapps.controller.client.facade.CloudControllerClient; -import org.cloudfoundry.multiapps.controller.core.model.BlueGreenApplicationNameSuffix; -import org.cloudfoundry.multiapps.controller.persistence.model.ConfigurationSubscription; -import org.cloudfoundry.multiapps.controller.persistence.services.ConfigurationSubscriptionService; -import org.cloudfoundry.multiapps.controller.process.Messages; -import org.cloudfoundry.multiapps.controller.process.variables.Variables; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.Scope; - -@Named("removeNewApplicationsSuffixStep") -@Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class RemoveNewApplicationsSuffixStep extends SyncFlowableStep { - - @Inject - private ConfigurationSubscriptionService subscriptionService; - - @Override - protected StepPhase executeStep(ProcessContext context) { - if (!context.getVariable(Variables.KEEP_ORIGINAL_APP_NAMES_AFTER_DEPLOY)) { - return StepPhase.DONE; - } - - List appsToProcess = context.getVariable(Variables.APPS_TO_DEPLOY); - CloudControllerClient client = context.getControllerClient(); - - for (String appName : appsToProcess) { - String newName = BlueGreenApplicationNameSuffix.removeSuffix(appName); - getStepLogger().info(Messages.RENAMING_APPLICATION_0_TO_1, appName, newName); - client.rename(appName, newName); - } - - String mtaId = context.getVariable(Variables.MTA_ID); - String spaceId = context.getVariable(Variables.SPACE_GUID); - updateConfigurationSubscribers(appsToProcess, mtaId, spaceId); - - return StepPhase.DONE; - } - - private void updateConfigurationSubscribers(List appsToProcess, String mtaId, String spaceId) { - List subscriptions = subscriptionService.createQuery() - .mtaId(mtaId) - .spaceId(spaceId) - .list(); - for (ConfigurationSubscription subscription : subscriptions) { - if (appsToProcess.contains(subscription.getAppName())) { - String newAppName = BlueGreenApplicationNameSuffix.removeSuffix(subscription.getAppName()); - getStepLogger().debug(Messages.UPDATING_CONFIGURATION_SUBSCRIPTION_0_WITH_NAME_1, subscription.getAppName(), newAppName); - updateConfigurationSubscription(subscription, newAppName); - } - } - } - - private void updateConfigurationSubscription(ConfigurationSubscription subscription, String newAppName) { - ConfigurationSubscription newSubscription = createNewSubscription(subscription, newAppName); - subscriptionService.update(subscription, newSubscription); - } - - private ConfigurationSubscription createNewSubscription(ConfigurationSubscription subscription, String newAppName) { - return new ConfigurationSubscription(subscription.getId(), subscription.getMtaId(), subscription.getSpaceId(), newAppName, - subscription.getFilter(), subscription.getModuleDto(), subscription.getResourceDto(), - subscription.getModuleId(), subscription.getResourceId()); - } - - @Override - protected String getStepErrorMessage(ProcessContext context) { - return Messages.ERROR_RENAMING_NEW_APPLICATIONS; - } - -} diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/StepsUtil.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/StepsUtil.java index 7228b15780..3dba3e9306 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/StepsUtil.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/StepsUtil.java @@ -216,7 +216,7 @@ static ApplicationCloudModelBuilder getApplicationCloudModelBuilder(ProcessConte shouldApplyIncrementalInstancesUpdate(context)); } - static AppSuffixDeterminer getAppSuffixDeterminer(ProcessContext context) { + public static AppSuffixDeterminer getAppSuffixDeterminer(ProcessContext context) { boolean keepOriginalNamesAfterDeploy = context.getVariable(Variables.KEEP_ORIGINAL_APP_NAMES_AFTER_DEPLOY); boolean isAfterResumePhase = context.getVariable(Variables.PHASE) == Phase.AFTER_RESUME; return new AppSuffixDeterminer(keepOriginalNamesAfterDeploy, isAfterResumePhase); diff --git a/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/xs2-bg-deploy.bpmn b/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/xs2-bg-deploy.bpmn index 0764bbbfa7..b50086161f 100644 --- a/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/xs2-bg-deploy.bpmn +++ b/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/xs2-bg-deploy.bpmn @@ -133,7 +133,6 @@ - @@ -219,19 +218,14 @@ - - - - - @@ -240,6 +234,10 @@ + + + + @@ -385,7 +383,7 @@ - + @@ -405,9 +403,6 @@ - - - @@ -427,10 +422,10 @@ - + - + @@ -439,10 +434,9 @@ - - - - + + + @@ -476,9 +470,9 @@ - - - + + + @@ -497,8 +491,8 @@ - - + + @@ -547,29 +541,25 @@ - - - + + + - - - + + + - - - + + + - - - - @@ -577,9 +567,9 @@ - - - + + + @@ -633,9 +623,9 @@ - - - + + + @@ -667,36 +657,36 @@ - - + + - - - + + + - - - + + + - - + + - - - - + + + + @@ -705,9 +695,9 @@ - - - + + + @@ -755,9 +745,9 @@ - - - + + + diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateStepWithExistingAppTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateStepWithExistingAppTest.java index 81dec8e5a0..78f20b5f65 100644 --- a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateStepWithExistingAppTest.java +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/CreateOrUpdateStepWithExistingAppTest.java @@ -28,12 +28,17 @@ import org.cloudfoundry.multiapps.controller.client.lib.domain.ImmutableCloudApplicationExtended; import org.cloudfoundry.multiapps.controller.core.Constants; import org.cloudfoundry.multiapps.controller.core.cf.clients.AppBoundServiceInstanceNamesGetter; +import org.cloudfoundry.multiapps.controller.core.model.Phase; import org.cloudfoundry.multiapps.controller.core.util.ApplicationURI; +import org.cloudfoundry.multiapps.controller.persistence.model.ConfigurationSubscription; +import org.cloudfoundry.multiapps.controller.persistence.query.ConfigurationSubscriptionQuery; +import org.cloudfoundry.multiapps.controller.persistence.services.ConfigurationSubscriptionService; import org.cloudfoundry.multiapps.controller.process.variables.Variables; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Answers; import org.mockito.Mock; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -59,6 +64,10 @@ class CreateOrUpdateStepWithExistingAppTest extends SyncFlowableStepTest testHandleStagingApplicationAttributes() { return Stream.of( @@ -217,7 +226,7 @@ private void prepareClient(CloudApplication application, Set routes, when(appServicesGetter.getServiceInstanceNamesBoundToApp(any())).thenReturn(services); when(client.getApplicationEnvironment(application.getGuid())).thenReturn(env); application = prepareAppWithStaging(application, staging); - when(client.getApplication(APP_NAME, false)).thenReturn(application); + when(client.getApplication(application.getName(), false)).thenReturn(application); when(client.getApplicationSshEnabled(application.getGuid())).thenReturn(staging.isSshEnabled() != null && staging.isSshEnabled()); when(client.getApplicationRoutes(application.getGuid())).thenReturn(List.copyOf(routes)); String command = staging.getCommand() == null ? DEFAULT_COMMAND : staging.getCommand(); @@ -471,6 +480,32 @@ private Map buildExpectedEnvWithDeployAttributes(Map { - - @Mock - private ConfigurationSubscriptionService subscriptionService; - - @Mock(answer = Answers.RETURNS_SELF) - private ConfigurationSubscriptionQuery query; - - @BeforeEach - void setUp() { - context.setVariable(Variables.KEEP_ORIGINAL_APP_NAMES_AFTER_DEPLOY, true); - Mockito.when(query.list()) - .thenReturn(Collections.emptyList()); - Mockito.when(subscriptionService.createQuery()) - .thenReturn(query); - } - - @Test - void testExecuteWithNoAppsToDeploy() { - context.setVariable(Variables.APPS_TO_DEPLOY, Collections.emptyList()); - - step.execute(execution); - assertStepFinishedSuccessfully(); - - Mockito.verify(client, Mockito.never()) - .rename(Mockito.anyString(), Mockito.anyString()); - } - - @Test - void testExecuteRenamesApps() { - List apps = List.of("a-idle", "b-idle"); - context.setVariable(Variables.APPS_TO_DEPLOY, apps); - - step.execute(execution); - assertStepFinishedSuccessfully(); - - for (String app : apps) { - Mockito.verify(client) - .rename(app, removeAppNameSuffix(app)); - } - } - - @Test - void testUpdatingOfConfigurationSubscriptions() { - Mockito.when(query.list()) - .thenReturn(List.of(new ConfigurationSubscription(0, "", "", "a-idle", null, null, null, null, null))); - Mockito.when(subscriptionService.createQuery()) - .thenReturn(query); - - context.setVariable(Variables.APPS_TO_DEPLOY, List.of("a-idle")); - - step.execute(execution); - assertStepFinishedSuccessfully(); - - Mockito.verify(subscriptionService) - .update(Mockito.any(), Mockito.eq(new ConfigurationSubscription(0, "", "", "a", null, null, null, null, null))); - } - - private static String removeAppNameSuffix(String appName) { - return appName.substring(0, appName.lastIndexOf('-')); - } - - @Override - protected RemoveNewApplicationsSuffixStep createStep() { - return new RemoveNewApplicationsSuffixStep(); - } - -} diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/util/ArchiveEntryExtractorTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/util/ArchiveEntryExtractorTest.java index 746b0808a6..dde1871106 100644 --- a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/util/ArchiveEntryExtractorTest.java +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/util/ArchiveEntryExtractorTest.java @@ -1,5 +1,11 @@ package org.cloudfoundry.multiapps.controller.process.util; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.UUID; +import java.util.stream.Stream; + import org.apache.commons.io.input.BoundedInputStream; import org.cloudfoundry.multiapps.common.ContentException; import org.cloudfoundry.multiapps.controller.persistence.services.FileContentConsumer; @@ -13,12 +19,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.UUID; -import java.util.stream.Stream; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -93,7 +93,7 @@ private FileEntryProperties buildFileEntryProperty(long maxFileSizeInBytes) { private void assertDeploymentDescriptorAreEqual(String actualDeploymentDescriptor) throws IOException { String expectedDeploymentDescriptor = new String(getClass().getResourceAsStream("expected-mtad.yaml") .readAllBytes()); - assertEquals(expectedDeploymentDescriptor, actualDeploymentDescriptor); + assertEquals(expectedDeploymentDescriptor.replace("\r", ""), actualDeploymentDescriptor.replace("\r", "")); } static Stream processFileEntryBytes() { diff --git a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java index dcfce4e70a..a69b9c5a24 100644 --- a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java +++ b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/resources/ApplicationShutdownResource.java @@ -3,6 +3,7 @@ import java.text.MessageFormat; import java.util.concurrent.CompletableFuture; +import jakarta.inject.Inject; import org.cloudfoundry.multiapps.controller.core.Messages; import org.cloudfoundry.multiapps.controller.core.model.ApplicationShutdown; import org.cloudfoundry.multiapps.controller.core.model.ImmutableApplicationShutdown; @@ -17,8 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import jakarta.inject.Inject; - @RestController @RequestMapping(value = Constants.Resources.APPLICATION_SHUTDOWN) public class ApplicationShutdownResource { @@ -30,17 +29,18 @@ public class ApplicationShutdownResource { @PostMapping(produces = { MediaType.APPLICATION_JSON_VALUE }) public ApplicationShutdown - shutdownFlowableJobExecutor(@RequestHeader(name = "x-cf-applicationid", required = false) String applicationId, - @RequestHeader(name = "x-cf-instanceid", required = false) String applicationInstanceId, - @RequestHeader(name = "x-cf-instanceindex", required = false) String applicationInstanceIndex) { + shutdownFlowableJobExecutor(@RequestHeader(name = "x-cf-applicationid", required = false) String applicationId, + @RequestHeader(name = "x-cf-instanceid", required = false) String applicationInstanceId, + @RequestHeader(name = "x-cf-instanceindex", required = false) String applicationInstanceIndex) { CompletableFuture.runAsync(() -> { - LOGGER.info(MessageFormat.format(Messages.APP_SHUTDOWN_REQUEST, applicationId, applicationInstanceId, - applicationInstanceIndex)); - flowableFacade.shutdownJobExecutor(); - }) - .thenRun(() -> LOGGER.info(MessageFormat.format(Messages.APP_SHUTDOWNED, applicationId, applicationInstanceId, - applicationInstanceIndex))); + LOGGER.info(MessageFormat.format(Messages.APP_SHUTDOWN_REQUEST, applicationId, applicationInstanceId, + applicationInstanceIndex)); + flowableFacade.shutdownJobExecutor(); + }) + .thenRun(() -> LOGGER.info( + MessageFormat.format(Messages.APP_SUCCESSFULLY_SHUTDOWN, applicationId, applicationInstanceId, + applicationInstanceIndex))); return ImmutableApplicationShutdown.builder() .status(getShutdownStatus()) @@ -56,13 +56,14 @@ private ApplicationShutdown.Status getShutdownStatus() { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public ApplicationShutdown - getFlowableJobExecutorShutdownStatus(@RequestHeader(name = "x-cf-applicationid", required = false) String applicationId, - @RequestHeader(name = "x-cf-instanceid", required = false) String applicationInstanceId, - @RequestHeader(name = "x-cf-instanceindex", required = false) String applicationInstanceIndex) { + getFlowableJobExecutorShutdownStatus(@RequestHeader(name = "x-cf-applicationid", required = false) String applicationId, + @RequestHeader(name = "x-cf-instanceid", required = false) String applicationInstanceId, + @RequestHeader(name = "x-cf-instanceindex", required = false) String applicationInstanceIndex) { ApplicationShutdown applicationShutdown = ImmutableApplicationShutdown.builder() .status(getShutdownStatus()) - .applicationInstanceIndex(Integer.parseInt(applicationInstanceIndex)) + .applicationInstanceIndex( + Integer.parseInt(applicationInstanceIndex)) .applicationId(applicationId) .applicationInstanceId(applicationInstanceId) .build();