feat(cf): add SpEL support for cf manifests
MODIFY
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/client/CloudFoundryApiException.java
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/client/CloudFoundryApiException.java
@@ -66,11 +66,16 @@ public class CloudFoundryApiException extends RuntimeException {
}
private static String getRetrofitErrorMessage(RetrofitError retrofitError) {
+ return Optional.ofNullable(retrofitError.getResponse())
+ .map(
+ response -> {
return "status: "
- + retrofitError.getResponse().getStatus()
+ + response.getStatus()
+ ". url: "
- + retrofitError.getResponse().getUrl()
+ + response.getUrl()
+ ". raw response body: "
- + retrofitError.getResponse().getBody();
+ + response.getBody();
+ })
+ .orElse("error, url :" + retrofitError.getUrl() + " body: " + retrofitError.getBody());
}
}

MODIFY
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/AbstractCloudFoundryAtomicOperationConverter.java
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/AbstractCloudFoundryAtomicOperationConverter.java
package com.netflix.spinnaker.clouddriver.cloudfoundry.deploy.converters;
-import com.netflix.spinnaker.clouddriver.artifacts.ArtifactDownloader;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClient;
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundrySpace;
import com.netflix.spinnaker.clouddriver.cloudfoundry.security.CloudFoundryCredentials;
import com.netflix.spinnaker.clouddriver.security.AbstractAtomicOperationsCredentialsSupport;
-import com.netflix.spinnaker.kork.artifacts.model.Artifact;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
import java.util.Map;
import java.util.Optional;
-import java.util.function.Consumer;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.SafeConstructor;
public abstract class AbstractCloudFoundryAtomicOperationConverter
extends AbstractAtomicOperationsCredentialsSupport {
@@ -42,15 +34,4 @@ public abstract class AbstractCloudFoundryAtomicOperationConverter
CloudFoundryCredentials credentials = getCredentialsObject(input.get("credentials").toString());
return credentials.getClient();
}
-
- void downloadAndProcessManifest(
- ArtifactDownloader downloader, Artifact manifest, Consumer<Map> processManifest) {
- try {
- InputStream manifestInput = downloader.download(manifest);
- Yaml parser = new Yaml(new SafeConstructor());
- processManifest.accept(parser.load(manifestInput));
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
}

MODIFY
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/CloneCloudFoundryServerGroupAtomicOperationConverter.java
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/CloneCloudFoundryServerGroupAtomicOperationConverter.java
package com.netflix.spinnaker.clouddriver.cloudfoundry.deploy.converters;
import com.netflix.spinnaker.clouddriver.artifacts.ArtifactCredentialsRepository;
-import com.netflix.spinnaker.clouddriver.artifacts.ArtifactDownloader;
import com.netflix.spinnaker.clouddriver.cloudfoundry.CloudFoundryOperation;
import com.netflix.spinnaker.clouddriver.helpers.OperationPoller;
import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations;
@@ -30,8 +29,7 @@ public class CloneCloudFoundryServerGroupAtomicOperationConverter
extends DeployCloudFoundryServerGroupAtomicOperationConverter {
public CloneCloudFoundryServerGroupAtomicOperationConverter(
@Qualifier("cloudFoundryOperationPoller") OperationPoller operationPoller,
- ArtifactCredentialsRepository credentialsRepository,
- ArtifactDownloader artifactDownloader) {
- super(operationPoller, credentialsRepository, artifactDownloader);
+ ArtifactCredentialsRepository credentialsRepository) {
+ super(operationPoller, credentialsRepository);
}
}

MODIFY
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServerGroupAtomicOperationConverter.java
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServerGroupAtomicOperationConverter.java
@@ -25,7 +25,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.netflix.spinnaker.clouddriver.artifacts.ArtifactCredentialsRepository;
-import com.netflix.spinnaker.clouddriver.artifacts.ArtifactDownloader;
import com.netflix.spinnaker.clouddriver.artifacts.config.ArtifactCredentials;
import com.netflix.spinnaker.clouddriver.cloudfoundry.CloudFoundryOperation;
import com.netflix.spinnaker.clouddriver.cloudfoundry.artifacts.CloudFoundryArtifactCredentials;
@@ -50,15 +49,12 @@ public class DeployCloudFoundryServerGroupAtomicOperationConverter
extends AbstractCloudFoundryServerGroupAtomicOperationConverter {
private final OperationPoller operationPoller;
private final ArtifactCredentialsRepository credentialsRepository;
- private final ArtifactDownloader artifactDownloader;
public DeployCloudFoundryServerGroupAtomicOperationConverter(
@Qualifier("cloudFoundryOperationPoller") OperationPoller operationPoller,
- ArtifactCredentialsRepository credentialsRepository,
- ArtifactDownloader artifactDownloader) {
+ ArtifactCredentialsRepository credentialsRepository) {
this.operationPoller = operationPoller;
this.credentialsRepository = credentialsRepository;
- this.artifactDownloader = artifactDownloader;
}
@Override
@@ -87,11 +83,9 @@ public class DeployCloudFoundryServerGroupAtomicOperationConverter
// the deploy operation.
converted.setArtifactCredentials(getArtifactCredentials(converted));
- downloadAndProcessManifest(
- artifactDownloader,
- converted.getManifest(),
- myMap -> converted.setApplicationAttributes(convertManifest(myMap)));
-
+ converted.setApplicationAttributes(
+ convertManifest(
+ converted.getManifest().stream().findFirst().orElse(Collections.emptyMap())));
return converted;
}
@@ -116,7 +110,8 @@ public class DeployCloudFoundryServerGroupAtomicOperationConverter
}
// visible for testing
- DeployCloudFoundryServerGroupDescription.ApplicationAttributes convertManifest(Map manifestMap) {
+ DeployCloudFoundryServerGroupDescription.ApplicationAttributes convertManifest(
+ Map<Object, Object> manifestMap) {
List<CloudFoundryManifest> manifestApps =
new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE)

MODIFY
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServiceAtomicOperationConverter.java
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServiceAtomicOperationConverter.java
@@ -20,20 +20,16 @@ import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
-import com.netflix.spinnaker.clouddriver.artifacts.ArtifactDownloader;
import com.netflix.spinnaker.clouddriver.cloudfoundry.CloudFoundryOperation;
import com.netflix.spinnaker.clouddriver.cloudfoundry.deploy.description.DeployCloudFoundryServiceDescription;
import com.netflix.spinnaker.clouddriver.cloudfoundry.deploy.ops.DeployCloudFoundryServiceAtomicOperation;
import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperation;
import com.netflix.spinnaker.clouddriver.orchestration.AtomicOperations;
-import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import java.io.IOException;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@@ -46,12 +42,11 @@ import org.springframework.stereotype.Component;
public class DeployCloudFoundryServiceAtomicOperationConverter
extends AbstractCloudFoundryAtomicOperationConverter {
private static final ObjectMapper objectMapper =
- new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- private final ArtifactDownloader artifactDownloader;
+ new ObjectMapper()
+ .setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE)
+ .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- public DeployCloudFoundryServiceAtomicOperationConverter(ArtifactDownloader artifactDownloader) {
- this.artifactDownloader = artifactDownloader;
- }
+ public DeployCloudFoundryServiceAtomicOperationConverter() {}
@Override
public AtomicOperation convertOperation(Map input) {
@@ -70,33 +65,22 @@ public class DeployCloudFoundryServiceAtomicOperationConverter
new IllegalArgumentException(
"Unable to find space '" + converted.getRegion() + "'.")));
- Map manifest = (Map) input.get("manifest");
- if (manifest.get("artifact") != null) {
- Artifact manifestArtifact =
- objectMapper.convertValue(manifest.get("artifact"), Artifact.class);
- downloadAndProcessManifest(
- artifactDownloader,
- manifestArtifact,
- myMap -> {
- if (converted.isUserProvided()) {
- converted.setUserProvidedServiceAttributes(convertUserProvidedServiceManifest(myMap));
- } else {
- converted.setServiceAttributes(convertManifest(myMap));
- }
- });
- } else if (manifest.get("direct") != null) {
+ List<Map<Object, Object>> manifest = converted.getManifest();
+
if (converted.isUserProvided()) {
converted.setUserProvidedServiceAttributes(
- convertUserProvidedServiceManifest(manifest.get("direct")));
+ convertUserProvidedServiceManifest(manifest.stream().findFirst().orElse(null)));
} else {
- converted.setServiceAttributes(convertManifest(manifest.get("direct")));
- }
+ converted.setServiceAttributes(convertManifest(manifest.stream().findFirst().orElse(null)));
}
return converted;
}
// visible for testing
DeployCloudFoundryServiceDescription.ServiceAttributes convertManifest(Object manifestMap) {
+ if (manifestMap == null) {
+ throw new IllegalArgumentException("No configurations detected");
+ }
ServiceManifest manifest = objectMapper.convertValue(manifestMap, ServiceManifest.class);
if (manifest.getService() == null) {
throw new IllegalArgumentException("Manifest is missing the service");
@@ -119,6 +103,9 @@ public class DeployCloudFoundryServiceAtomicOperationConverter
// visible for testing
DeployCloudFoundryServiceDescription.UserProvidedServiceAttributes
convertUserProvidedServiceManifest(Object manifestMap) {
+ if (manifestMap == null) {
+ throw new IllegalArgumentException("No configurations detected");
+ }
UserProvidedServiceManifest manifest =
objectMapper.convertValue(manifestMap, UserProvidedServiceManifest.class);
if (manifest.getServiceInstanceName() == null) {
@@ -140,10 +127,10 @@ public class DeployCloudFoundryServiceAtomicOperationConverter
private String service;
private boolean updatable = true;
- @JsonAlias("service_instance_name")
+ @JsonAlias({"service_instance_name", "serviceInstanceName"})
private String serviceInstanceName;
- @JsonAlias("service_plan")
+ @JsonAlias({"service_plan", "servicePlan"})
private String servicePlan;
@Nullable private Set<String> tags;
@@ -157,21 +144,21 @@ public class DeployCloudFoundryServiceAtomicOperationConverter
private static class UserProvidedServiceManifest {
private boolean updatable = true;
- @JsonAlias("service_instance_name")
+ @JsonAlias({"service_instance_name", "serviceInstanceName"})
private String serviceInstanceName;
@Nullable
- @JsonAlias("syslog_drain_url")
+ @JsonAlias({"syslog_drain_url", "syslogDrainUrl"})
private String syslogDrainUrl;
@Nullable
- @JsonAlias("route_service_url")
+ @JsonAlias({"route_service_url", "routeServiceUrl"})
private String routeServiceUrl;
@Nullable private Set<String> tags;
@Nullable
- @JsonAlias("credentials_map")
+ @JsonAlias({"credentials_map", "credentialsMap"})
@JsonDeserialize(using = OptionallySerializedMapDeserializer.class)
private Map<String, Object> credentials;
}

MODIFY
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/description/DeployCloudFoundryServerGroupDescription.java
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/description/DeployCloudFoundryServerGroupDescription.java
@@ -37,7 +37,7 @@ public class DeployCloudFoundryServerGroupDescription
private CloudFoundrySpace space;
private boolean startApplication;
private Artifact applicationArtifact;
- private Artifact manifest;
+ private List<Map<Object, Object>> manifest;
private String executionId;
private Map<String, Object> trigger;

MODIFY
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/description/DeployCloudFoundryServiceDescription.java
clouddriver-cloudfoundry/src/main/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/description/DeployCloudFoundryServiceDescription.java
package com.netflix.spinnaker.clouddriver.cloudfoundry.deploy.description;
import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.netflix.spinnaker.clouddriver.artifacts.config.ArtifactCredentials;
-import com.netflix.spinnaker.kork.artifacts.model.Artifact;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@@ -30,9 +29,7 @@ import lombok.EqualsAndHashCode;
public class DeployCloudFoundryServiceDescription extends AbstractCloudFoundryServiceDescription {
private boolean userProvided = false;
- @JsonIgnore private Artifact artifact;
-
- @JsonIgnore private ArtifactCredentials artifactCredentials;
+ private List<Map<Object, Object>> manifest;
@JsonIgnore private ServiceAttributes serviceAttributes;

MODIFY
clouddriver-cloudfoundry/src/test/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServerGroupAtomicOperationConverterTest.java
clouddriver-cloudfoundry/src/test/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServerGroupAtomicOperationConverterTest.java
@@ -22,7 +22,6 @@ import static org.mockito.Mockito.when;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.spinnaker.clouddriver.artifacts.ArtifactCredentialsRepository;
-import com.netflix.spinnaker.clouddriver.artifacts.ArtifactDownloader;
import com.netflix.spinnaker.clouddriver.cloudfoundry.artifacts.ArtifactCredentialsFromString;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClient;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.MockCloudFoundryClient;
@@ -105,9 +104,7 @@ class DeployCloudFoundryServerGroupAtomicOperationConverterTest {
private final DeployCloudFoundryServerGroupAtomicOperationConverter converter =
new DeployCloudFoundryServerGroupAtomicOperationConverter(
- null,
- artifactCredentialsRepository,
- new ArtifactDownloader(artifactCredentialsRepository));
+ null, artifactCredentialsRepository);
@BeforeEach
void initializeClassUnderTest() {

MODIFY
clouddriver-cloudfoundry/src/test/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServiceAtomicOperationConverterTest.java
clouddriver-cloudfoundry/src/test/java/com/netflix/spinnaker/clouddriver/cloudfoundry/deploy/converters/DeployCloudFoundryServiceAtomicOperationConverterTest.java
@@ -24,7 +24,6 @@ import static org.mockito.Mockito.when;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.netflix.spinnaker.clouddriver.artifacts.ArtifactCredentialsRepository;
-import com.netflix.spinnaker.clouddriver.artifacts.ArtifactDownloader;
import com.netflix.spinnaker.clouddriver.cloudfoundry.artifacts.ArtifactCredentialsFromString;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClient;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.MockCloudFoundryClient;
@@ -104,8 +103,7 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
private final AccountCredentialsProvider accountCredentialsProvider =
new DefaultAccountCredentialsProvider(accountCredentialsRepository);
private final DeployCloudFoundryServiceAtomicOperationConverter converter =
- new DeployCloudFoundryServiceAtomicOperationConverter(
- new ArtifactDownloader(artifactCredentialsRepository));
+ new DeployCloudFoundryServiceAtomicOperationConverter();
@BeforeEach
void initializeClassUnderTest() {
@@ -141,7 +139,7 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
HashMap.of(
"service_instance_name", "my-service-instance-name",
"service_plan", "my-service-plan",
- "tags", List.of("my-tag").asJava(),
+ "tags", Collections.singletonList("my-tag"),
"parameters", "{\"foo\": \"bar\"}")
.toJavaMap();
@@ -157,7 +155,7 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
HashMap.of(
"service_instance_name", "my-service-instance-name",
"service_plan", "my-service-plan",
- "tags", List.of("my-tag").asJava(),
+ "tags", Collections.singletonList("my-tag"),
"parameters", "{\"foo\": \"bar\"}")
.toJavaMap();
@@ -173,7 +171,7 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
HashMap.of(
"service", "my-service",
"service_instance_name", "my-service-instance-name",
- "tags", List.of("my-tag").asJava(),
+ "tags", Collections.singletonList("my-tag"),
"parameters", "{\"foo\": \"bar\"}")
.toJavaMap();
@@ -191,7 +189,7 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
"syslog_drain_url", "test-syslog-drain-url",
"updatable", false,
"route_service_url", "test-route-service-url",
- "tags", List.of("my-tag").asJava(),
+ "tags", Collections.singletonList("my-tag"),
"credentials_map", "{\"foo\": \"bar\"}")
.toJavaMap();
@@ -203,7 +201,7 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
.setRouteServiceUrl("test-route-service-url")
.setTags(Collections.singleton("my-tag"))
.setUpdatable(false)
- .setCredentials(HashMap.<String, Object>of("foo", "bar").toJavaMap()));
+ .setCredentials(Collections.singletonMap("foo", "bar")));
}
@Test
@@ -212,7 +210,7 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
HashMap.of(
"syslog_drain_url", "test-syslog-drain-url",
"route_service_url", "test-route-service-url",
- "tags", List.of("my-tag").asJava(),
+ "tags", Collections.singletonList("my-tag"),
"credentials_map", "{\"foo\": \"bar\"}")
.toJavaMap();
@@ -222,43 +220,6 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
"Manifest is missing the service name");
}
- @Test
- void convertDescriptionWithDownloadedManifest() {
- final Map input =
- HashMap.of(
- "credentials", "test",
- "region", "org > space",
- "manifest",
- HashMap.of(
- "artifact",
- HashMap.of(
- "artifactAccount", "test",
- "reference", "ref1",
- "type", "test")
- .toJavaMap())
- .toJavaMap())
- .toJavaMap();
-
- final DeployCloudFoundryServiceDescription result = converter.convertDescription(input);
-
- assertThat(result.getSpace())
- .isEqualToComparingFieldByFieldRecursively(
- CloudFoundrySpace.builder()
- .id("space-guid")
- .name("space")
- .organization(CloudFoundryOrganization.builder().id("org-guid").name("org").build())
- .build());
- assertThat(result.getServiceAttributes())
- .isEqualToComparingFieldByFieldRecursively(
- new DeployCloudFoundryServiceDescription.ServiceAttributes()
- .setService("my-service")
- .setServiceInstanceName("my-service-instance-name")
- .setServicePlan("my-service-plan")
- .setTags(Collections.singleton("tag1"))
- .setUpdatable(false)
- .setParameterMap(HashMap.<String, Object>of("foo", "bar").toJavaMap()));
- }
-
@Test
void convertDescriptionWithUserProvidedInput() {
final Map input =
@@ -270,16 +231,14 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
"userProvided",
true,
"manifest",
- HashMap.of(
- "direct",
+ Collections.singletonList(
HashMap.of(
"serviceInstanceName", "userProvidedServiceName",
- "tags", List.of("my-tag").asJava(),
+ "tags", Collections.singletonList("my-tag"),
"syslogDrainUrl", "http://syslogDrainUrl.io",
"credentials", "{\"foo\": \"bar\"}",
"routeServiceUrl", "http://routeServiceUrl.io")
- .toJavaMap())
- .toJavaMap())
+ .toJavaMap()))
.toJavaMap();
final DeployCloudFoundryServiceDescription result = converter.convertDescription(input);
@@ -295,15 +254,11 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
.setCredentials(HashMap.<String, Object>of("foo", "bar").toJavaMap()));
}
- private static <K, V> Map<K, V> mapOf(K key, V value) {
- return HashMap.of(key, value).toJavaMap();
- }
-
private static class WithMap {
public WithMap() {}
public WithMap(String key, Object value) {
- this.mapField = HashMap.of(key, value).toJavaMap();
+ this.mapField = Collections.singletonMap(key, value);
}
@Nullable
@@ -317,7 +272,8 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
@Test
void deserializeYamlSerializedMap() {
final WithMap result =
- new ObjectMapper().convertValue(mapOf("mapField", "key1: value1"), WithMap.class);
+ new ObjectMapper()
+ .convertValue(Collections.singletonMap("mapField", "key1: value1"), WithMap.class);
assertThat(result).isEqualToComparingFieldByFieldRecursively(new WithMap("key1", "value1"));
}
@@ -326,7 +282,8 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
void deserializeJsonSerializedMap() {
final WithMap result =
new ObjectMapper()
- .convertValue(mapOf("mapField", "{\"key1\": \"value1\"}}"), WithMap.class);
+ .convertValue(
+ Collections.singletonMap("mapField", "{\"key1\": \"value1\"}}"), WithMap.class);
assertThat(result).isEqualToComparingFieldByFieldRecursively(new WithMap("key1", "value1"));
}
@@ -334,21 +291,26 @@ class DeployCloudFoundryServiceAtomicOperationConverterTest {
@Test
void deserializeAlreadyDeserializedMap() {
final WithMap result =
- new ObjectMapper().convertValue(mapOf("mapField", mapOf("key1", "value1")), WithMap.class);
+ new ObjectMapper()
+ .convertValue(
+ Collections.singletonMap("mapField", Collections.singletonMap("key1", "value1")),
+ WithMap.class);
assertThat(result).isEqualToComparingFieldByFieldRecursively(new WithMap("key1", "value1"));
}
@Test
void deserializeEmptyStringAsMap() {
- final WithMap result = new ObjectMapper().convertValue(mapOf("mapField", ""), WithMap.class);
+ final WithMap result =
+ new ObjectMapper().convertValue(Collections.singletonMap("mapField", ""), WithMap.class);
assertThat(result).isEqualToComparingFieldByFieldRecursively(new WithMap());
}
@Test
void deserializeNullStringAsMap() {
- final WithMap result = new ObjectMapper().convertValue(mapOf("mapField", null), WithMap.class);
+ final WithMap result =
+ new ObjectMapper().convertValue(Collections.singletonMap("mapField", null), WithMap.class);
assertThat(result).isEqualToComparingFieldByFieldRecursively(new WithMap());
}

feat(cf): add SpEL support for cf manifests (#4167)