/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * 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.spring.dsl.model; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; import static java.util.Collections.singleton; import static java.util.Optional.empty; import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.junit.Assert.fail; import static org.mockito.Answers.RETURNS_DEEP_STUBS; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static org.mule.metadata.api.model.MetadataFormat.JAVA; import static org.mule.runtime.api.app.declaration.fluent.ElementDeclarer.newListValue; import static org.mule.runtime.api.app.declaration.fluent.ElementDeclarer.newObjectValue; import static org.mule.runtime.api.component.ComponentIdentifier.builder; import static org.mule.runtime.api.meta.model.parameter.ParameterRole.BEHAVIOUR; import static org.mule.runtime.api.meta.model.parameter.ParameterRole.CONTENT; import static org.mule.runtime.api.util.ExtensionModelTestUtils.visitableMock; import static org.mule.runtime.extension.api.util.ExtensionMetadataTypeUtils.getId; import static org.mule.runtime.internal.dsl.DslConstants.VALUE_ATTRIBUTE_NAME; import org.mule.metadata.api.ClassTypeLoader; import org.mule.metadata.api.builder.BaseTypeBuilder; import org.mule.metadata.api.builder.ObjectTypeBuilder; import org.mule.metadata.api.model.MetadataType; import org.mule.metadata.api.model.ObjectType; import org.mule.runtime.api.app.declaration.ConfigurationElementDeclaration; import org.mule.runtime.api.app.declaration.ElementDeclaration; import org.mule.runtime.api.app.declaration.OperationElementDeclaration; import org.mule.runtime.api.app.declaration.SourceElementDeclaration; import org.mule.runtime.api.app.declaration.TopLevelParameterDeclaration; import org.mule.runtime.api.app.declaration.fluent.ElementDeclarer; import org.mule.runtime.api.dsl.DslResolvingContext; import org.mule.runtime.api.meta.ExpressionSupport; import org.mule.runtime.api.meta.model.ExtensionModel; import org.mule.runtime.api.meta.model.ParameterDslConfiguration; import org.mule.runtime.api.meta.model.XmlDslModel; import org.mule.runtime.api.meta.model.config.ConfigurationModel; import org.mule.runtime.api.meta.model.connection.ConnectionProviderModel; import org.mule.runtime.api.meta.model.operation.OperationModel; 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.source.SourceModel; import org.mule.runtime.api.meta.type.TypeCatalog; import org.mule.runtime.extension.api.annotation.dsl.xml.XmlHints; import org.mule.runtime.extension.api.annotation.param.Content; import org.mule.runtime.extension.api.annotation.param.Parameter; import org.mule.runtime.extension.api.declaration.type.ExtensionsTypeLoaderFactory; import java.util.Optional; import java.util.stream.Stream; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class DeclarationElementModelFactoryTestCase { private static final String NAMESPACE = "mockns"; private static final String NAMESPACE_URI = "http://www.mulesoft.org/schema/mule/mockns"; private static final String SCHEMA_LOCATION = "http://www.mulesoft.org/schema/mule/mockns/current/mule-mockns.xsd"; private static final String CONTENT_NAME = "myCamelCaseName"; private static final String BEHAVIOUR_NAME = "otherName"; private static final String LIST_NAME = "listName"; private static final String EXTENSION_NAME = "extension"; private static final String OPERATION_NAME = "mockOperation"; private static final String SOURCE_NAME = "source"; private static final String CONFIGURATION_NAME = "configuration"; private static final String CONNECTION_PROVIDER_NAME = "connection"; private static final BaseTypeBuilder TYPE_BUILDER = BaseTypeBuilder.create(JAVA); @Mock private ExtensionModel extension; @Mock private ConfigurationModel configuration; @Mock private OperationModel operation; @Mock private ConnectionProviderModel connectionProvider; @Mock private ParameterModel contentParameter; @Mock private ParameterModel behaviourParameter; @Mock private ParameterModel listParameter; @Mock private ParameterGroupModel parameterGroupModel; @Mock(answer = RETURNS_DEEP_STUBS) private SourceModel source; @Mock private DslResolvingContext dslContext; @Mock private TypeCatalog typeCatalog; private ObjectType complexType; private ClassTypeLoader TYPE_LOADER = ExtensionsTypeLoaderFactory.getDefault().createTypeLoader(); @Before public void before() { initMocks(this); initializeExtensionMock(extension); when(configuration.getName()).thenReturn(CONFIGURATION_NAME); when(configuration.getParameterGroupModels()).thenReturn(asList(parameterGroupModel)); when(configuration.getOperationModels()).thenReturn(asList(operation)); when(configuration.getSourceModels()).thenReturn(asList(source)); when(configuration.getConnectionProviders()).thenReturn(asList(connectionProvider)); when(behaviourParameter.getName()).thenReturn(BEHAVIOUR_NAME); when(behaviourParameter.getExpressionSupport()).thenReturn(ExpressionSupport.NOT_SUPPORTED); when(behaviourParameter.getModelProperty(any())).thenReturn(empty()); when(behaviourParameter.getDslConfiguration()).thenReturn(ParameterDslConfiguration.getDefaultInstance()); when(behaviourParameter.getLayoutModel()).thenReturn(empty()); when(behaviourParameter.getRole()).thenReturn(BEHAVIOUR); when(behaviourParameter.getType()).thenReturn(TYPE_LOADER.load(String.class)); when(listParameter.getName()).thenReturn(LIST_NAME); when(listParameter.getExpressionSupport()).thenReturn(ExpressionSupport.NOT_SUPPORTED); when(listParameter.getModelProperty(any())).thenReturn(empty()); when(listParameter.getDslConfiguration()).thenReturn(ParameterDslConfiguration.getDefaultInstance()); when(listParameter.getLayoutModel()).thenReturn(empty()); when(listParameter.getRole()).thenReturn(BEHAVIOUR); when(listParameter.getType()).thenReturn(TYPE_BUILDER.arrayType().of(TYPE_LOADER.load(String.class)).build()); when(contentParameter.getName()).thenReturn(CONTENT_NAME); when(contentParameter.getExpressionSupport()).thenReturn(ExpressionSupport.SUPPORTED); when(contentParameter.getModelProperty(any())).thenReturn(empty()); when(contentParameter.getDslConfiguration()).thenReturn(ParameterDslConfiguration.getDefaultInstance()); when(contentParameter.getLayoutModel()).thenReturn(empty()); when(contentParameter.getRole()).thenReturn(CONTENT); ObjectTypeBuilder type = TYPE_BUILDER.objectType(); type.addField().key("field").value(TYPE_LOADER.load(String.class)).build(); when(contentParameter.getType()).thenReturn(type.build()); when(parameterGroupModel.getName()).thenReturn("GENERAL"); when(parameterGroupModel.isShowInDsl()).thenReturn(false); when(parameterGroupModel.getParameterModels()).thenReturn(asList(contentParameter)); when(source.getName()).thenReturn(SOURCE_NAME); when(source.getParameterGroupModels()).thenReturn(asList(parameterGroupModel)); when(source.getSuccessCallback()).thenReturn(empty()); when(source.getErrorCallback()).thenReturn(empty()); when(operation.getName()).thenReturn(OPERATION_NAME); when(operation.getParameterGroupModels()).thenReturn(asList(parameterGroupModel)); visitableMock(operation, source); when(connectionProvider.getName()).thenReturn(CONNECTION_PROVIDER_NAME); when(connectionProvider.getParameterGroupModels()).thenReturn(asList(parameterGroupModel)); when(typeCatalog.getSubTypes(any())).thenReturn(emptySet()); when(typeCatalog.getSuperTypes(any())).thenReturn(emptySet()); when(typeCatalog.getAllBaseTypes()).thenReturn(emptySet()); when(typeCatalog.getAllSubTypes()).thenReturn(emptySet()); when(typeCatalog.getTypes()).thenReturn(emptySet()); complexType = (ObjectType) TYPE_LOADER.load(ComplexTypePojo.class); when(typeCatalog.getType(any())).thenReturn(Optional.of(complexType)); when(typeCatalog.containsBaseType(any())).thenReturn(false); when(dslContext.getExtension(any())).thenReturn(Optional.of(extension)); when(dslContext.getExtensions()).thenReturn(singleton(extension)); when(dslContext.getTypeCatalog()).thenReturn(typeCatalog); Stream.of(configuration, operation, connectionProvider, source) .forEach(model -> when(model.getAllParameterModels()) .thenReturn(asList(contentParameter, behaviourParameter, listParameter))); } private void initializeExtensionMock(ExtensionModel extension) { when(extension.getName()).thenReturn(EXTENSION_NAME); when(extension.getXmlDslModel()).thenReturn(XmlDslModel.builder() .setXsdFileName("mule-mockns.xsd") .setPrefix(NAMESPACE) .setNamespace(NAMESPACE_URI) .setSchemaLocation(SCHEMA_LOCATION) .setSchemaVersion("4.0") .build()); when(extension.getSubTypes()).thenReturn(emptySet()); when(extension.getImportedTypes()).thenReturn(emptySet()); when(extension.getXmlDslModel()).thenReturn(XmlDslModel.builder() .setXsdFileName(EMPTY) .setPrefix(NAMESPACE) .setNamespace(NAMESPACE_URI) .setSchemaLocation(SCHEMA_LOCATION) .setSchemaVersion(EMPTY) .build()); when(extension.getConfigurationModels()).thenReturn(asList(configuration)); when(extension.getOperationModels()).thenReturn(asList(operation)); when(extension.getSourceModels()).thenReturn(asList(source)); when(extension.getConnectionProviders()).thenReturn(asList(connectionProvider)); } protected <T> DslElementModel<T> create(ElementDeclaration declaration) { Optional<DslElementModel<T>> elementModel = DslElementModelFactory.getDefault(dslContext).create(declaration); if (!elementModel.isPresent()) { fail("Could not create element model for declared element: " + declaration.getName()); } return elementModel.get(); } @Test public void testConfigDeclarationToElement() { ElementDeclarer ext = ElementDeclarer.forExtension(EXTENSION_NAME); ConfigurationElementDeclaration declaration = ext.newConfiguration(CONFIGURATION_NAME) .withRefName("sample") .withConnection(ext.newConnection(CONNECTION_PROVIDER_NAME) .withParameter(CONTENT_NAME, "#[{field: value}]") .getDeclaration()) .withParameter(BEHAVIOUR_NAME, "additional") .withParameter(LIST_NAME, newListValue().withValue("additional").build()) .getDeclaration(); DslElementModel<ConfigurationModel> element = create(declaration); assertThat(element.getModel(), is(configuration)); assertThat(element.getContainedElements().size(), is(3)); assertThat(element.findElement(LIST_NAME).isPresent(), is(true)); DslElementModel<Object> listModel = element.findElement(LIST_NAME).get(); assertThat(listModel.getContainedElements().size(), is(1)); assertThat(listModel.getContainedElements().get(0).getDsl().getElementName(), is("list-name-item")); DslElementModel<Object> itemModel = listModel.getContainedElements().get(0); assertThat(itemModel.getContainedElements().get(0).getDsl().getAttributeName(), is(VALUE_ATTRIBUTE_NAME)); assertThat(itemModel.getContainedElements().get(0).getValue().get(), is("additional")); assertThat(element.findElement(CONNECTION_PROVIDER_NAME).isPresent(), is(true)); assertThat(element.findElement(CONTENT_NAME).get().getConfiguration().get().getValue().get(), is("#[{field: value}]")); assertThat(element.getConfiguration().get().getParameters().get(BEHAVIOUR_NAME), is("additional")); } @Test public void testOperationDeclarationToElement() { ElementDeclarer ext = ElementDeclarer.forExtension(EXTENSION_NAME); OperationElementDeclaration declaration = ext.newOperation(OPERATION_NAME) .withConfig(CONFIGURATION_NAME) .withParameter(BEHAVIOUR_NAME, "additional") .withParameter(CONTENT_NAME, "#[{field: value}]") .getDeclaration(); DslElementModel<OperationModel> element = create(declaration); assertThat(element.getModel(), is(operation)); assertThat(element.getContainedElements().size(), is(2)); assertThat(element.findElement(BEHAVIOUR_NAME).isPresent(), is(true)); assertThat(element.findElement(CONTENT_NAME).get().getConfiguration().get().getValue().get(), is("#[{field: value}]")); assertThat(element.getConfiguration().get().getParameters().get(BEHAVIOUR_NAME), is("additional")); } @Test public void testSourceDeclarationToElement() { ElementDeclarer ext = ElementDeclarer.forExtension(EXTENSION_NAME); SourceElementDeclaration declaration = ext.newSource(SOURCE_NAME) .withConfig(CONFIGURATION_NAME) .withParameter(BEHAVIOUR_NAME, "additional") .withParameter(CONTENT_NAME, "#[{field: value}]") .getDeclaration(); DslElementModel<SourceModel> element = create(declaration); assertThat(element.getModel(), is(source)); assertThat(element.getContainedElements().size(), is(2)); assertThat(element.findElement(BEHAVIOUR_NAME).isPresent(), is(true)); assertThat(element.findElement(CONTENT_NAME).get().getConfiguration().get().getValue().get(), is("#[{field: value}]")); assertThat(element.getConfiguration().get().getParameters().get(BEHAVIOUR_NAME), is("additional")); } @Test public void testGlobalParameterDeclarationToElement() { ElementDeclarer ext = ElementDeclarer.forExtension(EXTENSION_NAME); TopLevelParameterDeclaration declaration = ext.newGlobalParameter(SOURCE_NAME) .withRefName("globalParameter") .withValue(newObjectValue() .ofType(getId(complexType)) .withParameter(BEHAVIOUR_NAME, "additional") .withParameter(CONTENT_NAME, "#[{field: value}]") .build()) .getDeclaration(); DslElementModel<MetadataType> element = create(declaration); assertThat(element.getModel(), is(complexType)); assertThat(element.getContainedElements().size(), is(2)); assertThat(element.findElement(BEHAVIOUR_NAME).isPresent(), is(true)); assertThat(element.findElement(builder() .withName("my-camel-case-name") .withNamespace("mockns") .build()).get().getConfiguration().get() .getValue().get(), is("#[{field: value}]")); assertThat(element.getConfiguration().get().getParameters().get(BEHAVIOUR_NAME), is("additional")); } @Test public void testConfigNoConnectionNoParams() { ConfigurationModel emptyConfig = mock(ConfigurationModel.class); when(emptyConfig.getName()).thenReturn(CONFIGURATION_NAME); when(emptyConfig.getParameterGroupModels()).thenReturn(emptyList()); when(emptyConfig.getOperationModels()).thenReturn(emptyList()); when(emptyConfig.getSourceModels()).thenReturn(emptyList()); when(emptyConfig.getConnectionProviders()).thenReturn(emptyList()); ExtensionModel extensionModel = mock(ExtensionModel.class); initializeExtensionMock(extensionModel); when(extensionModel.getConfigurationModels()).thenReturn(asList(emptyConfig)); ConfigurationElementDeclaration declaration = ElementDeclarer.forExtension(EXTENSION_NAME).newConfiguration(CONFIGURATION_NAME) .withRefName("sample") .getDeclaration(); DslElementModel<ConfigurationModel> element = create(declaration); assertThat(element.getModel(), is(configuration)); assertThat(element.getContainedElements().isEmpty(), is(true)); } @Test public void testConfigNoParams() { ConfigurationElementDeclaration declaration = ElementDeclarer.forExtension(EXTENSION_NAME) .newConfiguration(CONFIGURATION_NAME) .withRefName("sample") .getDeclaration(); DslElementModel<ConfigurationModel> element = create(declaration); assertThat(element.getModel(), is(configuration)); assertThat(element.getContainedElements().isEmpty(), is(true)); } @XmlHints(allowTopLevelDefinition = true) public static class ComplexTypePojo { @Parameter private String otherName; @Parameter @Content private String myCamelCaseName; public String getOtherName() { return otherName; } public void setOtherName(String otherName) { this.otherName = otherName; } public String getMyCamelCaseName() { return myCamelCaseName; } public void setMyCamelCaseName(String myCamelCaseName) { this.myCamelCaseName = myCamelCaseName; } } }