From af88f820b35ae2e3689dd5c1619c1cfc6c4909f2 Mon Sep 17 00:00:00 2001 From: Rodrigo Merino Date: Thu, 19 Dec 2024 19:02:27 -0300 Subject: [PATCH 1/3] W-17475148: Simple type params handler not handling certain expression (#14097) param values --- .../dsl/spring/BeanDefinitionCreator.java | 11 ++- .../CreateComponentBeanDefinitionRequest.java | 5 ++ ...ateDslParamGroupBeanDefinitionRequest.java | 7 ++ .../CreateParamBeanDefinitionRequest.java | 8 ++ .../SimpleTypeBeanBaseDefinitionCreator.java | 14 +++- .../SimpleTypeBeanParamDefinitionCreator.java | 5 ++ ...ypeBeanParamDefinitionCreatorTestCase.java | 75 +++++++++++++++++++ 7 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java index a29369f76a75..edb73fe95d36 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java @@ -6,8 +6,11 @@ */ package org.mule.runtime.config.internal.dsl.spring; +import static org.mule.runtime.api.i18n.I18nMessageFactory.createStaticMessage; + import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition; +import org.mule.runtime.api.exception.MuleRuntimeException; import org.mule.runtime.ast.api.ComponentAst; import org.mule.runtime.config.internal.dsl.model.SpringComponentModel; import org.mule.runtime.config.internal.factories.ConstantFactoryBean; @@ -41,8 +44,12 @@ public void setNext(BeanDefinitionCreator nextBeanDefinitionCreator) { * @param request */ public final void processRequest(Map springComponentModels, R request) { - if (handleRequest(springComponentModels, request)) { - return; + try { + if (handleRequest(springComponentModels, request)) { + return; + } + } catch (Exception e) { + throw new MuleRuntimeException(createStaticMessage("Exception processing " + request.toString()), e); } if (next != null) { next.processRequest(springComponentModels, request); diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java index 1d4f65a25ffd..1b037148f59e 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java @@ -34,4 +34,9 @@ public ComponentAst resolveConfigurationComponent() { public Consumer getNestedComponentParamProcessor() { return nestedComponentParamProcessor; } + + @Override + public String toString() { + return "component request for `" + getComponent().toString(); + } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java index 37a218746a6a..2ba6fc0b63f5 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java @@ -49,4 +49,11 @@ public ParameterGroupModel getParamGroupModel() { public ComponentParameterAst getParameter(String parameterName) { return paramOwnerComponent.getParameter(paramGroupModel.getName(), parameterName); } + + @Override + public String toString() { + return "DSL param group request for `" + + getParamGroupModel().getName() + "` in component `" + + getParamOwnerComponent().toString(); + } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java index 3b951f182da7..5f464861686f 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java @@ -65,4 +65,12 @@ public ComponentParameterAst getParameter(String parameterName) { .findFirst() .orElse(null); } + + @Override + public String toString() { + return "param request for `" + + getParam().getGroupModel().getName() + "." + + getParam().getModel().getName() + "` in component `" + + getParamOwnerComponent().toString(); + } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java index 5a0c90659625..24de05a9a4b9 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java @@ -31,12 +31,18 @@ protected final boolean handleRequest(Map sp R createBeanDefinitionRequest) { Class type = createBeanDefinitionRequest.getSpringComponentModel().getType(); - if (!isSimpleType(type)) { - return false; + if (isSimpleType(type) + // Expressions are String, which are simple values for the spring bean definitions + || isExpressionValue(createBeanDefinitionRequest)) { + createBeanDefinitionRequest.getSpringComponentModel().setType(type); + return doHandleRequest(createBeanDefinitionRequest, type); } - createBeanDefinitionRequest.getSpringComponentModel().setType(type); - return doHandleRequest(createBeanDefinitionRequest, type); + return false; + } + + protected boolean isExpressionValue(R request) { + return false; } protected abstract boolean doHandleRequest(R createBeanDefinitionRequest, Class type); diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java index c80262636958..cc6b726c3b9c 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java @@ -41,6 +41,11 @@ protected boolean doHandleRequest(CreateParamBeanDefinitionRequest createBeanDef return true; } + @Override + protected boolean isExpressionValue(CreateParamBeanDefinitionRequest request) { + return request.getParam().getValue().isLeft(); + } + static Object resolveParamValue(final ComponentParameterAst param, boolean disableTrimWhitespaces, boolean disablePojoCdataTrimWhitespaces) { return param.getValue() diff --git a/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java b/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java new file mode 100644 index 000000000000..0348dae9425f --- /dev/null +++ b/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java @@ -0,0 +1,75 @@ +/* + * Copyright 2023 Salesforce, Inc. All rights reserved. + * The software in this package is published under the terms of the CPAL v1.0 + * license, a copy of which has been included with this distribution in the + * LICENSE.txt file. + */ +package org.mule.runtime.config.internal.dsl.spring; + +import static org.mule.runtime.api.functional.Either.left; +import static org.mule.runtime.api.functional.Either.right; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.mule.runtime.ast.api.ComponentAst; +import org.mule.runtime.ast.api.ComponentParameterAst; +import org.mule.runtime.config.internal.dsl.model.SpringComponentModel; +import org.mule.runtime.dsl.api.component.ComponentBuildingDefinition; +import org.mule.tck.junit4.AbstractMuleTestCase; + +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import io.qameta.allure.Issue; + +public class SimpleTypeBeanParamDefinitionCreatorTestCase extends AbstractMuleTestCase { + + private SimpleTypeBeanParamDefinitionCreator simpleTypeParamDefinitionCreator; + private CreateParamBeanDefinitionRequest createParamDefinitionRequest; + private Map springComponentModels; + + @Before + public void setUp() { + simpleTypeParamDefinitionCreator = new SimpleTypeBeanParamDefinitionCreator(true, true); + createParamDefinitionRequest = mock(CreateParamBeanDefinitionRequest.class); + SpringComponentModel springComponentModel = new SpringComponentModel(); + when(createParamDefinitionRequest.getSpringComponentModel()).thenReturn(springComponentModel); + when(createParamDefinitionRequest.getComponentBuildingDefinition()).thenReturn(mock(ComponentBuildingDefinition.class)); + } + + @Test + @Issue("W-17475148") + public void complexObjectFromExpression() { + SpringComponentModel springComponentModel = createParamDefinitionRequest.getSpringComponentModel(); + springComponentModel.setType(Map.class); + + final ComponentParameterAst param = mock(ComponentParameterAst.class); + when(param.getValue()).thenReturn(left("'some DW expression'")); + + when(createParamDefinitionRequest.getParam()).thenReturn(param); + + boolean result = simpleTypeParamDefinitionCreator.handleRequest(springComponentModels, createParamDefinitionRequest); + assertThat("request not handled when it must", result, is(true)); + } + + @Test + @Issue("W-17475148") + public void complexObjectInlineNotHandled() { + SpringComponentModel springComponentModel = createParamDefinitionRequest.getSpringComponentModel(); + springComponentModel.setType(Map.class); + + final ComponentParameterAst param = mock(ComponentParameterAst.class); + when(param.getValue()).thenReturn(right(mock(ComponentAst.class))); + + when(createParamDefinitionRequest.getParam()).thenReturn(param); + + boolean result = simpleTypeParamDefinitionCreator.handleRequest(springComponentModels, createParamDefinitionRequest); + assertThat("request handled when it must not", result, is(false)); + } + +} From a01357af25e2a34ae2847b7de34d58649cc598cf Mon Sep 17 00:00:00 2001 From: elrodro83 Date: Mon, 23 Dec 2024 10:24:44 -0300 Subject: [PATCH 2/3] Revert "W-17475148: Simple type params handler not handling certain expression (#14097)" This reverts commit af88f820b35ae2e3689dd5c1619c1cfc6c4909f2. --- .../dsl/spring/BeanDefinitionCreator.java | 11 +-- .../CreateComponentBeanDefinitionRequest.java | 5 -- ...ateDslParamGroupBeanDefinitionRequest.java | 7 -- .../CreateParamBeanDefinitionRequest.java | 8 -- .../SimpleTypeBeanBaseDefinitionCreator.java | 14 +--- .../SimpleTypeBeanParamDefinitionCreator.java | 5 -- ...ypeBeanParamDefinitionCreatorTestCase.java | 75 ------------------- 7 files changed, 6 insertions(+), 119 deletions(-) delete mode 100644 modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java index edb73fe95d36..a29369f76a75 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java @@ -6,11 +6,8 @@ */ package org.mule.runtime.config.internal.dsl.spring; -import static org.mule.runtime.api.i18n.I18nMessageFactory.createStaticMessage; - import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition; -import org.mule.runtime.api.exception.MuleRuntimeException; import org.mule.runtime.ast.api.ComponentAst; import org.mule.runtime.config.internal.dsl.model.SpringComponentModel; import org.mule.runtime.config.internal.factories.ConstantFactoryBean; @@ -44,12 +41,8 @@ public void setNext(BeanDefinitionCreator nextBeanDefinitionCreator) { * @param request */ public final void processRequest(Map springComponentModels, R request) { - try { - if (handleRequest(springComponentModels, request)) { - return; - } - } catch (Exception e) { - throw new MuleRuntimeException(createStaticMessage("Exception processing " + request.toString()), e); + if (handleRequest(springComponentModels, request)) { + return; } if (next != null) { next.processRequest(springComponentModels, request); diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java index 1b037148f59e..1d4f65a25ffd 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java @@ -34,9 +34,4 @@ public ComponentAst resolveConfigurationComponent() { public Consumer getNestedComponentParamProcessor() { return nestedComponentParamProcessor; } - - @Override - public String toString() { - return "component request for `" + getComponent().toString(); - } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java index 2ba6fc0b63f5..37a218746a6a 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java @@ -49,11 +49,4 @@ public ParameterGroupModel getParamGroupModel() { public ComponentParameterAst getParameter(String parameterName) { return paramOwnerComponent.getParameter(paramGroupModel.getName(), parameterName); } - - @Override - public String toString() { - return "DSL param group request for `" - + getParamGroupModel().getName() + "` in component `" - + getParamOwnerComponent().toString(); - } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java index 5f464861686f..3b951f182da7 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java @@ -65,12 +65,4 @@ public ComponentParameterAst getParameter(String parameterName) { .findFirst() .orElse(null); } - - @Override - public String toString() { - return "param request for `" - + getParam().getGroupModel().getName() + "." - + getParam().getModel().getName() + "` in component `" - + getParamOwnerComponent().toString(); - } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java index 24de05a9a4b9..5a0c90659625 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java @@ -31,18 +31,12 @@ protected final boolean handleRequest(Map sp R createBeanDefinitionRequest) { Class type = createBeanDefinitionRequest.getSpringComponentModel().getType(); - if (isSimpleType(type) - // Expressions are String, which are simple values for the spring bean definitions - || isExpressionValue(createBeanDefinitionRequest)) { - createBeanDefinitionRequest.getSpringComponentModel().setType(type); - return doHandleRequest(createBeanDefinitionRequest, type); + if (!isSimpleType(type)) { + return false; } - return false; - } - - protected boolean isExpressionValue(R request) { - return false; + createBeanDefinitionRequest.getSpringComponentModel().setType(type); + return doHandleRequest(createBeanDefinitionRequest, type); } protected abstract boolean doHandleRequest(R createBeanDefinitionRequest, Class type); diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java index cc6b726c3b9c..c80262636958 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java @@ -41,11 +41,6 @@ protected boolean doHandleRequest(CreateParamBeanDefinitionRequest createBeanDef return true; } - @Override - protected boolean isExpressionValue(CreateParamBeanDefinitionRequest request) { - return request.getParam().getValue().isLeft(); - } - static Object resolveParamValue(final ComponentParameterAst param, boolean disableTrimWhitespaces, boolean disablePojoCdataTrimWhitespaces) { return param.getValue() diff --git a/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java b/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java deleted file mode 100644 index 0348dae9425f..000000000000 --- a/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2023 Salesforce, Inc. All rights reserved. - * The software in this package is published under the terms of the CPAL v1.0 - * license, a copy of which has been included with this distribution in the - * LICENSE.txt file. - */ -package org.mule.runtime.config.internal.dsl.spring; - -import static org.mule.runtime.api.functional.Either.left; -import static org.mule.runtime.api.functional.Either.right; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.mule.runtime.ast.api.ComponentAst; -import org.mule.runtime.ast.api.ComponentParameterAst; -import org.mule.runtime.config.internal.dsl.model.SpringComponentModel; -import org.mule.runtime.dsl.api.component.ComponentBuildingDefinition; -import org.mule.tck.junit4.AbstractMuleTestCase; - -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import io.qameta.allure.Issue; - -public class SimpleTypeBeanParamDefinitionCreatorTestCase extends AbstractMuleTestCase { - - private SimpleTypeBeanParamDefinitionCreator simpleTypeParamDefinitionCreator; - private CreateParamBeanDefinitionRequest createParamDefinitionRequest; - private Map springComponentModels; - - @Before - public void setUp() { - simpleTypeParamDefinitionCreator = new SimpleTypeBeanParamDefinitionCreator(true, true); - createParamDefinitionRequest = mock(CreateParamBeanDefinitionRequest.class); - SpringComponentModel springComponentModel = new SpringComponentModel(); - when(createParamDefinitionRequest.getSpringComponentModel()).thenReturn(springComponentModel); - when(createParamDefinitionRequest.getComponentBuildingDefinition()).thenReturn(mock(ComponentBuildingDefinition.class)); - } - - @Test - @Issue("W-17475148") - public void complexObjectFromExpression() { - SpringComponentModel springComponentModel = createParamDefinitionRequest.getSpringComponentModel(); - springComponentModel.setType(Map.class); - - final ComponentParameterAst param = mock(ComponentParameterAst.class); - when(param.getValue()).thenReturn(left("'some DW expression'")); - - when(createParamDefinitionRequest.getParam()).thenReturn(param); - - boolean result = simpleTypeParamDefinitionCreator.handleRequest(springComponentModels, createParamDefinitionRequest); - assertThat("request not handled when it must", result, is(true)); - } - - @Test - @Issue("W-17475148") - public void complexObjectInlineNotHandled() { - SpringComponentModel springComponentModel = createParamDefinitionRequest.getSpringComponentModel(); - springComponentModel.setType(Map.class); - - final ComponentParameterAst param = mock(ComponentParameterAst.class); - when(param.getValue()).thenReturn(right(mock(ComponentAst.class))); - - when(createParamDefinitionRequest.getParam()).thenReturn(param); - - boolean result = simpleTypeParamDefinitionCreator.handleRequest(springComponentModels, createParamDefinitionRequest); - assertThat("request handled when it must not", result, is(false)); - } - -} From 7c3e48013fdaf90050000103d50f5d885d93a2f7 Mon Sep 17 00:00:00 2001 From: Rodrigo Merino Date: Mon, 23 Dec 2024 09:09:34 -0300 Subject: [PATCH 3/3] W-17475148/W-17484538: Fix NPE in MapEntryBeanDefinitionCreator/MapBeanDefinitionCreator * W-17475148: Simple type params handler not handling certain expression param values (#14097) * W-17484538: Disambiguate colliding componentIds in ComponentBuildingDefinitionRegistry (#14105) --- modules/spring-config/api-changes.json | 14 +++ .../ComponentBuildingDefinitionRegistry.java | 45 ++++++++-- .../dsl/spring/BeanDefinitionCreator.java | 11 ++- .../dsl/spring/BeanDefinitionFactory.java | 52 ++++++++--- .../CreateComponentBeanDefinitionRequest.java | 14 ++- ...ateDslParamGroupBeanDefinitionRequest.java | 7 ++ .../CreateParamBeanDefinitionRequest.java | 8 ++ .../spring/MapEntryBeanDefinitionCreator.java | 9 +- .../SimpleTypeBeanBaseDefinitionCreator.java | 14 ++- .../SimpleTypeBeanParamDefinitionCreator.java | 5 ++ ...entBuildingDefinitionRegistryTestCase.java | 89 +++++++++++++++++++ ...ypeBeanParamDefinitionCreatorTestCase.java | 75 ++++++++++++++++ 12 files changed, 320 insertions(+), 23 deletions(-) create mode 100644 modules/spring-config/src/test/java/org/mule/runtime/config/dsl/model/ComponentBuildingDefinitionRegistryTestCase.java create mode 100644 modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java diff --git a/modules/spring-config/api-changes.json b/modules/spring-config/api-changes.json index 0bc6df7d6a43..24199ff7529b 100644 --- a/modules/spring-config/api-changes.json +++ b/modules/spring-config/api-changes.json @@ -1,4 +1,18 @@ { + "4.6.11": { + "revapi": { + "differences": { + "differences": [ + { + "ignore": true, + "code": "java.method.added", + "new": "method java.util.Optional> org.mule.runtime.config.api.dsl.model.ComponentBuildingDefinitionRegistry::getBuildingDefinition(org.mule.runtime.api.component.ComponentIdentifier, java.util.function.Predicate>)", + "justification": "W-17484538: Disambiguate colliding componentIds in ComponentBuildingDefinitionRegistry" + } + ] + } + } + }, "4.5.0": { "revapi": { "ignore": [ diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/api/dsl/model/ComponentBuildingDefinitionRegistry.java b/modules/spring-config/src/main/java/org/mule/runtime/config/api/dsl/model/ComponentBuildingDefinitionRegistry.java index 7a806dbafc1f..2960e298e68d 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/api/dsl/model/ComponentBuildingDefinitionRegistry.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/api/dsl/model/ComponentBuildingDefinitionRegistry.java @@ -6,23 +6,31 @@ */ package org.mule.runtime.config.api.dsl.model; -import static java.util.Optional.ofNullable; import static org.mule.runtime.config.api.dsl.model.ComponentBuildingDefinitionRegistry.WrapperElementType.COLLECTION; import static org.mule.runtime.config.api.dsl.model.ComponentBuildingDefinitionRegistry.WrapperElementType.MAP; import static org.mule.runtime.config.api.dsl.model.ComponentBuildingDefinitionRegistry.WrapperElementType.SINGLE; import static org.mule.runtime.internal.dsl.DslConstants.CORE_PREFIX; +import static java.util.Collections.emptyList; +import static java.util.Optional.empty; +import static java.util.Optional.ofNullable; + import org.mule.runtime.api.component.ComponentIdentifier; import org.mule.runtime.config.api.dsl.processor.AbstractAttributeDefinitionVisitor; import org.mule.runtime.dsl.api.component.AttributeDefinition; import org.mule.runtime.dsl.api.component.ComponentBuildingDefinition; import org.mule.runtime.dsl.api.component.ComponentBuildingDefinitionProvider; import org.mule.runtime.dsl.api.component.KeyAttributeDefinitionPair; +import org.mule.runtime.dsl.api.component.SetterAttributeDefinition; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.function.Consumer; +import java.util.function.Predicate; /** * Registry with all {@link ComponentBuildingDefinition} that where discovered in the classpath. @@ -35,7 +43,7 @@ @Deprecated public final class ComponentBuildingDefinitionRegistry { - private final Map> builderDefinitionsMap = new HashMap<>(); + private final Map>> builderDefinitionsMap = new HashMap<>(); private final Map wrapperIdentifierAndTypeMap = new HashMap<>(); /** @@ -44,7 +52,11 @@ public final class ComponentBuildingDefinitionRegistry { * @param builderDefinition definition to be added in the registry */ public void register(ComponentBuildingDefinition builderDefinition) { - builderDefinitionsMap.put(builderDefinition.getComponentIdentifier(), builderDefinition); + builderDefinitionsMap.computeIfAbsent(builderDefinition.getComponentIdentifier(), + // Use a stack structure so the order is consistent across executions + // and keep the behavior that the last element to be added takes precedence + k -> new ArrayDeque<>()) + .push(builderDefinition); wrapperIdentifierAndTypeMap.putAll(getWrapperIdentifierAndTypeMap(builderDefinition)); } @@ -55,7 +67,30 @@ public void register(ComponentBuildingDefinition builderDefinition) { * @return the definition to build the component */ public Optional> getBuildingDefinition(ComponentIdentifier identifier) { - return ofNullable(builderDefinitionsMap.get(identifier)); + final Deque> definitions = builderDefinitionsMap.get(identifier); + return definitions == null + ? empty() + : ofNullable(definitions.peek()); + } + + /** + * Lookups a {@code ComponentBuildingDefinition} for a certain configuration component and a certain condition. + * + * @param identifier the component identifier + * @param condition how to determine which of the available definitions to use + * @return the definition to build the component + */ + public Optional> getBuildingDefinition(ComponentIdentifier identifier, + Predicate> condition) { + Collection> buildingDefinitions = builderDefinitionsMap.get(identifier); + if (buildingDefinitions == null) { + buildingDefinitions = emptyList(); + } + + return buildingDefinitions + .stream() + .filter(condition) + .findFirst(); } /** @@ -109,7 +144,7 @@ public void onMultipleValues(KeyAttributeDefinitionPair[] definitions) { Consumer collectWrappersConsumer = attributeDefinition -> attributeDefinition.accept(wrapperIdentifiersCollector); buildingDefinition.getSetterParameterDefinitions().stream() - .map(setterAttributeDefinition -> setterAttributeDefinition.getAttributeDefinition()) + .map(SetterAttributeDefinition::getAttributeDefinition) .forEach(collectWrappersConsumer); buildingDefinition.getConstructorAttributeDefinition().stream().forEach(collectWrappersConsumer); return wrapperIdentifierAndTypeMap; diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java index a29369f76a75..edb73fe95d36 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionCreator.java @@ -6,8 +6,11 @@ */ package org.mule.runtime.config.internal.dsl.spring; +import static org.mule.runtime.api.i18n.I18nMessageFactory.createStaticMessage; + import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition; +import org.mule.runtime.api.exception.MuleRuntimeException; import org.mule.runtime.ast.api.ComponentAst; import org.mule.runtime.config.internal.dsl.model.SpringComponentModel; import org.mule.runtime.config.internal.factories.ConstantFactoryBean; @@ -41,8 +44,12 @@ public void setNext(BeanDefinitionCreator nextBeanDefinitionCreator) { * @param request */ public final void processRequest(Map springComponentModels, R request) { - if (handleRequest(springComponentModels, request)) { - return; + try { + if (handleRequest(springComponentModels, request)) { + return; + } + } catch (Exception e) { + throw new MuleRuntimeException(createStaticMessage("Exception processing " + request.toString()), e); } if (next != null) { next.processRequest(springComponentModels, request); diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionFactory.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionFactory.java index 07bb23cd5c23..1080a792d47a 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionFactory.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/BeanDefinitionFactory.java @@ -63,6 +63,8 @@ import org.mule.runtime.config.internal.context.SpringConfigurationComponentLocator; import org.mule.runtime.config.internal.dsl.model.SpringComponentModel; import org.mule.runtime.dsl.api.component.ComponentBuildingDefinition; +import org.mule.runtime.dsl.api.component.TypeDefinition.MapEntryType; +import org.mule.runtime.dsl.api.component.TypeDefinitionVisitor; import org.mule.runtime.extension.api.property.NoWrapperModelProperty; import java.util.ArrayList; @@ -205,7 +207,8 @@ public void resolveComponent(Map springCompo resolveComponentBeanDefinition(springComponentModels, componentHierarchy, component, paramsModels, registry, componentLocator, nestedComp -> resolveComponent(springComponentModels, nestedHierarchy, nestedComp, - registry, componentLocator)); + registry, componentLocator), + false); } private List resolveParameterGroup(Map springComponentModels, @@ -272,20 +275,21 @@ private List resolveParamBeanDefinitionFixedValue(Map model = new AtomicReference<>(); param.getModel().getType().accept(new MetadataTypeVisitor() { - protected void visitMultipleChildren(List values) { + protected void visitMultipleChildren(List values, boolean mapType) { final List updatedHierarchy = new ArrayList<>(componentHierarchy); updatedHierarchy.add(paramOwnerComponent); if (values != null) { values.stream() - .filter(child -> child instanceof ComponentAst) + .filter(ComponentAst.class::isInstance) .forEach(child -> resolveComponentBeanDefinition(springComponentModels, updatedHierarchy, (ComponentAst) child, emptyList(), registry, componentLocator, nestedComp -> resolveComponent(springComponentModels, updatedHierarchy, nestedComp, registry, - componentLocator))); + componentLocator), + mapType)); } resolveComponentBeanDefinitionComplexParam(springComponentModels, updatedHierarchy, paramOwnerComponent, param, @@ -299,7 +303,7 @@ protected void visitMultipleChildren(List values) { public void visitArrayType(ArrayType arrayType) { final Object complexValue = param.getValue().getRight(); if (complexValue instanceof List) { - visitMultipleChildren((List) complexValue); + visitMultipleChildren((List) complexValue, false); } else { // references to a list defined elsewhere resolveParamBeanDefinitionSimpleType(springComponentModels, componentHierarchy, paramOwnerComponent, param, registry, @@ -314,7 +318,7 @@ public void visitObject(ObjectType objectType) { if (isMap(objectType)) { if (complexValue instanceof List) { - visitMultipleChildren((List) complexValue); + visitMultipleChildren((List) complexValue, true); } else { // references to a map defined elsewhere resolveParamBeanDefinitionSimpleType(springComponentModels, componentHierarchy, paramOwnerComponent, param, registry, @@ -329,7 +333,6 @@ public void visitObject(ObjectType objectType) { if (complexValue instanceof ComponentAst) { final ComponentAst child = (ComponentAst) complexValue; - List childParamsModels = new ArrayList<>(); child.getModel(ParameterizedModel.class) @@ -400,13 +403,19 @@ private Optional resolveComponentBeanDefinition(Map paramsModels, BeanDefinitionRegistry registry, SpringConfigurationComponentLocator componentLocator, - Consumer nestedComponentParamProcessor) { + Consumer nestedComponentParamProcessor, + boolean parentMapType) { Optional> buildingDefinitionOptional = - componentBuildingDefinitionRegistry.getBuildingDefinition(component.getIdentifier()); + componentBuildingDefinitionRegistry.getBuildingDefinition(component.getIdentifier(), bd -> { + final IsMapEntryTypeVisitor isMapEntryTypeVisitor = new IsMapEntryTypeVisitor(); + bd.getTypeDefinition().visit(isMapEntryTypeVisitor); + return parentMapType == isMapEntryTypeVisitor.isMapType(); + }); if (buildingDefinitionOptional.isPresent() || customBuildersComponentIdentifiers.contains(component.getIdentifier())) { final CreateComponentBeanDefinitionRequest request = new CreateComponentBeanDefinitionRequest(componentHierarchy, component, paramsModels, - buildingDefinitionOptional.orElse(null), nestedComponentParamProcessor); + buildingDefinitionOptional.orElse(null), nestedComponentParamProcessor, + parentMapType); this.componentProcessor.processRequest(springComponentModels, request); handleSpringComponentModel(request.getSpringComponentModel(), springComponentModels, registry, componentLocator); @@ -416,6 +425,29 @@ private Optional resolveComponentBeanDefinition(Map type) {} + + @Override + public void onMapType(MapEntryType mapEntryType) { + this.mapType = true; + } + + @Override + public void onConfigurationAttribute(String groupName, String attributeName, Class enforcedClass) {} + + @Override + public void onConfigurationAttribute(String attributeName, Class enforcedClass) {} + + public boolean isMapType() { + return mapType; + } + } + private Optional resolveComponentBeanDefinitionComplexParam(Map springComponentModels, List componentHierarchy, ComponentAst paramOwnerComponent, diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java index 1d4f65a25ffd..ab2c223851d4 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateComponentBeanDefinitionRequest.java @@ -16,14 +16,17 @@ public class CreateComponentBeanDefinitionRequest extends CreateBeanDefinitionRequest { private final Consumer nestedComponentParamProcessor; + private final boolean parentMapType; public CreateComponentBeanDefinitionRequest(List componentHierarchy, ComponentAst component, List paramsModels, ComponentBuildingDefinition componentBuildingDefinition, - Consumer nestedComponentParamProcessor) { + Consumer nestedComponentParamProcessor, + boolean parentMapType) { super(componentHierarchy, component, paramsModels, componentBuildingDefinition, component.getIdentifier()); this.nestedComponentParamProcessor = nestedComponentParamProcessor; + this.parentMapType = parentMapType; } @Override @@ -34,4 +37,13 @@ public ComponentAst resolveConfigurationComponent() { public Consumer getNestedComponentParamProcessor() { return nestedComponentParamProcessor; } + + public boolean isParentMapType() { + return parentMapType; + } + + @Override + public String toString() { + return "component request for `" + getComponent().toString(); + } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java index 37a218746a6a..2ba6fc0b63f5 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateDslParamGroupBeanDefinitionRequest.java @@ -49,4 +49,11 @@ public ParameterGroupModel getParamGroupModel() { public ComponentParameterAst getParameter(String parameterName) { return paramOwnerComponent.getParameter(paramGroupModel.getName(), parameterName); } + + @Override + public String toString() { + return "DSL param group request for `" + + getParamGroupModel().getName() + "` in component `" + + getParamOwnerComponent().toString(); + } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java index 3b951f182da7..5f464861686f 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/CreateParamBeanDefinitionRequest.java @@ -65,4 +65,12 @@ public ComponentParameterAst getParameter(String parameterName) { .findFirst() .orElse(null); } + + @Override + public String toString() { + return "param request for `" + + getParam().getGroupModel().getName() + "." + + getParam().getModel().getName() + "` in component `" + + getParamOwnerComponent().toString(); + } } diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/MapEntryBeanDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/MapEntryBeanDefinitionCreator.java index 1be163127763..8e75189d896e 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/MapEntryBeanDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/MapEntryBeanDefinitionCreator.java @@ -6,10 +6,12 @@ */ package org.mule.runtime.config.internal.dsl.spring; -import static java.util.stream.Collectors.toCollection; import static org.mule.runtime.api.meta.model.parameter.ParameterGroupModel.DEFAULT_GROUP_NAME; import static org.mule.runtime.config.internal.dsl.processor.ObjectTypeVisitor.DEFAULT_COLLECTION_TYPE; import static org.mule.runtime.dsl.api.component.DslSimpleType.SIMPLE_TYPE_VALUE_PARAMETER_NAME; + +import static java.util.stream.Collectors.toCollection; + import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition; import org.mule.runtime.ast.api.ComponentAst; @@ -61,11 +63,16 @@ class MapEntryBeanDefinitionCreator extends BeanDefinitionCreator springComponentModels, CreateComponentBeanDefinitionRequest request) { + if (!request.isParentMapType()) { + return false; + } + ComponentAst component = request.getComponent(); Class type = request.getSpringComponentModel().getType(); if (!(MapEntryType.class.isAssignableFrom(type))) { return false; } + ComponentBuildingDefinition componentBuildingDefinition = request.getComponentBuildingDefinition(); request.getSpringComponentModel().setType(type); final String key = component.getParameter(DEFAULT_GROUP_NAME, ENTRY_TYPE_KEY_PARAMETER_NAME).getResolvedRawValue(); diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java index 5a0c90659625..24de05a9a4b9 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanBaseDefinitionCreator.java @@ -31,12 +31,18 @@ protected final boolean handleRequest(Map sp R createBeanDefinitionRequest) { Class type = createBeanDefinitionRequest.getSpringComponentModel().getType(); - if (!isSimpleType(type)) { - return false; + if (isSimpleType(type) + // Expressions are String, which are simple values for the spring bean definitions + || isExpressionValue(createBeanDefinitionRequest)) { + createBeanDefinitionRequest.getSpringComponentModel().setType(type); + return doHandleRequest(createBeanDefinitionRequest, type); } - createBeanDefinitionRequest.getSpringComponentModel().setType(type); - return doHandleRequest(createBeanDefinitionRequest, type); + return false; + } + + protected boolean isExpressionValue(R request) { + return false; } protected abstract boolean doHandleRequest(R createBeanDefinitionRequest, Class type); diff --git a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java index c80262636958..cc6b726c3b9c 100644 --- a/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java +++ b/modules/spring-config/src/main/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreator.java @@ -41,6 +41,11 @@ protected boolean doHandleRequest(CreateParamBeanDefinitionRequest createBeanDef return true; } + @Override + protected boolean isExpressionValue(CreateParamBeanDefinitionRequest request) { + return request.getParam().getValue().isLeft(); + } + static Object resolveParamValue(final ComponentParameterAst param, boolean disableTrimWhitespaces, boolean disablePojoCdataTrimWhitespaces) { return param.getValue() diff --git a/modules/spring-config/src/test/java/org/mule/runtime/config/dsl/model/ComponentBuildingDefinitionRegistryTestCase.java b/modules/spring-config/src/test/java/org/mule/runtime/config/dsl/model/ComponentBuildingDefinitionRegistryTestCase.java new file mode 100644 index 000000000000..2fd24eecc8fd --- /dev/null +++ b/modules/spring-config/src/test/java/org/mule/runtime/config/dsl/model/ComponentBuildingDefinitionRegistryTestCase.java @@ -0,0 +1,89 @@ +/* + * Copyright 2023 Salesforce, Inc. All rights reserved. + * The software in this package is published under the terms of the CPAL v1.0 + * license, a copy of which has been included with this distribution in the + * LICENSE.txt file. + */ +package org.mule.runtime.config.dsl.model; + +import static org.mule.runtime.api.component.ComponentIdentifier.buildFromStringRepresentation; + +import static java.util.Optional.empty; +import static java.util.Optional.of; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.sameInstance; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.mule.runtime.api.component.ComponentIdentifier; +import org.mule.runtime.config.api.dsl.model.ComponentBuildingDefinitionRegistry; +import org.mule.runtime.dsl.api.component.ComponentBuildingDefinition; +import org.mule.runtime.dsl.api.component.TypeConverter; +import org.mule.tck.junit4.AbstractMuleTestCase; + +import org.junit.Test; + +import io.qameta.allure.Issue; + +public class ComponentBuildingDefinitionRegistryTestCase extends AbstractMuleTestCase { + + @Test + @Issue("W-17484538") + public void lastRegisteredTakesPrecedence() { + final ComponentBuildingDefinitionRegistry registry = new ComponentBuildingDefinitionRegistry(); + + final ComponentIdentifier collidingComponentIdentifier = buildFromStringRepresentation("ext:comp"); + + final ComponentBuildingDefinition definition1 = mock(ComponentBuildingDefinition.class); + when(definition1.getComponentIdentifier()).thenReturn(collidingComponentIdentifier); + registry.register(definition1); + + final ComponentBuildingDefinition definition2 = mock(ComponentBuildingDefinition.class); + when(definition2.getComponentIdentifier()).thenReturn(collidingComponentIdentifier); + registry.register(definition2); + + assertThat(registry.getBuildingDefinition(collidingComponentIdentifier).get(), + sameInstance(definition2)); + } + + @Test + @Issue("W-17484538") + public void lastRegisteredTakesPrecedenceWithPredicate() { + final ComponentBuildingDefinitionRegistry registry = new ComponentBuildingDefinitionRegistry(); + + final ComponentIdentifier collidingComponentIdentifier = buildFromStringRepresentation("ext:comp"); + + final ComponentBuildingDefinition definition1 = mock(ComponentBuildingDefinition.class); + when(definition1.getComponentIdentifier()).thenReturn(collidingComponentIdentifier); + registry.register(definition1); + + final ComponentBuildingDefinition definition2 = mock(ComponentBuildingDefinition.class); + when(definition2.getComponentIdentifier()).thenReturn(collidingComponentIdentifier); + registry.register(definition2); + + assertThat(registry.getBuildingDefinition(collidingComponentIdentifier, d -> true).get(), + sameInstance(definition2)); + } + + @Test + @Issue("W-17484538") + public void getRegisteredWithPredicate() { + final ComponentBuildingDefinitionRegistry registry = new ComponentBuildingDefinitionRegistry(); + + final ComponentIdentifier collidingComponentIdentifier = buildFromStringRepresentation("ext:comp"); + + final ComponentBuildingDefinition definition1 = mock(ComponentBuildingDefinition.class); + when(definition1.getComponentIdentifier()).thenReturn(collidingComponentIdentifier); + when(definition1.getTypeConverter()).thenReturn(of(mock(TypeConverter.class))); + registry.register(definition1); + + final ComponentBuildingDefinition definition2 = mock(ComponentBuildingDefinition.class); + when(definition2.getComponentIdentifier()).thenReturn(collidingComponentIdentifier); + when(definition2.getTypeConverter()).thenReturn(empty()); + registry.register(definition2); + + assertThat(registry.getBuildingDefinition(collidingComponentIdentifier, d -> d.getTypeConverter().isPresent()).get(), + sameInstance(definition1)); + } +} diff --git a/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java b/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java new file mode 100644 index 000000000000..0348dae9425f --- /dev/null +++ b/modules/spring-config/src/test/java/org/mule/runtime/config/internal/dsl/spring/SimpleTypeBeanParamDefinitionCreatorTestCase.java @@ -0,0 +1,75 @@ +/* + * Copyright 2023 Salesforce, Inc. All rights reserved. + * The software in this package is published under the terms of the CPAL v1.0 + * license, a copy of which has been included with this distribution in the + * LICENSE.txt file. + */ +package org.mule.runtime.config.internal.dsl.spring; + +import static org.mule.runtime.api.functional.Either.left; +import static org.mule.runtime.api.functional.Either.right; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.mule.runtime.ast.api.ComponentAst; +import org.mule.runtime.ast.api.ComponentParameterAst; +import org.mule.runtime.config.internal.dsl.model.SpringComponentModel; +import org.mule.runtime.dsl.api.component.ComponentBuildingDefinition; +import org.mule.tck.junit4.AbstractMuleTestCase; + +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import io.qameta.allure.Issue; + +public class SimpleTypeBeanParamDefinitionCreatorTestCase extends AbstractMuleTestCase { + + private SimpleTypeBeanParamDefinitionCreator simpleTypeParamDefinitionCreator; + private CreateParamBeanDefinitionRequest createParamDefinitionRequest; + private Map springComponentModels; + + @Before + public void setUp() { + simpleTypeParamDefinitionCreator = new SimpleTypeBeanParamDefinitionCreator(true, true); + createParamDefinitionRequest = mock(CreateParamBeanDefinitionRequest.class); + SpringComponentModel springComponentModel = new SpringComponentModel(); + when(createParamDefinitionRequest.getSpringComponentModel()).thenReturn(springComponentModel); + when(createParamDefinitionRequest.getComponentBuildingDefinition()).thenReturn(mock(ComponentBuildingDefinition.class)); + } + + @Test + @Issue("W-17475148") + public void complexObjectFromExpression() { + SpringComponentModel springComponentModel = createParamDefinitionRequest.getSpringComponentModel(); + springComponentModel.setType(Map.class); + + final ComponentParameterAst param = mock(ComponentParameterAst.class); + when(param.getValue()).thenReturn(left("'some DW expression'")); + + when(createParamDefinitionRequest.getParam()).thenReturn(param); + + boolean result = simpleTypeParamDefinitionCreator.handleRequest(springComponentModels, createParamDefinitionRequest); + assertThat("request not handled when it must", result, is(true)); + } + + @Test + @Issue("W-17475148") + public void complexObjectInlineNotHandled() { + SpringComponentModel springComponentModel = createParamDefinitionRequest.getSpringComponentModel(); + springComponentModel.setType(Map.class); + + final ComponentParameterAst param = mock(ComponentParameterAst.class); + when(param.getValue()).thenReturn(right(mock(ComponentAst.class))); + + when(createParamDefinitionRequest.getParam()).thenReturn(param); + + boolean result = simpleTypeParamDefinitionCreator.handleRequest(springComponentModels, createParamDefinitionRequest); + assertThat("request handled when it must not", result, is(false)); + } + +}