From 696f4bcaa4d5a5d9c2513a8e38d3dfb08c39b2a3 Mon Sep 17 00:00:00 2001 From: Yavor16 Date: Mon, 8 Apr 2024 10:58:29 +0300 Subject: [PATCH] add live router resolver --- .../LiveRoutesProvidedParametersResolver.java | 93 +++++++++++++++++++ ...utesProvidedParametersResolverBuilder.java | 18 ++++ ...eRoutesProvidedParametersResolverTest.java | 43 +++++++++ ...ith-use-live-routes-in-provides-param.yaml | 23 +++++ ...rom-use-live-routes-in-provides-param.json | 78 ++++++++++++++++ 5 files changed, 255 insertions(+) create mode 100644 multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolver.java create mode 100644 multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverBuilder.java create mode 100644 multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverTest.java create mode 100644 multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/mtad-with-use-live-routes-in-provides-param.yaml create mode 100644 multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/result-from-use-live-routes-in-provides-param.json diff --git a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolver.java b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolver.java new file mode 100644 index 00000000..b6324d9d --- /dev/null +++ b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolver.java @@ -0,0 +1,93 @@ +package org.cloudfoundry.multiapps.mta.resolvers; + +import java.util.List; +import java.util.Map; + +import org.cloudfoundry.multiapps.common.util.MiscUtil; +import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor; +import org.cloudfoundry.multiapps.mta.model.Module; +import org.cloudfoundry.multiapps.mta.model.ProvidedDependency; + +public class LiveRoutesProvidedParametersResolver implements Resolver { + + private static final String ROUTES_KEY_NAME = "routes"; + private static final String ROUTES_PLACEHOLDER_PREFIX = "{routes/"; + private static final String ROUTE_KEY_NAME = "route"; + private static final String DASH_SYMBOL = "/"; + private final DeploymentDescriptor descriptor; + private final String useLiveRoutesParameterKeyName; + + public LiveRoutesProvidedParametersResolver(DeploymentDescriptor descriptor, String useLiveRoutesParameterKeyName) { + this.descriptor = descriptor; + this.useLiveRoutesParameterKeyName = useLiveRoutesParameterKeyName; + } + + @Override + public DeploymentDescriptor resolve() { + descriptor.getModules() + .stream() + .filter(module -> module.getParameters() + .containsKey(ROUTES_KEY_NAME)) + .forEach(this::resolveProvidedDependencyOfModule); + + return descriptor; + } + + private void resolveProvidedDependencyOfModule(Module module) { + module.getProvidedDependencies() + .stream() + .filter(this::shouldUseLiveRoutes) + .forEach(providedDependency -> resolveProvidedDependencyParameters(providedDependency, module)); + } + + private boolean shouldUseLiveRoutes(ProvidedDependency providedDependency) { + if (providedDependency.getParameters() + .containsKey(useLiveRoutesParameterKeyName)) { + return MiscUtil. cast(providedDependency.getParameters() + .get(useLiveRoutesParameterKeyName)); + } + return false; + } + + private void resolveProvidedDependencyParameters(ProvidedDependency providedDependency, Module module) { + for (Map.Entry property : providedDependency.getProperties() + .entrySet()) { + if (!(property.getValue() instanceof String)) { + continue; + } + + List matchedReferences = ReferencePattern.PLACEHOLDER.match(MiscUtil.cast(property.getValue())); + + for (Reference reference : matchedReferences) { + handlePropertyReferences(module, property, MiscUtil.cast(property.getValue()), reference); + } + } + } + + private void handlePropertyReferences(Module module, Map.Entry property, String propertyValueString, + Reference reference) { + if (!reference.getMatchedPattern() + .contains(ROUTES_PLACEHOLDER_PREFIX)) { + return; + } + + int routeIndex = getRouteIndex(reference.getKey()); + + List> routes = MiscUtil.cast(module.getParameters() + .get(ROUTES_KEY_NAME)); + + String route = (String) routes.get(routeIndex) + .get(ROUTE_KEY_NAME); + String newPropertyValue = propertyValueString.replace(reference.getMatchedPattern(), route); + + property.setValue(newPropertyValue); + } + + private int getRouteIndex(String propertyValueString) { + int indexOfSlash = propertyValueString.indexOf(DASH_SYMBOL); + int indexOfSecondSlash = propertyValueString.indexOf(DASH_SYMBOL, indexOfSlash + 1); + String routeIndex = propertyValueString.substring(indexOfSlash + 1, indexOfSecondSlash); + + return Integer.parseInt(routeIndex); + } +} diff --git a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverBuilder.java b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverBuilder.java new file mode 100644 index 00000000..23069847 --- /dev/null +++ b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverBuilder.java @@ -0,0 +1,18 @@ +package org.cloudfoundry.multiapps.mta.resolvers; + +import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor; + +public class LiveRoutesProvidedParametersResolverBuilder { + + private final DeploymentDescriptor descriptor; + private final String useLiveRoutesParameterKeyName; + + public LiveRoutesProvidedParametersResolverBuilder(DeploymentDescriptor descriptor, String useLiveRoutesParameterKeyName) { + this.descriptor = descriptor; + this.useLiveRoutesParameterKeyName = useLiveRoutesParameterKeyName; + } + + public LiveRoutesProvidedParametersResolver build() { + return new LiveRoutesProvidedParametersResolver(descriptor, useLiveRoutesParameterKeyName); + } +} diff --git a/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverTest.java b/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverTest.java new file mode 100644 index 00000000..a5de362b --- /dev/null +++ b/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/resolvers/LiveRoutesProvidedParametersResolverTest.java @@ -0,0 +1,43 @@ +package org.cloudfoundry.multiapps.mta.resolvers; + +import org.cloudfoundry.multiapps.common.test.Tester; +import org.cloudfoundry.multiapps.mta.handlers.DescriptorParserFacade; +import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.InputStream; +import java.util.stream.Stream; + +public class LiveRoutesProvidedParametersResolverTest { + + public static final String USE_LIVE_ROUTES = "use-live-routes"; + protected final Tester tester = Tester.forClass(getClass()); + private LiveRoutesProvidedParametersResolver resolver; + + static Stream testResolve() { + return Stream.of( + Arguments.of("mtad-with-use-live-routes-in-provides-param.yaml", + new Tester.Expectation(Tester.Expectation.Type.JSON, "result-from-use-live-routes-in-provides-param.json"))); + } + + @ParameterizedTest + @MethodSource + void testResolve(String descriptorLocation, Tester.Expectation expectation) { + init(descriptorLocation); + + tester.test(() -> resolver.resolve(), expectation); + } + + private void init(String descriptorLocation) { + DeploymentDescriptor deploymentDescriptor = parseDeploymentDescriptor(descriptorLocation); + resolver = new LiveRoutesProvidedParametersResolver(deploymentDescriptor, USE_LIVE_ROUTES); + } + + private DeploymentDescriptor parseDeploymentDescriptor(String descriptorLocation) { + DescriptorParserFacade parser = new DescriptorParserFacade(); + InputStream descriptor = getClass().getResourceAsStream(descriptorLocation); + return parser.parseDeploymentDescriptor(descriptor); + } +} diff --git a/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/mtad-with-use-live-routes-in-provides-param.yaml b/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/mtad-with-use-live-routes-in-provides-param.yaml new file mode 100644 index 00000000..23a0b873 --- /dev/null +++ b/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/mtad-with-use-live-routes-in-provides-param.yaml @@ -0,0 +1,23 @@ +_schema-version: "3.0.0" +ID: hello +version: 0.1.0 + +modules: + - name: ztanaa + type: java.tomcat + path: backend.war + provides: + - name: backend-live + properties: + url: ${routes/0/route} + url1: ${routes/1/route} + parameters: + use-live-routes: true + - name: backend-idle + properties: + url: ${routes/0/route} + url1: ${routes/1/route} + parameters: + routes: + - route: "default-route.default-host.default-domain" + - route: "custom-route.custom-host.custom-domain" \ No newline at end of file diff --git a/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/result-from-use-live-routes-in-provides-param.json b/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/result-from-use-live-routes-in-provides-param.json new file mode 100644 index 00000000..f94817a0 --- /dev/null +++ b/multiapps-mta/src/test/resources/org/cloudfoundry/multiapps/mta/resolvers/result-from-use-live-routes-in-provides-param.json @@ -0,0 +1,78 @@ +{ + "majorSchemaVersion" : 3, + "schemaVersion" : "3.0.0", + "id" : "hello", + "version" : "0.1.0", + "modules" : [ { + "majorSchemaVersion" : 3, + "name" : "ztanaa", + "type" : "java.tomcat", + "path" : "backend.war", + "properties" : { }, + "parameters" : { + "routes" : [ { + "route" : "default-route.default-host.default-domain" + }, { + "route" : "custom-route.custom-host.custom-domain" + } ] + }, + "requiredDependencies" : [ ], + "providedDependencies" : [ { + "majorSchemaVersion" : 3, + "name" : "backend-live", + "isPublic" : false, + "properties" : { + "url" : "default-route.default-host.default-domain", + "url1" : "custom-route.custom-host.custom-domain" + }, + "parameters" : { + "use-live-routes" : true + }, + "propertiesMetadata" : { + "metadata" : { } + }, + "parametersMetadata" : { + "metadata" : { } + } + }, { + "majorSchemaVersion" : 3, + "name" : "backend-idle", + "isPublic" : false, + "properties" : { + "url" : "${routes/0/route}", + "url1" : "${routes/1/route}" + }, + "parameters" : { }, + "propertiesMetadata" : { + "metadata" : { } + }, + "parametersMetadata" : { + "metadata" : { } + } + }, { + "majorSchemaVersion" : 3, + "name" : "ztanaa", + "isPublic" : false, + "properties" : { }, + "parameters" : { }, + "propertiesMetadata" : { + "metadata" : { } + }, + "parametersMetadata" : { + "metadata" : { } + } + } ], + "propertiesMetadata" : { + "metadata" : { } + }, + "parametersMetadata" : { + "metadata" : { } + }, + "hooks" : [ ] + } ], + "resources" : [ ], + "parameters" : { }, + "parametersMetadata" : { + "metadata" : { } + } +} \ No newline at end of file