Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

W-17579307: Add missing logic to create pojos from a ComponentParameterization #14158

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.mule.runtime.extension.api.util.ExtensionMetadataTypeUtils.getExpressionSupport;
import static org.mule.runtime.extension.api.util.ExtensionMetadataTypeUtils.getType;
import static org.mule.runtime.extension.api.util.ExtensionMetadataTypeUtils.isMap;
import static org.mule.runtime.extension.api.util.NameUtils.getAliasName;
import static org.mule.runtime.module.extension.internal.runtime.resolver.ComponentParameterizationUtils.createComponentParameterization;
import static org.mule.runtime.module.extension.internal.runtime.resolver.ParametersResolver.fromValues;

Expand All @@ -33,6 +34,7 @@
import org.mule.runtime.api.el.BindingContext;
import org.mule.runtime.api.exception.MuleException;
import org.mule.runtime.api.exception.MuleRuntimeException;
import org.mule.runtime.api.lifecycle.InitialisationException;
import org.mule.runtime.api.meta.ExpressionSupport;
import org.mule.runtime.api.meta.model.ModelProperty;
import org.mule.runtime.api.meta.model.parameter.ParameterGroupModel;
Expand Down Expand Up @@ -176,7 +178,8 @@ public static ResolverSet getResolverSetFromParameters(ParameterizedModel model,
disableValidations,
reflectionCache,
expressionManager,
parametersOwner).getParametersAsResolverSet(model, muleContext);
parametersOwner)
.getParametersAsResolverSet(model, muleContext);
}

private static Map<String, ValueResolver> getParameterGroupValueResolvers(BiFunction<ParameterGroupModel, ParameterModel, Object> params,
Expand Down Expand Up @@ -205,15 +208,16 @@ private static Map<String, ValueResolver> getParameterGroupValueResolvers(BiFunc

}
ValueResolver objectBuilderValuerResolver = new ObjectBuilderValueResolver<>(defaultObjectBuilder, muleContext);
return of(getGroupName(parameterGroupModelProperty), objectBuilderValuerResolver);

return of(getGroupName(parameterGroupModelProperty.get()), objectBuilderValuerResolver);
}
}
}
return parameterGroupParametersValueResolvers;
}

