diff --git a/multiapps-common-test/src/main/java/org/cloudfoundry/multiapps/common/test/Tester.java b/multiapps-common-test/src/main/java/org/cloudfoundry/multiapps/common/test/Tester.java index bb0a6afb..29e26943 100644 --- a/multiapps-common-test/src/main/java/org/cloudfoundry/multiapps/common/test/Tester.java +++ b/multiapps-common-test/src/main/java/org/cloudfoundry/multiapps/common/test/Tester.java @@ -1,9 +1,5 @@ package org.cloudfoundry.multiapps.common.test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.text.MessageFormat; import java.util.List; import java.util.Objects; @@ -15,6 +11,10 @@ import org.cloudfoundry.multiapps.common.util.JsonUtil; import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + public class Tester { private final Class testedClass; @@ -94,12 +94,13 @@ private void validateSuccessForSetExpectation(Set expectedSet, Set> { + private static final String FULL_PATH_TEMPLATE = "%s%s%s"; + private Map properties; private String prefix; private ProvidedValuesResolver valuesResolver; @@ -150,7 +152,9 @@ private boolean referenceResolutionIsPossible(String referenceKey, Map) currentProperty, deepReferenceKey); + currentProperty = resolveKeyInIterable(reference, (Collection) currentProperty, keyPart); keyPart = ""; } else if (currentProperty instanceof Map) { @SuppressWarnings("unchecked") @@ -184,12 +188,16 @@ protected Object resolveReferenceInDepth(Reference reference, Map listOfProperties, String longKey) { - if (StringUtils.isNumeric(key)) { + private Object resolveKeyInIterable(Reference reference, Collection listOfProperties, String longKey) { + if (StringUtils.isNumeric(longKey)) { try { - return IterableUtils.get(listOfProperties, Integer.parseInt(key)); + return IterableUtils.get(listOfProperties, Integer.parseInt(longKey)); } catch (IndexOutOfBoundsException e) { - throw new ContentException(e, Messages.UNABLE_TO_RESOLVE, NameUtil.getPrefixedName(prefix, longKey)); + throw new ContentException(e, Messages.UNABLE_TO_RESOLVE, buildFullQualifiedPath(reference)); } } - throw new ContentException(Messages.UNABLE_TO_RESOLVE, NameUtil.getPrefixedName(prefix, longKey)); + throw new ContentException(Messages.UNABLE_TO_RESOLVE, buildFullQualifiedPath(reference)); + } + + private String buildFullQualifiedPath(Reference reference) { + String referenceKey = reference.getDependencyName() != null + ? String.format(FULL_PATH_TEMPLATE, reference.getDependencyName(), NameUtil.DEFAULT_PREFIX_SEPARATOR, reference.getKey()) + : reference.getKey(); + return NameUtil.getPrefixedPath(prefix, referenceKey); } private String getReferencedPropertyKeyWithSuffix(Reference reference) { diff --git a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/util/NameUtil.java b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/util/NameUtil.java index 12ee364a..4d705305 100644 --- a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/util/NameUtil.java +++ b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/util/NameUtil.java @@ -20,4 +20,10 @@ public static String getPrefixedName(String prefix, String name, String separato return prefix + separator + name; } + public static String getPrefixedPath(String prefix, String path) { + if (StringUtils.isEmpty(prefix) || path.startsWith(prefix + DEFAULT_PREFIX_SEPARATOR)) { + return path; + } + return prefix + DEFAULT_PREFIX_SEPARATOR + path; + } } diff --git a/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/v3/DescriptorReferenceResolverTest.java b/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/v3/DescriptorReferenceResolverTest.java index 2e801144..a54b4dc7 100644 --- a/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/v3/DescriptorReferenceResolverTest.java +++ b/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/v3/DescriptorReferenceResolverTest.java @@ -21,18 +21,21 @@ class DescriptorReferenceResolverTest { static Stream testResolve() { return Stream.of( - // (0) Resolve references in resources: - Arguments.of("merged-01.yaml", new Expectation(Expectation.Type.JSON, "resolved-01.yaml.json")), - // (1) Resolve references in resources - cyclic dependencies & corner cases: - Arguments.of("merged-02.yaml", new Expectation(Expectation.Type.JSON, "resolved-02.yaml.json")), - // (2) Test error reporting on failure to resolve value: - Arguments.of("merged-03.yaml", - new Expectation(Expectation.Type.EXCEPTION, "Unable to resolve \"baz##non-existing\"")), - // (3) Resolve references in hooks: - Arguments.of("merged-04.yaml", new Expectation(Expectation.Type.JSON, "resolved-03.yaml.json")), - // (4) - Arguments.of("mtad-with-escaped-references.yaml", - new Expectation(Expectation.Type.JSON, "result-from-escaped-references.json"))); + // (0) Resolve references in resources: + Arguments.of("merged-01.yaml", new Expectation(Expectation.Type.JSON, "resolved-01.yaml.json")), + // (1) Resolve references in resources - cyclic dependencies & corner cases: + Arguments.of("merged-02.yaml", new Expectation(Expectation.Type.JSON, "resolved-02.yaml.json")), + // (2) Test error reporting on failure to resolve value: + Arguments.of("merged-03.yaml", + new Expectation(Expectation.Type.EXCEPTION, "Unable to resolve \"baz##bar#non-existing\"")), + // (3) Resolve references in hooks: + Arguments.of("merged-04.yaml", new Expectation(Expectation.Type.JSON, "resolved-03.yaml.json")), + // (4) + Arguments.of("mtad-with-escaped-references.yaml", + new Expectation(Expectation.Type.JSON, "result-from-escaped-references.json")), + // (5) + Arguments.of("merged-05.yaml", + new Expectation(Expectation.Type.EXCEPTION, "Unable to resolve \"module-a##module-b#invalid/0/url\""))); } @ParameterizedTest diff --git a/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/v3/merged-05.yaml b/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/v3/merged-05.yaml new file mode 100644 index 00000000..3b17d0c9 --- /dev/null +++ b/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/v3/merged-05.yaml @@ -0,0 +1,50 @@ +ID: com.sap.mta.v2.test.config-02 +_schema-version: 3.3.0 +version: 1.0.0 + +modules: + - name: module-a + type: com.sap.application.content + parameters: + content: + subaccount: + existing_destinations_policy: update + destinations: + - Name: destination-a + URL: ~{module-b/invalid/0/url} + forwardAuthToken: true + ServiceInstanceName: "service-a" + requires: + - name: service-destination + parameters: + content-target: true + - name: service-a + - name: module-b + + - name: module-b + type: application + path: "appBits.zip" + requires: + - name: service-a + parameters: + buildpack: staticfile_buildpack + memory: 1G + disk-quota: 1G + provides: + - name: module-b + properties: + default-url: ${default-url} + +resources: + - name: service-destination + type: org.cloudfoundry.managed-service + parameters: + service: destination + service-name: service-destination + service-plan: lite + + - name: service-a + type: org.cloudfoundry.managed-service + parameters: + service: xsuaa + service-plan: application