/* * 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.module.extension.internal.config.dsl.source; import static java.lang.String.format; import static java.util.stream.Collectors.toList; import static org.mule.runtime.api.i18n.I18nMessageFactory.createStaticMessage; import static org.mule.runtime.core.api.lifecycle.LifecycleUtils.initialiseIfNeeded; import static org.mule.runtime.core.util.ClassUtils.withContextClassLoader; import static org.mule.runtime.module.extension.internal.util.MuleExtensionUtils.getClassLoader; import org.mule.runtime.api.exception.MuleRuntimeException; import org.mule.runtime.api.lifecycle.InitialisationException; import org.mule.runtime.api.meta.model.ExtensionModel; import org.mule.runtime.api.meta.model.source.SourceCallbackModel; import org.mule.runtime.api.meta.model.source.SourceModel; import org.mule.runtime.core.api.MuleContext; import org.mule.runtime.core.api.config.ConfigurationException; import org.mule.runtime.core.api.retry.RetryPolicyTemplate; import org.mule.runtime.core.internal.connection.ConnectionManagerAdapter; import org.mule.runtime.core.streaming.CursorProviderFactory; import org.mule.runtime.extension.api.runtime.ConfigurationProvider; import org.mule.runtime.extension.api.runtime.source.Source; import org.mule.runtime.module.extension.internal.config.dsl.AbstractExtensionObjectFactory; import org.mule.runtime.module.extension.internal.runtime.resolver.ParametersResolver; import org.mule.runtime.module.extension.internal.runtime.resolver.ResolverSet; import org.mule.runtime.module.extension.internal.runtime.source.ExtensionMessageSource; import org.mule.runtime.module.extension.internal.runtime.source.SourceAdapter; import org.mule.runtime.module.extension.internal.runtime.source.SourceAdapterFactory; import org.mule.runtime.module.extension.internal.runtime.source.SourceConfigurer; import org.mule.runtime.module.extension.internal.util.MuleExtensionUtils; import com.google.common.base.Joiner; import java.util.List; import java.util.Optional; import javax.inject.Inject; /** * An {@link AbstractExtensionObjectFactory} that produces instances of {@link ExtensionMessageSource} * * @since 4.0 */ public class ExtensionSourceObjectFactory extends AbstractExtensionObjectFactory<ExtensionMessageSource> { private final ExtensionModel extensionModel; private final SourceModel sourceModel; private ConfigurationProvider configurationProvider; private RetryPolicyTemplate retryPolicyTemplate; private CursorProviderFactory cursorProviderFactory; @Inject private ConnectionManagerAdapter connectionManager; public ExtensionSourceObjectFactory(ExtensionModel extensionModel, SourceModel sourceModel, MuleContext muleContext) { super(muleContext); this.extensionModel = extensionModel; this.sourceModel = sourceModel; } protected ParametersResolver getParametersResolver(MuleContext muleContext) { return ParametersResolver.fromValues(parameters, muleContext); } @Override public ExtensionMessageSource doGetObject() throws ConfigurationException, InitialisationException { return withContextClassLoader(getClassLoader(extensionModel), () -> { parametersResolver.checkParameterGroupExclusiveness(sourceModel, parameters.keySet()); ResolverSet nonCallbackParameters = getNonCallbackParameters(); if (nonCallbackParameters.isDynamic()) { throw dynamicParameterException(nonCallbackParameters, sourceModel); } ResolverSet responseCallbackParameters = getCallbackParameters(sourceModel.getSuccessCallback()); ResolverSet errorCallbackParameters = getCallbackParameters(sourceModel.getErrorCallback()); initialiseIfNeeded(nonCallbackParameters, true, muleContext); initialiseIfNeeded(responseCallbackParameters, true, muleContext); initialiseIfNeeded(errorCallbackParameters, true, muleContext); return new ExtensionMessageSource(extensionModel, sourceModel, getSourceFactory(nonCallbackParameters, responseCallbackParameters, errorCallbackParameters), configurationProvider, getRetryPolicyTemplate(), cursorProviderFactory, muleContext.getExtensionManager()); }); } private ResolverSet getNonCallbackParameters() throws ConfigurationException { return parametersResolver.getParametersAsResolverSet(sourceModel, sourceModel.getParameterGroupModels().stream() .flatMap(g -> g.getParameterModels().stream()) .collect(toList()), muleContext); } private ResolverSet getCallbackParameters(Optional<SourceCallbackModel> callbackModel) throws ConfigurationException { if (callbackModel.isPresent()) { return parametersResolver.getParametersAsResolverSet(callbackModel.get(), muleContext); } return new ResolverSet(muleContext); } private SourceAdapterFactory getSourceFactory(ResolverSet nonCallbackParameters, ResolverSet successCallbackParameters, ResolverSet errorCallbackParameters) { return (configurationInstance, sourceCallbackFactory) -> { Source source = MuleExtensionUtils.getSourceFactory(sourceModel).createSource(); try { source = new SourceConfigurer(sourceModel, nonCallbackParameters, muleContext) .configure(source, configurationInstance); return new SourceAdapter(extensionModel, sourceModel, source, configurationInstance, sourceCallbackFactory, nonCallbackParameters, successCallbackParameters, errorCallbackParameters); } catch (Exception e) { throw new MuleRuntimeException(createStaticMessage(format("Could not create generator for source '%s'", sourceModel.getName())), e); } }; } private RetryPolicyTemplate getRetryPolicyTemplate() throws ConfigurationException { return retryPolicyTemplate != null ? retryPolicyTemplate : connectionManager.getDefaultRetryPolicyTemplate(); } public void setRetryPolicyTemplate(RetryPolicyTemplate retryPolicyTemplate) { this.retryPolicyTemplate = retryPolicyTemplate; } private ConfigurationException dynamicParameterException(ResolverSet resolverSet, SourceModel model) { List<String> dynamicParams = resolverSet.getResolvers().entrySet().stream().filter(entry -> entry.getValue().isDynamic()) .map(entry -> entry.getKey()).collect(toList()); return new ConfigurationException( createStaticMessage(format("The '%s' message source is using expressions, which are not allowed on message sources. " + "Offending parameters are: [%s]", model.getName(), Joiner.on(',').join(dynamicParams)))); } public void setConfigurationProvider(ConfigurationProvider configurationProvider) { this.configurationProvider = configurationProvider; } public void setCursorProviderFactory(CursorProviderFactory cursorProviderFactory) { this.cursorProviderFactory = cursorProviderFactory; } }