diff --git a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/actions/javadsl/translators/core/ForeachTranslator.java b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/actions/javadsl/translators/core/ForeachTranslator.java new file mode 100644 index 000000000..85d0f7912 --- /dev/null +++ b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/actions/javadsl/translators/core/ForeachTranslator.java @@ -0,0 +1,76 @@ +package org.springframework.sbm.mule.actions.javadsl.translators.core; + +import org.mulesoft.schema.mule.core.ForeachProcessorType; +import org.springframework.sbm.mule.actions.javadsl.translators.Bean; +import org.springframework.sbm.mule.actions.javadsl.translators.DslSnippet; +import org.springframework.sbm.mule.actions.javadsl.translators.MuleComponentToSpringIntegrationDslTranslator; +import org.springframework.sbm.mule.api.toplevel.ForeachTopLevelElement; +import org.springframework.sbm.mule.api.toplevel.configuration.MuleConfigurations; +import org.springframework.stereotype.Component; + +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static java.util.Collections.emptySet; + +@Component +public class ForeachTranslator implements MuleComponentToSpringIntegrationDslTranslator { + @Override + public Class getSupportedMuleType() { + return ForeachProcessorType.class; + } + + @Override + public DslSnippet translate(int id, + ForeachProcessorType component, + QName name, + MuleConfigurations muleConfigurations, + String flowName, + Map translatorsMap + ) { + + ForeachTopLevelElement forEachTopLevelTranslations = + new ForeachTopLevelElement( + flowName, + component.getMessageProcessorOrOutboundEndpoint(), + muleConfigurations, + translatorsMap + ); + + Set beans = forEachTopLevelTranslations + .getDslSnippets() + .stream() + .map(DslSnippet::getBeans) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + + Set requiredImports = forEachTopLevelTranslations + .getDslSnippets() + .stream() + .map(DslSnippet::getRequiredImports) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + Set dependencies = forEachTopLevelTranslations + .getDslSnippets() + .stream() + .map(DslSnippet::getRequiredDependencies) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + return new DslSnippet( + " //TODO: translate expression " + component.getCollection() + " which must produces an array\n" + + " // to iterate over\n" + + " .split()\n" + + " " + forEachTopLevelTranslations.renderDslSnippet() + "\n" + + " .aggregate()", + requiredImports, + dependencies, + beans + ); + } +} diff --git a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/actions/javadsl/translators/db/SelectTranslator.java b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/actions/javadsl/translators/db/SelectTranslator.java index 216faee29..20da2e9ec 100644 --- a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/actions/javadsl/translators/db/SelectTranslator.java +++ b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/actions/javadsl/translators/db/SelectTranslator.java @@ -44,9 +44,11 @@ public DslSnippet translate(int id, SelectMessageProcessorType component, String limitString = component.getMaxRows() == null ? "" : " LIMIT " + component.getMaxRows(); + String query = component.getDynamicQuery() == null ? component.getParameterizedQuery() + : component.getDynamicQuery(); return new DslSnippet("// TODO: substitute expression language with appropriate java code \n" + " .handle((p, h) -> jdbcTemplate.queryForList(\"" + - escapeDoubleQuotes(component.getDynamicQuery()) + escapeDoubleQuotes(query) + limitString + "\"))", Collections.emptySet(), Set.of( diff --git a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ApiRouterKitFlowTopLevelElement.java b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ApiRouterKitFlowTopLevelElement.java index 25306930b..9a62538c8 100644 --- a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ApiRouterKitFlowTopLevelElement.java +++ b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ApiRouterKitFlowTopLevelElement.java @@ -65,6 +65,7 @@ protected String composeSuffixDslCode() { public Set getRequiredImports() { Set requiredImports = super.getRequiredImports(); requiredImports.add("org.springframework.http.HttpMethod"); + requiredImports.add("org.springframework.integration.http.dsl.Http"); return requiredImports; } diff --git a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ChoiceTopLevelElement.java b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ChoiceTopLevelElement.java index 99e622b68..33931261f 100644 --- a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ChoiceTopLevelElement.java +++ b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ChoiceTopLevelElement.java @@ -35,7 +35,6 @@ public String renderDslSnippet() { Set requiredImports = getRequiredImports(); requiredImports.add("org.springframework.integration.dsl.IntegrationFlow"); requiredImports.add("org.springframework.integration.dsl.IntegrationFlows"); - requiredImports.add("org.springframework.integration.amqp.dsl.Amqp"); getDslSnippets().forEach(ds -> requiredImports.addAll(ds.getRequiredImports())); return sb.toString(); } diff --git a/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ForeachTopLevelElement.java b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ForeachTopLevelElement.java new file mode 100644 index 000000000..3b99abb74 --- /dev/null +++ b/components/sbm-recipes-mule-to-boot/src/main/java/org/springframework/sbm/mule/api/toplevel/ForeachTopLevelElement.java @@ -0,0 +1,31 @@ +package org.springframework.sbm.mule.api.toplevel; + +import org.springframework.sbm.mule.actions.javadsl.translators.DslSnippet; +import org.springframework.sbm.mule.actions.javadsl.translators.MuleComponentToSpringIntegrationDslTranslator; +import org.springframework.sbm.mule.api.toplevel.configuration.MuleConfigurations; + +import javax.xml.bind.JAXBElement; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class ForeachTopLevelElement extends AbstractTopLevelElement{ + + protected String composePrefixDslCode() { + return ""; + } + + public String renderDslSnippet() { + StringBuilder sb = new StringBuilder(); + String dsl = getDslSnippets().stream().map(DslSnippet::getRenderedSnippet).collect(Collectors.joining("\n")); + sb.append(dsl); + return sb.toString(); + } + + public ForeachTopLevelElement(String flowName, + List> elements, + MuleConfigurations muleConfigurations, + Map translatorsMap) { + super(flowName, elements, muleConfigurations, translatorsMap); + } +} diff --git a/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/JavaDSLActionBaseTest.java b/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/JavaDSLActionBaseTest.java index c3ed38c20..8bd0cdc9f 100644 --- a/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/JavaDSLActionBaseTest.java +++ b/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/JavaDSLActionBaseTest.java @@ -76,7 +76,8 @@ public void setup() { new DwlTransformTranslator(), new HttpRequestTranslator(), new ChoiceTranslator(), - new SelectTranslator() + new SelectTranslator(), + new ForeachTranslator() ); List topLevelTypeFactories = List.of( new FlowTopLevelElementFactory(translators), diff --git a/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/MuleToJavaDSLDBTest.java b/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/MuleToJavaDSLDBTest.java index 594caa235..0323312b9 100644 --- a/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/MuleToJavaDSLDBTest.java +++ b/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/MuleToJavaDSLDBTest.java @@ -26,7 +26,7 @@ public class MuleToJavaDSLDBTest extends JavaDSLActionBaseTest { @Test - public void translateDbSelectQuery() { + public void translateDbSelectDynamicQuery() { String muleXml = "\n" + "\n" + "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " " + + " \n" + + "\n"; + + addXMLFileToResource(muleXml); + runAction(); + assertThat(projectContext.getProjectJavaSources().list()).hasSize(1); + assertThat(projectContext.getProjectJavaSources().list().get(0).print()) + .isEqualTo( + "package com.example.javadsl;\n" + + "import org.springframework.context.annotation.Bean;\n" + + "import org.springframework.context.annotation.Configuration;\n" + + "import org.springframework.integration.dsl.IntegrationFlow;\n" + + "import org.springframework.integration.dsl.IntegrationFlows;\n" + + "import org.springframework.integration.handler.LoggingHandler;\n" + + "import org.springframework.integration.http.dsl.Http;\n" + + "\n" + + "@Configuration\n" + + "public class FlowConfigurations {\n" + + " void dbMysql_config() {\n" + + " //FIXME: element is not supported for conversion: \n" + + " }\n" + + "\n" + + " @Bean\n" + + " IntegrationFlow dbFlow(org.springframework.jdbc.core.JdbcTemplate jdbcTemplate) {\n" + + " return IntegrationFlows.from(Http.inboundChannelAdapter(\"/\")).handle((p, h) -> p)\n" + + " .log(LoggingHandler.Level.INFO)\n" + + " // TODO: substitute expression language with appropriate java code \n" + + " .handle((p, h) -> jdbcTemplate.queryForList(\"SELECT * FROM STUDENTS LIMIT 500\"))\n" + + " .get();\n" + + " }}"); + } } diff --git a/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/MuleToJavaDSLForeachTest.java b/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/MuleToJavaDSLForeachTest.java new file mode 100644 index 000000000..0ffbe0a63 --- /dev/null +++ b/components/sbm-recipes-mule-to-boot/src/test/java/org/springframework/sbm/mule/actions/MuleToJavaDSLForeachTest.java @@ -0,0 +1,242 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm.mule.actions; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MuleToJavaDSLForeachTest extends JavaDSLActionBaseTest { + + @Test + public void simpleForEachTest() { + String xml = "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + addXMLFileToResource(xml); + runAction(); + assertThat(getGeneratedConfigFile()).isEqualTo( + "package com.example.javadsl;\n" + + "import org.springframework.context.annotation.Bean;\n" + + "import org.springframework.context.annotation.Configuration;\n" + + "import org.springframework.integration.dsl.IntegrationFlow;\n" + + "import org.springframework.integration.dsl.IntegrationFlows;\n" + + "import org.springframework.integration.handler.LoggingHandler;\n" + + "import org.springframework.integration.http.dsl.Http;\n" + + "\n" + + "@Configuration\n" + + "public class FlowConfigurations {\n" + + " @Bean\n" + + " IntegrationFlow foreach() {\n" + + " return IntegrationFlows.from(Http.inboundChannelAdapter(\"/foreach\")).handle((p, h) -> p)\n" + + " //TODO: translate expression #[['apple', 'banana', 'orange']] which must produces an array\n" + + " // to iterate over\n" + + " .split()\n" + + " .log(LoggingHandler.Level.INFO, \"${payload}\")\n" + + " .aggregate()\n" + + " .log(LoggingHandler.Level.INFO, \"Done with for looping\")\n" + + " .get();\n" + + " }}"); + } + + @Test + public void forEachWithChoice() { + + String xml = "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + addXMLFileToResource(xml); + runAction(); + + assertThat(getGeneratedConfigFile()).isEqualTo( + "package com.example.javadsl;\n" + + "import org.springframework.context.annotation.Bean;\n" + + "import org.springframework.context.annotation.Configuration;\n" + + "import org.springframework.integration.dsl.IntegrationFlow;\n" + + "import org.springframework.integration.dsl.IntegrationFlows;\n" + + "import org.springframework.integration.handler.LoggingHandler;\n" + + "import org.springframework.integration.http.dsl.Http;\n" + + "\n" + + "@Configuration\n" + + "public class FlowConfigurations {\n" + + " @Bean\n" + + " IntegrationFlow foreach() {\n" + + " return IntegrationFlows.from(Http.inboundChannelAdapter(\"/foreach\")).handle((p, h) -> p)\n" + + " //TODO: translate expression #[[1, 2, 3, 4]] which must produces an array\n" + + " // to iterate over\n" + + " .split()\n" + + " /* TODO: LinkedMultiValueMap might not be apt, substitute with right input type*/\n" + + " ., String>route(\n" + + " p -> p.getFirst(\"dataKey\") /*TODO: use apt condition*/,\n" + + " m -> m\n" + + " .subFlowMapping(\"dataValue\" /*TODO: Translate dataValue to #[payload == 1]*/,\n" + + " sf -> sf.log(LoggingHandler.Level.INFO, \"Ondu\")\n" + + " )\n" + + " .subFlowMapping(\"dataValue\" /*TODO: Translate dataValue to #[payload == 2]*/,\n" + + " sf -> sf.log(LoggingHandler.Level.INFO, \"Eradu\")\n" + + " )\n" + + " .subFlowMapping(\"dataValue\" /*TODO: Translate dataValue to #[payload == 3]*/,\n" + + " sf -> sf.log(LoggingHandler.Level.INFO, \"Mooru\")\n" + + " )\n" + + " .resolutionRequired(false)\n" + + " .defaultSubFlowMapping(sf -> sf.log(LoggingHandler.Level.INFO, \"Moorina mele\"))\n" + + " )\n" + + " .aggregate()\n" + + " .log(LoggingHandler.Level.INFO, \"Done with for looping\")\n" + + " .get();\n" + + " }}"); + } + + @Test + public void forEachWithCallToSubflow() { + + String xml = "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + addXMLFileToResource(xml); + runAction(); + + assertThat(getGeneratedConfigFile()).isEqualTo( + "package com.example.javadsl;\n" + + "import org.springframework.context.annotation.Bean;\n" + + "import org.springframework.context.annotation.Configuration;\n" + + "import org.springframework.integration.dsl.IntegrationFlow;\n" + + "import org.springframework.integration.dsl.IntegrationFlows;\n" + + "import org.springframework.integration.handler.LoggingHandler;\n" + + "import org.springframework.integration.http.dsl.Http;\n" + + "import org.springframework.util.LinkedMultiValueMap;\n" + + "\n" + + "@Configuration\n" + + "public class FlowConfigurations {\n" + + " @Bean\n" + + " IntegrationFlow foreach(org.springframework.integration.dsl.IntegrationFlow logOneInKannada) {\n" + + " return IntegrationFlows.from(Http.inboundChannelAdapter(\"/foreach\")).handle((p, h) -> p)\n" + + " //TODO: translate expression #[[1, 2, 3, 4]] which must produces an array\n" + + " // to iterate over\n" + + " .split()\n" + + " /* TODO: LinkedMultiValueMap might not be apt, substitute with right input type*/\n" + + " ., String>route(\n" + + " p -> p.getFirst(\"dataKey\") /*TODO: use apt condition*/,\n" + + " m -> m\n" + + " .subFlowMapping(\"dataValue\" /*TODO: Translate dataValue to #[payload == 1]*/,\n" + + " sf -> sf.gateway(logOneInKannada)\n" + + " )\n" + + " .subFlowMapping(\"dataValue\" /*TODO: Translate dataValue to #[payload == 2]*/,\n" + + " sf -> sf.log(LoggingHandler.Level.INFO, \"Eradu\")\n" + + " )\n" + + " .subFlowMapping(\"dataValue\" /*TODO: Translate dataValue to #[payload == 3]*/,\n" + + " sf -> sf.log(LoggingHandler.Level.INFO, \"Mooru\")\n" + + " )\n" + + " .resolutionRequired(false)\n" + + " .defaultSubFlowMapping(sf -> sf.log(LoggingHandler.Level.INFO, \"Moorina mele\"))\n" + + " )\n" + + " .aggregate()\n" + + " .log(LoggingHandler.Level.INFO, \"Done with for looping\")\n" + + " .get();\n" + + " }\n" + + "\n" + + " @Bean\n" + + " IntegrationFlow logOneInKannada() {\n" + + " return flow -> flow\n" + + " .log(LoggingHandler.Level.INFO, \"Ondu\");\n" + + " }}"); + } + + private String getGeneratedConfigFile() { + return projectContext.getProjectJavaSources().list().get(0).print(); + } +}