diff --git a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsCommon.java b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsCommon.java index 79b50ab809..d2444d09b7 100644 --- a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsCommon.java +++ b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsCommon.java @@ -16,30 +16,25 @@ package org.cloudfoundry.operations.applications; -import static java.util.Collections.emptyMap; +import org.cloudfoundry.util.tuple.Consumer2; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import reactor.core.Exceptions; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.TreeMap; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.cloudfoundry.util.tuple.Consumer2; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import reactor.core.Exceptions; + +import static java.util.Collections.emptyMap; /** * Common base class for dealing with manifests @@ -71,6 +66,7 @@ static T toApplicationManifestCom asString(application, "domain", variables, builder::domain); asListOfString(application, "domains", variables, builder::domain); asMapOfStringString(application, "env", variables, builder::environmentVariable); + asMap(application, "features", variables, String::valueOf, (k,v) -> builder.feature(k, Boolean.valueOf(v))); asString( application, "health-check-http-endpoint", @@ -430,6 +426,7 @@ static Map toApplicationYaml(_ApplicationManifestCommon applicat ApplicationManifestUtilsCommon::toDockerYaml); putIfPresent(yaml, "domains", applicationManifest.getDomains()); putIfPresent(yaml, "env", applicationManifest.getEnvironmentVariables()); + putIfPresent(yaml, "features", applicationManifest.getFeatures()); putIfPresent( yaml, "health-check-http-endpoint", diff --git a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/_ApplicationManifestCommon.java b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/_ApplicationManifestCommon.java index 95d53c6930..14a79607b7 100644 --- a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/_ApplicationManifestCommon.java +++ b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/_ApplicationManifestCommon.java @@ -46,6 +46,10 @@ interface Builder { Builder environmentVariable(Map.Entry entry); Builder environmentVariables(@Nullable Map entries); Builder putAllEnvironmentVariables(Map entries); + Builder feature(String key, Object value); + Builder feature(Map.Entry entry); + Builder features(@Nullable Map entries); + Builder putAllFeatures(Map entries); Builder healthCheckHttpEndpoint(@Nullable String healthCheckHttpEndpoint); Builder healthCheckType(@Nullable ApplicationHealthCheck healthCheckType); Builder host(String element); @@ -142,6 +146,13 @@ void check() { @Nullable abstract Map getEnvironmentVariables(); + /** + * Manage whether optional capabilities are enabled + */ + @AllowNulls + @Nullable + abstract Map getFeatures(); + /** * The HTTP health check endpoint */ diff --git a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsV3Test.java b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsV3Test.java index cf54b8120b..b8e71da756 100644 --- a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsV3Test.java +++ b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsV3Test.java @@ -1,15 +1,44 @@ package org.cloudfoundry.operations.applications; -import static org.junit.jupiter.api.Assertions.*; +import org.cloudfoundry.client.v3.Metadata; +import org.cloudfoundry.client.v3.processes.ReadinessHealthCheckType; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import org.cloudfoundry.client.v3.Metadata; -import org.cloudfoundry.client.v3.processes.ReadinessHealthCheckType; -import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; class ApplicationManifestUtilsV3Test { + @Test + void testWithDockerApp() throws IOException { + ManifestV3 manifest = + ManifestV3.builder() + .application( + ManifestV3Application.builder() + .name("test-app") + .docker(Docker.builder().image("test-image").build()) + .build()) + .build(); + + assertSerializeDeserialize(manifest); + } + + @Test + void testWithFeature() throws IOException { + ManifestV3 manifest = + ManifestV3.builder() + .application( + ManifestV3Application.builder() + .name("test-app") + .feature("file-based-vcap-services", true) + .build()) + .build(); + + assertSerializeDeserialize(manifest); + } + @Test void testGenericApplication() throws IOException { ManifestV3 manifest = @@ -47,20 +76,6 @@ void testGenericApplication() throws IOException { assertSerializeDeserialize(manifest); } - @Test - void testWithDockerApp() throws IOException { - ManifestV3 manifest = - ManifestV3.builder() - .application( - ManifestV3Application.builder() - .name("test-app") - .docker(Docker.builder().image("test-image").build()) - .build()) - .build(); - - assertSerializeDeserialize(manifest); - } - @Test void testWithMetadata() throws IOException { ManifestV3 manifest =