diff --git a/src/main/java/org/opensearch/geospatial/ip2geo/common/Ip2GeoLockService.java b/src/main/java/org/opensearch/geospatial/ip2geo/common/Ip2GeoLockService.java index 89174f95..81a4e9e7 100644 --- a/src/main/java/org/opensearch/geospatial/ip2geo/common/Ip2GeoLockService.java +++ b/src/main/java/org/opensearch/geospatial/ip2geo/common/Ip2GeoLockService.java @@ -30,7 +30,7 @@ public class Ip2GeoLockService { public static final long LOCK_DURATION_IN_SECONDS = 300l; public static final long RENEW_AFTER_IN_SECONDS = 120l; private final ClusterService clusterService; - private final LockService lockService; + private LockService lockService; /** * Constructor @@ -43,6 +43,19 @@ public Ip2GeoLockService(final ClusterService clusterService, final Client clien this.lockService = new LockService(client, clusterService); } + /** + * Constructor + * + * @param clusterService the cluster service + */ + public Ip2GeoLockService(final ClusterService clusterService) { + this.clusterService = clusterService; + } + + public void initialize(final LockService lockService) { + this.lockService = lockService; + } + /** * Wrapper method of LockService#acquireLockWithId * diff --git a/src/main/java/org/opensearch/geospatial/plugin/GeospatialPlugin.java b/src/main/java/org/opensearch/geospatial/plugin/GeospatialPlugin.java index d64f20b4..14f4ac42 100644 --- a/src/main/java/org/opensearch/geospatial/plugin/GeospatialPlugin.java +++ b/src/main/java/org/opensearch/geospatial/plugin/GeospatialPlugin.java @@ -16,10 +16,14 @@ import org.opensearch.action.ActionRequest; import org.opensearch.client.Client; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; +import org.opensearch.cluster.node.DiscoveryNode; import org.opensearch.cluster.node.DiscoveryNodes; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.collect.MapBuilder; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.lifecycle.Lifecycle; import org.opensearch.common.lifecycle.LifecycleComponent; +import org.opensearch.common.lifecycle.LifecycleListener; import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.IndexScopedSettings; import org.opensearch.common.settings.Setting; @@ -73,7 +77,9 @@ import org.opensearch.index.mapper.Mapper; import org.opensearch.indices.SystemIndexDescriptor; import org.opensearch.ingest.Processor; +import org.opensearch.jobscheduler.spi.utils.LockService; import org.opensearch.plugins.ActionPlugin; +import org.opensearch.plugins.ClusterPlugin; import org.opensearch.plugins.IngestPlugin; import org.opensearch.plugins.MapperPlugin; import org.opensearch.plugins.Plugin; @@ -94,11 +100,22 @@ * to interact with Cluster. */ @Log4j2 -public class GeospatialPlugin extends Plugin implements IngestPlugin, ActionPlugin, MapperPlugin, SearchPlugin, SystemIndexPlugin { +public class GeospatialPlugin extends Plugin + implements + IngestPlugin, + ActionPlugin, + MapperPlugin, + SearchPlugin, + SystemIndexPlugin, + ClusterPlugin { private Ip2GeoCachedDao ip2GeoCachedDao; private DatasourceDao datasourceDao; private GeoIpDataDao geoIpDataDao; private URLDenyListChecker urlDenyListChecker; + private ClusterService clusterService; + private Ip2GeoLockService ip2GeoLockService; + private Ip2GeoExecutor ip2GeoExecutor; + private DatasourceUpdateService datasourceUpdateService; @Override public Collection getSystemIndexDescriptors(Settings settings) { @@ -127,7 +144,10 @@ public void onIndexModule(IndexModule indexModule) { @Override public Collection> getGuiceServiceClasses() { - return List.of(Ip2GeoListener.class); + final List> services = new ArrayList<>(2); + services.add(Ip2GeoListener.class); + services.add(GuiceHolder.class); + return services; } @Override @@ -156,20 +176,10 @@ public Collection createComponents( IndexNameExpressionResolver indexNameExpressionResolver, Supplier repositoriesServiceSupplier ) { - DatasourceUpdateService datasourceUpdateService = new DatasourceUpdateService( - clusterService, - datasourceDao, - geoIpDataDao, - urlDenyListChecker - ); - Ip2GeoExecutor ip2GeoExecutor = new Ip2GeoExecutor(threadPool); - Ip2GeoLockService ip2GeoLockService = new Ip2GeoLockService(clusterService, client); - /** - * We don't need to return datasource runner because it is used only by job scheduler and job scheduler - * does not use DI but it calls DatasourceExtension#getJobRunner to get DatasourceRunner instance. - */ - DatasourceRunner.getJobRunnerInstance() - .initialize(clusterService, datasourceUpdateService, ip2GeoExecutor, datasourceDao, ip2GeoLockService); + this.clusterService = clusterService; + this.datasourceUpdateService = new DatasourceUpdateService(clusterService, datasourceDao, geoIpDataDao, urlDenyListChecker); + this.ip2GeoExecutor = new Ip2GeoExecutor(threadPool); + this.ip2GeoLockService = new Ip2GeoLockService(clusterService); return List.of( UploadStats.getInstance(), @@ -257,4 +267,52 @@ public List getAggregations() { return List.of(geoHexGridSpec); } + + @Override + public void onNodeStarted(DiscoveryNode localNode) { + LockService lockService = GuiceHolder.getLockService(); + ip2GeoLockService.initialize(lockService); + + /** + * We don't need to return datasource runner because it is used only by job scheduler and job scheduler + * does not use DI but it calls DatasourceExtension#getJobRunner to get DatasourceRunner instance. + */ + DatasourceRunner.getJobRunnerInstance() + .initialize(this.clusterService, this.datasourceUpdateService, this.ip2GeoExecutor, this.datasourceDao, this.ip2GeoLockService); + } + + public static class GuiceHolder implements LifecycleComponent { + + private static LockService lockService; + + @Inject + public GuiceHolder(final LockService lockService) { + GuiceHolder.lockService = lockService; + } + + public static LockService getLockService() { + return lockService; + } + + @Override + public void close() {} + + @Override + public Lifecycle.State lifecycleState() { + return null; + } + + @Override + public void addLifecycleListener(LifecycleListener listener) {} + + @Override + public void removeLifecycleListener(LifecycleListener listener) {} + + @Override + public void start() {} + + @Override + public void stop() {} + + } } diff --git a/src/test/java/org/opensearch/geospatial/ClusterSettingHelper.java b/src/test/java/org/opensearch/geospatial/ClusterSettingHelper.java index 93bde1b6..c979a075 100644 --- a/src/test/java/org/opensearch/geospatial/ClusterSettingHelper.java +++ b/src/test/java/org/opensearch/geospatial/ClusterSettingHelper.java @@ -24,7 +24,6 @@ import org.opensearch.common.network.NetworkModule; import org.opensearch.common.settings.Settings; import org.opensearch.env.Environment; -import org.opensearch.geospatial.plugin.GeospatialPlugin; import org.opensearch.node.MockNode; import org.opensearch.node.Node; import org.opensearch.plugins.Plugin; @@ -49,7 +48,7 @@ private List> basePlugins() { List> plugins = new ArrayList<>(); plugins.add(getTestTransportPlugin()); plugins.add(MockHttpTransport.TestPlugin.class); - plugins.add(GeospatialPlugin.class); + plugins.add(TestGeospatialPlugin.class); return plugins; } diff --git a/src/test/java/org/opensearch/geospatial/TestGeospatialPlugin.java b/src/test/java/org/opensearch/geospatial/TestGeospatialPlugin.java new file mode 100644 index 00000000..291c384a --- /dev/null +++ b/src/test/java/org/opensearch/geospatial/TestGeospatialPlugin.java @@ -0,0 +1,29 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.geospatial; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.opensearch.common.lifecycle.LifecycleComponent; +import org.opensearch.geospatial.ip2geo.listener.Ip2GeoListener; +import org.opensearch.geospatial.plugin.GeospatialPlugin; + +/** + * This class is needed for ClusterSettingsHelper.createMockNode to instantiate a test instance of the + * GeospatialPlugin without the JobSchedulerPlugin installed. Without overriding this class, the + * GeospatialPlugin would try to Inject JobScheduler's LockService in the GuiceHolder which will + * fail because JobScheduler is not installed + */ +public class TestGeospatialPlugin extends GeospatialPlugin { + @Override + public Collection> getGuiceServiceClasses() { + final List> services = new ArrayList<>(1); + services.add(Ip2GeoListener.class); + return services; + } +} diff --git a/src/test/java/org/opensearch/geospatial/plugin/GeospatialPluginTests.java b/src/test/java/org/opensearch/geospatial/plugin/GeospatialPluginTests.java index 5bfb489d..0ac04e29 100644 --- a/src/test/java/org/opensearch/geospatial/plugin/GeospatialPluginTests.java +++ b/src/test/java/org/opensearch/geospatial/plugin/GeospatialPluginTests.java @@ -167,7 +167,7 @@ public void testCreateComponents() { } public void testGetGuiceServiceClasses() { - Collection> classes = List.of(Ip2GeoListener.class); + Collection> classes = List.of(Ip2GeoListener.class, GeospatialPlugin.GuiceHolder.class); assertEquals(classes, plugin.getGuiceServiceClasses()); }