/*
* 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;
import static java.util.Arrays.asList;
import static java.util.Collections.emptySet;
import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static org.apache.commons.lang.StringUtils.join;
import static org.apache.commons.lang3.ArrayUtils.addAll;
import static org.mule.runtime.api.component.ComponentIdentifier.buildFromStringRepresentation;
import static org.mule.runtime.api.util.Preconditions.checkArgument;
import static org.mule.runtime.config.spring.XmlConfigurationDocumentLoader.schemaValidatingDocumentLoader;
import static org.mule.runtime.config.spring.dsl.model.ApplicationModel.CONFIGURATION_IDENTIFIER;
import static org.mule.runtime.config.spring.dsl.model.ApplicationModel.MULE_IDENTIFIER;
import static org.mule.runtime.config.spring.dsl.spring.BeanDefinitionFactory.SPRING_SINGLETON_OBJECT;
import static org.mule.runtime.config.spring.parsers.generic.AutoIdUtils.uniqueValue;
import static org.mule.runtime.core.api.config.MuleProperties.OBJECT_CONNECTIVITY_TESTING_SERVICE;
import static org.mule.runtime.core.api.config.MuleProperties.OBJECT_METADATA_SERVICE;
import static org.mule.runtime.core.api.config.MuleProperties.OBJECT_MULE_CONFIGURATION;
import static org.mule.runtime.core.api.config.MuleProperties.OBJECT_MULE_CONTEXT;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
import static org.springframework.context.annotation.AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME;
import static org.springframework.context.annotation.AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME;
import static org.springframework.context.annotation.AnnotationConfigUtils.REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME;
import org.mule.runtime.api.app.declaration.ArtifactDeclaration;
import org.mule.runtime.api.component.ComponentIdentifier;
import org.mule.runtime.api.component.location.Location;
import org.mule.runtime.api.dsl.DslResolvingContext;
import org.mule.runtime.api.exception.MuleRuntimeException;
import org.mule.runtime.api.meta.model.ExtensionModel;
import org.mule.runtime.api.metadata.MetadataService;
import org.mule.runtime.config.spring.dsl.model.ApplicationModel;
import org.mule.runtime.config.spring.dsl.model.ComponentBuildingDefinitionRegistry;
import org.mule.runtime.config.spring.dsl.model.ComponentModel;
import org.mule.runtime.config.spring.dsl.model.MinimalApplicationModelGenerator;
import org.mule.runtime.config.spring.dsl.processor.ArtifactConfig;
import org.mule.runtime.config.spring.dsl.processor.ConfigFile;
import org.mule.runtime.config.spring.dsl.processor.ConfigLine;
import org.mule.runtime.config.spring.dsl.processor.xml.XmlApplicationParser;
import org.mule.runtime.config.spring.dsl.processor.xml.XmlApplicationServiceRegistry;
import org.mule.runtime.config.spring.dsl.spring.BeanDefinitionFactory;
import org.mule.runtime.config.spring.editors.MulePropertyEditorRegistrar;
import org.mule.runtime.config.spring.processors.ComponentLocatorCreatePostProcessor;
import org.mule.runtime.config.spring.processors.ContextExclusiveInjectorProcessor;
import org.mule.runtime.config.spring.processors.DiscardedOptionalBeanPostProcessor;
import org.mule.runtime.config.spring.processors.LifecycleStatePostProcessor;
import org.mule.runtime.config.spring.processors.MuleInjectorProcessor;
import org.mule.runtime.config.spring.processors.PostRegistrationActionsPostProcessor;
import org.mule.runtime.config.spring.util.LaxInstantiationStrategyWrapper;
import org.mule.runtime.core.api.MuleContext;
import org.mule.runtime.core.api.connectivity.ConnectivityTestingService;
import org.mule.runtime.core.api.extension.ExtensionManager;
import org.mule.runtime.core.api.registry.ServiceRegistry;
import org.mule.runtime.core.api.registry.TransformerResolver;
import org.mule.runtime.core.api.transformer.Converter;
import org.mule.runtime.core.config.ConfigResource;
import org.mule.runtime.core.config.bootstrap.ArtifactType;
import org.mule.runtime.core.registry.MuleRegistryHelper;
import org.mule.runtime.core.registry.SpiServiceRegistry;
import org.mule.runtime.core.util.IOUtils;
import org.mule.runtime.dsl.api.component.ComponentBuildingDefinitionProvider;
import org.mule.runtime.module.extension.internal.config.ExtensionBuildingDefinitionProvider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.w3c.dom.Document;
/**
* <code>MuleArtifactContext</code> is a simple extension application context that allows resources to be loaded from the
* Classpath of file system using the MuleBeanDefinitionReader.
*/
public class MuleArtifactContext extends AbstractXmlApplicationContext {
private static final Logger LOGGER = LoggerFactory.getLogger(MuleArtifactContext.class);
private static final ThreadLocal<MuleContext> currentMuleContext = new ThreadLocal<>();
public static final String INNER_BEAN_PREFIX = "(inner bean)";
protected final ComponentBuildingDefinitionRegistry componentBuildingDefinitionRegistry =
new ComponentBuildingDefinitionRegistry();
private final OptionalObjectsController optionalObjectsController;
private final Map<String, String> artifactProperties;
private final ArtifactDeclaration artifactDeclaration;
private final XmlConfigurationDocumentLoader xmlConfigurationDocumentLoader;
protected ApplicationModel applicationModel;
protected MuleContext muleContext;
private Resource[] artifactConfigResources;
protected BeanDefinitionFactory beanDefinitionFactory;
private MuleXmlBeanDefinitionReader beanDefinitionReader;
private final ServiceRegistry serviceRegistry = new SpiServiceRegistry();
protected boolean useNewParsingMechanism = true;
protected final XmlApplicationParser xmlApplicationParser;
private ArtifactType artifactType;
private List<ComponentIdentifier> componentNotSupportedByNewParsers = new ArrayList<>();
private SpringConfigurationComponentLocator componentLocator = new SpringConfigurationComponentLocator();
/**
* Parses configuration files creating a spring ApplicationContext which is used as a parent registry using the SpringRegistry
* registry implementation to wraps the spring ApplicationContext
*
* @param muleContext the {@link MuleContext} that own this context
* @param artifactDeclaration the mule configuration defined programmatically
* @param optionalObjectsController the {@link OptionalObjectsController} to use. Cannot be {@code null} @see
* org.mule.runtime.config.spring.SpringRegistry
* @param pluginsClassLoaders the classloades of the plugins included in the artifact, on hwich contexts the parsers will
* process.
* @since 3.7.0
*/
public MuleArtifactContext(MuleContext muleContext, ConfigResource[] artifactConfigResources,
ArtifactDeclaration artifactDeclaration, OptionalObjectsController optionalObjectsController,
Map<String, String> artifactProperties, ArtifactType artifactType,
List<ClassLoader> pluginsClassLoaders)
throws BeansException {
this(muleContext, convert(artifactConfigResources), artifactDeclaration, optionalObjectsController, artifactProperties,
artifactType, pluginsClassLoaders);
}
public MuleArtifactContext(MuleContext muleContext, Resource[] artifactConfigResources,
ArtifactDeclaration artifactDeclaration, OptionalObjectsController optionalObjectsController,
Map<String, String> artifactProperties, ArtifactType artifactType,
List<ClassLoader> pluginsClassLoaders) {
checkArgument(optionalObjectsController != null, "optionalObjectsController cannot be null");
this.muleContext = muleContext;
this.artifactConfigResources = artifactConfigResources;
this.optionalObjectsController = optionalObjectsController;
this.artifactProperties = artifactProperties;
this.artifactType = artifactType;
this.artifactDeclaration = artifactDeclaration;
this.xmlConfigurationDocumentLoader = newXmlConfigurationDocumentLoader();
serviceRegistry.lookupProviders(ComponentBuildingDefinitionProvider.class, MuleArtifactContext.class.getClassLoader())
.forEach(componentBuildingDefinitionProvider -> {
if (componentBuildingDefinitionProvider instanceof ExtensionBuildingDefinitionProvider) {
((ExtensionBuildingDefinitionProvider) componentBuildingDefinitionProvider)
.setExtensionModels(muleContext.getExtensionManager() != null ? muleContext.getExtensionManager().getExtensions()
: emptySet());
}
componentBuildingDefinitionProvider.init();
componentBuildingDefinitionProvider.getComponentBuildingDefinitions()
.forEach(componentBuildingDefinitionRegistry::register);
});
for (ClassLoader pluginArtifactClassLoader : pluginsClassLoaders) {
serviceRegistry.lookupProviders(ComponentBuildingDefinitionProvider.class, pluginArtifactClassLoader)
.forEach(componentBuildingDefinitionProvider -> {
if (!(componentBuildingDefinitionProvider instanceof ExtensionBuildingDefinitionProvider)) {
componentBuildingDefinitionProvider.init();
componentBuildingDefinitionProvider.getComponentBuildingDefinitions()
.forEach(componentBuildingDefinitionRegistry::register);
}
});
}
xmlApplicationParser = createApplicationParser(pluginsClassLoaders);
this.beanDefinitionFactory =
new BeanDefinitionFactory(componentBuildingDefinitionRegistry, muleContext.getErrorTypeRepository());
createApplicationModel();
determineIfOnlyNewParsingMechanismCanBeUsed();
}
protected XmlConfigurationDocumentLoader newXmlConfigurationDocumentLoader() {
return schemaValidatingDocumentLoader();
}
private XmlApplicationParser createApplicationParser(List<ClassLoader> pluginsClassLoaders) {
ExtensionManager extensionManager = muleContext.getExtensionManager();
ServiceRegistry customRegistry = extensionManager != null
? new XmlApplicationServiceRegistry(serviceRegistry, DslResolvingContext.getDefault(extensionManager.getExtensions()))
: serviceRegistry;
return new XmlApplicationParser(customRegistry, pluginsClassLoaders);
}
private void determineIfOnlyNewParsingMechanismCanBeUsed() {
if (applicationModel.hasSpringConfig()) {
componentNotSupportedByNewParsers.add(buildFromStringRepresentation("spring:springConfig"));
useNewParsingMechanism = false;
return;
}
applicationModel.executeOnEveryComponentTree(componentModel -> {
Optional<ComponentIdentifier> parentIdentifierOptional = ofNullable(componentModel.getParent())
.flatMap(parentComponentModel -> ofNullable(parentComponentModel.getIdentifier()));
if (!beanDefinitionFactory.hasDefinition(componentModel.getIdentifier(), parentIdentifierOptional)) {
componentNotSupportedByNewParsers.add(componentModel.getIdentifier());
useNewParsingMechanism = false;
}
});
}
private void createApplicationModel() {
try {
ArtifactConfig.Builder applicationConfigBuilder = new ArtifactConfig.Builder();
applicationConfigBuilder.setApplicationProperties(this.artifactProperties);
for (Resource springResource : artifactConfigResources) {
Document document =
xmlConfigurationDocumentLoader.loadDocument(muleContext.getExtensionManager() == null ? emptySet()
: muleContext.getExtensionManager().getExtensions(),
springResource.getFilename(),
springResource.getInputStream());
ConfigLine mainConfigLine = xmlApplicationParser.parse(document.getDocumentElement()).get();
applicationConfigBuilder.addConfigFile(new ConfigFile(getFilename(springResource), asList(mainConfigLine)));
}
applicationConfigBuilder.setApplicationName(muleContext.getConfiguration().getId());
Set<ExtensionModel> extensions =
muleContext.getExtensionManager() != null ? muleContext.getExtensionManager().getExtensions() : emptySet();
applicationModel = new ApplicationModel(applicationConfigBuilder.build(), artifactDeclaration,
extensions, of(componentBuildingDefinitionRegistry));
} catch (Exception e) {
throw new MuleRuntimeException(e);
}
}
private String getFilename(Resource resource) {
if (resource instanceof ByteArrayResource) {
return resource.getDescription();
}
return resource.getFilename();
}
@Override
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.prepareBeanFactory(beanFactory);
registerEditors(beanFactory);
addBeanPostProcessors(beanFactory,
new MuleContextPostProcessor(muleContext),
new GlobalNamePostProcessor(),
new PostRegistrationActionsPostProcessor((MuleRegistryHelper) muleContext.getRegistry(), beanFactory),
new DiscardedOptionalBeanPostProcessor(optionalObjectsController,
(DefaultListableBeanFactory) beanFactory),
new LifecycleStatePostProcessor(muleContext.getLifecycleManager().getState()),
new ComponentLocatorCreatePostProcessor(componentLocator));
beanFactory.registerSingleton(OBJECT_MULE_CONTEXT, muleContext);
}
private void registerEditors(ConfigurableListableBeanFactory beanFactory) {
MulePropertyEditorRegistrar registrar = new MulePropertyEditorRegistrar();
registrar.setMuleContext(muleContext);
beanFactory.addPropertyEditorRegistrar(registrar);
}
private void addBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, BeanPostProcessor... processors) {
for (BeanPostProcessor processor : processors) {
beanFactory.addBeanPostProcessor(processor);
}
}
@Override
public void close() {
super.close();
beanDefinitionFactory.destroy();
}
private static Resource[] convert(ConfigResource[] resources) {
Resource[] configResources = new Resource[resources.length];
for (int i = 0; i < resources.length; i++) {
ConfigResource resource = resources[i];
if (resource.getUrl() != null) {
configResources[i] = new UrlResource(resource.getUrl());
} else {
try {
configResources[i] = new ByteArrayResource(IOUtils.toByteArray(resource.getInputStream()), resource.getResourceName());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
return configResources;
}
@Override
protected Resource[] getConfigResources() {
return addAll(artifactConfigResources);
}
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
BeanDefinitionReader beanDefinitionReader = createBeanDefinitionReader(beanFactory);
// Communicate mule context to parsers
try {
currentMuleContext.set(muleContext);
createInitialApplicationComponents(beanFactory, beanDefinitionReader);
} finally {
currentMuleContext.remove();
}
}
protected void createInitialApplicationComponents(DefaultListableBeanFactory beanFactory,
BeanDefinitionReader beanDefinitionReader) {
if (useNewParsingMechanism) {
createApplicationComponents(beanFactory, applicationModel, true);
} else {
// TODO MULE-9638 - Remove log line
LOGGER
.warn("Using mixed mechanism to load configuration since there are some components that were not yet migrated to the new mechanism: "
+ getOldParsingMechanismComponentIdentifiers());
beanDefinitionReader.loadBeanDefinitions(getConfigResources());
}
}
protected List<String> createApplicationComponents(DefaultListableBeanFactory beanFactory, ApplicationModel applicationModel,
boolean mustBeRoot) {
List<String> createdComponentModels = new ArrayList<>();
applicationModel.executeOnEveryMuleComponentTree(componentModel -> {
if (!mustBeRoot || componentModel.isRoot()) {
if (componentModel.getIdentifier().equals(MULE_IDENTIFIER) || !componentModel.isEnabled()) {
return;
}
if (componentModel.getNameAttribute() != null) {
createdComponentModels.add(componentModel.getNameAttribute());
}
beanDefinitionFactory.resolveComponentRecursively(componentModel.getParent() != null ? componentModel.getParent()
: applicationModel.getRootComponentModel(), componentModel,
beanFactory,
(resolvedComponentModel, registry) -> {
if (resolvedComponentModel.isRoot()) {
String nameAttribute =
resolvedComponentModel.getNameAttribute();
if (resolvedComponentModel.getIdentifier()
.equals(CONFIGURATION_IDENTIFIER)) {
nameAttribute = OBJECT_MULE_CONFIGURATION;
} else if (nameAttribute == null) {
// This may be a configuration that does not requires a name.
nameAttribute = uniqueValue(resolvedComponentModel
.getBeanDefinition().getBeanClassName());
}
registry.registerBeanDefinition(nameAttribute,
resolvedComponentModel
.getBeanDefinition());
postProcessBeanDefinition(componentModel, registry,
nameAttribute);
}
}, null);
}
});
return createdComponentModels;
}
protected String getOldParsingMechanismComponentIdentifiers() {
return join(componentNotSupportedByNewParsers.stream().map(comp -> comp.getNamespace() + ":" + comp.getName()).toArray(),
",");
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
super.customizeBeanFactory(beanFactory);
new SpringMuleContextServiceConfigurator(muleContext, applicationModel.getArtifactProperties(), artifactType,
optionalObjectsController, beanFactory, componentLocator)
.createArtifactServices();
}
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
Optional<ComponentModel> configurationOptional =
applicationModel.findComponentDefinitionModel(ApplicationModel.CONFIGURATION_IDENTIFIER);
if (configurationOptional.isPresent()) {
return;
}
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
beanDefinitionRegistry.registerBeanDefinition(OBJECT_MULE_CONFIGURATION,
genericBeanDefinition(MuleConfigurationConfigurator.class).getBeanDefinition());
}
protected BeanDefinitionReader createBeanDefinitionReader(DefaultListableBeanFactory beanFactory) {
beanDefinitionReader =
new MuleXmlBeanDefinitionReader(beanFactory, createBeanDefinitionDocumentReader(beanDefinitionFactory));
// annotate parsed elements with metadata
beanDefinitionReader.setDocumentLoader(createLoader());
// hook in our custom hierarchical reader
beanDefinitionReader.setDocumentReaderClass(getBeanDefinitionDocumentReaderClass());
// add error reporting
beanDefinitionReader.setProblemReporter(new MissingParserProblemReporter());
registerAnnotationConfigProcessors(beanDefinitionReader.getRegistry(), null);
return beanDefinitionReader;
}
protected MuleBeanDefinitionDocumentReader createBeanDefinitionDocumentReader(BeanDefinitionFactory beanDefinitionFactory) {
if (artifactType.equals(ArtifactType.DOMAIN)) {
return new MuleDomainBeanDefinitionDocumentReader(beanDefinitionFactory, xmlApplicationParser,
componentBuildingDefinitionRegistry);
}
return new MuleBeanDefinitionDocumentReader(beanDefinitionFactory, xmlApplicationParser, componentBuildingDefinitionRegistry);
}
protected MuleDocumentLoader createLoader() {
return new MuleDocumentLoader();
}
private void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {
registerAnnotationConfigProcessor(registry, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,
ConfigurationClassPostProcessor.class, source);
registerAnnotationConfigProcessor(registry, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME,
RequiredAnnotationBeanPostProcessor.class, source);
registerInjectorProcessor(registry);
}
protected void registerInjectorProcessor(BeanDefinitionRegistry registry) {
if (artifactType.equals(ArtifactType.APP)) {
registerAnnotationConfigProcessor(registry, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, MuleInjectorProcessor.class, null);
} else if (artifactType.equals(ArtifactType.DOMAIN)) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ContextExclusiveInjectorProcessor.class);
builder.addConstructorArgValue(this);
registerPostProcessor(registry, (RootBeanDefinition) builder.getBeanDefinition(), AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME);
}
}
private void registerAnnotationConfigProcessor(BeanDefinitionRegistry registry, String key, Class<?> type, Object source) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(type);
beanDefinition.setSource(source);
registerPostProcessor(registry, beanDefinition, key);
}
protected void registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
}
protected Class<? extends MuleBeanDefinitionDocumentReader> getBeanDefinitionDocumentReaderClass() {
if (artifactType.equals(ArtifactType.DOMAIN)) {
return MuleDomainBeanDefinitionDocumentReader.class;
}
return MuleBeanDefinitionDocumentReader.class;
}
@Override
protected DefaultListableBeanFactory createBeanFactory() {
// Copy all postProcessors defined in the defaultMuleConfig so that they get applied to the child container
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(getInternalParentBeanFactory());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
beanFactory.setInstantiationStrategy(new LaxInstantiationStrategyWrapper(new CglibSubclassingInstantiationStrategy(),
optionalObjectsController));
return beanFactory;
}
/**
* {@inheritDoc} This implementation returns {@code false} if the context hasn't been initialised yet, in opposition to the
* default implementation which throws an exception
*/
@Override
public boolean isRunning() {
try {
return super.isRunning();
} catch (IllegalStateException e) {
return false;
}
}
/**
* Forces the registration of instances of {@link TransformerResolver} and {@link Converter} to be created, so that
* {@link PostRegistrationActionsPostProcessor} can work its magic and add them to the transformation graph
*/
protected static void postProcessBeanDefinition(ComponentModel resolvedComponent, BeanDefinitionRegistry registry,
String beanName) {
if (Converter.class.isAssignableFrom(resolvedComponent.getType())) {
GenericBeanDefinition converterBeanDefinitionCopy = new GenericBeanDefinition(resolvedComponent.getBeanDefinition());
converterBeanDefinitionCopy.setScope(SPRING_SINGLETON_OBJECT);
registry.registerBeanDefinition(beanName + "-" + "converter", converterBeanDefinitionCopy);
}
}
public MuleContext getMuleContext() {
return muleContext;
}
protected OptionalObjectsController getOptionalObjectsController() {
return optionalObjectsController;
}
public static ThreadLocal<MuleContext> getCurrentMuleContext() {
return currentMuleContext;
}
public void initializeComponent(Location location) {
MinimalApplicationModelGenerator minimalApplicationModelGenerator =
new MinimalApplicationModelGenerator(this.applicationModel, componentBuildingDefinitionRegistry);
ApplicationModel minimalApplicationModel = minimalApplicationModelGenerator.getMinimalModel(location);
createApplicationComponents((DefaultListableBeanFactory) this.getBeanFactory(), minimalApplicationModel, false);
}
public ConnectivityTestingService getConnectivityTestingService() {
return muleContext.getRegistry().lookupObject(OBJECT_CONNECTIVITY_TESTING_SERVICE);
}
public MetadataService getMetadataService() {
return muleContext.getRegistry().get(OBJECT_METADATA_SERVICE);
}
}