From 628391715abc34817edc57bde07464659e083e50 Mon Sep 17 00:00:00 2001 From: theghost5800 Date: Thu, 10 Jul 2025 18:12:07 +0300 Subject: [PATCH 1/3] Fix typo in compatibility word JIRA:LMCROSSITXSADEPLOY-3111 --- ...a => CompatibilityParameterValidator.java} | 2 +- ... => CompatibilityParametersValidator.java} | 4 +-- ... => IdleRoutesCompatibilityValidator.java} | 2 +- ...java => RoutesCompatibilityValidator.java} | 2 +- ...ptorParametersCompatibilityValidator.java} | 12 ++++----- ...duleParametersCompatibilityValidator.java} | 26 +++++++++---------- ...ParametersCompatibilityValidatorTest.java} | 22 ++++++++-------- ...eParametersCompatibilityValidatorTest.java | 20 +++++++------- 8 files changed, 45 insertions(+), 45 deletions(-) rename multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/{CompatabilityParameterValidator.java => CompatibilityParameterValidator.java} (81%) rename multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/{CompatabilityParametersValidator.java => CompatibilityParametersValidator.java} (72%) rename multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/{IdleRoutesCompatabilityValidator.java => IdleRoutesCompatibilityValidator.java} (92%) rename multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/{RoutesCompatabilityValidator.java => RoutesCompatibilityValidator.java} (92%) rename multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/{DescriptorParametersCompatabilityValidator.java => DescriptorParametersCompatibilityValidator.java} (73%) rename multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/{ModuleParametersCompatabilityValidator.java => ModuleParametersCompatibilityValidator.java} (69%) rename multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/{DescriptorParametersCompatabilityValidatorTest.java => DescriptorParametersCompatibilityValidatorTest.java} (79%) diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatabilityParameterValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatibilityParameterValidator.java similarity index 81% rename from multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatabilityParameterValidator.java rename to multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatibilityParameterValidator.java index f1a23b693a..7e537f8b27 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatabilityParameterValidator.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatibilityParameterValidator.java @@ -2,7 +2,7 @@ import java.util.List; -public interface CompatabilityParameterValidator { +public interface CompatibilityParameterValidator { boolean isCompatible(String parameter); diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatabilityParametersValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatibilityParametersValidator.java similarity index 72% rename from multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatabilityParametersValidator.java rename to multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatibilityParametersValidator.java index 996e24aa27..1ac8ce49c6 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatabilityParametersValidator.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/CompatibilityParametersValidator.java @@ -2,11 +2,11 @@ import org.cloudfoundry.multiapps.controller.core.util.UserMessageLogger; -public abstract class CompatabilityParametersValidator { +public abstract class CompatibilityParametersValidator { protected final UserMessageLogger userMessageLogger; - protected CompatabilityParametersValidator(UserMessageLogger userMessageLoger) { + protected CompatibilityParametersValidator(UserMessageLogger userMessageLoger) { this.userMessageLogger = userMessageLoger; } diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/IdleRoutesCompatabilityValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/IdleRoutesCompatibilityValidator.java similarity index 92% rename from multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/IdleRoutesCompatabilityValidator.java rename to multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/IdleRoutesCompatibilityValidator.java index 4d439bf82b..d92d75e4f7 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/IdleRoutesCompatabilityValidator.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/IdleRoutesCompatibilityValidator.java @@ -5,7 +5,7 @@ import org.cloudfoundry.multiapps.controller.core.model.SupportedParameters; -public class IdleRoutesCompatabilityValidator implements CompatabilityParameterValidator { +public class IdleRoutesCompatibilityValidator implements CompatibilityParameterValidator { @Override public boolean isCompatible(String parameter) { diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/RoutesCompatabilityValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/RoutesCompatibilityValidator.java similarity index 92% rename from multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/RoutesCompatabilityValidator.java rename to multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/RoutesCompatibilityValidator.java index 3b2d5f6f8c..8d9a72ecc2 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/RoutesCompatabilityValidator.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/RoutesCompatibilityValidator.java @@ -5,7 +5,7 @@ import org.cloudfoundry.multiapps.controller.core.model.SupportedParameters; -public class RoutesCompatabilityValidator implements CompatabilityParameterValidator { +public class RoutesCompatibilityValidator implements CompatibilityParameterValidator { @Override public boolean isCompatible(String parameter) { diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatabilityValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatibilityValidator.java similarity index 73% rename from multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatabilityValidator.java rename to multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatibilityValidator.java index 3b451daa10..fdf442de53 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatabilityValidator.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatibilityValidator.java @@ -4,15 +4,15 @@ import java.util.stream.Collectors; import org.cloudfoundry.multiapps.controller.core.util.UserMessageLogger; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatabilityParametersValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatibilityParametersValidator; import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor; import org.cloudfoundry.multiapps.mta.model.Module; -public class DescriptorParametersCompatabilityValidator extends CompatabilityParametersValidator { +public class DescriptorParametersCompatibilityValidator extends CompatibilityParametersValidator { private final DeploymentDescriptor descriptor; - public DescriptorParametersCompatabilityValidator(DeploymentDescriptor descriptor, UserMessageLogger userMessageLogger) { + public DescriptorParametersCompatibilityValidator(DeploymentDescriptor descriptor, UserMessageLogger userMessageLogger) { super(userMessageLogger); this.descriptor = descriptor; } @@ -36,11 +36,11 @@ private List validateModules(List modules) { } private Module validate(Module module) { - return getModuleParametersCompatabilityValidator(module).validate(); + return getModuleParametersCompatibilityValidator(module).validate(); } - protected ModuleParametersCompatabilityValidator getModuleParametersCompatabilityValidator(Module module) { - return new ModuleParametersCompatabilityValidator(module, userMessageLogger); + protected ModuleParametersCompatibilityValidator getModuleParametersCompatibilityValidator(Module module) { + return new ModuleParametersCompatibilityValidator(module, userMessageLogger); } } diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatabilityValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidator.java similarity index 69% rename from multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatabilityValidator.java rename to multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidator.java index f05ff0af89..72166d06ca 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatabilityValidator.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidator.java @@ -8,34 +8,34 @@ import org.cloudfoundry.multiapps.controller.core.Messages; import org.cloudfoundry.multiapps.controller.core.util.UserMessageLogger; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatabilityParameterValidator; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatabilityParametersValidator; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.IdleRoutesCompatabilityValidator; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.RoutesCompatabilityValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatibilityParameterValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatibilityParametersValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.IdleRoutesCompatibilityValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.RoutesCompatibilityValidator; import org.cloudfoundry.multiapps.mta.model.Module; -public class ModuleParametersCompatabilityValidator extends CompatabilityParametersValidator { +public class ModuleParametersCompatibilityValidator extends CompatibilityParametersValidator { private final Module module; - public ModuleParametersCompatabilityValidator(Module module, UserMessageLogger userMessageLogger) { + public ModuleParametersCompatibilityValidator(Module module, UserMessageLogger userMessageLogger) { super(userMessageLogger); this.module = module; } @Override public Module validate() { - List moduleValidators = getModuleValidators(); - checkParametersCompatability(module.getParameters(), moduleValidators); + List moduleValidators = getModuleValidators(); + checkParametersCompatibility(module.getParameters(), moduleValidators); return module; } - private List getModuleValidators() { - return Arrays.asList(new RoutesCompatabilityValidator(), new IdleRoutesCompatabilityValidator()); + private List getModuleValidators() { + return Arrays.asList(new RoutesCompatibilityValidator(), new IdleRoutesCompatibilityValidator()); } - private void checkParametersCompatability(Map parameters, List moduleValidators) { - for (CompatabilityParameterValidator validator : moduleValidators) { + private void checkParametersCompatibility(Map parameters, List moduleValidators) { + for (CompatibilityParameterValidator validator : moduleValidators) { List incompatibleParameters = getIncompatibleParameters(validator, parameters); if (!incompatibleParameters.isEmpty()) { warnForIncompatibleParameters(validator.getParameterName(), incompatibleParameters); @@ -43,7 +43,7 @@ private void checkParametersCompatability(Map parameters, List getIncompatibleParameters(CompatabilityParameterValidator validator, Map parameters) { + private List getIncompatibleParameters(CompatibilityParameterValidator validator, Map parameters) { String parameterNameToValidate = validator.getParameterName(); if (parameters.containsKey(parameterNameToValidate)) { return parameters.keySet() diff --git a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatabilityValidatorTest.java b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatibilityValidatorTest.java similarity index 79% rename from multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatabilityValidatorTest.java rename to multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatibilityValidatorTest.java index 407d0fa022..d1e0c77f98 100644 --- a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatabilityValidatorTest.java +++ b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/DescriptorParametersCompatibilityValidatorTest.java @@ -1,8 +1,5 @@ package org.cloudfoundry.multiapps.controller.core.validators.parameters.v2; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.when; - import java.util.Collection; import java.util.List; import java.util.Map; @@ -15,7 +12,10 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -class DescriptorParametersCompatabilityValidatorTest { +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +class DescriptorParametersCompatibilityValidatorTest { private static final String MODULE_NAME = "test-module"; private static final Map MODULE_PARAMETERS = Map.of("test-param", "test-value"); @@ -23,7 +23,7 @@ class DescriptorParametersCompatabilityValidatorTest { @Mock private UserMessageLogger userMessageLogger; @Mock - private ModuleParametersCompatabilityValidator moduleParametersCompatabilityValidator; + private ModuleParametersCompatibilityValidator moduleParametersCompatibilityValidator; @BeforeEach void setUp() throws Exception { @@ -36,13 +36,13 @@ void testDescriptorValidator() { Module module = buildModule(); DeploymentDescriptor descriptor = buildDeploymentDescriptor(module); - prepareModuleParametersCompatabilityValidator(module); + prepareModuleParametersCompatibilityValidator(module); - DescriptorParametersCompatabilityValidator descriptorValidator = new DescriptorParametersCompatabilityValidator(descriptor, + DescriptorParametersCompatibilityValidator descriptorValidator = new DescriptorParametersCompatibilityValidator(descriptor, userMessageLogger) { @Override - protected ModuleParametersCompatabilityValidator getModuleParametersCompatabilityValidator(Module module) { - return moduleParametersCompatabilityValidator; + protected ModuleParametersCompatibilityValidator getModuleParametersCompatibilityValidator(Module module) { + return moduleParametersCompatibilityValidator; } }; @@ -62,8 +62,8 @@ private DeploymentDescriptor buildDeploymentDescriptor(Module module) { .setModules(List.of(module)); } - private void prepareModuleParametersCompatabilityValidator(Module module) { - when(moduleParametersCompatabilityValidator.validate()).thenReturn(module); + private void prepareModuleParametersCompatibilityValidator(Module module) { + when(moduleParametersCompatibilityValidator.validate()).thenReturn(module); } private void assertModules(Module expectedModule, List validatedModules) { diff --git a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java index 51aac65ace..2573b8ef6f 100644 --- a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java +++ b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java @@ -1,12 +1,5 @@ package org.cloudfoundry.multiapps.controller.core.validators.parameters.v2; -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.atLeastOnce; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -22,6 +15,13 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; +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.atLeastOnce; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + class ModuleParametersCompatibilityValidatorTest { @Mock @@ -33,7 +33,7 @@ void setUp() throws Exception { .close(); } - static Stream testModuleParametersCompatability() { + static Stream testModuleParametersCompatibility() { return Stream.of(Arguments.of(List.of(SupportedParameters.HOST, SupportedParameters.ROUTES), true), Arguments.of(List.of(SupportedParameters.ROUTES, SupportedParameters.IDLE_ROUTES), false), Arguments.of(List.of(SupportedParameters.HOSTS, SupportedParameters.DOMAINS, SupportedParameters.ROUTES), true), @@ -52,10 +52,10 @@ static Stream testModuleParametersCompatability() { @ParameterizedTest @MethodSource - void testModuleParametersCompatability(List moduleParameters, boolean shouldWarnMessage) { + void testModuleParametersCompatibility(List moduleParameters, boolean shouldWarnMessage) { Module module = buildModule(moduleParameters); - Module validatedModule = new ModuleParametersCompatabilityValidator(module, userMessageLogger).validate(); + Module validatedModule = new ModuleParametersCompatibilityValidator(module, userMessageLogger).validate(); assertEquals(module.getParameters(), validatedModule.getParameters()); verifyUserMessageLogger(shouldWarnMessage); From 414af06e622c0c29fc9a2bb8c7ab50565dff504f Mon Sep 17 00:00:00 2001 From: theghost5800 Date: Tue, 1 Jul 2025 17:47:57 +0300 Subject: [PATCH 2/3] Add support for app features enablement JIRA:LMCROSSITXSADEPLOY-3111 --- .../ResilientCloudControllerClient.java | 6 + .../client/facade/CloudControllerClient.java | 23 +- .../facade/CloudControllerClientImpl.java | 14 +- .../client/facade/domain/Staging.java | 10 + .../rest/CloudControllerRestClient.java | 9 +- .../rest/CloudControllerRestClientImpl.java | 257 +++--- ...sCloudControllerClientIntegrationTest.java | 54 +- .../multiapps/controller/core/Constants.java | 2 + .../core/cf/CloudHandlerFactory.java | 4 +- .../core/cf/v2/CloudHandlerFactoryV2.java | 6 +- .../core/cf/v3/CloudHandlerFactoryV3.java | 6 +- .../core/helpers/MtaDescriptorMerger.java | 2 +- .../MtaDescriptorPropertiesResolver.java | 31 +- .../core/model/SupportedParameters.java | 3 +- .../core/parser/StagingParametersParser.java | 21 +- .../AppFeaturesCompatibilityValidator.java | 37 + .../parameters/AppFeaturesValidator.java | 31 + ...oduleParametersCompatibilityValidator.java | 4 +- .../core/cf/v2/CloudModelBuilderTest.java | 838 ++++++++++-------- .../parameters/AppFeaturesValidatorTest.java | 58 ++ ...eParametersCompatibilityValidatorTest.java | 35 +- .../app-features/apps-app-features-empty.json | 54 ++ .../apps-app-features-single.json | 56 ++ .../mta/app-features/apps-app-features.json | 58 ++ .../app-features/config-app-features.mtaext | 4 + .../app-features/mtad-app-features-empty.yaml | 11 + .../mtad-app-features-single.yaml | 12 + .../mta/app-features/mtad-app-features.yaml | 14 + .../src/test/resources/mta/devxdi/apps.json | 27 +- .../test/resources/mta/devxdi/xs2-apps.json | 27 +- .../test/resources/mta/devxwebide/apps.json | 9 +- .../resources/mta/devxwebide/xs2-apps.json | 5 +- .../mta/javahelloworld/apps-ns-1.json | 43 +- .../mta/javahelloworld/apps-ns-2.json | 43 +- .../mta/javahelloworld/apps-ns-3.json | 43 +- .../mta/javahelloworld/apps-patch-ns.json | 15 +- .../mta/javahelloworld/apps-patch.json | 11 +- .../resources/mta/javahelloworld/apps.json | 57 +- .../mta/javahelloworld/xs2-apps.json | 31 +- .../src/test/resources/mta/sample/apps.json | 33 +- .../src/test/resources/mta/shine/apps.json | 33 +- .../skip-deploy/apps-skip-deploy-false.json | 6 +- .../skip-deploy/apps-skip-deploy-true.json | 3 +- .../controller/core/cf/v2/apps-01.json | 5 +- .../controller/core/cf/v2/apps-02.json | 12 +- .../controller/core/cf/v2/apps-03.json | 22 +- .../controller/core/cf/v2/apps-05.json | 22 +- .../controller/core/cf/v2/apps-06.json | 5 +- .../controller/core/cf/v2/apps-07.json | 7 +- .../controller/core/cf/v2/apps-08.json | 7 +- .../controller/core/cf/v2/apps-09.json | 28 +- .../controller/core/cf/v2/apps-10.json | 7 +- .../controller/core/cf/v2/apps-12.json | 5 +- .../controller/core/cf/v2/apps-13.json | 5 +- .../controller/core/cf/v2/apps-14.json | 13 +- .../controller/core/cf/v2/apps-15.json | 7 +- .../controller/core/cf/v2/apps-16.json | 7 +- ...-health-check-type-http-with-endpoint.json | 7 +- ...alth-check-type-http-without-endpoint.json | 7 +- .../v2/apps-with-health-check-type-port.json | 7 +- .../core/cf/v2/apps-with-nohostname.json | 45 +- .../apps-with-restart-parameters-false.json | 23 +- .../cf/v2/apps-with-ssh-enabled-false.json | 9 +- .../cf/v2/apps-with-ssh-enabled-true.json | 9 +- .../apps-with-existing-routes.json | 7 +- .../apps-with-nohostname.json | 45 +- .../core/cf/v2/keep-existing-routes/apps.json | 7 +- .../controller/core/cf/v3/apps-01.json | 7 +- .../controller/process/Messages.java | 1 + .../client/LoggingCloudControllerClient.java | 6 + .../StagingApplicationAttributeUpdater.java | 17 +- 71 files changed, 1442 insertions(+), 953 deletions(-) create mode 100644 multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/AppFeaturesCompatibilityValidator.java create mode 100644 multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/AppFeaturesValidator.java create mode 100644 multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/AppFeaturesValidatorTest.java create mode 100644 multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-empty.json create mode 100644 multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-single.json create mode 100644 multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features.json create mode 100644 multiapps-controller-core/src/test/resources/mta/app-features/config-app-features.mtaext create mode 100644 multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-empty.yaml create mode 100644 multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-single.yaml create mode 100644 multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features.yaml diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/ResilientCloudControllerClient.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/ResilientCloudControllerClient.java index 51023de044..0cb70df31a 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/ResilientCloudControllerClient.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/ResilientCloudControllerClient.java @@ -11,6 +11,7 @@ import java.util.function.Supplier; import org.cloudfoundry.client.v3.Metadata; +import org.cloudfoundry.multiapps.controller.client.util.ResilientCloudOperationExecutor; import org.cloudfoundry.multiapps.controller.client.facade.ApplicationServicesUpdateCallback; import org.cloudfoundry.multiapps.controller.client.facade.CloudControllerClient; import org.cloudfoundry.multiapps.controller.client.facade.CloudControllerClientImpl; @@ -190,6 +191,11 @@ public boolean getApplicationSshEnabled(UUID applicationGuid) { return executeWithRetry(() -> delegate.getApplicationSshEnabled(applicationGuid)); } + @Override + public Map getApplicationFeatures(UUID applicationGuid) { + return executeWithRetry(() -> delegate.getApplicationFeatures(applicationGuid)); + } + @Override public List getApplications() { return executeWithRetry(delegate::getApplications, HttpStatus.NOT_FOUND); diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClient.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClient.java index 38248b40a0..e8e057cbcc 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClient.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClient.java @@ -9,7 +9,6 @@ import java.util.UUID; import org.cloudfoundry.client.v3.Metadata; - import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudAsyncJob; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudBuild; @@ -37,7 +36,6 @@ /** * The interface defining operations making up the Cloud Foundry Java client's API. - * */ public interface CloudControllerClient { @@ -104,7 +102,6 @@ Optional bindServiceInstance(String bindingName, String applicationName, String createServiceBroker(CloudServiceBroker serviceBroker); /** - * * @param keyModel service-key cloud object * @param serviceInstanceName name of related service instance * @return the service-key object populated with new guid @@ -112,7 +109,6 @@ Optional bindServiceInstance(String bindingName, String applicationName, CloudServiceKey createAndFetchServiceKey(CloudServiceKey keyModel, String serviceInstanceName); /** - * * @param keyModel service-key cloud object * @param serviceInstanceName name of related service instance * @return job id for async polling if present @@ -121,7 +117,7 @@ Optional bindServiceInstance(String bindingName, String applicationName, /** * Create a service key. - * + * * @param serviceInstanceName name of service instance * @param serviceKeyName name of service-key * @param parameters parameters of service-key @@ -171,7 +167,6 @@ Optional bindServiceInstance(String bindingName, String applicationName, void deleteServiceInstance(String serviceInstance); /** - * * @param serviceInstance {@link CloudServiceInstance} */ void deleteServiceInstance(CloudServiceInstance serviceInstance); @@ -194,7 +189,7 @@ Optional bindServiceInstance(String bindingName, String applicationName, /** * Delete a service binding. - * + * * @param serviceInstanceName name of service instance * @param serviceKeyName name of service key * @return job id for async polling if present @@ -203,7 +198,7 @@ Optional bindServiceInstance(String bindingName, String applicationName, /** * Delete a service binding. - * + * * @param bindingGuid The GUID of the binding * @param serviceBindingOperationCallback callback used for error handling * @return job id for async polling if present @@ -287,6 +282,8 @@ Optional bindServiceInstance(String bindingName, String applicationName, boolean getApplicationSshEnabled(UUID applicationGuid); + Map getApplicationFeatures(UUID applicationGuid); + /** * Get all applications in the currently targeted space. This method has EXTREMELY poor performance for spaces with a lot of * applications. @@ -364,7 +361,7 @@ Optional bindServiceInstance(String bindingName, String applicationName, /** * Get the GUID of a service instance. - * + * * @param serviceInstanceName the name of the service instance * @return the service instance GUID */ @@ -447,7 +444,7 @@ Optional bindServiceInstance(String bindingName, String applicationName, /** * Get all user-provided service instance parameters - * + * * @param guid The service instance guid * @return user-provided service instance parameters in key-value pairs */ @@ -670,7 +667,7 @@ CloudPackage asyncUploadApplicationWithExponentialBackoff(String applicationName /** * Get the list of one-off tasks currently known for the given application. - * + * * @param applicationName the application to look for tasks * @return the list of known tasks * @throws UnsupportedOperationException if the targeted controller does not support tasks @@ -679,7 +676,7 @@ CloudPackage asyncUploadApplicationWithExponentialBackoff(String applicationName /** * Run a one-off task on an application. - * + * * @param applicationName the application to run the task on * @param task the task to run * @return the ran task @@ -689,7 +686,7 @@ CloudPackage asyncUploadApplicationWithExponentialBackoff(String applicationName /** * Cancel the given task. - * + * * @param taskGuid the GUID of the task to cancel * @return the cancelled task */ diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClientImpl.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClientImpl.java index 648d07210d..9bf88c3bc9 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClientImpl.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/CloudControllerClientImpl.java @@ -12,9 +12,6 @@ import org.cloudfoundry.AbstractCloudFoundryException; import org.cloudfoundry.client.v3.Metadata; -import org.springframework.http.HttpStatus; -import org.springframework.util.Assert; - import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudAsyncJob; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudBuild; @@ -42,10 +39,11 @@ import org.cloudfoundry.multiapps.controller.client.facade.rest.CloudControllerRestClient; import org.cloudfoundry.multiapps.controller.client.facade.rest.CloudControllerRestClientFactory; import org.cloudfoundry.multiapps.controller.client.facade.rest.ImmutableCloudControllerRestClientFactory; +import org.springframework.http.HttpStatus; +import org.springframework.util.Assert; /** * A Java client to exercise the Cloud Foundry API. - * */ public class CloudControllerClientImpl implements CloudControllerClient { @@ -61,7 +59,8 @@ public CloudControllerClientImpl(URL controllerUrl, CloudCredentials credentials public CloudControllerClientImpl(URL controllerUrl, CloudCredentials credentials, CloudSpace target, boolean trustSelfSignedCerts) { Assert.notNull(controllerUrl, "URL for cloud controller cannot be null"); CloudControllerRestClientFactory restClientFactory = ImmutableCloudControllerRestClientFactory.builder() - .shouldTrustSelfSignedCertificates(trustSelfSignedCerts) + .shouldTrustSelfSignedCertificates( + trustSelfSignedCerts) .build(); this.delegate = restClientFactory.createClient(controllerUrl, credentials, target); } @@ -264,6 +263,11 @@ public boolean getApplicationSshEnabled(UUID applicationGuid) { return handleExceptions(() -> delegate.getApplicationSshEnabled(applicationGuid)); } + @Override + public Map getApplicationFeatures(UUID applicationGuid) { + return handleExceptions(() -> delegate.getApplicationFeatures(applicationGuid)); + } + @Override public List getApplications() { return handleExceptions(() -> delegate.getApplications()); diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/Staging.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/Staging.java index a613849536..5a17454a50 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/Staging.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/Staging.java @@ -1,6 +1,7 @@ package org.cloudfoundry.multiapps.controller.client.facade.domain; import java.util.List; +import java.util.Map; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -55,6 +56,15 @@ public interface Staging { @Nullable Boolean isSshEnabled(); + /** + * Retrieves the application features map. The map contains feature names as keys and their enabled/disabled state as Boolean values. + * This allows specifying which features should be enabled or disabled for the application during staging. + * + * @return a map of application features and their enabled/disabled state + */ + @SkipNulls + Map getAppFeatures(); + /** * @return the stack to use when staging the application, or null to use the default stack */ diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClient.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClient.java index aaab7f1977..61c3b2b8bd 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClient.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClient.java @@ -8,9 +8,7 @@ import java.util.Set; import java.util.UUID; -import org.cloudfoundry.multiapps.controller.client.facade.dto.ApplicationToCreateDto; import org.cloudfoundry.client.v3.Metadata; - import org.cloudfoundry.multiapps.controller.client.facade.UploadStatusCallback; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudAsyncJob; @@ -35,10 +33,10 @@ import org.cloudfoundry.multiapps.controller.client.facade.domain.Staging; import org.cloudfoundry.multiapps.controller.client.facade.domain.Upload; import org.cloudfoundry.multiapps.controller.client.facade.domain.UserRole; +import org.cloudfoundry.multiapps.controller.client.facade.dto.ApplicationToCreateDto; /** * Interface defining operations available for the cloud controller REST client implementations - * */ public interface CloudControllerRestClient { @@ -50,7 +48,8 @@ public interface CloudControllerRestClient { Optional bindServiceInstance(String bindingName, String applicationName, String serviceInstanceName); - Optional bindServiceInstance(String bindingName, String applicationName, String serviceInstanceName, Map parameters); + Optional bindServiceInstance(String bindingName, String applicationName, String serviceInstanceName, + Map parameters); void createApplication(ApplicationToCreateDto applicationToCreateDto); @@ -110,6 +109,8 @@ public interface CloudControllerRestClient { boolean getApplicationSshEnabled(UUID applicationGuid); + Map getApplicationFeatures(UUID applicationGuid); + List getApplications(); CloudDomain getDefaultDomain(); diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClientImpl.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClientImpl.java index 8d1c65c75f..10df9a4bd2 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClientImpl.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClientImpl.java @@ -19,67 +19,6 @@ import java.util.function.Supplier; import java.util.stream.Collectors; -import org.cloudfoundry.multiapps.controller.client.facade.CloudOperationException; -import org.cloudfoundry.multiapps.controller.client.facade.Constants; -import org.cloudfoundry.multiapps.controller.client.facade.Messages; -import org.cloudfoundry.multiapps.controller.client.facade.UploadStatusCallback; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudApplication; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudAsyncJob; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudBuild; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudDomain; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudEvent; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudPackage; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudProcess; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudRoute; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceBinding; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceBroker; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceInstance; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceKey; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceOffering; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServicePlan; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudStack; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudTask; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawInstancesInfo; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawUserRole; -import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawV3CloudServiceInstance; -import org.cloudfoundry.multiapps.controller.client.facade.domain.BitsData; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudAsyncJob; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudBuild; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudDomain; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudEntity; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudEvent; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudMetadata; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudPackage; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudProcess; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudRoute; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceBinding; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceBroker; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceInstance; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceKey; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceOffering; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServicePlan; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudSpace; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudStack; -import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudTask; -import org.cloudfoundry.multiapps.controller.client.facade.domain.Derivable; -import org.cloudfoundry.multiapps.controller.client.facade.domain.DockerCredentials; -import org.cloudfoundry.multiapps.controller.client.facade.domain.DockerInfo; -import org.cloudfoundry.multiapps.controller.client.facade.domain.DropletInfo; -import org.cloudfoundry.multiapps.controller.client.facade.domain.ErrorDetails; -import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableDropletInfo; -import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableErrorDetails; -import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableInstancesInfo; -import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableUpload; -import org.cloudfoundry.multiapps.controller.client.facade.domain.InstancesInfo; -import org.cloudfoundry.multiapps.controller.client.facade.domain.RouteDestination; -import org.cloudfoundry.multiapps.controller.client.facade.domain.ServicePlanVisibility; -import org.cloudfoundry.multiapps.controller.client.facade.domain.Staging; -import org.cloudfoundry.multiapps.controller.client.facade.domain.Status; -import org.cloudfoundry.multiapps.controller.client.facade.domain.Upload; -import org.cloudfoundry.multiapps.controller.client.facade.domain.UserRole; -import org.cloudfoundry.multiapps.controller.client.facade.dto.ApplicationToCreateDto; -import org.cloudfoundry.multiapps.controller.client.facade.util.JobV3Util; import org.cloudfoundry.AbstractCloudFoundryException; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.BuildpackData; @@ -91,6 +30,7 @@ import org.cloudfoundry.client.v3.Resource; import org.cloudfoundry.client.v3.ToOneRelationship; import org.cloudfoundry.client.v3.applications.Application; +import org.cloudfoundry.client.v3.applications.ApplicationFeature; import org.cloudfoundry.client.v3.applications.ApplicationRelationships; import org.cloudfoundry.client.v3.applications.ApplicationState; import org.cloudfoundry.client.v3.applications.CreateApplicationRequest; @@ -108,6 +48,7 @@ import org.cloudfoundry.client.v3.applications.GetApplicationSshEnabledRequest; import org.cloudfoundry.client.v3.applications.GetApplicationSshEnabledResponse; import org.cloudfoundry.client.v3.applications.ListApplicationBuildsRequest; +import org.cloudfoundry.client.v3.applications.ListApplicationFeaturesRequest; import org.cloudfoundry.client.v3.applications.ListApplicationPackagesRequest; import org.cloudfoundry.client.v3.applications.ListApplicationRoutesRequest; import org.cloudfoundry.client.v3.applications.ListApplicationsRequest; @@ -208,6 +149,67 @@ import org.cloudfoundry.client.v3.tasks.GetTaskRequest; import org.cloudfoundry.client.v3.tasks.ListTasksRequest; import org.cloudfoundry.client.v3.tasks.Task; +import org.cloudfoundry.multiapps.controller.client.facade.CloudOperationException; +import org.cloudfoundry.multiapps.controller.client.facade.Constants; +import org.cloudfoundry.multiapps.controller.client.facade.Messages; +import org.cloudfoundry.multiapps.controller.client.facade.UploadStatusCallback; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudApplication; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudAsyncJob; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudBuild; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudDomain; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudEvent; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudPackage; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudProcess; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudRoute; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceBinding; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceBroker; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceInstance; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceKey; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServiceOffering; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudServicePlan; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudStack; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawCloudTask; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawInstancesInfo; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawUserRole; +import org.cloudfoundry.multiapps.controller.client.facade.adapters.ImmutableRawV3CloudServiceInstance; +import org.cloudfoundry.multiapps.controller.client.facade.domain.BitsData; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudAsyncJob; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudBuild; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudDomain; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudEntity; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudEvent; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudMetadata; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudPackage; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudProcess; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudRoute; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceBinding; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceBroker; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceInstance; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceKey; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceOffering; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServicePlan; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudSpace; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudStack; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudTask; +import org.cloudfoundry.multiapps.controller.client.facade.domain.Derivable; +import org.cloudfoundry.multiapps.controller.client.facade.domain.DockerCredentials; +import org.cloudfoundry.multiapps.controller.client.facade.domain.DockerInfo; +import org.cloudfoundry.multiapps.controller.client.facade.domain.DropletInfo; +import org.cloudfoundry.multiapps.controller.client.facade.domain.ErrorDetails; +import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableDropletInfo; +import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableErrorDetails; +import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableInstancesInfo; +import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableUpload; +import org.cloudfoundry.multiapps.controller.client.facade.domain.InstancesInfo; +import org.cloudfoundry.multiapps.controller.client.facade.domain.RouteDestination; +import org.cloudfoundry.multiapps.controller.client.facade.domain.ServicePlanVisibility; +import org.cloudfoundry.multiapps.controller.client.facade.domain.Staging; +import org.cloudfoundry.multiapps.controller.client.facade.domain.Status; +import org.cloudfoundry.multiapps.controller.client.facade.domain.Upload; +import org.cloudfoundry.multiapps.controller.client.facade.domain.UserRole; +import org.cloudfoundry.multiapps.controller.client.facade.dto.ApplicationToCreateDto; +import org.cloudfoundry.multiapps.controller.client.facade.util.JobV3Util; import org.cloudfoundry.util.PaginationUtils; import org.springframework.http.HttpStatus; import org.springframework.util.Assert; @@ -321,8 +323,7 @@ private Lifecycle buildApplicationLifecycle(Staging staging) { // Determine lifecycle type, defaulting to BUILDPACK if lifecycleType is null LifecycleType lifecycleType = staging.getLifecycleType() != null ? LifecycleType.valueOf(staging.getLifecycleType() - .name()) - : LifecycleType.BUILDPACK; + .name()) : LifecycleType.BUILDPACK; return createLifecycleByType(staging, lifecycleType); } @@ -382,9 +383,9 @@ private void updateApplicationAttributes(ApplicationToCreateDto applicationToCre } private void updateApplicationProcess(UUID applicationGuid, Staging staging) { - if (staging.isSshEnabled() != null) { - updateSsh(applicationGuid, staging.isSshEnabled()); - } + staging.getAppFeatures() + .entrySet() + .forEach(entry -> updateAppFeature(applicationGuid, entry.getKey(), entry.getValue())); GetApplicationProcessResponse getApplicationProcessResponse = getApplicationProcessResource(applicationGuid); UpdateProcessRequest.Builder updateProcessRequestBuilder = UpdateProcessRequest.builder() .processId(getApplicationProcessResponse.getId()) @@ -397,11 +398,11 @@ private void updateApplicationProcess(UUID applicationGuid, Staging staging) { .block(); } - private void updateSsh(UUID applicationGuid, boolean isSshEnabled) { + private void updateAppFeature(UUID applicationGuid, String featureName, boolean enabled) { delegate.applicationsV3() .updateFeature(UpdateApplicationFeatureRequest.builder() - .featureName("ssh") - .enabled(isSshEnabled) + .featureName(featureName) + .enabled(enabled) .applicationId(applicationGuid.toString()) .build()) .block(); @@ -494,9 +495,9 @@ public CloudServiceKey createAndFetchServiceKey(CloudServiceKey keyModel, String CloudServiceInstance serviceInstance = getServiceInstance(serviceInstanceName); doCreateServiceKeySync(keyModel.getName(), keyModel.getCredentials(), keyModel.getV3Metadata(), serviceInstance); - return fetchWithAuxiliaryContent(() -> getServiceKeyResourceByNameAndServiceInstanceGuid(keyModel.getName(), - getGuid(serviceInstance)), - fetchedKey -> zipWithAuxiliaryServiceKeyContent(fetchedKey, serviceInstance)); + return fetchWithAuxiliaryContent( + () -> getServiceKeyResourceByNameAndServiceInstanceGuid(keyModel.getName(), getGuid(serviceInstance)), + fetchedKey -> zipWithAuxiliaryServiceKeyContent(fetchedKey, serviceInstance)); } @Override @@ -536,8 +537,8 @@ private Optional doCreateServiceKey(String name, Map par private CreateServiceBindingRequest buildServiceCredentialBindingRequest(String name, Map parameters, Metadata metadata, CloudServiceInstance serviceInstance) { if (serviceInstance.getType() != ServiceInstanceType.MANAGED) { - throw new IllegalArgumentException(String.format(Messages.CANT_CREATE_SERVICE_KEY_FOR_USER_PROVIDED_SERVICE, - serviceInstance.getName())); + throw new IllegalArgumentException( + String.format(Messages.CANT_CREATE_SERVICE_KEY_FOR_USER_PROVIDED_SERVICE, serviceInstance.getName())); } UUID serviceInstanceGuid = getGuid(serviceInstance); @@ -621,8 +622,7 @@ public void deleteRoute(String host, String domainName, String path) { assertSpaceProvided("delete route for domain"); UUID routeGuid = getRouteGuid(getRequiredDomainGuid(domainName), host, path); if (routeGuid == null) { - throw new CloudOperationException(HttpStatus.NOT_FOUND, - "Not Found", + throw new CloudOperationException(HttpStatus.NOT_FOUND, "Not Found", "Host " + host + " not found for domain " + domainName + "."); } doDeleteRoute(routeGuid); @@ -750,6 +750,19 @@ public boolean getApplicationSshEnabled(UUID applicationGuid) { .block(); } + @Override + public Map getApplicationFeatures(UUID applicationGuid) { + IntFunction pageRequestSupplier = page -> ListApplicationFeaturesRequest.builder() + .applicationId( + applicationGuid.toString()) + .page(page) + .build(); + return PaginationUtils.requestClientV3Resources(page -> delegate.applicationsV3() + .listFeatures(pageRequestSupplier.apply(page))) + .collect(Collectors.toMap(ApplicationFeature::getName, ApplicationFeature::getEnabled)) + .block(); + } + @Override public List getApplications() { return fetchList(this::getApplicationResources, application -> ImmutableRawCloudApplication.builder() @@ -953,11 +966,11 @@ private Mono> getServiceKeyCredentials(String keyGuid) { .serviceBindingId(keyGuid) .build()) // CF V3 API returns 404 when fetching credentials of a service key which creation failed - .onErrorResume(t -> doesErrorMatchStatusCode(t, HttpStatus.NOT_FOUND), - t -> Mono.just(GetServiceBindingDetailsResponse.builder() - .volumeMounts(Collections.emptyList()) - .credentials(Collections.emptyMap()) - .build())) + .onErrorResume(t -> doesErrorMatchStatusCode(t, HttpStatus.NOT_FOUND), t -> Mono.just( + GetServiceBindingDetailsResponse.builder() + .volumeMounts(Collections.emptyList()) + .credentials(Collections.emptyMap()) + .build())) .map(GetServiceBindingDetailsResponse::getCredentials); } @@ -1347,8 +1360,8 @@ private boolean isProtocolChanged(UUID applicationGuid, CloudRoute currentRoute, return currentRoute.getDestinations() .stream() .filter(routeDestination -> Objects.equals(routeDestination.getApplicationGuid(), applicationGuid)) - .noneMatch(routeDestination -> Objects.equals(routeDestination.getProtocol(), - updatedRoute.getRequestedProtocol())); + .noneMatch( + routeDestination -> Objects.equals(routeDestination.getProtocol(), updatedRoute.getRequestedProtocol())); } private Set getNewRoutes(UUID applicationGuid, List currentRoutes, Set updatedRoutes) { @@ -1501,8 +1514,7 @@ public DropletInfo getCurrentDropletForApplication(UUID applicationGuid) { .build()) .block(); if (dropletResponse == null) { - throw new CloudOperationException(HttpStatus.NOT_FOUND, - "Not found", + throw new CloudOperationException(HttpStatus.NOT_FOUND, "Not found", "Application with guid " + applicationGuid + " does not have a droplet"); } return parseDropletInfo(dropletResponse); @@ -1567,8 +1579,7 @@ public CloudAsyncJob getAsyncJob(String jobId) { return fetch(() -> delegate.jobsV3() .get(GetJobRequest.builder() .jobId(jobId) - .build()), - ImmutableRawCloudAsyncJob::of); + .build()), ImmutableRawCloudAsyncJob::of); } private void addNonNullDockerCredentials(DockerCredentials dockerCredentials, @@ -1673,20 +1684,20 @@ private Mono> zipWithAuxiliaryServiceInstanceCon .getData() .getId(); - return getServicePlanResource(servicePlanGuid, - serviceInstanceResource.getName()).zipWhen( - servicePlan -> getServiceOffering(servicePlan.getRelationships() - .getServiceOffering() - .getData() - .getId())) - .map(tuple -> ImmutableRawCloudServiceInstance.builder() - .resource( - serviceInstanceResource) - .servicePlan( - tuple.getT1()) - .serviceOffering( - tuple.getT2()) - .build()); + return getServicePlanResource(servicePlanGuid, serviceInstanceResource.getName()).zipWhen(servicePlan -> getServiceOffering( + servicePlan.getRelationships() + .getServiceOffering() + .getData() + .getId())) + .map( + tuple -> ImmutableRawCloudServiceInstance.builder() + .resource( + serviceInstanceResource) + .servicePlan( + tuple.getT1()) + .serviceOffering( + tuple.getT2()) + .build()); } private boolean isUserProvided(ServiceInstanceResource serviceInstanceResource) { @@ -1705,8 +1716,8 @@ private Flux getServiceBindingResourcesByServi .list(pageRequestSupplier.apply(page))); } - private Mono - getServiceBindingResourceByApplicationGuidAndServiceInstanceGuid(UUID applicationGuid, UUID serviceInstanceGuid) { + private Mono getServiceBindingResourceByApplicationGuidAndServiceInstanceGuid(UUID applicationGuid, + UUID serviceInstanceGuid) { IntFunction pageRequestSupplier = page -> ListServiceBindingsRequest.builder() .applicationId( applicationGuid.toString()) @@ -1726,8 +1737,8 @@ private Flux getServiceBindingResourcesByAppli return getApplicationServiceBindingResources(pageRequestSupplier); } - private Flux - getApplicationServiceBindingResources(IntFunction pageRequestSupplier) { + private Flux getApplicationServiceBindingResources( + IntFunction pageRequestSupplier) { return PaginationUtils.requestClientV3Resources(page -> delegate.serviceBindingsV3() .list(pageRequestSupplier.apply(page))); } @@ -1909,8 +1920,7 @@ private void validateDomainForRoute(CloudRoute route, Map existing String domain = route.getDomain() .getName(); if (!StringUtils.hasLength(domain) || !existingDomains.containsKey(domain)) { - throw new CloudOperationException(HttpStatus.NOT_FOUND, - HttpStatus.NOT_FOUND.getReasonPhrase(), + throw new CloudOperationException(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), "Domain '" + domain + "' not found for URI " + route.getUrl()); } } @@ -2008,8 +2018,7 @@ private void doDeleteServiceInstance(UUID serviceInstanceGuid) { private Optional doUnbindServiceInstance(UUID applicationGuid, UUID serviceInstanceGuid) { UUID serviceBindingGuid = getServiceBindingGuid(applicationGuid, serviceInstanceGuid); if (serviceBindingGuid == null) { - throw new CloudOperationException(HttpStatus.NOT_FOUND, - "Not Found", + throw new CloudOperationException(HttpStatus.NOT_FOUND, "Not Found", "Service binding between service with GUID " + serviceInstanceGuid + " and application with GUID " + applicationGuid + " not found."); } @@ -2172,18 +2181,14 @@ protected Mono getServiceOffering(String offeringId) return delegate.serviceOfferingsV3() .get(request) .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.FORBIDDEN), - t -> new CloudOperationException(HttpStatus.FORBIDDEN, - HttpStatus.FORBIDDEN.getReasonPhrase(), + t -> new CloudOperationException(HttpStatus.FORBIDDEN, HttpStatus.FORBIDDEN.getReasonPhrase(), MessageFormat.format( - Messages.SERVICE_OFFERING_WITH_GUID_0_IS_NOT_AVAILABLE, - offeringId), + Messages.SERVICE_OFFERING_WITH_GUID_0_IS_NOT_AVAILABLE, offeringId), t)) .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.NOT_FOUND), - t -> new CloudOperationException(HttpStatus.NOT_FOUND, - HttpStatus.NOT_FOUND.getReasonPhrase(), + t -> new CloudOperationException(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), MessageFormat.format(Messages.SERVICE_OFFERING_WITH_GUID_0_NOT_FOUND, - offeringId), - t)); + offeringId), t)); } private Flux getServiceResourcesByBrokerGuid(UUID brokerGuid) { @@ -2245,18 +2250,14 @@ protected Mono getServicePlanResource(String servicePlanG return delegate.servicePlansV3() .get(request) .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.FORBIDDEN), - t -> new CloudOperationException(HttpStatus.FORBIDDEN, - HttpStatus.FORBIDDEN.getReasonPhrase(), + t -> new CloudOperationException(HttpStatus.FORBIDDEN, HttpStatus.FORBIDDEN.getReasonPhrase(), MessageFormat.format( Messages.SERVICE_PLAN_WITH_GUID_0_NOT_AVAILABLE_FOR_SERVICE_INSTANCE_1, - servicePlanGuid, serviceInstanceName), - t)) + servicePlanGuid, serviceInstanceName), t)) .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.NOT_FOUND), - t -> new CloudOperationException(HttpStatus.NOT_FOUND, - HttpStatus.NOT_FOUND.getReasonPhrase(), + t -> new CloudOperationException(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), MessageFormat.format(Messages.NO_SERVICE_PLAN_FOUND, servicePlanGuid, - serviceInstanceName), - t)); + serviceInstanceName), t)); } private Flux getServicePlanResourcesByServiceOfferingGuid(UUID serviceOfferingGuid) { @@ -2433,9 +2434,9 @@ private Map getDomainsFromRoutes(Set routes) { } private UUID getRouteGuid(UUID domainGuid, String host, String path) { - List routeEntitiesResource = getRouteResourcesByDomainGuidHostAndPath(domainGuid, host, - path).collect(Collectors.toList()) - .block(); + List routeEntitiesResource = getRouteResourcesByDomainGuidHostAndPath(domainGuid, host, path).collect( + Collectors.toList()) + .block(); if (CollectionUtils.isEmpty(routeEntitiesResource)) { return null; } diff --git a/multiapps-controller-client/src/test/java/org/cloudfoundry/multiapps/controller/client/facade/ApplicationsCloudControllerClientIntegrationTest.java b/multiapps-controller-client/src/test/java/org/cloudfoundry/multiapps/controller/client/facade/ApplicationsCloudControllerClientIntegrationTest.java index dd185a4695..a344342580 100644 --- a/multiapps-controller-client/src/test/java/org/cloudfoundry/multiapps/controller/client/facade/ApplicationsCloudControllerClientIntegrationTest.java +++ b/multiapps-controller-client/src/test/java/org/cloudfoundry/multiapps/controller/client/facade/ApplicationsCloudControllerClientIntegrationTest.java @@ -9,6 +9,8 @@ import java.util.Set; import java.util.UUID; +import org.cloudfoundry.client.v3.Metadata; +import org.cloudfoundry.client.v3.processes.HealthCheckType; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudBuild; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudMetadata; @@ -27,8 +29,6 @@ import org.cloudfoundry.multiapps.controller.client.facade.domain.Status; import org.cloudfoundry.multiapps.controller.client.facade.dto.ApplicationToCreateDto; import org.cloudfoundry.multiapps.controller.client.facade.dto.ImmutableApplicationToCreateDto; -import org.cloudfoundry.client.v3.Metadata; -import org.cloudfoundry.client.v3.processes.HealthCheckType; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; @@ -166,7 +166,8 @@ void updateApplicationHealthcheckType() { .build()) .block(); CloudProcess cloudProcess = client.getApplicationProcess(applicationGuid); - assertEquals(org.cloudfoundry.multiapps.controller.client.facade.domain.HealthCheckType.NONE, cloudProcess.getHealthCheckType()); + assertEquals(org.cloudfoundry.multiapps.controller.client.facade.domain.HealthCheckType.NONE, + cloudProcess.getHealthCheckType()); } catch (Exception e) { fail(e); } finally { @@ -298,8 +299,7 @@ void createDockerPackage() { try { verifyApplicationWillBeCreated(applicationName, ImmutableStaging.builder() .dockerInfo(dockerInfo) - .build(), - Set.of(getImmutableCloudRoute())); + .build(), Set.of(getImmutableCloudRoute())); UUID applicationGuid = client.getApplicationGuid(applicationName); CloudPackage dockerPackage = client.createDockerPackage(applicationGuid, dockerInfo); assertEquals(CloudPackage.Type.DOCKER, dockerPackage.getType()); @@ -344,8 +344,7 @@ void getPackagesForApplication() { try { verifyApplicationWillBeCreated(applicationName, ImmutableStaging.builder() .dockerInfo(dockerInfo) - .build(), - Set.of(getImmutableCloudRoute())); + .build(), Set.of(getImmutableCloudRoute())); UUID applicationGuid = client.getApplicationGuid(applicationName); CloudPackage dockerPackage = client.createDockerPackage(applicationGuid, dockerInfo); List packagesForApplication = client.getPackagesForApplication(applicationGuid); @@ -374,10 +373,9 @@ void getBuildsForApplication() { .map(CloudMetadata::getGuid) .anyMatch(buildGuid -> buildGuid.equals(build.getGuid()))); assertEquals(build.getMetadata() - .getGuid(), - client.getBuild(build.getMetadata() - .getGuid()) - .getGuid()); + .getGuid(), client.getBuild(build.getMetadata() + .getGuid()) + .getGuid()); } catch (Exception e) { fail(e); } finally { @@ -444,6 +442,22 @@ void createCnbApplication() { } } + @Test + @DisplayName("Crete application with enabled SSH and vcap-file-based services feature") + void createApplicationWithSshAndVcapFileBasedServices() { + String applicationName = "test-app-18"; + Staging staging = ImmutableStaging.builder() + .appFeatures(Map.of("file-based-vcap-services", true, "ssh", true)) + .build(); + try { + verifyApplicationWillBeCreated(applicationName, staging, Set.of(getImmutableCloudRoute())); + } catch (Exception e) { + fail(e); + } finally { + client.deleteApplication(applicationName); + } + } + private void verifyApplicationWillBeCreated(String applicationName, Staging staging, Set routes) { ApplicationToCreateDto applicationToCreateDto = ImmutableApplicationToCreateDto.builder() .name(applicationName) @@ -457,8 +471,7 @@ private void verifyApplicationWillBeCreated(String applicationName, Staging stag .name(applicationName) .state(CloudApplication.State.STOPPED) .lifecycle(createLifecycle(staging)) - .build(), - staging, routes); + .build(), staging, routes); } private static void assertApplicationExists(CloudApplication cloudApplication, Staging staging, Set routes) { @@ -473,12 +486,23 @@ private static void assertApplicationExists(CloudApplication cloudApplication, S } assertEquals(MEMORY_IN_MB, process.getMemoryInMb()); assertEquals(DISK_IN_MB, process.getDiskInMb()); + assertAppFeatures(staging, application); + } + + private static void assertAppFeatures(Staging staging, CloudApplication application) { + var appFeatures = client.getApplicationFeatures(application.getGuid()); + for (Map.Entry entry : staging.getAppFeatures() + .entrySet()) { + String featureName = entry.getKey(); + Boolean expectedValue = entry.getValue(); + Boolean actualValue = appFeatures.get(featureName); + assertEquals(expectedValue, actualValue); + } } private void createAndVerifyDefaultApplication(String applicationName) { verifyApplicationWillBeCreated(applicationName, ImmutableStaging.builder() - .build(), - Set.of(getImmutableCloudRoute())); + .build(), Set.of(getImmutableCloudRoute())); } private ImmutableCloudRoute getImmutableCloudRoute() { diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Constants.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Constants.java index e3588eb994..218c216626 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Constants.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/Constants.java @@ -34,6 +34,8 @@ public class Constants { public static final int TOKEN_SERVICE_DELETION_MAXIMUM_POOL_SIZE = 3; public static final int TOKEN_SERVICE_DELETION_KEEP_ALIVE_THREAD_IN_SECONDS = 30; + public static final String APP_FEATURE_SSH = "ssh"; + protected Constants() { } } diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/CloudHandlerFactory.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/CloudHandlerFactory.java index ea8ef10e8b..bf05b8650a 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/CloudHandlerFactory.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/CloudHandlerFactory.java @@ -20,7 +20,7 @@ import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration; import org.cloudfoundry.multiapps.controller.core.util.UserMessageLogger; import org.cloudfoundry.multiapps.controller.core.validators.parameters.ParameterValidator; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersCompatabilityValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersCompatibilityValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersValidator; import org.cloudfoundry.multiapps.controller.persistence.model.CloudTarget; import org.cloudfoundry.multiapps.controller.persistence.services.ConfigurationEntryService; @@ -65,7 +65,7 @@ LiveRoutesProvidedParametersResolver getLiveRoutesProvidedParametersResolver(Dep DescriptorParametersValidator getDescriptorParametersValidator(DeploymentDescriptor descriptor, List parameterValidators, boolean doNotCorrect); - DescriptorParametersCompatabilityValidator getDescriptorParametersCompatabilityValidator(DeploymentDescriptor descriptor, + DescriptorParametersCompatibilityValidator getDescriptorParametersCompatibilityValidator(DeploymentDescriptor descriptor, UserMessageLogger userMessageLogger); PlatformMerger getPlatformMerger(Platform platform); diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudHandlerFactoryV2.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudHandlerFactoryV2.java index 83faaf7131..08e893a010 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudHandlerFactoryV2.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudHandlerFactoryV2.java @@ -17,7 +17,7 @@ import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration; import org.cloudfoundry.multiapps.controller.core.util.UserMessageLogger; import org.cloudfoundry.multiapps.controller.core.validators.parameters.ParameterValidator; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersCompatabilityValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersCompatibilityValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersValidator; import org.cloudfoundry.multiapps.controller.persistence.model.CloudTarget; import org.cloudfoundry.multiapps.controller.persistence.services.ConfigurationEntryService; @@ -87,9 +87,9 @@ public DescriptorParametersValidator getDescriptorParametersValidator(Deployment } @Override - public DescriptorParametersCompatabilityValidator getDescriptorParametersCompatabilityValidator(DeploymentDescriptor descriptor, + public DescriptorParametersCompatibilityValidator getDescriptorParametersCompatibilityValidator(DeploymentDescriptor descriptor, UserMessageLogger userMessageLogger) { - return new DescriptorParametersCompatabilityValidator(descriptor, userMessageLogger); + return new DescriptorParametersCompatibilityValidator(descriptor, userMessageLogger); } @Override diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v3/CloudHandlerFactoryV3.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v3/CloudHandlerFactoryV3.java index 4a535123df..3d89cbffc8 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v3/CloudHandlerFactoryV3.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/cf/v3/CloudHandlerFactoryV3.java @@ -16,7 +16,7 @@ import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration; import org.cloudfoundry.multiapps.controller.core.util.UserMessageLogger; import org.cloudfoundry.multiapps.controller.core.validators.parameters.ParameterValidator; -import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersCompatabilityValidator; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersCompatibilityValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.v2.DescriptorParametersValidator; import org.cloudfoundry.multiapps.controller.persistence.model.CloudTarget; import org.cloudfoundry.multiapps.controller.persistence.services.ConfigurationEntryService; @@ -85,9 +85,9 @@ public DescriptorParametersValidator getDescriptorParametersValidator(Deployment } @Override - public DescriptorParametersCompatabilityValidator getDescriptorParametersCompatabilityValidator(DeploymentDescriptor descriptor, + public DescriptorParametersCompatibilityValidator getDescriptorParametersCompatibilityValidator(DeploymentDescriptor descriptor, UserMessageLogger userMessageLogger) { - return new DescriptorParametersCompatabilityValidator(descriptor, userMessageLogger); + return new DescriptorParametersCompatibilityValidator(descriptor, userMessageLogger); } @Override diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorMerger.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorMerger.java index a9c29e3945..b24d569c36 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorMerger.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorMerger.java @@ -43,7 +43,7 @@ public DeploymentDescriptor merge(DeploymentDescriptor deploymentDescriptor, Lis handlerFactory.getPlatformMerger(platform) .mergeInto(mergedDescriptor); - deploymentDescriptor = handlerFactory.getDescriptorParametersCompatabilityValidator(mergedDescriptor, userMessageLogger) + deploymentDescriptor = handlerFactory.getDescriptorParametersCompatibilityValidator(mergedDescriptor, userMessageLogger) .validate(); logDebug(Messages.MERGED_DESCRIPTOR, SecureSerialization.toJson(deploymentDescriptor)); diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorPropertiesResolver.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorPropertiesResolver.java index 2fd46d8749..ef806917b9 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorPropertiesResolver.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/helpers/MtaDescriptorPropertiesResolver.java @@ -13,6 +13,7 @@ import org.cloudfoundry.multiapps.controller.core.model.ResolvedConfigurationReference; import org.cloudfoundry.multiapps.controller.core.model.SupportedParameters; import org.cloudfoundry.multiapps.controller.core.util.ApplicationURI; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.AppFeaturesValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.ApplicationNameValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.DomainValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.HostValidator; @@ -45,17 +46,14 @@ public MtaDescriptorPropertiesResolver(MtaDescriptorPropertiesResolverContext co public List getValidatorsList() { return List.of(new HostValidator(), new DomainValidator(), - new RoutesValidator(context.getNamespace(), - context.applyNamespaceAppRoutesGlobalLevel(), - context.applyNamespaceAppRoutesProcessVariable(), - context.applyNamespaceAsSuffixGlobalLevel(), + new RoutesValidator(context.getNamespace(), context.applyNamespaceAppRoutesGlobalLevel(), + context.applyNamespaceAppRoutesProcessVariable(), context.applyNamespaceAsSuffixGlobalLevel(), context.applyNamespaceAsSuffixProcessVariable()), - new IdleRoutesValidator(context.getNamespace(), - context.applyNamespaceAppRoutesGlobalLevel(), + new IdleRoutesValidator(context.getNamespace(), context.applyNamespaceAppRoutesGlobalLevel(), context.applyNamespaceAppRoutesProcessVariable(), context.applyNamespaceAsSuffixGlobalLevel(), - context.applyNamespaceAsSuffixProcessVariable()), - new TasksValidator(), new VisibilityValidator(), new RestartOnEnvChangeValidator()); + context.applyNamespaceAsSuffixProcessVariable()), new TasksValidator(), + new VisibilityValidator(), new RestartOnEnvChangeValidator(), new AppFeaturesValidator()); } public DeploymentDescriptor resolve(DeploymentDescriptor descriptor) { @@ -122,16 +120,13 @@ private void unescapeEscapedReferences(DeploymentDescriptor descriptor) { } private DeploymentDescriptor correctEntityNames(DeploymentDescriptor descriptor) { - List correctors = Arrays.asList(new ApplicationNameValidator(context.getNamespace(), - context.applyNamespaceAppNamesGlobalLevel(), - context.applyNamespaceAppNamesProcessVariable(), - context.applyNamespaceAsSuffixGlobalLevel(), - context.applyNamespaceAsSuffixProcessVariable()), - new ServiceNameValidator(context.getNamespace(), - context.applyNamespaceServiceNamesGlobalLevel(), - context.applyNamespaceServiceNamesProcessVariable(), - context.applyNamespaceAsSuffixGlobalLevel(), - context.applyNamespaceAsSuffixProcessVariable())); + List correctors = Arrays.asList( + new ApplicationNameValidator(context.getNamespace(), context.applyNamespaceAppNamesGlobalLevel(), + context.applyNamespaceAppNamesProcessVariable(), context.applyNamespaceAsSuffixGlobalLevel(), + context.applyNamespaceAsSuffixProcessVariable()), + new ServiceNameValidator(context.getNamespace(), context.applyNamespaceServiceNamesGlobalLevel(), + context.applyNamespaceServiceNamesProcessVariable(), context.applyNamespaceAsSuffixGlobalLevel(), + context.applyNamespaceAsSuffixProcessVariable())); return context.getHandlerFactory() .getDescriptorParametersValidator(descriptor, correctors) .validate(); diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/model/SupportedParameters.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/model/SupportedParameters.java index 5dfc7a0654..babc772371 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/model/SupportedParameters.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/model/SupportedParameters.java @@ -80,6 +80,7 @@ public class SupportedParameters { public static final String INSTANCES = "instances"; public static final String DEFAULT_INSTANCES = "default-instances"; public static final String ENABLE_SSH = "enable-ssh"; + public static final String APP_FEATURES = "app-features"; public static final String NO_HOSTNAME = "no-hostname"; public static final String NO_ROUTE = "no-route"; public static final String ROUTE_PROTOCOL = "protocol"; @@ -199,7 +200,7 @@ public class SupportedParameters { REGISTER_SERVICE_URL, REGISTER_SERVICE_URL_SERVICE_NAME, REGISTER_SERVICE_URL_SERVICE_URL, MODULE_CONFIG, MANAGED, PATH, APPS_UPLOAD_TIMEOUT, APPS_TASK_EXECUTION_TIMEOUT, APPS_START_TIMEOUT, - APPS_STAGE_TIMEOUT, SKIP_DEPLOY); + APPS_STAGE_TIMEOUT, SKIP_DEPLOY, APP_FEATURES); public static final Set RESOURCE_PARAMETERS = Set.of(APPLY_NAMESPACE, SERVICE_CONFIG, SYSLOG_DRAIN_URL, DEFAULT_CONTAINER_NAME, DEFAULT_SERVICE_NAME, DEFAULT_XS_APP_NAME, SERVICE, SERVICE_KEYS, diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParser.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParser.java index 43f2b334ea..a5c2ddf924 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParser.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParser.java @@ -1,10 +1,13 @@ package org.cloudfoundry.multiapps.controller.core.parser; import java.text.MessageFormat; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.cloudfoundry.multiapps.common.ContentException; +import org.cloudfoundry.multiapps.controller.core.Constants; import org.cloudfoundry.multiapps.controller.client.facade.domain.DockerInfo; import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableStaging; import org.cloudfoundry.multiapps.controller.client.facade.domain.LifecycleType; @@ -39,6 +42,8 @@ public Staging parse(List> parametersList) { SupportedParameters.HEALTH_CHECK_HTTP_ENDPOINT, getDefaultHealthCheckHttpEndpoint(healthCheckType)); Boolean isSshEnabled = (Boolean) PropertiesUtil.getPropertyValue(parametersList, SupportedParameters.ENABLE_SSH, null); + Map appFeatures = getAppFeatures(parametersList); + overrideSshFeatureIfMissing(appFeatures, isSshEnabled); DockerInfo dockerInfo = new DockerInfoParser().parse(parametersList); LifecycleType lifecycleType = parseLifecycleType(parametersList); @@ -53,11 +58,24 @@ public Staging parse(List> parametersList) { .healthCheckType(healthCheckType) .healthCheckHttpEndpoint(healthCheckHttpEndpoint) .isSshEnabled(isSshEnabled) + .appFeatures(appFeatures) .dockerInfo(dockerInfo) .lifecycleType(lifecycleType) .build(); } + @SuppressWarnings("unchecked") + private Map getAppFeatures(List> parametersList) { + return new HashMap<>((Map) PropertiesUtil.getPropertyValue(parametersList, SupportedParameters.APP_FEATURES, + Collections.emptyMap())); + } + + private void overrideSshFeatureIfMissing(Map appFeatures, Boolean isSshEnabled) { + if (isSshEnabled != null && !appFeatures.containsKey(Constants.APP_FEATURE_SSH)) { + appFeatures.put(Constants.APP_FEATURE_SSH, isSshEnabled); + } + } + private LifecycleType parseLifecycleType(List> parametersList) { String lifecycleValue = (String) PropertiesUtil.getPropertyValue(parametersList, SupportedParameters.LIFECYCLE, null); if (lifecycleValue == null) { @@ -99,8 +117,7 @@ private void validateBuildpacksWithDocker(LifecycleType lifecycleType, List parameters; + + public AppFeaturesCompatibilityValidator(Map parameters) { + this.parameters = parameters; + } + + @Override + public boolean isCompatible(String parameter) { + if (getIncompatibleParameters().contains(parameter)) { + Object appFeaturesObj = parameters.get(SupportedParameters.APP_FEATURES); + if (appFeaturesObj instanceof Map appFeatures) { + return !appFeatures.containsKey(Constants.APP_FEATURE_SSH); + } + } + return true; + } + + @Override + public String getParameterName() { + return SupportedParameters.APP_FEATURES; + } + + @Override + public List getIncompatibleParameters() { + return List.of(SupportedParameters.ENABLE_SSH); + } +} diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/AppFeaturesValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/AppFeaturesValidator.java new file mode 100644 index 0000000000..b79eaa2a6d --- /dev/null +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/AppFeaturesValidator.java @@ -0,0 +1,31 @@ +package org.cloudfoundry.multiapps.controller.core.validators.parameters; + +import java.util.Map; + +import org.cloudfoundry.multiapps.common.util.MiscUtil; +import org.cloudfoundry.multiapps.controller.core.model.SupportedParameters; +import org.cloudfoundry.multiapps.mta.model.Module; + +public class AppFeaturesValidator implements ParameterValidator { + + @Override + public boolean isValid(Object appFeaturesParameter, Map relatedParameters) { + if (!(appFeaturesParameter instanceof Map)) { + return false; + } + Map appFeatures = MiscUtil.cast(appFeaturesParameter); + return appFeatures.values() + .stream() + .allMatch(Boolean.class::isInstance); + } + + @Override + public String getParameterName() { + return SupportedParameters.APP_FEATURES; + } + + @Override + public Class getContainerType() { + return Module.class; + } +} diff --git a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidator.java b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidator.java index 72166d06ca..1e8019df45 100644 --- a/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidator.java +++ b/multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidator.java @@ -8,6 +8,7 @@ import org.cloudfoundry.multiapps.controller.core.Messages; import org.cloudfoundry.multiapps.controller.core.util.UserMessageLogger; +import org.cloudfoundry.multiapps.controller.core.validators.parameters.AppFeaturesCompatibilityValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatibilityParameterValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.CompatibilityParametersValidator; import org.cloudfoundry.multiapps.controller.core.validators.parameters.IdleRoutesCompatibilityValidator; @@ -31,7 +32,8 @@ public Module validate() { } private List getModuleValidators() { - return Arrays.asList(new RoutesCompatibilityValidator(), new IdleRoutesCompatibilityValidator()); + return Arrays.asList(new RoutesCompatibilityValidator(), new IdleRoutesCompatibilityValidator(), + new AppFeaturesCompatibilityValidator(module.getParameters())); } private void checkParametersCompatibility(Map parameters, List moduleValidators) { diff --git a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudModelBuilderTest.java b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudModelBuilderTest.java index 028496b488..8661cc3a15 100644 --- a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudModelBuilderTest.java +++ b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/cf/v2/CloudModelBuilderTest.java @@ -53,6 +53,28 @@ public class CloudModelBuilderTest { protected static final String DEFAULT_DOMAIN_XS = "sofd60245639a"; protected static final AppSuffixDeterminer DEFAULT_APP_SUFFIX_DETERMINER = new AppSuffixDeterminer(false, false); protected static final String DEPLOY_ID = "123"; + // Constants for mtaArchiveModules, mtaModules, and deployedApps + private static final String JAVA_HELLO_WORLD = "java-hello-world"; + private static final String JAVA_HELLO_WORLD_DB = "java-hello-world-db"; + private static final String JAVA_HELLO_WORLD_BACKEND = "java-hello-world-backend"; + private static final String SHINE = "shine"; + private static final String SHINE_XSJS = "shine-xsjs"; + private static final String SHINE_ODATA = "shine-odata"; + private static final String PRICING = "pricing"; + private static final String PRICING_DB = "pricing-db"; + private static final String WEB_SERVER = "web-server"; + private static final String WEBIDE = "webide"; + private static final String DI_CORE = "di-core"; + private static final String DI_BUILDER = "di-builder"; + private static final String DI_RUNNER = "di-runner"; + private static final String FOO = "foo"; + private static final String MODULE_1 = "module-1"; + private static final String MODULE_2 = "module-2"; + private static final String MODULE_3 = "module-3"; + private static final String MODULE_4 = "module-4"; + private static final String FRAMEWORK = "framework"; + private static final String FEATURE_APP = "feature-app"; + private static final String SKIP_DEPLOY_APP = "skip-deploy-app"; protected final Tester tester = Tester.forClass(getClass()); protected final DescriptorParser descriptorParser = getDescriptorParser(); @@ -75,398 +97,428 @@ public class CloudModelBuilderTest { private static Stream getParameters() { return Stream.of( // @formatter:off - // (01) Full MTA: - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", - "/mta/cf-platform.json", null, null, false, - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services.json"), - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (02) - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/xs2-config.mtaext", - "/mta/xs-platform.json", null, null, false, - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/xs2-services.json"), - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/xs2-apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (03) Full MTA with namespace: - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", - "/mta/cf-platform.json", null, "namespace1", true, - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-ns-1.json"), - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-ns-1.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (04) Full MTA with long namespace: - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", - "/mta/cf-platform.json", null, "namespace2-but-it-is-really-really-long", true, - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-ns-2.json"), - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-ns-2.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (05) Patch MTA (resolved inter-module dependencies): - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", - "/mta/cf-platform.json", null, null, false, new String[] { "java-hello-world" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-patch.json"), - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-patch.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (06) Patch MTA with namespaces (resolved inter-module dependencies): - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", - "/mta/cf-platform.json", null, "namespace", true, new String[] { "java-hello-world" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-patch-ns.json"), - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-patch-ns.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (07) Patch MTA (unresolved inter-module dependencies): - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", - "/mta/cf-platform.json", null, null, false, new String[] { "java-hello-world" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] { "java-hello-world", }, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-patch.json"), - new Expectation(Expectation.Type.EXCEPTION, - "Unresolved MTA modules [java-hello-world-backend, java-hello-world-db]"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (08) - Arguments.of("/mta/shine/mtad.yaml", "/mta/shine/config.mtaext", "/mta/cf-platform.json", null, null, - false, new String[] { "shine", "shine-xsjs", "shine-odata" }, // mtaArchiveModules - new String[] { "shine", "shine-xsjs", "shine-odata" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/shine/services.json"), - new Expectation(Expectation.Type.JSON, "/mta/shine/apps.json"), DEFAULT_APP_SUFFIX_DETERMINER), - // (09) - Arguments.of("/mta/sample/mtad.yaml", "/mta/sample/config.mtaext", "/mta/sample/platform.json", null, - null, false, new String[] { "pricing", "pricing-db", "web-server" }, // mtaArchiveModules - new String[] { "pricing", "pricing-db", "web-server" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/sample/services.json"), - new Expectation(Expectation.Type.JSON, "/mta/sample/apps.json"), DEFAULT_APP_SUFFIX_DETERMINER), - // (10) - Arguments.of("/mta/devxwebide/mtad.yaml", "/mta/devxwebide/config.mtaext", "/mta/cf-platform.json", - null, null, false, new String[] { "webide" }, // mtaArchiveModules - new String[] { "webide" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/devxwebide/services.json"), - new Expectation(Expectation.Type.JSON, "/mta/devxwebide/apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (11) - Arguments.of("/mta/devxwebide/mtad.yaml", "/mta/devxwebide/xs2-config-1.mtaext", - "/mta/xs-platform.json", null, null, false, new String[] { "webide" }, // mtaArchiveModules - new String[] { "webide" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/devxwebide/services.json"), - new Expectation(Expectation.Type.JSON, "/mta/devxwebide/xs2-apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (12) - Arguments.of("/mta/devxdi/mtad.yaml", "/mta/devxdi/config.mtaext", "/mta/cf-platform.json", null, null, - false, new String[] { "di-core", "di-builder", "di-runner" }, // mtaArchiveModules - new String[] { "di-core", "di-builder", "di-runner" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/devxdi/services.json"), - new Expectation(Expectation.Type.JSON, "/mta/devxdi/apps.json"), DEFAULT_APP_SUFFIX_DETERMINER), - // (13) - Arguments.of("/mta/devxdi/mtad.yaml", "/mta/devxdi/xs2-config-1.mtaext", "/mta/xs-platform.json", null, - null, false, new String[] { "di-core", "di-builder", "di-runner" }, // mtaArchiveModules - new String[] { "di-core", "di-builder", "di-runner" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-services.json"), - new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (14) - Arguments.of("/mta/devxwebide/mtad.yaml", "/mta/devxwebide/xs2-config-2.mtaext", - "/mta/xs-platform.json", null, null, false, new String[] { "webide" }, // mtaArchiveModules - new String[] { "webide" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/devxwebide/services.json"), - new Expectation(Expectation.Type.JSON, "/mta/devxwebide/xs2-apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (15) Unknown typed resource parameters: - Arguments.of("/mta/devxdi/mtad.yaml", "/mta/devxdi/xs2-config-2.mtaext", "/mta/xs-platform.json", null, - null, false, new String[] { "di-core", "di-builder", "di-runner" }, // mtaArchiveModules - new String[] { "di-core", "di-builder", "di-runner" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-services.json"), - new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (16) Service binding parameters in requires dependency: - Arguments.of("mtad-01.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, - new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-01.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (17) Service binding parameters in requires dependency: - Arguments.of("mtad-02.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, - new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.EXCEPTION, - "Invalid type for key \"foo#bar#config\", expected \"Map\" but got \"String\""), - DEFAULT_APP_SUFFIX_DETERMINER), - // (18) Custom application names are used: - Arguments.of("mtad-03.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, - new String[] { "module-1", "module-2" }, // mtaArchiveModules - new String[] { "module-1", "module-2" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-02.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (19) Custom application names are used: - Arguments.of("mtad-03.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, "something", true, - new String[] { "module-1", "module-2" }, // mtaArchiveModules - new String[] { "module-1", "module-2" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-03.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (20) Temporary URIs are used: - Arguments.of("mtad-05.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, - new String[] { "module-1", "module-2" }, // mtaArchiveModules - new String[] { "module-1", "module-2" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-05.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (21) Use list parameter: - Arguments.of("mtad-06.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, - new String[] { "framework" }, // mtaArchiveModules - new String[] { "framework" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-06.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (22) Use partial plugin: - Arguments.of("mtad-07.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, - new String[] { "framework" }, // mtaArchiveModules - new String[] { "framework" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-07.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (23) Overwrite service-name resource property in ext. descriptor: - Arguments.of("mtad-08.yaml", "config-03.mtaext", "/mta/xs-platform.json", null, null, false, - new String[] { "module-1" }, // mtaArchiveModules - new String[] { "module-1" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "services-03.json"), - new Expectation(Expectation.Type.JSON, "apps-08.json"), DEFAULT_APP_SUFFIX_DETERMINER), - // (24) Test support for one-off tasks: - Arguments.of("mtad-09.yaml", "config-03.mtaext", "/mta/xs-platform.json", null, null, false, - new String[] { "module-1", "module-2", "module-3", "module-4" }, // mtaArchiveModules - new String[] { "module-1", "module-2", "module-3", "module-4" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-09.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (25) With 'health-check-type' set to 'port': - Arguments.of("mtad-health-check-type-port.yaml", "config-03.mtaext", "/mta/xs-platform.json", null, - null, false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "apps-with-health-check-type-port.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (26) With 'health-check-type' set to 'http' and a non-default - // 'health-check-http-endpoint': - Arguments.of("mtad-health-check-type-http-with-endpoint.yaml", "config-03.mtaext", - "/mta/xs-platform.json", null, null, false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "apps-with-health-check-type-http-with-endpoint.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (27) With 'health-check-type' set to 'http' and no - // 'health-check-http-endpoint': - Arguments.of("mtad-health-check-type-http-without-endpoint.yaml", "config-03.mtaext", - "/mta/xs-platform.json", null, null, false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, - "apps-with-health-check-type-http-without-endpoint.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (28) Test inject service keys: - Arguments.of("mtad-10.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, - new String[] { "module-1" }, // mtaArchiveModules - new String[] { "module-1" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-10.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (29) With 'enable-ssh' set to true: - Arguments.of("mtad-ssh-enabled-true.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, - false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "apps-with-ssh-enabled-true.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (30) With 'enable-ssh' set to false: - Arguments.of("mtad-ssh-enabled-false.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, - false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "apps-with-ssh-enabled-false.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (31) Do not restart on env change - bg-deploy - Arguments.of("mtad-restart-on-env-change.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, - false, new String[] { "module-1", "module-2", "module-3" }, // mtaArchiveModules - new String[] { "module-1", "module-2", "module-3" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "apps-with-restart-parameters-false.json") // services - , DEFAULT_APP_SUFFIX_DETERMINER), - // (32) With 'keep-existing-routes' set to true and no deployed MTA: - Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, - false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (33) With 'keep-existing-routes' set to true and no deployed module: - Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", - "keep-existing-routes/deployed-mta-without-foo-module.json", null, false, - new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (34) With 'keep-existing-routes' set to true and an already deployed module - // with no URIs: - Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", - "keep-existing-routes/deployed-mta-without-routes.json", null, false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (35) With 'keep-existing-routes' set to true and an already deployed module: - Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", - "keep-existing-routes/deployed-mta.json", null, false, new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps-with-existing-routes.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (36) With global 'keep-existing-routes' set to true and an already deployed - // module: - Arguments.of("keep-existing-routes/mtad-with-global-parameter.yaml", "config-02.mtaext", - "/mta/xs-platform.json", "keep-existing-routes/deployed-mta.json", null, false, - new String[] { "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps-with-existing-routes.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (37) With new parameter - 'route' - Arguments.of("mtad-12.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, - new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // services - new Expectation(Expectation.Type.JSON, "apps-12.json") // applications - , DEFAULT_APP_SUFFIX_DETERMINER), - // (38) With new parameter - 'routes' - Arguments.of("mtad-13.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, - new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // services - new Expectation(Expectation.Type.JSON, "apps-13.json") // applications - , DEFAULT_APP_SUFFIX_DETERMINER), - // (39) Test plural priority over singular for hosts and domains - Arguments.of("mtad-14.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, - new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // services - new Expectation(Expectation.Type.JSON, "apps-14.json") // applications - , DEFAULT_APP_SUFFIX_DETERMINER), - // (40) Test multiple buildpacks functionality - Arguments.of("mtad-15.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, - new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // services - new Expectation(Expectation.Type.JSON, "apps-15.json") // applications - , DEFAULT_APP_SUFFIX_DETERMINER), - // (41) Full MTA with namespace, global apply flag set to false: - Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", - "/mta/cf-platform.json", null, "namespace3", false, - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaArchiveModules - new String[] { "java-hello-world", "java-hello-world-db", "java-hello-world-backend" }, // mtaModules - new String[] {}, // deployedApps - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-ns-3.json"), - new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-ns-3.json"), - DEFAULT_APP_SUFFIX_DETERMINER), - // (42) Test app-name parameter resolution: - Arguments.of("mtad-16.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, - new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // services - new Expectation(Expectation.Type.JSON, "apps-16.json") // applications - , new AppSuffixDeterminer(true, true)), - // (43) With hostless routes - Arguments.of("mtad-routes-with-nohostname.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, - null, false, new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // services - new Expectation(Expectation.Type.JSON, "apps-with-nohostname.json") // applications - , DEFAULT_APP_SUFFIX_DETERMINER), - // (44) With hostless routes and existing mta - Arguments.of("keep-existing-routes/mtad-routes-with-nohostname.yaml", "config-01.mtaext", "/mta/cf-platform.json", - "keep-existing-routes/deployed-mta.json", null, false, new String[] { "foo", }, // mtaArchiveModules - new String[] { "foo", }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // services - new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps-with-nohostname.json") // applications - , DEFAULT_APP_SUFFIX_DETERMINER), - // (45) Test skip-deploy 1 of 2 modules - Arguments.of("/mta/skip-deploy/mtad-skip-deploy-true.yaml", "config-01.mtaext", "/mta/cf-platform.json", - null, // deployedMtaLocation - null, // namespace - false, // applyNamespace - new String[] { "skip-deploy-app", "foo" }, // mtaArchiveModules - new String[] { "foo" }, // mtaModules - new String[] {}, // deployedApps - new Expectation("[]"), // expectedServices - new Expectation(Expectation.Type.JSON, "/mta/skip-deploy/apps-skip-deploy-true.json"), // expectedApps (should contain only foo) - DEFAULT_APP_SUFFIX_DETERMINER), - // (46) Test skip-deploy module parameter with string "true" - Arguments.of( - "/mta/skip-deploy/mtad-skip-deploy-string-true.yaml", - "config-01.mtaext", - "/mta/cf-platform.json", - null, - null, - false, - new String[] { "skip-deploy-app", "foo" }, - new String[] { "foo" }, - new String[] {}, - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "/mta/skip-deploy/apps-skip-deploy-true.json"), - DEFAULT_APP_SUFFIX_DETERMINER - ), - // (47) Test skip-deploy module parameter with false - Arguments.of( - "/mta/skip-deploy/mtad-skip-deploy-false.yaml", - "config-01.mtaext", - "/mta/cf-platform.json", - null, - null, - false, - new String[] { "skip-deploy-app", "foo" }, - new String[] { "skip-deploy-app", "foo" }, - new String[] {}, - new Expectation("[]"), - new Expectation(Expectation.Type.JSON, "/mta/skip-deploy/apps-skip-deploy-false.json"), - DEFAULT_APP_SUFFIX_DETERMINER - ) + // (01) Full MTA: + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", + "/mta/cf-platform.json", null, null, false, + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services.json"), + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (02) + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/xs2-config.mtaext", + "/mta/xs-platform.json", null, null, false, + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/xs2-services.json"), + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/xs2-apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (03) Full MTA with namespace: + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", + "/mta/cf-platform.json", null, "namespace1", true, + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-ns-1.json"), + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-ns-1.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (04) Full MTA with long namespace: + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", + "/mta/cf-platform.json", null, "namespace2-but-it-is-really-really-long", true, + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-ns-2.json"), + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-ns-2.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (05) Patch MTA (resolved inter-module dependencies): + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", + "/mta/cf-platform.json", null, null, false, new String[] { JAVA_HELLO_WORLD }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-patch.json"), + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-patch.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (06) Patch MTA with namespaces (resolved inter-module dependencies): + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", + "/mta/cf-platform.json", null, "namespace", true, new String[] { JAVA_HELLO_WORLD }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-patch-ns.json"), + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-patch-ns.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (07) Patch MTA (unresolved inter-module dependencies): + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", + "/mta/cf-platform.json", null, null, false, new String[] { JAVA_HELLO_WORLD }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] { JAVA_HELLO_WORLD }, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-patch.json"), + new Expectation(Expectation.Type.EXCEPTION, + "Unresolved MTA modules [java-hello-world-backend, java-hello-world-db]"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (08) + Arguments.of("/mta/shine/mtad.yaml", "/mta/shine/config.mtaext", "/mta/cf-platform.json", null, null, + false, new String[] { SHINE, SHINE_XSJS, SHINE_ODATA }, // mtaArchiveModules + new String[] { SHINE, SHINE_XSJS, SHINE_ODATA }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/shine/services.json"), + new Expectation(Expectation.Type.JSON, "/mta/shine/apps.json"), DEFAULT_APP_SUFFIX_DETERMINER), + // (09) + Arguments.of("/mta/sample/mtad.yaml", "/mta/sample/config.mtaext", "/mta/sample/platform.json", null, + null, false, new String[] { PRICING, PRICING_DB, WEB_SERVER }, // mtaArchiveModules + new String[] { PRICING, PRICING_DB, WEB_SERVER }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/sample/services.json"), + new Expectation(Expectation.Type.JSON, "/mta/sample/apps.json"), DEFAULT_APP_SUFFIX_DETERMINER), + // (10) + Arguments.of("/mta/devxwebide/mtad.yaml", "/mta/devxwebide/config.mtaext", "/mta/cf-platform.json", + null, null, false, new String[] { WEBIDE }, // mtaArchiveModules + new String[] { WEBIDE }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/devxwebide/services.json"), + new Expectation(Expectation.Type.JSON, "/mta/devxwebide/apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (11) + Arguments.of("/mta/devxwebide/mtad.yaml", "/mta/devxwebide/xs2-config-1.mtaext", + "/mta/xs-platform.json", null, null, false, new String[] { WEBIDE }, // mtaArchiveModules + new String[] { WEBIDE }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/devxwebide/services.json"), + new Expectation(Expectation.Type.JSON, "/mta/devxwebide/xs2-apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (12) + Arguments.of("/mta/devxdi/mtad.yaml", "/mta/devxdi/config.mtaext", "/mta/cf-platform.json", null, null, + false, new String[] { DI_CORE, DI_BUILDER, DI_RUNNER }, // mtaArchiveModules + new String[] { DI_CORE, DI_BUILDER, DI_RUNNER }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/devxdi/services.json"), + new Expectation(Expectation.Type.JSON, "/mta/devxdi/apps.json"), DEFAULT_APP_SUFFIX_DETERMINER), + // (13) + Arguments.of("/mta/devxdi/mtad.yaml", "/mta/devxdi/xs2-config-1.mtaext", "/mta/xs-platform.json", null, + null, false, new String[] { DI_CORE, DI_BUILDER, DI_RUNNER }, // mtaArchiveModules + new String[] { DI_CORE, DI_BUILDER, DI_RUNNER }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-services.json"), + new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (14) + Arguments.of("/mta/devxwebide/mtad.yaml", "/mta/devxwebide/xs2-config-2.mtaext", + "/mta/xs-platform.json", null, null, false, new String[] { WEBIDE }, // mtaArchiveModules + new String[] { WEBIDE }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/devxwebide/services.json"), + new Expectation(Expectation.Type.JSON, "/mta/devxwebide/xs2-apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (15) Unknown typed resource parameters: + Arguments.of("/mta/devxdi/mtad.yaml", "/mta/devxdi/xs2-config-2.mtaext", "/mta/xs-platform.json", null, + null, false, new String[] { DI_CORE, DI_BUILDER, DI_RUNNER }, // mtaArchiveModules + new String[] { DI_CORE, DI_BUILDER, DI_RUNNER }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-services.json"), + new Expectation(Expectation.Type.JSON, "/mta/devxdi/xs2-apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (16) Service binding parameters in requires dependency: + Arguments.of("mtad-01.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-01.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (17) Service binding parameters in requires dependency: + Arguments.of("mtad-02.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.EXCEPTION, + "Invalid type for key \"foo#bar#config\", expected \"Map\" but got \"String\""), + DEFAULT_APP_SUFFIX_DETERMINER), + // (18) Custom application names are used: + Arguments.of("mtad-03.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, + new String[] { MODULE_1, MODULE_2 }, // mtaArchiveModules + new String[] { MODULE_1, MODULE_2 }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-02.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (19) Custom application names are used: + Arguments.of("mtad-03.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, "something", true, + new String[] { MODULE_1, MODULE_2 }, // mtaArchiveModules + new String[] { MODULE_1, MODULE_2 }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-03.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (20) Temporary URIs are used: + Arguments.of("mtad-05.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, + new String[] { MODULE_1, MODULE_2 }, // mtaArchiveModules + new String[] { MODULE_1, MODULE_2 }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-05.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (21) Use list parameter: + Arguments.of("mtad-06.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, + new String[] { FRAMEWORK }, // mtaArchiveModules + new String[] { FRAMEWORK }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-06.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (22) Use partial plugin: + Arguments.of("mtad-07.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, + new String[] { FRAMEWORK }, // mtaArchiveModules + new String[] { FRAMEWORK }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-07.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (23) Overwrite service-name resource property in ext. descriptor: + Arguments.of("mtad-08.yaml", "config-03.mtaext", "/mta/xs-platform.json", null, null, false, + new String[] { MODULE_1 }, // mtaArchiveModules + new String[] { MODULE_1 }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "services-03.json"), + new Expectation(Expectation.Type.JSON, "apps-08.json"), DEFAULT_APP_SUFFIX_DETERMINER), + // (24) Test support for one-off tasks: + Arguments.of("mtad-09.yaml", "config-03.mtaext", "/mta/xs-platform.json", null, null, false, + new String[] { MODULE_1, MODULE_2, MODULE_3, MODULE_4 }, // mtaArchiveModules + new String[] { MODULE_1, MODULE_2, MODULE_3, MODULE_4 }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-09.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (25) With 'health-check-type' set to 'port': + Arguments.of("mtad-health-check-type-port.yaml", "config-03.mtaext", "/mta/xs-platform.json", null, + null, false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "apps-with-health-check-type-port.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (26) With 'health-check-type' set to 'http' and a non-default + // 'health-check-http-endpoint': + Arguments.of("mtad-health-check-type-http-with-endpoint.yaml", "config-03.mtaext", + "/mta/xs-platform.json", null, null, false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "apps-with-health-check-type-http-with-endpoint.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (27) With 'health-check-type' set to 'http' and no + // 'health-check-http-endpoint': + Arguments.of("mtad-health-check-type-http-without-endpoint.yaml", "config-03.mtaext", + "/mta/xs-platform.json", null, null, false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, + "apps-with-health-check-type-http-without-endpoint.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (28) Test inject service keys: + Arguments.of("mtad-10.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, false, + new String[] { MODULE_1 }, // mtaArchiveModules + new String[] { MODULE_1 }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "apps-10.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (29) With 'enable-ssh' set to true: + Arguments.of("mtad-ssh-enabled-true.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, + false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "apps-with-ssh-enabled-true.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (30) With 'enable-ssh' set to false: + Arguments.of("mtad-ssh-enabled-false.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, + false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "apps-with-ssh-enabled-false.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (31) Do not restart on env change - bg-deploy + Arguments.of("mtad-restart-on-env-change.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, + false, new String[] { MODULE_1, MODULE_2, MODULE_3 }, // mtaArchiveModules + new String[] { MODULE_1, MODULE_2, MODULE_3 }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "apps-with-restart-parameters-false.json") // services + , DEFAULT_APP_SUFFIX_DETERMINER), + // (32) With 'keep-existing-routes' set to true and no deployed MTA: + Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", null, null, + false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (33) With 'keep-existing-routes' set to true and no deployed module: + Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", + "keep-existing-routes/deployed-mta-without-foo-module.json", null, false, + new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (34) With 'keep-existing-routes' set to true and an already deployed module + // with no URIs: + Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", + "keep-existing-routes/deployed-mta-without-routes.json", null, false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (35) With 'keep-existing-routes' set to true and an already deployed module: + Arguments.of("keep-existing-routes/mtad.yaml", "config-02.mtaext", "/mta/xs-platform.json", + "keep-existing-routes/deployed-mta.json", null, false, new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps-with-existing-routes.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (36) With global 'keep-existing-routes' set to true and an already deployed + // module: + Arguments.of("keep-existing-routes/mtad-with-global-parameter.yaml", "config-02.mtaext", + "/mta/xs-platform.json", "keep-existing-routes/deployed-mta.json", null, false, + new String[] { FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps-with-existing-routes.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (37) With new parameter - 'route' + Arguments.of("mtad-12.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "apps-12.json") // applications + , DEFAULT_APP_SUFFIX_DETERMINER), + // (38) With new parameter - 'routes' + Arguments.of("mtad-13.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "apps-13.json") // applications + , DEFAULT_APP_SUFFIX_DETERMINER), + // (39) Test plural priority over singular for hosts and domains + Arguments.of("mtad-14.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "apps-14.json") // applications + , DEFAULT_APP_SUFFIX_DETERMINER), + // (40) Test multiple buildpacks functionality + Arguments.of("mtad-15.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "apps-15.json") // applications + , DEFAULT_APP_SUFFIX_DETERMINER), + // (41) Full MTA with namespace, global apply flag set to false: + Arguments.of("/mta/javahelloworld/mtad.yaml", "/mta/javahelloworld/config.mtaext", + "/mta/cf-platform.json", null, "namespace3", false, + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaArchiveModules + new String[] { JAVA_HELLO_WORLD, JAVA_HELLO_WORLD_DB, JAVA_HELLO_WORLD_BACKEND }, // mtaModules + new String[] {}, // deployedApps + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/services-ns-3.json"), + new Expectation(Expectation.Type.JSON, "/mta/javahelloworld/apps-ns-3.json"), + DEFAULT_APP_SUFFIX_DETERMINER), + // (42) Test app-name parameter resolution: + Arguments.of("mtad-16.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "apps-16.json") // applications + , new AppSuffixDeterminer(true, true)), + // (43) With hostless routes + Arguments.of("mtad-routes-with-nohostname.yaml", "config-01.mtaext", "/mta/cf-platform.json", null, + null, false, new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "apps-with-nohostname.json") // applications + , DEFAULT_APP_SUFFIX_DETERMINER), + // (44) With hostless routes and existing mta + Arguments.of("keep-existing-routes/mtad-routes-with-nohostname.yaml", "config-01.mtaext", "/mta/cf-platform.json", + "keep-existing-routes/deployed-mta.json", null, false, new String[] { FOO, }, // mtaArchiveModules + new String[] { FOO, }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "keep-existing-routes/apps-with-nohostname.json") // applications + , DEFAULT_APP_SUFFIX_DETERMINER), + // (45) Test skip-deploy 1 of 2 modules + Arguments.of("/mta/skip-deploy/mtad-skip-deploy-true.yaml", "config-01.mtaext", "/mta/cf-platform.json", + null, // deployedMtaLocation + null, // namespace + false, // applyNamespace + new String[] { SKIP_DEPLOY_APP, FOO }, // mtaArchiveModules + new String[] { FOO }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // expectedServices + new Expectation(Expectation.Type.JSON, "/mta/skip-deploy/apps-skip-deploy-true.json"), // expectedApps (should contain only foo) + DEFAULT_APP_SUFFIX_DETERMINER), + // (46) Test skip-deploy module parameter with string "true" + Arguments.of( + "/mta/skip-deploy/mtad-skip-deploy-string-true.yaml", + "config-01.mtaext", + "/mta/cf-platform.json", + null, + null, + false, + new String[] { SKIP_DEPLOY_APP, FOO }, + new String[] { FOO }, + new String[] {}, + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "/mta/skip-deploy/apps-skip-deploy-true.json"), + DEFAULT_APP_SUFFIX_DETERMINER + ), + // (47) Test skip-deploy module parameter with false + Arguments.of( + "/mta/skip-deploy/mtad-skip-deploy-false.yaml", + "config-01.mtaext", + "/mta/cf-platform.json", + null, + null, + false, + new String[] { SKIP_DEPLOY_APP, FOO }, + new String[] { SKIP_DEPLOY_APP, FOO }, + new String[] {}, + new Expectation("[]"), + new Expectation(Expectation.Type.JSON, "/mta/skip-deploy/apps-skip-deploy-false.json"), + DEFAULT_APP_SUFFIX_DETERMINER + ), + // (48) app-features parameter with multiple features enabled/disabled + Arguments.of( + "/mta/app-features/mtad-app-features.yaml", "/mta/app-features/config-app-features.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FEATURE_APP }, // mtaArchiveModules + new String[] { FEATURE_APP }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "/mta/app-features/apps-app-features.json"), // applications + DEFAULT_APP_SUFFIX_DETERMINER + ), + // (49) app-features parameter with empty map + Arguments.of( + "/mta/app-features/mtad-app-features-empty.yaml", "/mta/app-features/config-app-features.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FEATURE_APP }, // mtaArchiveModules + new String[] { FEATURE_APP }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "/mta/app-features/apps-app-features-empty.json"), // applications + DEFAULT_APP_SUFFIX_DETERMINER + ), + // (50) app-features parameter with only one feature enabled + Arguments.of( + "/mta/app-features/mtad-app-features-single.yaml", "/mta/app-features/config-app-features.mtaext", "/mta/cf-platform.json", null, null, false, + new String[] { FEATURE_APP }, // mtaArchiveModules + new String[] { FEATURE_APP }, // mtaModules + new String[] {}, // deployedApps + new Expectation("[]"), // services + new Expectation(Expectation.Type.JSON, "/mta/app-features/apps-app-features-single.json"), // applications + DEFAULT_APP_SUFFIX_DETERMINER + ) // @formatter:on ); } @@ -672,4 +724,4 @@ private ModulesCloudModelBuilderContentCalculator getModulesCalculator(Set testIsValid() { + return Stream.of( + // (1) All features are boolean + Arguments.of(Map.of(FEATURE_A, true, FEATURE_B, false), true), + // (2) Some features are not boolean + Arguments.of(Map.of(FEATURE_A, true, FEATURE_B, "notBoolean"), false), + // (3) Empty map is valid + Arguments.of(Map.of(), true), + // (4) null object is invalid + Arguments.of(null, false), + // (5) Non-map object is invalid + Arguments.of("notAMap", false)); + } + + @ParameterizedTest + @MethodSource + void testIsValid(Object parameters, boolean expected) { + assertEquals(expected, validator.isValid(parameters, null)); + } + + @Test + void testGetParameterName() { + assertEquals(SupportedParameters.APP_FEATURES, validator.getParameterName()); + } + + @Test + void testGetContainerType() { + assertEquals(Module.class, validator.getContainerType()); + } + +} diff --git a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java index 2573b8ef6f..ce2ea163b2 100644 --- a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java +++ b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/validators/parameters/v2/ModuleParametersCompatibilityValidatorTest.java @@ -1,8 +1,8 @@ package org.cloudfoundry.multiapps.controller.core.validators.parameters.v2; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.cloudfoundry.multiapps.controller.core.model.SupportedParameters; @@ -37,22 +37,23 @@ static Stream testModuleParametersCompatibility() { return Stream.of(Arguments.of(List.of(SupportedParameters.HOST, SupportedParameters.ROUTES), true), Arguments.of(List.of(SupportedParameters.ROUTES, SupportedParameters.IDLE_ROUTES), false), Arguments.of(List.of(SupportedParameters.HOSTS, SupportedParameters.DOMAINS, SupportedParameters.ROUTES), true), - Arguments.of(List.of(SupportedParameters.IDLE_ROUTES, SupportedParameters.IDLE_HOST), true), - Arguments.of(List.of(SupportedParameters.IDLE_ROUTES, SupportedParameters.IDLE_HOSTS, - SupportedParameters.IDLE_DOMAINS), - true), + Arguments.of(List.of(SupportedParameters.IDLE_ROUTES, SupportedParameters.IDLE_HOST), true), Arguments.of( + List.of(SupportedParameters.IDLE_ROUTES, SupportedParameters.IDLE_HOSTS, SupportedParameters.IDLE_DOMAINS), true), Arguments.of(List.of(SupportedParameters.ROUTES, SupportedParameters.IDLE_ROUTES, SupportedParameters.BUILDPACKS), false), Arguments.of(List.of(SupportedParameters.ROUTES, SupportedParameters.IDLE_ROUTES, "not-supported-parameter"), - false), - Arguments.of(List.of(SupportedParameters.HOSTS, SupportedParameters.ROUTES, SupportedParameters.ROUTE_PATH, - SupportedParameters.IDLE_HOSTS, SupportedParameters.IDLE_ROUTES), - true)); + false), Arguments.of( + List.of(SupportedParameters.HOSTS, SupportedParameters.ROUTES, SupportedParameters.ROUTE_PATH, + SupportedParameters.IDLE_HOSTS, SupportedParameters.IDLE_ROUTES), true), + Arguments.of(List.of(SupportedParameters.ENABLE_SSH), false), Arguments.of( + List.of(SupportedParameters.ENABLE_SSH, Map.of(SupportedParameters.APP_FEATURES, Map.of("ssh", true))), true), Arguments.of( + List.of(SupportedParameters.ENABLE_SSH, + Map.of(SupportedParameters.APP_FEATURES, Map.of("file-based-vcap-services", false))), false)); } @ParameterizedTest @MethodSource - void testModuleParametersCompatibility(List moduleParameters, boolean shouldWarnMessage) { + void testModuleParametersCompatibility(List moduleParameters, boolean shouldWarnMessage) { Module module = buildModule(moduleParameters); Module validatedModule = new ModuleParametersCompatibilityValidator(module, userMessageLogger).validate(); @@ -61,10 +62,16 @@ void testModuleParametersCompatibility(List moduleParameters, boolean sh verifyUserMessageLogger(shouldWarnMessage); } - private Module buildModule(List moduleParameters) { - Map moduleParametersMap = moduleParameters.stream() - .collect(Collectors.toMap(parameterName -> parameterName, - parameterValue -> "")); + private Module buildModule(List moduleParameters) { + Map moduleParametersMap = new HashMap<>(); + for (Object parameter : moduleParameters) { + if (parameter instanceof String) { + moduleParametersMap.put((String) parameter, ""); + } + if (parameter instanceof Map) { + moduleParametersMap.putAll((Map) parameter); + } + } return Module.createV2() .setParameters(moduleParametersMap); } diff --git a/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-empty.json b/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-empty.json new file mode 100644 index 0000000000..510a916b02 --- /dev/null +++ b/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-empty.json @@ -0,0 +1,54 @@ +[ + { + "name": "feature-app", + "v3Metadata": { + "annotations": { + "mta_id": "app-features-test", + "mta_version": "0.0.1", + "mta_module": "{\"name\":\"feature-app\"}", + "mta_module_provided_dependencies": "[\"feature-app\"]", + "mta_bound_services": "[]" + }, + "labels": { + "mta_id": "4572c447a636063e61744a390feb4077" + } + }, + "moduleName": "feature-app", + "memory": 0, + "diskQuota": 0, + "instances": 0, + "staging": { + "buildpacks": [], + "appFeatures": {} + }, + "routes": [ + { + "appsUsingRoute": 0, + "domain": { + "name": "cfapps.neo.ondemand.com" + }, + "host": "feature-app", + "path": "", + "url": "feature-app.cfapps.neo.ondemand.com" + } + ], + "services": [], + "env": { + "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" + }, + "idleRoutes": [], + "bindingParameters": {}, + "tasks": [], + "serviceKeysToInject": [], + "restartParameters": { + "shouldRestartOnVcapAppChange": true, + "shouldRestartOnVcapServicesChange": true, + "shouldRestartOnUserProvidedChange": true + }, + "attributesUpdateStrategy": { + "shouldKeepExistingEnv": false, + "shouldKeepExistingServiceBindings": false, + "shouldKeepExistingRoutes": false + } + } +] \ No newline at end of file diff --git a/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-single.json b/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-single.json new file mode 100644 index 0000000000..fea9651101 --- /dev/null +++ b/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features-single.json @@ -0,0 +1,56 @@ +[ + { + "name": "feature-app", + "v3Metadata": { + "annotations": { + "mta_id": "app-features-test", + "mta_version": "0.0.1", + "mta_module": "{\"name\":\"feature-app\"}", + "mta_module_provided_dependencies": "[\"feature-app\"]", + "mta_bound_services": "[]" + }, + "labels": { + "mta_id": "4572c447a636063e61744a390feb4077" + } + }, + "moduleName": "feature-app", + "memory": 0, + "diskQuota": 0, + "instances": 0, + "staging": { + "buildpacks": [], + "appFeatures": { + "featureA": true + } + }, + "routes": [ + { + "appsUsingRoute": 0, + "domain": { + "name": "cfapps.neo.ondemand.com" + }, + "host": "feature-app", + "path": "", + "url": "feature-app.cfapps.neo.ondemand.com" + } + ], + "services": [], + "env": { + "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" + }, + "idleRoutes": [], + "bindingParameters": {}, + "tasks": [], + "serviceKeysToInject": [], + "restartParameters": { + "shouldRestartOnVcapAppChange": true, + "shouldRestartOnVcapServicesChange": true, + "shouldRestartOnUserProvidedChange": true + }, + "attributesUpdateStrategy": { + "shouldKeepExistingEnv": false, + "shouldKeepExistingServiceBindings": false, + "shouldKeepExistingRoutes": false + } + } +] \ No newline at end of file diff --git a/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features.json b/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features.json new file mode 100644 index 0000000000..fd22c32a93 --- /dev/null +++ b/multiapps-controller-core/src/test/resources/mta/app-features/apps-app-features.json @@ -0,0 +1,58 @@ +[ + { + "name": "feature-app", + "v3Metadata": { + "annotations": { + "mta_id": "app-features-test", + "mta_version": "0.0.1", + "mta_module": "{\"name\":\"feature-app\"}", + "mta_module_provided_dependencies": "[\"feature-app\"]", + "mta_bound_services": "[]" + }, + "labels": { + "mta_id": "4572c447a636063e61744a390feb4077" + } + }, + "moduleName": "feature-app", + "memory": 0, + "diskQuota": 0, + "instances": 0, + "staging": { + "buildpacks": [], + "appFeatures": { + "featureA": true, + "featureB": false, + "featureC": true + } + }, + "routes": [ + { + "appsUsingRoute": 0, + "domain": { + "name": "cfapps.neo.ondemand.com" + }, + "host": "feature-app", + "path": "", + "url": "feature-app.cfapps.neo.ondemand.com" + } + ], + "services": [], + "env": { + "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" + }, + "idleRoutes": [], + "bindingParameters": {}, + "tasks": [], + "serviceKeysToInject": [], + "restartParameters": { + "shouldRestartOnVcapAppChange": true, + "shouldRestartOnVcapServicesChange": true, + "shouldRestartOnUserProvidedChange": true + }, + "attributesUpdateStrategy": { + "shouldKeepExistingEnv": false, + "shouldKeepExistingServiceBindings": false, + "shouldKeepExistingRoutes": false + } + } +] \ No newline at end of file diff --git a/multiapps-controller-core/src/test/resources/mta/app-features/config-app-features.mtaext b/multiapps-controller-core/src/test/resources/mta/app-features/config-app-features.mtaext new file mode 100644 index 0000000000..c39b72b7a5 --- /dev/null +++ b/multiapps-controller-core/src/test/resources/mta/app-features/config-app-features.mtaext @@ -0,0 +1,4 @@ +ID: app-features-test.ext +_schema-version: '2.1' +extends: app-features-test + diff --git a/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-empty.yaml b/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-empty.yaml new file mode 100644 index 0000000000..2e03ef517a --- /dev/null +++ b/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-empty.yaml @@ -0,0 +1,11 @@ +ID: app-features-test +_schema-version: '2.1' +version: 0.0.1 + +modules: + - name: feature-app + type: java + path: . + parameters: + app-features: { } + diff --git a/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-single.yaml b/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-single.yaml new file mode 100644 index 0000000000..456521692e --- /dev/null +++ b/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features-single.yaml @@ -0,0 +1,12 @@ +ID: app-features-test +_schema-version: '2.1' +version: 0.0.1 + +modules: + - name: feature-app + type: java + path: . + parameters: + app-features: + featureA: true + diff --git a/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features.yaml b/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features.yaml new file mode 100644 index 0000000000..944f4ca6a0 --- /dev/null +++ b/multiapps-controller-core/src/test/resources/mta/app-features/mtad-app-features.yaml @@ -0,0 +1,14 @@ +ID: app-features-test +_schema-version: '2.1' +version: 0.0.1 + +modules: + - name: feature-app + type: java + path: . + parameters: + app-features: + featureA: true + featureB: false + featureC: true + diff --git a/multiapps-controller-core/src/test/resources/mta/devxdi/apps.json b/multiapps-controller-core/src/test/resources/mta/devxdi/apps.json index a7e6a59e45..8755528450 100644 --- a/multiapps-controller-core/src/test/resources/mta/devxdi/apps.json +++ b/multiapps-controller-core/src/test/resources/mta/devxdi/apps.json @@ -13,13 +13,15 @@ "mta_id": "81530aa8411b2e488fa727eda264e137" } }, + "moduleName": "di-core", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -44,11 +46,8 @@ "SERVICE_TO_JNDI_NAME_MAPPING": "{\"di-core-hdi\":\"jdbc/DefaultDB\"}\n", "TARGET_RUNTIME": "tomcat" }, - "moduleName": "di-core", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -76,13 +75,15 @@ "mta_id": "81530aa8411b2e488fa727eda264e137" } }, + "moduleName": "di-builder", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "http://i027947-di-core.cfapps.neo.ondemand.com/system/builderbp.git/" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -104,11 +105,8 @@ "JBP_CONFIG_TOMCAT": "[tomcat: {version: 7.0.+}]", "TARGET_RUNTIME": "tomcat" }, - "moduleName": "di-builder", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -136,13 +134,15 @@ "mta_id": "81530aa8411b2e488fa727eda264e137" } }, + "moduleName": "di-runner", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -165,11 +165,8 @@ "TARGET_RUNTIME": "tomcat", "UI5_CONTENT_URL": "http://i027947-ui5-content.cfapps.neo.ondemand.com" }, - "moduleName": "di-runner", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/devxdi/xs2-apps.json b/multiapps-controller-core/src/test/resources/mta/devxdi/xs2-apps.json index 52593f4e48..7aaac0b573 100644 --- a/multiapps-controller-core/src/test/resources/mta/devxdi/xs2-apps.json +++ b/multiapps-controller-core/src/test/resources/mta/devxdi/xs2-apps.json @@ -13,11 +13,13 @@ "mta_id": "81530aa8411b2e488fa727eda264e137" } }, + "moduleName": "di-core", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -44,11 +46,8 @@ "TARGET_RUNTIME": "tomcat", "XS_PATH": "/usr/sap/xs2runtime/bin/xs" }, - "moduleName": "di-core", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -76,13 +75,15 @@ "mta_id": "81530aa8411b2e488fa727eda264e137" } }, + "moduleName": "di-builder", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "http://di-core.sofd60245639a/system/builderbp.git/" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -105,11 +106,8 @@ "TARGET_RUNTIME": "tomcat", "XS_PATH": "/usr/sap/xs2runtime/bin/xs" }, - "moduleName": "di-builder", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -137,11 +135,13 @@ "mta_id": "81530aa8411b2e488fa727eda264e137" } }, + "moduleName": "di-runner", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -165,11 +165,8 @@ "UI5_CONTENT_URL": "http://ui5.sofd60245639a", "XS_PATH": "/usr/sap/xs2runtime/bin/xs" }, - "moduleName": "di-runner", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/devxwebide/apps.json b/multiapps-controller-core/src/test/resources/mta/devxwebide/apps.json index 96ad9f097a..2de7f83aa4 100644 --- a/multiapps-controller-core/src/test/resources/mta/devxwebide/apps.json +++ b/multiapps-controller-core/src/test/resources/mta/devxwebide/apps.json @@ -13,11 +13,13 @@ "mta_id": "33940e667a1d39f2c6fe8b2f658f9f40" } }, + "moduleName": "webide", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -37,11 +39,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"sapui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"},{\"name\":\"che\",\"url\":\"http://i027947-di-core.cfapps.neo.ondemand.com\"}]" }, - "moduleName": "webide", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/devxwebide/xs2-apps.json b/multiapps-controller-core/src/test/resources/mta/devxwebide/xs2-apps.json index 92cbda9bde..95c41b1ca2 100644 --- a/multiapps-controller-core/src/test/resources/mta/devxwebide/xs2-apps.json +++ b/multiapps-controller-core/src/test/resources/mta/devxwebide/xs2-apps.json @@ -13,11 +13,13 @@ "mta_id": "33940e667a1d39f2c6fe8b2f658f9f40" } }, + "moduleName": "webide", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -37,7 +39,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"sapui5\",\"proxyHost\":\"proxy\",\"proxyPort\":\"8080\",\"url\":\"https://sapui5.netweaver.ondemand.com\"},{\"name\":\"che\",\"url\":\"http://che.sofd60245639a\"}]" }, - "moduleName": "webide", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-1.json b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-1.json index 792247be16..77feeedfae 100644 --- a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-1.json +++ b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-1.json @@ -5,21 +5,23 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace1", "mta_module": "{\"name\":\"java-hello-world\"}", "mta_module_provided_dependencies": "[\"java-hello-world\"]", - "mta_bound_services": "[\"namespace1-uaa\"]", - "mta_namespace": "namespace1" + "mta_bound_services": "[\"namespace1-uaa\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "612897f0683dd83be850731b14801182" } }, + "moduleName": "java-hello-world", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world", - "path" : "", + "path": "", "url": "i027947-java-hello-world.cfapps.neo.ondemand.com" } ], @@ -39,11 +41,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"java\",\"url\":\"http://i027947-java-hello-world-backend.cfapps.neo.ondemand.com\"},{\"name\":\"ui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "java-hello-world", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -63,23 +62,25 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace1", "mta_module": "{\"name\":\"java-hello-world-backend\"}", "mta_module_provided_dependencies": "[\"java\",\"java-hello-world-backend\"]", - "mta_bound_services": "[\"namespace1-uaa\",\"namespace1-java-hdi-container\"]", - "mta_namespace": "namespace1" + "mta_bound_services": "[\"namespace1-uaa\",\"namespace1-java-hdi-container\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "612897f0683dd83be850731b14801182" } }, + "moduleName": "java-hello-world-backend", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -88,7 +89,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world-backend", - "path" : "", + "path": "", "url": "i027947-java-hello-world-backend.cfapps.neo.ondemand.com" } ], @@ -100,11 +101,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "java-hello-world-backend", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -124,23 +122,25 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace1", "mta_module": "{\"name\":\"java-hello-world-db\"}", "mta_module_provided_dependencies": "[\"java-hello-world-db\"]", - "mta_bound_services": "[\"namespace1-java-hdi-container\"]", - "mta_namespace": "namespace1" + "mta_bound_services": "[\"namespace1-java-hdi-container\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "612897f0683dd83be850731b14801182" } }, + "moduleName": "java-hello-world-db", "memory": 256, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2/hdi-deploy-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [], "services": [ @@ -150,11 +150,8 @@ "DEPLOY_ATTRIBUTES": "{\"check-deploy-id\":true,\"dependency-type\":\"soft\",\"execute-app\":true,\"failure-marker\":\"STDERR:Deployment failed\",\"stop-app\":true,\"success-marker\":\"STDOUT:Deployment done\"}", "DEPLOY_ID": "123" }, - "moduleName": "java-hello-world-db", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-2.json b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-2.json index 817cc8fd64..dad53cfef5 100644 --- a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-2.json +++ b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-2.json @@ -5,21 +5,23 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace2-but-it-is-really-really-long", "mta_module": "{\"name\":\"java-hello-world\"}", "mta_module_provided_dependencies": "[\"java-hello-world\"]", - "mta_bound_services": "[\"namespace2-but-it-is-really-really-long-uaa\"]", - "mta_namespace": "namespace2-but-it-is-really-really-long" + "mta_bound_services": "[\"namespace2-but-it-is-really-really-long-uaa\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "f2748a3f7a3ccdaa81947be34bd4464b" } }, + "moduleName": "java-hello-world", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world", - "path" : "", + "path": "", "url": "i027947-java-hello-world.cfapps.neo.ondemand.com" } ], @@ -39,11 +41,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"java\",\"url\":\"http://i027947-java-hello-world-backend.cfapps.neo.ondemand.com\"},{\"name\":\"ui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "java-hello-world", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -63,23 +62,25 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace2-but-it-is-really-really-long", "mta_module": "{\"name\":\"java-hello-world-backend\"}", "mta_module_provided_dependencies": "[\"java\",\"java-hello-world-backend\"]", - "mta_bound_services": "[\"namespace2-but-it-is-really-really-long-uaa\",\"namespace2-but-it-is-really-really-long-ja4fcad984\"]", - "mta_namespace": "namespace2-but-it-is-really-really-long" + "mta_bound_services": "[\"namespace2-but-it-is-really-really-long-uaa\",\"namespace2-but-it-is-really-really-long-ja4fcad984\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "f2748a3f7a3ccdaa81947be34bd4464b" } }, + "moduleName": "java-hello-world-backend", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -88,7 +89,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world-backend", - "path" : "", + "path": "", "url": "i027947-java-hello-world-backend.cfapps.neo.ondemand.com" } ], @@ -100,11 +101,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "java-hello-world-backend", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -124,23 +122,25 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace2-but-it-is-really-really-long", "mta_module": "{\"name\":\"java-hello-world-db\"}", "mta_module_provided_dependencies": "[\"java-hello-world-db\"]", - "mta_bound_services": "[\"namespace2-but-it-is-really-really-long-ja4fcad984\"]", - "mta_namespace": "namespace2-but-it-is-really-really-long" + "mta_bound_services": "[\"namespace2-but-it-is-really-really-long-ja4fcad984\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "f2748a3f7a3ccdaa81947be34bd4464b" } }, + "moduleName": "java-hello-world-db", "memory": 256, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2/hdi-deploy-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [], "services": [ @@ -150,11 +150,8 @@ "DEPLOY_ATTRIBUTES": "{\"check-deploy-id\":true,\"dependency-type\":\"soft\",\"execute-app\":true,\"failure-marker\":\"STDERR:Deployment failed\",\"stop-app\":true,\"success-marker\":\"STDOUT:Deployment done\"}", "DEPLOY_ID": "123" }, - "moduleName": "java-hello-world-db", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-3.json b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-3.json index da530e1079..3f0ce02e8c 100644 --- a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-3.json +++ b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-ns-3.json @@ -5,21 +5,23 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace3", "mta_module": "{\"name\":\"java-hello-world\"}", "mta_module_provided_dependencies": "[\"java-hello-world\"]", - "mta_bound_services": "[\"uaa\"]", - "mta_namespace": "namespace3" + "mta_bound_services": "[\"uaa\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "597179610e593e09b3dd04d4dc6327fb" } }, + "moduleName": "java-hello-world", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world", - "path" : "", + "path": "", "url": "i027947-java-hello-world.cfapps.neo.ondemand.com" } ], @@ -39,11 +41,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"java\",\"url\":\"http://i027947-java-hello-world-backend.cfapps.neo.ondemand.com\"},{\"name\":\"ui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "java-hello-world", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -63,23 +62,25 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace3", "mta_module": "{\"name\":\"java-hello-world-backend\"}", "mta_module_provided_dependencies": "[\"java\",\"java-hello-world-backend\"]", - "mta_bound_services": "[\"uaa\",\"java-hdi-container\"]", - "mta_namespace": "namespace3" + "mta_bound_services": "[\"uaa\",\"java-hdi-container\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "597179610e593e09b3dd04d4dc6327fb" } }, + "moduleName": "java-hello-world-backend", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -88,7 +89,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world-backend", - "path" : "", + "path": "", "url": "i027947-java-hello-world-backend.cfapps.neo.ondemand.com" } ], @@ -100,11 +101,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "java-hello-world-backend", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -124,23 +122,25 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace3", "mta_module": "{\"name\":\"java-hello-world-db\"}", "mta_module_provided_dependencies": "[\"java-hello-world-db\"]", - "mta_bound_services": "[\"java-hdi-container\"]", - "mta_namespace": "namespace3" + "mta_bound_services": "[\"java-hdi-container\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "597179610e593e09b3dd04d4dc6327fb" } }, + "moduleName": "java-hello-world-db", "memory": 256, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2/hdi-deploy-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [], "services": [ @@ -150,11 +150,8 @@ "DEPLOY_ATTRIBUTES": "{\"check-deploy-id\":true,\"dependency-type\":\"soft\",\"execute-app\":true,\"failure-marker\":\"STDERR:Deployment failed\",\"stop-app\":true,\"success-marker\":\"STDOUT:Deployment done\"}", "DEPLOY_ID": "123" }, - "moduleName": "java-hello-world-db", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch-ns.json b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch-ns.json index dd51e0915f..41315f7c7b 100644 --- a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch-ns.json +++ b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch-ns.json @@ -5,21 +5,23 @@ "annotations": { "mta_id": "com.sap.xs2.samples.javahelloworld", "mta_version": "0.1.0", + "mta_namespace": "namespace", "mta_module": "{\"name\":\"java-hello-world\"}", "mta_module_provided_dependencies": "[\"java-hello-world\"]", - "mta_bound_services": "[\"namespace-uaa\"]", - "mta_namespace": "namespace" + "mta_bound_services": "[\"namespace-uaa\"]" }, "labels": { "mta_id": "c232c91455fc92b226129257682792b2", "mta_namespace": "89801e9e98979062e84647433a8ed3e9" } }, + "moduleName": "java-hello-world", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world", - "path" : "", + "path": "", "url": "i027947-java-hello-world.cfapps.neo.ondemand.com" } ], @@ -39,11 +41,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"java\",\"url\":\"http://i027947-java-hello-world-backend.cfapps.neo.ondemand.com\"},{\"name\":\"ui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "java-hello-world", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch.json b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch.json index f4a8f76827..968b6993ad 100644 --- a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch.json +++ b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps-patch.json @@ -13,11 +13,13 @@ "mta_id": "c232c91455fc92b226129257682792b2" } }, + "moduleName": "java-hello-world", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-java-hello-world", - "path" : "", + "path": "", "url": "i027947-java-hello-world.cfapps.neo.ondemand.com" } ], @@ -37,11 +39,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"java\",\"url\":\"http://i027947-java-hello-world-backend.cfapps.neo.ondemand.com\"},{\"name\":\"ui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "java-hello-world", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps.json b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps.json index e86a7d309c..c2b01d3f57 100644 --- a/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps.json +++ b/multiapps-controller-core/src/test/resources/mta/javahelloworld/apps.json @@ -13,21 +13,25 @@ "mta_id": "c232c91455fc92b226129257682792b2" } }, + "moduleName": "java-hello-world", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, - "routes" : [ { - "appsUsingRoute": 0, - "domain" : { - "name": "cfapps.neo.ondemand.com" - }, - "host" : "i027947-java-hello-world", - "path" : "", - "url": "i027947-java-hello-world.cfapps.neo.ondemand.com" - } ], + "routes": [ + { + "appsUsingRoute": 0, + "domain": { + "name": "cfapps.neo.ondemand.com" + }, + "host": "i027947-java-hello-world", + "path": "", + "url": "i027947-java-hello-world.cfapps.neo.ondemand.com" + } + ], "services": [ "uaa" ], @@ -35,8 +39,7 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"java\",\"url\":\"http://i027947-java-hello-world-backend.cfapps.neo.ondemand.com\"},{\"name\":\"ui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "java-hello-world", - "idleRoutes" : [ ], + "idleRoutes": [], "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], @@ -65,23 +68,27 @@ "mta_id": "c232c91455fc92b226129257682792b2" } }, + "moduleName": "java-hello-world-backend", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, - "routes" : [ { - "appsUsingRoute": 0, - "domain" : { - "name": "cfapps.neo.ondemand.com" - }, - "host" : "i027947-java-hello-world-backend", - "path" : "", - "url": "i027947-java-hello-world-backend.cfapps.neo.ondemand.com" - } ], + "routes": [ + { + "appsUsingRoute": 0, + "domain": { + "name": "cfapps.neo.ondemand.com" + }, + "host": "i027947-java-hello-world-backend", + "path": "", + "url": "i027947-java-hello-world-backend.cfapps.neo.ondemand.com" + } + ], "services": [ "uaa", "java-hdi-container" @@ -90,7 +97,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "java-hello-world-backend", "idleRoutes": [], "bindingParameters": {}, "tasks": [], @@ -120,13 +126,15 @@ "mta_id": "c232c91455fc92b226129257682792b2" } }, + "moduleName": "java-hello-world-db", "memory": 256, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2/hdi-deploy-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [], "services": [ @@ -136,7 +144,6 @@ "DEPLOY_ATTRIBUTES": "{\"check-deploy-id\":true,\"dependency-type\":\"soft\",\"execute-app\":true,\"failure-marker\":\"STDERR:Deployment failed\",\"stop-app\":true,\"success-marker\":\"STDOUT:Deployment done\"}", "DEPLOY_ID": "123" }, - "moduleName": "java-hello-world-db", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/mta/javahelloworld/xs2-apps.json b/multiapps-controller-core/src/test/resources/mta/javahelloworld/xs2-apps.json index 2793b1dfd4..90f009930c 100644 --- a/multiapps-controller-core/src/test/resources/mta/javahelloworld/xs2-apps.json +++ b/multiapps-controller-core/src/test/resources/mta/javahelloworld/xs2-apps.json @@ -13,11 +13,13 @@ "mta_id": "c232c91455fc92b226129257682792b2" } }, + "moduleName": "java-hello-world", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "java-hello-world", - "path" : "", + "path": "", "url": "java-hello-world.sofd60245639a" } ], @@ -37,11 +39,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"java\",\"url\":\"http://java-hello-world-backend.sofd60245639a\"},{\"name\":\"ui5\",\"proxyHost\":\"proxy\",\"proxyPort\":\"8080\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "java-hello-world", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -69,11 +68,13 @@ "mta_id": "c232c91455fc92b226129257682792b2" } }, + "moduleName": "java-hello-world-backend", "memory": 512, "diskQuota": 0, "instances": 1, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -82,7 +83,7 @@ "name": "sofd60245639a" }, "host": "java-hello-world-backend", - "path" : "", + "path": "", "url": "java-hello-world-backend.sofd60245639a" } ], @@ -94,11 +95,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "java-hello-world-backend", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -126,11 +124,13 @@ "mta_id": "c232c91455fc92b226129257682792b2" } }, + "moduleName": "java-hello-world-db", "memory": 256, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [], "services": [ @@ -139,11 +139,8 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\",\"execute-app\":false}" }, - "moduleName": "java-hello-world-db", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/sample/apps.json b/multiapps-controller-core/src/test/resources/mta/sample/apps.json index 527ea8ae49..65f2803854 100644 --- a/multiapps-controller-core/src/test/resources/mta/sample/apps.json +++ b/multiapps-controller-core/src/test/resources/mta/sample/apps.json @@ -13,11 +13,13 @@ "mta_id": "57675a73021035bde9f4f77efa07dad8" } }, + "moduleName": "web-server", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "bestprice.sap.com" }, "host": "www", - "path" : "", + "path": "", "url": "www.bestprice.sap.com" } ], @@ -39,11 +41,8 @@ "docu-url": "http://help.sap.com/saphelp_nw74/en/5c", "odata.svc_root": "odata/" }, - "moduleName": "web-server", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -71,13 +70,15 @@ "mta_id": "57675a73021035bde9f4f77efa07dad8" } }, + "moduleName": "pricing", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "nodejs-test" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -86,7 +87,7 @@ "name": "bestprice.sap.com" }, "host": "api", - "path" : "", + "path": "", "url": "api.bestprice.sap.com" } ], @@ -101,11 +102,8 @@ "secret-key": "cd171f7c-560d-4a62-8d65-16b87419a58c", "url": "https://marketwatch.il/v2/" }, - "moduleName": "pricing", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -133,11 +131,13 @@ "mta_id": "57675a73021035bde9f4f77efa07dad8" } }, + "moduleName": "pricing-db", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -146,7 +146,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "pricing-db", - "path" : "", + "path": "", "url": "pricing-db.cfapps.neo.ondemand.com" } ], @@ -157,11 +157,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "default-locale": "zho" }, - "moduleName": "pricing-db", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/shine/apps.json b/multiapps-controller-core/src/test/resources/mta/shine/apps.json index d2ceb04fa5..671c3b9de9 100644 --- a/multiapps-controller-core/src/test/resources/mta/shine/apps.json +++ b/multiapps-controller-core/src/test/resources/mta/shine/apps.json @@ -13,11 +13,13 @@ "mta_id": "be5ee71b7aaf0d059a831b9babd5547c" } }, + "moduleName": "shine", "memory": 128, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-shine", - "path" : "", + "path": "", "url": "i027947-shine.cfapps.neo.ondemand.com" } ], @@ -37,11 +39,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "destinations": "[{\"name\":\"xsjs\",\"url\":\"http://i027947-shine-xsjs.cfapps.neo.ondemand.com\"},{\"name\":\"xsodata\",\"url\":\"http://i027947-shine-odata.cfapps.neo.ondemand.com\"},{\"name\":\"ui5\",\"url\":\"https://sapui5.netweaver.ondemand.com\"}]" }, - "moduleName": "shine", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -69,11 +68,13 @@ "mta_id": "be5ee71b7aaf0d059a831b9babd5547c" } }, + "moduleName": "shine-xsjs", "memory": 256, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -82,7 +83,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-shine-xsjs", - "path" : "", + "path": "", "url": "i027947-shine-xsjs.cfapps.neo.ondemand.com" } ], @@ -94,11 +95,8 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "HANA_SERVICE_NAME": "shine-database" }, - "moduleName": "shine-xsjs", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { @@ -126,13 +124,15 @@ "mta_id": "be5ee71b7aaf0d059a831b9babd5547c" } }, + "moduleName": "shine-odata", "memory": 256, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -141,7 +141,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "i027947-shine-odata", - "path" : "", + "path": "", "url": "i027947-shine-odata.cfapps.neo.ondemand.com" } ], @@ -154,11 +154,8 @@ "SERVICE_TO_JNDI_NAME_MAPPING": "{\"shine-database\":\"jdbc/DefaultDB\"}", "TARGET_RUNTIME": "tomcat" }, - "moduleName": "shine-odata", "idleRoutes": [], - "bindingParameters": { - - }, + "bindingParameters": {}, "tasks": [], "serviceKeysToInject": [], "restartParameters": { diff --git a/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-false.json b/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-false.json index cd0233bf22..23b64a82aa 100644 --- a/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-false.json +++ b/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-false.json @@ -18,7 +18,8 @@ "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -69,7 +70,8 @@ "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { diff --git a/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-true.json b/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-true.json index e041955ed3..b08c5db413 100644 --- a/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-true.json +++ b/multiapps-controller-core/src/test/resources/mta/skip-deploy/apps-skip-deploy-true.json @@ -18,7 +18,8 @@ "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-01.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-01.json index b17505dd9e..fe1c6f6236 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-01.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-01.json @@ -13,11 +13,13 @@ "mta_id": "157ed173764cbd03d45546cc8d70248f" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -34,7 +36,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": { "bar": { diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-02.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-02.json index 5dc17e3a99..d3eba88c44 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-02.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-02.json @@ -13,11 +13,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-1", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "test-host", - "path" : "/test", + "path": "/test", "url": "test-host.sofd60245639a/test" } ], @@ -35,7 +37,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "module-1", "idleRoutes": [], "bindingParameters": {}, "tasks": [], @@ -65,11 +66,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-2", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -87,7 +90,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "module-2", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-03.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-03.json index 33eaae87f6..9690daeca4 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-03.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-03.json @@ -5,21 +5,23 @@ "annotations": { "mta_id": "com.sap.sample.mta", "mta_version": "0.1.0", + "mta_namespace": "something", "mta_module": "{\"name\":\"module-1\"}", "mta_module_provided_dependencies": "[\"module-1\"]", - "mta_bound_services": "[]", - "mta_namespace": "something" + "mta_bound_services": "[]" }, "labels": { "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba", "mta_namespace": "437b930db84b8079c2dd804a71936b5f" } }, + "moduleName": "module-1", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "sofd60245639a" }, "host": "test-host", - "path" : "/test", + "path": "/test", "url": "test-host.sofd60245639a/test" } ], @@ -37,7 +39,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "module-1", "idleRoutes": [], "bindingParameters": {}, "tasks": [], @@ -59,21 +60,23 @@ "annotations": { "mta_id": "com.sap.sample.mta", "mta_version": "0.1.0", + "mta_namespace": "something", "mta_module": "{\"name\":\"module-2\"}", "mta_module_provided_dependencies": "[\"module-2\"]", - "mta_bound_services": "[]", - "mta_namespace": "something" + "mta_bound_services": "[]" }, "labels": { "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba", "mta_namespace": "437b930db84b8079c2dd804a71936b5f" } }, + "moduleName": "module-2", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -82,7 +85,7 @@ "name": "sofd60245639a" }, "host": "module-2", - "path" : "", + "path": "", "url": "module-2.sofd60245639a" } ], @@ -91,7 +94,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "module-2", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-05.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-05.json index bfb625bc17..c4ff09b946 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-05.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-05.json @@ -13,11 +13,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-1", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "module-1", - "path" : "", + "path": "", "url": "module-1.sofd60245639a" } ], @@ -35,7 +37,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "module-1", "idleRoutes": [ { "appsUsingRoute": 0, @@ -43,7 +44,7 @@ "name": "localhost" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.localhost" }, { @@ -52,7 +53,7 @@ "name": "localhost" }, "host": "bar", - "path" : "", + "path": "", "url": "bar.localhost" } ], @@ -84,11 +85,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-2", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -97,7 +100,7 @@ "name": "sofd60245639a" }, "host": "module-2", - "path" : "", + "path": "", "url": "module-2.sofd60245639a" } ], @@ -106,7 +109,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "module-2", "idleRoutes": [ { "appsUsingRoute": 0, @@ -114,7 +116,7 @@ "name": "localhost" }, "host": "baz", - "path" : "", + "path": "", "url": "baz.localhost" }, { @@ -123,7 +125,7 @@ "name": "localhost" }, "host": "qux", - "path" : "", + "path": "", "url": "qux.localhost" } ], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-06.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-06.json index aa91b23eeb..12e696508b 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-06.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-06.json @@ -13,11 +13,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "framework", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -35,7 +37,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "plugins": "[{\"name\":\"plugins.0\",\"plugin_name\":\"foo\",\"url\":\"https://foo.localhost\"},{\"name\":\"plugins.1\",\"plugin_name\":\"bar\",\"url\":\"https://bar.localhost\"}]" }, - "moduleName": "framework", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-07.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-07.json index 6414b4ffc6..1f9ad324c6 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-07.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-07.json @@ -13,11 +13,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "framework", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "framework", - "path" : "", + "path": "", "url": "framework.sofd60245639a" } ], @@ -35,7 +37,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "plugins": "[{\"name\":\"plugins.0\",\"plugin_name\":\"plugin-0\",\"url\":\"https://localhost:52001\"},{\"name\":\"plugins.1\",\"plugin_name\":\"plugin-1\"}]" }, - "moduleName": "framework", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-08.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-08.json index 1816a208d6..4d17c263db 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-08.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-08.json @@ -13,11 +13,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-1", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "module-1", - "path" : "", + "path": "", "url": "module-1.sofd60245639a" } ], @@ -45,7 +47,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "module-1", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-09.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-09.json index 2c292cea64..4f9f17af70 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-09.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-09.json @@ -13,11 +13,13 @@ "mta_id": "30a5c6eb633271c624fc7c1f2aec51c4" } }, + "moduleName": "module-1", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "module-1", - "path" : "", + "path": "", "url": "module-1.sofd60245639a" } ], @@ -34,7 +36,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\",\"no-start\":true}" }, - "moduleName": "module-1", "idleRoutes": [], "bindingParameters": {}, "tasks": [ @@ -78,11 +79,13 @@ "mta_id": "30a5c6eb633271c624fc7c1f2aec51c4" } }, + "moduleName": "module-2", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -91,7 +94,7 @@ "name": "sofd60245639a" }, "host": "module-2", - "path" : "", + "path": "", "url": "module-2.sofd60245639a" } ], @@ -99,7 +102,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "module-2", "idleRoutes": [], "bindingParameters": {}, "tasks": [], @@ -129,11 +131,13 @@ "mta_id": "30a5c6eb633271c624fc7c1f2aec51c4" } }, + "moduleName": "module-3", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -142,7 +146,7 @@ "name": "sofd60245639a" }, "host": "module-3", - "path" : "", + "path": "", "url": "module-3.sofd60245639a" } ], @@ -150,7 +154,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "module-3", "idleRoutes": [], "bindingParameters": {}, "tasks": [], @@ -180,11 +183,13 @@ "mta_id": "30a5c6eb633271c624fc7c1f2aec51c4" } }, + "moduleName": "module-4", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -193,7 +198,7 @@ "name": "sofd60245639a" }, "host": "module-4", - "path" : "", + "path": "", "url": "module-4.sofd60245639a" } ], @@ -202,7 +207,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\",\"no-start\":false}", "tasks": "[{\"command\":\"echo 3\",\"memory\":\"256M\",\"name\":\"task-3\"},{\"command\":\"echo 4\",\"memory\":\"512M\",\"name\":\"task-4\"}]" }, - "moduleName": "module-4", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-10.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-10.json index 3e7234f3eb..edaca2e21f 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-10.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-10.json @@ -13,11 +13,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-1", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "module-1", - "path" : "", + "path": "", "url": "module-1.sofd60245639a" } ], @@ -34,7 +36,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "module-1", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-12.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-12.json index f15afbb85a..fec123245d 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-12.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-12.json @@ -13,13 +13,15 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -37,7 +39,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", "idleRoutes": [ { "appsUsingRoute": 0, diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-13.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-13.json index 21e80ae82f..7f92f18ae4 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-13.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-13.json @@ -13,13 +13,15 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -46,7 +48,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", "idleRoutes": [ { "appsUsingRoute": 0, diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-14.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-14.json index 42cf279f3b..6dda7c7dbf 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-14.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-14.json @@ -13,13 +13,15 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "cfapps.domain.com" }, "host": "abc", - "path" : "", + "path": "", "url": "abc.cfapps.domain.com" }, { @@ -37,7 +39,7 @@ "name": "cfapps.domain.com" }, "host": "cba", - "path" : "", + "path": "", "url": "cba.cfapps.domain.com" }, { @@ -46,7 +48,7 @@ "name": "cfapps.domain.moc" }, "host": "abc", - "path" : "", + "path": "", "url": "abc.cfapps.domain.moc" }, { @@ -55,7 +57,7 @@ "name": "cfapps.domain.moc" }, "host": "cba", - "path" : "", + "path": "", "url": "cba.cfapps.domain.moc" } ], @@ -64,7 +66,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-15.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-15.json index 48cddfad7d..1ff52b84b1 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-15.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-15.json @@ -13,6 +13,7 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, @@ -20,7 +21,8 @@ "buildpacks": [ "java_buildpack", "staticfile_buildpack" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -29,7 +31,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.cfapps.neo.ondemand.com" } ], @@ -38,7 +40,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-16.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-16.json index d98f4727ae..7d0b18ea29 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-16.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-16.json @@ -13,13 +13,15 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.cfapps.neo.ondemand.com" } ], @@ -37,7 +39,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-with-endpoint.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-with-endpoint.json index 1c1e65ab2c..b1d69773e8 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-with-endpoint.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-with-endpoint.json @@ -13,13 +13,15 @@ "mta_id": "098f6bcd4621d373cade4e832627b4f6" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [], "healthCheckType": "http", - "healthCheckHttpEndpoint": "/health" + "healthCheckHttpEndpoint": "/health", + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "sofd60245639a" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.sofd60245639a" } ], @@ -36,7 +38,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-without-endpoint.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-without-endpoint.json index 7ea59fbf0d..a5061e4ef6 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-without-endpoint.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-http-without-endpoint.json @@ -13,13 +13,15 @@ "mta_id": "098f6bcd4621d373cade4e832627b4f6" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [], "healthCheckType": "http", - "healthCheckHttpEndpoint": "/" + "healthCheckHttpEndpoint": "/", + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "sofd60245639a" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.sofd60245639a" } ], @@ -36,7 +38,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-port.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-port.json index 3c0b3796c0..50c38dc520 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-port.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-health-check-type-port.json @@ -13,12 +13,14 @@ "mta_id": "098f6bcd4621d373cade4e832627b4f6" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [], - "healthCheckType": "port" + "healthCheckType": "port", + "appFeatures": {} }, "routes": [ { @@ -27,7 +29,7 @@ "name": "sofd60245639a" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.sofd60245639a" } ], @@ -35,7 +37,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-nohostname.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-nohostname.json index 9331548892..57167831d5 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-nohostname.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-nohostname.json @@ -13,40 +13,42 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, - "routes" : [ + "routes": [ { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "domain.to.test" }, - "host" : "normal-host", - "path" : "", + "host": "normal-host", + "path": "", "url": "normal-host.domain.to.test" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.sub.domain.to.test" }, - "host" : "", - "path" : "/with/path", + "host": "", + "path": "/with/path", "url": "sub.sub.domain.to.test/with/path" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.domain.to.test" }, - "host" : "", - "path" : "", + "host": "", + "path": "", "url": "sub.domain.to.test" } ], @@ -55,33 +57,32 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", - "idleRoutes" : [ + "idleRoutes": [ { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "domain.to.test" }, - "host" : "normal-host", - "path" : "", + "host": "normal-host", + "path": "", "url": "normal-host.domain.to.test" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.sub.domain.to.test" }, - "host" : "", - "path" : "/with/path", + "host": "", + "path": "/with/path", "url": "sub.sub.domain.to.test/with/path" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.domain.to.test" }, - "host" : "", - "path" : "", + "host": "", + "path": "", "url": "sub.domain.to.test" } ], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-restart-parameters-false.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-restart-parameters-false.json index 8898e89b0b..ba80ab1539 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-restart-parameters-false.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-restart-parameters-false.json @@ -13,11 +13,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-1", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,15 +28,14 @@ "name": "sofd60245639a" }, "host": "module-1", - "path" : "", - "url": "module-1.sofd60245639a" + "path": "", + "url": "module-1.sofd60245639a" } ], "services": [], "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "module-1", "idleRoutes": [], "bindingParameters": {}, "tasks": [], @@ -64,11 +65,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-2", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -77,7 +80,7 @@ "name": "sofd60245639a" }, "host": "module-2", - "path" : "", + "path": "", "url": "module-2.sofd60245639a" } ], @@ -85,7 +88,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "module-2", "idleRoutes": [], "bindingParameters": {}, "tasks": [], @@ -115,11 +117,13 @@ "mta_id": "c3ec54a0d8eadd33b207c005ab4825ba" } }, + "moduleName": "module-3", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -128,7 +132,7 @@ "name": "sofd60245639a" }, "host": "module-3", - "path" : "", + "path": "", "url": "module-3.sofd60245639a" } ], @@ -136,7 +140,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "module-3", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-false.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-false.json index 7db83fc36d..847d44fa6b 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-false.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-false.json @@ -13,12 +13,16 @@ "mta_id": "098f6bcd4621d373cade4e832627b4f6" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "isSshEnabled": false, - "buildpacks": [] + "buildpacks": [], + "appFeatures": { + "ssh": false + } }, "routes": [ { @@ -27,7 +31,7 @@ "name": "sofd60245639a" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.sofd60245639a" } ], @@ -35,7 +39,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-true.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-true.json index 2f418072ee..e802492adf 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-true.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/apps-with-ssh-enabled-true.json @@ -13,12 +13,16 @@ "mta_id": "098f6bcd4621d373cade4e832627b4f6" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "isSshEnabled": true, - "buildpacks": [] + "buildpacks": [], + "appFeatures": { + "ssh": true + } }, "routes": [ { @@ -27,7 +31,7 @@ "name": "sofd60245639a" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.sofd60245639a" } ], @@ -35,7 +39,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-existing-routes.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-existing-routes.json index 48bdcd15ad..c938d9426c 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-existing-routes.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-existing-routes.json @@ -13,11 +13,13 @@ "mta_id": "eea6b9aae1732740b3a782ea0fa2ff66" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.sofd60245639a" } ], @@ -34,7 +36,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-nohostname.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-nohostname.json index c469072f66..113cc7193d 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-nohostname.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps-with-nohostname.json @@ -13,40 +13,42 @@ "mta_id": "eea6b9aae1732740b3a782ea0fa2ff66" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, - "routes" : [ + "routes": [ { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "domain.to.test" }, - "host" : "normal-host", - "path" : "", + "host": "normal-host", + "path": "", "url": "normal-host.domain.to.test" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.sub.domain.to.test" }, - "host" : "", - "path" : "/with/path", + "host": "", + "path": "/with/path", "url": "sub.sub.domain.to.test/with/path" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.domain.to.test" }, - "host" : "", - "path" : "", + "host": "", + "path": "", "url": "sub.domain.to.test" } ], @@ -55,33 +57,32 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", - "idleRoutes" : [ + "idleRoutes": [ { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "domain.to.test" }, - "host" : "normal-host", - "path" : "", + "host": "normal-host", + "path": "", "url": "normal-host.domain.to.test" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.sub.domain.to.test" }, - "host" : "", - "path" : "/with/path", + "host": "", + "path": "/with/path", "url": "sub.sub.domain.to.test/with/path" }, { "appsUsingRoute": 0, - "domain" : { + "domain": { "name": "sub.domain.to.test" }, - "host" : "", - "path" : "", + "host": "", + "path": "", "url": "sub.domain.to.test" } ], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps.json index 48bdcd15ad..c938d9426c 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v2/keep-existing-routes/apps.json @@ -13,11 +13,13 @@ "mta_id": "eea6b9aae1732740b3a782ea0fa2ff66" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { - "buildpacks": [] + "buildpacks": [], + "appFeatures": {} }, "routes": [ { @@ -26,7 +28,7 @@ "name": "sofd60245639a" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.sofd60245639a" } ], @@ -34,7 +36,6 @@ "env": { "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], diff --git a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v3/apps-01.json b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v3/apps-01.json index b219079e2d..8b4b3297a8 100644 --- a/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v3/apps-01.json +++ b/multiapps-controller-core/src/test/resources/org/cloudfoundry/multiapps/controller/core/cf/v3/apps-01.json @@ -13,13 +13,15 @@ "mta_id": "157ed173764cbd03d45546cc8d70248f" } }, + "moduleName": "foo", "memory": 0, "diskQuota": 0, "instances": 0, "staging": { "buildpacks": [ "git://github.example.com/xs2-java/java-buildpack.git" - ] + ], + "appFeatures": {} }, "routes": [ { @@ -28,7 +30,7 @@ "name": "cfapps.neo.ondemand.com" }, "host": "foo", - "path" : "", + "path": "", "url": "foo.cfapps.neo.ondemand.com" } ], @@ -37,7 +39,6 @@ "DEPLOY_ATTRIBUTES": "{\"dependency-type\":\"soft\"}", "TARGET_RUNTIME": "tomee" }, - "moduleName": "foo", "idleRoutes": [], "bindingParameters": {}, "tasks": [], 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 fd59692774..e9e9fcc14d 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 @@ -782,6 +782,7 @@ public class Messages { public static final String DELETING_BACKUP_DESCRIPTORS_STORED_BEFORE_0 = "Deleting backup descriptors stored before \"{0}\""; public static final String DELETED_BACKUP_DESCRIPTORS_0 = "Deleted backup descriptors: {0}"; public static final String CALCULATED_TIMEOUT_FOR_INCREMENTAL_APP_INSTANCES_UPDATE_0_SECONDS = "Calculated timeout for incremental app instances update: {0} seconds"; + public static final String GETTING_FEATURES_FOR_APPLICATION_0 = "Getting features for application \"{0}\""; public static final String TOTAL_SIZE_OF_ALL_RESOLVED_CONTENT_0 = "Total size for all resolved content {0}"; diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/client/LoggingCloudControllerClient.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/client/LoggingCloudControllerClient.java index 461f261c74..fe471d9a88 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/client/LoggingCloudControllerClient.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/client/LoggingCloudControllerClient.java @@ -276,6 +276,12 @@ public boolean getApplicationSshEnabled(UUID applicationGuid) { return delegate.getApplicationSshEnabled(applicationGuid); } + @Override + public Map getApplicationFeatures(UUID applicationGuid) { + logger.debug(Messages.GETTING_FEATURES_FOR_APPLICATION_0, applicationGuid); + return delegate.getApplicationFeatures(applicationGuid); + } + @Override public List getApplications() { logger.debug(Messages.GETTING_APPLICATIONS); diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/StagingApplicationAttributeUpdater.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/StagingApplicationAttributeUpdater.java index 53ce7fb9c6..ec148d5c23 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/StagingApplicationAttributeUpdater.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/StagingApplicationAttributeUpdater.java @@ -1,5 +1,6 @@ package org.cloudfoundry.multiapps.controller.process.util; +import java.util.Map; import java.util.Objects; import org.apache.commons.lang3.StringUtils; @@ -28,15 +29,14 @@ public StagingApplicationAttributeUpdater(Context context, CloudProcess process) @Override protected boolean shouldUpdateAttribute(CloudApplication existingApplication, CloudApplicationExtended application) { Staging staging = application.getStaging(); - boolean isSshEnabled = getControllerClient().getApplicationSshEnabled(existingApplication.getGuid()); - return hasStagingChanged(staging, existingApplication, isSshEnabled); + Map appFeatures = getControllerClient().getApplicationFeatures(existingApplication.getGuid()); + return hasStagingChanged(staging, existingApplication, appFeatures); } - private boolean hasStagingChanged(Staging staging, CloudApplication existingApp, boolean existingSshEnabled) { + private boolean hasStagingChanged(Staging staging, CloudApplication existingApp, Map existingAppFeatures) { String command = staging.getCommand(); var healthCheck = HealthCheckInfo.fromStaging(staging); var existingHealthCheck = HealthCheckInfo.fromProcess(existingProcess); - boolean sshEnabled = staging.isSshEnabled() != null && staging.isSshEnabled(); var dropletInfo = dropletInfoFactory.createDropletInfo(staging); var existingDropletInfo = dropletInfoFactory.createDropletInfo(existingApp, getControllerClient()); @@ -44,13 +44,20 @@ private boolean hasStagingChanged(Staging staging, CloudApplication existingApp, processContext.setVariable(Variables.APP_NEEDS_RESTAGE, true); return true; } - return !healthCheck.equals(existingHealthCheck) || sshEnabled != existingSshEnabled; + return !healthCheck.equals(existingHealthCheck) || areAppFeaturesChanged(staging.getAppFeatures(), existingAppFeatures); } private boolean isCommandDifferent(String newCommand) { return !StringUtils.isBlank(newCommand) && !Objects.equals(newCommand, existingProcess.getCommand()); } + private boolean areAppFeaturesChanged(Map newAppFeatures, Map existingAppFeatures) { + return newAppFeatures.entrySet() + .stream() + .anyMatch(newAppFeature -> !Objects.equals(newAppFeature.getValue(), + existingAppFeatures.get(newAppFeature.getKey()))); + } + @Override protected void updateAttribute(CloudApplication existingApplication, CloudApplicationExtended application) { getControllerClient().updateApplicationStaging(application.getName(), application.getStaging()); From 72204f8ccc3602b23d9f686859858efda08c4071 Mon Sep 17 00:00:00 2001 From: theghost5800 Date: Mon, 21 Jul 2025 14:38:54 +0300 Subject: [PATCH 3/3] Fix simulate app execution JIRA:LMCROSSITXSADEPLOY-3111 --- .../controller/process/deploy-app.bpmn | 168 +++++++++--------- 1 file changed, 86 insertions(+), 82 deletions(-) diff --git a/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/deploy-app.bpmn b/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/deploy-app.bpmn index 7d33810803..9b47042e37 100644 --- a/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/deploy-app.bpmn +++ b/multiapps-controller-process/src/main/resources/org/cloudfoundry/multiapps/controller/process/deploy-app.bpmn @@ -78,40 +78,42 @@ - + - - - - - - - - - - - - + + + + + + + + + + + + - + - - - - - - - - - - - - - + + + + + + + + + + + + + - + + + @@ -120,23 +122,25 @@ - + - - - - - - - - - - - - - + + + + + + + + + + + + + - + + + @@ -229,12 +233,6 @@ - - - - - - @@ -253,6 +251,12 @@ + + + + + + @@ -398,7 +402,7 @@ - + @@ -431,18 +435,18 @@ - - - - + + + + - - - + + + - - - + + + @@ -465,16 +469,16 @@ - + - - + + - - - + + + @@ -485,12 +489,12 @@ - + - + @@ -503,9 +507,9 @@ - - - + + + @@ -520,9 +524,9 @@ - - - + + + @@ -536,9 +540,9 @@ - - - + + + @@ -636,9 +640,9 @@ - - - + + + @@ -669,11 +673,11 @@ - + - +