Skip to content

Commit

Permalink
providing an option for the plugins to use Spring DI
Browse files Browse the repository at this point in the history
Signed-off-by: Santhosh Gandhe <[email protected]>
  • Loading branch information
san81 committed Oct 1, 2024
1 parent db9a849 commit af194e3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,16 @@
* @since 1.2
*/
Class<?> pluginConfigurationType() default PluginSetting.class;

/**
* Optional Packages to scan for Data Prepper DI components.
* Plugins provide this list if they want to use Dependency Injection in its module.
* Providing this value, implicitly assumes and initiates plugin specific isolated ApplictionContext.
* <p>
* The package names that spring context scans will be picked up by these marker classes.
*
* @return Array of packages to scan
* @since 2.2
*/
Class[] packagesToScanForDI() default {};
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.opensearch.dataprepper.model.sink.SinkContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.annotation.DependsOn;

import javax.inject.Inject;
Expand Down Expand Up @@ -115,13 +116,15 @@ private <T> ComponentPluginArgumentsContext getConstructionContext(final PluginS
final PluginConfigObservable pluginConfigObservable = pluginConfigurationObservableFactory
.createDefaultPluginConfigObservable(pluginConfigurationConverter, pluginConfigurationType, pluginSetting);

BeanFactory beanFactory =
pluginBeanFactoryProvider.initializePluginSpecificIsolatedContextCombinedWithShared(pluginAnnotation);
return new ComponentPluginArgumentsContext.Builder()
.withPluginSetting(pluginSetting)
.withPipelineDescription(pluginSetting)
.withPluginConfiguration(configuration)
.withPluginFactory(this)
.withSinkContext(sinkContext)
.withBeanFactory(pluginBeanFactoryProvider.get())
.withBeanFactory(beanFactory)
.withPluginConfigurationObservable(pluginConfigObservable)
.withTypeArgumentSuppliers(applicationContextToTypedSuppliers.getArgumentsSuppliers())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@

package org.opensearch.dataprepper.plugin;

import org.opensearch.dataprepper.model.annotations.DataPrepperPlugin;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import java.util.Arrays;
import java.util.Objects;

/**
Expand All @@ -25,7 +27,7 @@
* <p><i>publicContext</i> is the root {@link ApplicationContext}</p>
*/
@Named
class PluginBeanFactoryProvider implements Provider<BeanFactory> {
class PluginBeanFactoryProvider {
private final GenericApplicationContext sharedPluginApplicationContext;
private final GenericApplicationContext coreApplicationContext;

Expand Down Expand Up @@ -57,8 +59,17 @@ GenericApplicationContext getCoreApplicationContext() {
* instead, a new isolated {@link ApplicationContext} should be created.
* @return BeanFactory A BeanFactory that inherits from {@link PluginBeanFactoryProvider#sharedPluginApplicationContext}
*/
public BeanFactory get() {
final GenericApplicationContext isolatedPluginApplicationContext = new GenericApplicationContext(sharedPluginApplicationContext);
return isolatedPluginApplicationContext.getBeanFactory();
public BeanFactory initializePluginSpecificIsolatedContextCombinedWithShared(DataPrepperPlugin pluginAnnotation) {
AnnotationConfigApplicationContext pluginDIContext = new AnnotationConfigApplicationContext();
if(pluginAnnotation.packagesToScanForDI().length>0) {
// If packages to scan is provided in this plugin annotation, which indicates
// that this plugin is interested in using Dependency Injection isolated for its module
Arrays.stream(pluginAnnotation.packagesToScanForDI())
.map(Class::getPackageName)
.forEach(pluginDIContext::scan);
pluginDIContext.refresh();
}
pluginDIContext.setParent(sharedPluginApplicationContext);
return pluginDIContext.getBeanFactory();
}
}

0 comments on commit af194e3

Please sign in to comment.