private static String getGroupName(Optional<ParameterGroupModelProperty> groupModelProperty) {
Object container = groupModelProperty.get().getDescriptor().getContainer();
private static String getGroupName(ParameterGroupModelProperty groupModelProperty) {
Object container = groupModelProperty.getDescriptor().getContainer();
if (container instanceof Field) {
return ((Field) container).getName();
} else if (container instanceof Parameter) {
Expand Down Expand Up @@ -249,7 +253,7 @@ private static ValueResolver getParameterValueResolver(String parameterName, Met
Set<ModelProperty> modelProperties, ReflectionCache reflectionCache,
MuleContext muleContext, ValueResolverFactory valueResolverFactory,
boolean acceptsReferences)
throws MuleException {
throws InitialisationException {
Reference<ValueResolver> resolverReference = new Reference<>();

if (type.getMetadataFormat().equals(MetadataFormat.JAVA)) {
Expand Down Expand Up @@ -381,26 +385,45 @@ private static Object resolveAndInjectIfStatic(ValueResolver valueResolver, Mule
private static Optional<ValueResolver> getPojoParameterValueResolver(String parameterName, ObjectType objectType, Object value,
ReflectionCache reflectionCache, MuleContext muleContext,
ValueResolverFactory valueResolverFactory)
throws MuleException {
throws InitialisationException {

Optional<Class<Object>> pojoClass = getType(objectType);

if (pojoClass.isPresent() && value instanceof Map) {
DefaultObjectBuilder objectBuilder = new DefaultObjectBuilder(pojoClass.get(), reflectionCache);
for (ObjectFieldType objectFieldType : objectType.getFields()) {
if (pojoClass.isPresent()) {
if (value instanceof Map) {
Map valuesMap = (Map) value;
if (valuesMap.containsKey(objectFieldType.getKey().getName().toString())) {
objectBuilder.addPropertyResolver(objectFieldType.getKey().getName().toString(),
getParameterValueResolver(parameterName, objectFieldType.getValue(),
valuesMap
.get(objectFieldType.getKey().getName().toString()),
emptySet(), reflectionCache,
muleContext, valueResolverFactory, false));
DefaultObjectBuilder objectBuilder = new DefaultObjectBuilder(pojoClass.get(), reflectionCache);
for (ObjectFieldType objectFieldType : objectType.getFields()) {
if (valuesMap.containsKey(objectFieldType.getKey().getName().toString())) {
objectBuilder.addPropertyResolver(objectFieldType.getKey().getName().toString(),
getParameterValueResolver(parameterName, objectFieldType.getValue(),
valuesMap
.get(objectFieldType.getKey().getName().toString()),
emptySet(), reflectionCache,
muleContext, valueResolverFactory, false));
}
}
}

ObjectBuilderValueResolver objectBuilderValueResolver = new ObjectBuilderValueResolver(objectBuilder, muleContext);
return Optional.of(objectBuilderValueResolver);
return Optional.of(new ObjectBuilderValueResolver(objectBuilder, muleContext));
} else if (value instanceof ComponentParameterization) {
ComponentParameterization valuesParameterization = (ComponentParameterization) value;
DefaultObjectBuilder objectBuilder = new DefaultObjectBuilder(pojoClass.get(), reflectionCache);
String aliasName = getAliasName(objectType);
for (ObjectFieldType objectFieldType : objectType.getFields()) {
Object paramValue = valuesParameterization.getParameter(aliasName, objectFieldType.getKey().getName().getLocalPart());
if (paramValue != null) {
objectBuilder.addPropertyResolver(objectFieldType.getKey().getName().toString(),
getParameterValueResolver(parameterName, objectFieldType.getValue(),
paramValue,
emptySet(), reflectionCache,
muleContext, valueResolverFactory, false));
}
}

return Optional.of(new ObjectBuilderValueResolver(objectBuilder, muleContext));
} else {
return empty();
}
} else {
return empty();
}
Expand Down Expand Up @@ -431,8 +454,7 @@ private static ValueResolver getParameterValueResolverForMap(String parameterNam
ReflectionCache reflectionCache,
MuleContext muleContext, ValueResolverFactory valueResolverFactory)
throws MuleException {
Optional<Class<Object>> mapClassOptional = getType(type);
Class mapClass = mapClassOptional.get();
Class mapClass = getType(type).get();

MetadataType valueType = type.getOpenRestriction().orElse(null);
Function<Object, ValueResolver<Object>> valueValueResolverFunction;
Expand All @@ -446,7 +468,7 @@ private static ValueResolver getParameterValueResolverForMap(String parameterNam
}
};
} else {
valueValueResolverFunction = value -> new StaticValueResolver<>(value);
valueValueResolverFunction = StaticValueResolver::new;
}

List<ValueResolver<Object>> keyResolvers = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* 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.module.extension.internal.runtime.resolver;

import static org.mule.runtime.module.extension.internal.runtime.resolver.ResolverSetUtils.getResolverSetFromParameters;

import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static java.util.Optional.of;

import static org.hamcrest.MatcherAssert.assertThat;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;

import org.mule.metadata.api.model.MetadataType;
import org.mule.runtime.api.exception.MuleException;
import org.mule.runtime.api.meta.model.ParameterDslConfiguration;
import org.mule.runtime.api.meta.model.parameter.ParameterGroupModel;
import org.mule.runtime.api.meta.model.parameter.ParameterModel;
import org.mule.runtime.api.meta.model.parameter.ParameterizedModel;
import org.mule.runtime.api.parameterization.ComponentParameterization;
import org.mule.runtime.core.api.Injector;
import org.mule.runtime.core.api.MuleContext;
import org.mule.runtime.module.extension.api.runtime.resolver.ResolverSet;
import org.mule.runtime.module.extension.api.runtime.resolver.ValueResolver;
import org.mule.runtime.module.extension.internal.runtime.resolver.resolver.ValueResolverFactory;
import org.mule.runtime.module.extension.internal.util.ReflectionCache;
import org.mule.tck.junit4.AbstractMuleTestCase;
import org.mule.test.module.extension.internal.util.ExtensionsTestUtils;

import org.junit.Test;

import io.qameta.allure.Issue;

public class ResolverSetUtilsTestCase extends AbstractMuleTestCase {

@Test
@Issue("W-17579307")
public void pojoFromComponentParameterization() throws MuleException {
MetadataType pojoType = ExtensionsTestUtils.TYPE_LOADER.load(MyPojo.class);
ParameterizedModel pmzdModel = createModelWithPojoPram(pojoType);
ParameterizedModel pojoModel = createPojoModel();

ComponentParameterization<ParameterizedModel> componentParameterization =
ComponentParameterization.builder(pojoModel)
.withParameter("textValue", "hello me")
.withParameter("numberValue", 42)
.build();

ResolverSet resolvers = getResolverSetFromParameters(pmzdModel,
(pgm, pm) -> componentParameterization,
createMuleContext(),
true,
new ReflectionCache(),
null, "",
new ValueResolverFactory());
ValueResolver<?> paramResolver = resolvers.getResolvers().get("paramName");
Object resolvedValue = paramResolver.resolve(null);

assertThat(resolvedValue, instanceOf(MyPojo.class));
assertThat(((MyPojo) resolvedValue).getTextValue(), is("hello me"));
assertThat(((MyPojo) resolvedValue).getNumberValue(), is(42));
}

private ParameterizedModel createModelWithPojoPram(MetadataType pojoType) {
ParameterModel paramModel = mock(ParameterModel.class);
when(paramModel.getName()).thenReturn("paramName");
when(paramModel.getType()).thenReturn(pojoType);
when(paramModel.getModelProperties()).thenReturn(emptySet());
when(paramModel.getDslConfiguration()).thenReturn(new ParameterDslConfiguration());

ParameterGroupModel paramGroupModel = mock(ParameterGroupModel.class);
when(paramGroupModel.getParameterModels()).thenReturn(singletonList(paramModel));

ParameterizedModel pmzdModel = mock(ParameterizedModel.class);
when(pmzdModel.getParameterGroupModels()).thenReturn(singletonList(paramGroupModel));
when(pmzdModel.getAllParameterModels()).thenReturn(singletonList(paramModel));
return pmzdModel;
}

private ParameterizedModel createPojoModel() {
ParameterModel pojoTextParamModel = mock(ParameterModel.class);
when(pojoTextParamModel.getName()).thenReturn("textValue");
when(pojoTextParamModel.getType()).thenReturn(ExtensionsTestUtils.TYPE_LOADER.load(String.class));
when(pojoTextParamModel.getModelProperties()).thenReturn(emptySet());
when(pojoTextParamModel.getDslConfiguration()).thenReturn(new ParameterDslConfiguration());

ParameterModel pojoNumberParamModel = mock(ParameterModel.class);
when(pojoNumberParamModel.getName()).thenReturn("numberValue");
when(pojoNumberParamModel.getType()).thenReturn(ExtensionsTestUtils.TYPE_LOADER.load(String.class));
when(pojoNumberParamModel.getModelProperties()).thenReturn(emptySet());
when(pojoNumberParamModel.getDslConfiguration()).thenReturn(new ParameterDslConfiguration());

ParameterGroupModel pojoParamGroupModel = mock(ParameterGroupModel.class);
when(pojoParamGroupModel.getName()).thenReturn("MyPojo");
when(pojoParamGroupModel.getParameterModels()).thenReturn(singletonList(pojoTextParamModel));
when(pojoParamGroupModel.getParameter("textValue")).thenReturn(of(pojoTextParamModel));
when(pojoParamGroupModel.getParameter("numberValue")).thenReturn(of(pojoNumberParamModel));

ParameterizedModel pojoModel = mock(ParameterizedModel.class);
when(pojoModel.getParameterGroupModels()).thenReturn(singletonList(pojoParamGroupModel));
return pojoModel;
}

private MuleContext createMuleContext() {
MuleContext muleContext = mock(MuleContext.class);
when(muleContext.getInjector()).thenReturn(mock(Injector.class));
return muleContext;
}

public static class MyPojo {

private String textValue;

private int numberValue;

public String getTextValue() {
return textValue;
}

public void setTextValue(String textValue) {
this.textValue = textValue;
}

public int getNumberValue() {
return numberValue;
}

public void setNumberValue(int numberValue) {
this.numberValue = numberValue;
}

}
}