Skip to content

Commit

Permalink
Added getNamedWriteableRegistry() API for extensions (#553)
Browse files Browse the repository at this point in the history
* Created ScriptExtension interface #318

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Created ScriptExtension interface #318

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Created ScriptExtension interface #318

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Created ScriptExtension interface #318

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Created ScriptExtension interface #318

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Created ScriptExtension interface #318

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Fixed Tests. Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Fixed Tests. Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Fixed Tests. Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Fixed Tests. Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

* Fixed Tests. Added getNamedWriteableRegistry() API for extensions #291

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>

---------

Signed-off-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>
Signed-off-by: petiveriaalliacea <77691894+petiveriaalliacea@users.noreply.github.com>
Co-authored-by: Aisara Imangaliyeva <imangaliyeva.aisara@gmail.com>
Co-authored-by: Ryan Bogan <10944539+ryanbogan@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 27, 2023
1 parent ebc684a commit e13aed8
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/main/java/org/opensearch/sdk/BaseExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* An abstract class that simplifies extension initialization and provides an instance of the runner.
*/
public abstract class BaseExtension implements Extension {

/**
* The {@link ExtensionsRunner} instance running this extension
*/
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/org/opensearch/sdk/Extension.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Collection;
import java.util.List;

import org.opensearch.common.io.stream.NamedWriteableRegistry;
import org.opensearch.common.settings.Setting;
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.threadpool.ExecutorBuilder;
Expand Down Expand Up @@ -49,14 +50,23 @@ default List<Setting<?>> getSettings() {
}

/**
* Gets an optional list of custom {@link NamedXContentRegistry.Entry} for the extension to combine with OpenSearch NamedXConent.
* Gets an optional list of custom {@link NamedXContentRegistry.Entry} for the extension to combine with OpenSearch NamedWriteable.
*
* @return a list of custom NamedXConent this extension uses.
*/
default List<NamedXContentRegistry.Entry> getNamedXContent() {
return Collections.emptyList();
}

/**
* Gets an optional list of custom {@link NamedWriteableRegistry.Entry} for the extension to combine with OpenSearch NamedXWriteable.
*
* @return a list of custom NamedWriteable this extension uses.
*/
default List<NamedWriteableRegistry.Entry> getNamedWriteables() {
return Collections.emptyList();
}

/**
* Returns components added by this extension.
*
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/org/opensearch/sdk/ExtensionsRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.opensearch.action.support.TransportAction;
import org.opensearch.cluster.ClusterState;
import org.opensearch.cluster.node.DiscoveryNode;
import org.opensearch.common.io.stream.NamedWriteableRegistry;
import org.opensearch.extensions.rest.ExtensionRestRequest;
import org.opensearch.extensions.rest.RegisterRestActionsRequest;
import org.opensearch.extensions.settings.RegisterCustomSettingsRequest;
Expand Down Expand Up @@ -105,6 +106,11 @@ public class ExtensionsRunner {
* Custom namedXContent from the extension's getNamedXContent. This field is initialized in the constructor.
*/
private final List<NamedXContentRegistry.Entry> customNamedXContent;
/**
* Custom namedWriteable from the extension's getNamedWriteable. This field is initialized in the constructor.
*/
private final List<NamedWriteableRegistry.Entry> customNamedWriteables;

/**
* Custom settings from the extension's getSettings. This field is initialized in the constructor.
*/
Expand Down Expand Up @@ -132,6 +138,7 @@ public class ExtensionsRunner {
private final Injector injector;

private final SDKNamedXContentRegistry sdkNamedXContentRegistry;
private final SDKNamedWriteableRegistry sdkNamedWriteableRegistry;
private final SDKClient sdkClient;
private final SDKClusterService sdkClusterService;
private final SDKTransportService sdkTransportService;
Expand Down Expand Up @@ -176,8 +183,13 @@ protected ExtensionsRunner(Extension extension) throws IOException {
this.customSettings = extension.getSettings();
// save custom namedXContent
this.customNamedXContent = extension.getNamedXContent();
// save custom namedWriteable
this.customNamedWriteables = extension.getNamedWriteables();
// initialize NamedXContent Registry. Must happen after getting extension namedXContent
this.sdkNamedXContentRegistry = new SDKNamedXContentRegistry(this);
// initialize NamedWriteable Registry. Must happen after getting extension namedWriteable
this.sdkNamedWriteableRegistry = new SDKNamedWriteableRegistry(this);

// initialize SDKClient. Must happen after getting extensionSettings
this.sdkClient = new SDKClient(extensionSettings);
// initialize SDKClusterService. Must happen after extension field assigned
Expand Down Expand Up @@ -294,6 +306,13 @@ public void updateNamedXContentRegistry() {
this.sdkNamedXContentRegistry.updateNamedXContentRegistry(this);
}

/**
* Updates the NamedXContentRegistry. Called from {@link ExtensionsInitRequestHandler}.
*/
public void updateNamedWriteableRegistry() {
this.sdkNamedWriteableRegistry.updateNamedWriteableRegistry(this);
}

/**
* Gets the NamedXContentRegistry. Only valid if {@link #isInitialized()} returns true.
*
Expand All @@ -303,6 +322,15 @@ public SDKNamedXContentRegistry getNamedXContentRegistry() {
return this.sdkNamedXContentRegistry;
}

/**
* Gets the SDKNamedWriteableRegistry. Only valid if {@link #isInitialized()} returns true.
*
* @return the NamedWriteableRegistry if initialized, an empty registry otherwise.
*/
public SDKNamedWriteableRegistry getNamedWriteableRegistry() {
return this.sdkNamedWriteableRegistry;
}

/**
* Sets the Unique ID, used in REST requests to uniquely identify this extension
*
Expand Down Expand Up @@ -341,6 +369,10 @@ public List<NamedXContentRegistry.Entry> getCustomNamedXContent() {
return this.customNamedXContent;
}

public List<NamedWriteableRegistry.Entry> getCustomNamedWriteables() {
return this.customNamedWriteables;
}

/**
* Starts a TransportService.
*
Expand Down
22 changes: 1 addition & 21 deletions src/main/java/org/opensearch/sdk/NettyTransport.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,14 @@
package org.opensearch.sdk;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.opensearch.Version;
import org.opensearch.cluster.ClusterModule;
import org.opensearch.cluster.node.DiscoveryNode;
import org.opensearch.common.io.stream.NamedWriteableRegistry;
import org.opensearch.common.network.NetworkModule;
import org.opensearch.common.network.NetworkService;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.util.PageCacheRecycler;
import org.opensearch.indices.IndicesModule;
import org.opensearch.indices.breaker.CircuitBreakerService;
import org.opensearch.indices.breaker.NoneCircuitBreakerService;
import org.opensearch.search.SearchModule;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.SharedGroupFactory;
import org.opensearch.transport.TransportInterceptor;
Expand Down Expand Up @@ -63,17 +54,6 @@ public NettyTransport(ExtensionsRunner extensionsRunner) {
public Netty4Transport getNetty4Transport(Settings settings, ThreadPool threadPool) {
NetworkService networkService = new NetworkService(Collections.emptyList());
PageCacheRecycler pageCacheRecycler = new PageCacheRecycler(settings);
IndicesModule indicesModule = new IndicesModule(Collections.emptyList());
SearchModule searchModule = new SearchModule(settings, Collections.emptyList());

List<NamedWriteableRegistry.Entry> namedWriteables = Stream.of(
NetworkModule.getNamedWriteables().stream(),
indicesModule.getNamedWriteables().stream(),
searchModule.getNamedWriteables().stream(),
ClusterModule.getNamedWriteables().stream()
).flatMap(Function.identity()).collect(Collectors.toList());

final NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry(namedWriteables);

final CircuitBreakerService circuitBreakerService = new NoneCircuitBreakerService();

Expand All @@ -83,7 +63,7 @@ public Netty4Transport getNetty4Transport(Settings settings, ThreadPool threadPo
threadPool,
networkService,
pageCacheRecycler,
namedWriteableRegistry,
extensionsRunner.getNamedWriteableRegistry().getRegistry(),
circuitBreakerService,
new SharedGroupFactory(settings)
);
Expand Down
78 changes: 78 additions & 0 deletions src/main/java/org/opensearch/sdk/SDKNamedWriteableRegistry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.sdk;

import org.opensearch.cluster.ClusterModule;
import org.opensearch.common.io.stream.NamedWriteableRegistry;
import org.opensearch.common.io.stream.NamedWriteableRegistry.Entry;
import org.opensearch.common.network.NetworkModule;
import org.opensearch.common.settings.Settings;
import org.opensearch.indices.IndicesModule;
import org.opensearch.search.SearchModule;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
* Combines Extension NamedWriteable with core OpenSearch NamedWriteable
*/
public class SDKNamedWriteableRegistry {
private NamedWriteableRegistry namedWriteableRegistry;

/**
* Creates and populates a NamedWriteableRegistry with the NamedWriteableRegistry entries for this extension and locally defined content.
*
* @param runner The ExtensionsRunner instance.
*/
public SDKNamedWriteableRegistry(ExtensionsRunner runner) {
this.namedWriteableRegistry = createRegistry(runner.getEnvironmentSettings(), runner.getCustomNamedWriteables());
}

/**
* Updates the NamedWriteableRegistry with the NamedWriteableRegistry entries for this extension and locally defined content.
* <p>
* Only necessary if environment settings have changed.
*
* @param runner The ExtensionsRunner instance.
*/
public void updateNamedWriteableRegistry(ExtensionsRunner runner) {
this.namedWriteableRegistry = createRegistry(runner.getEnvironmentSettings(), runner.getCustomNamedWriteables());
}

private NamedWriteableRegistry createRegistry(Settings settings, List<Entry> extensionNamedWriteable) {
Stream<Entry> extensionContent = extensionNamedWriteable == null ? Stream.empty() : extensionNamedWriteable.stream();
return new NamedWriteableRegistry(
Stream.of(
extensionContent,
NetworkModule.getNamedWriteables().stream(),
new IndicesModule(Collections.emptyList()).getNamedWriteables().stream(),
new SearchModule(settings, Collections.emptyList()).getNamedWriteables().stream(),
ClusterModule.getNamedWriteables().stream()
).flatMap(Function.identity()).collect(toList())
);
}

/**
* Gets the NamedWriteableRegistry.
*
* @return The NamedWriteableRegistry. Includes both extension-defined Writeable and core OpenSearch Writeable.
*/
public NamedWriteableRegistry getRegistry() {
return this.namedWriteableRegistry;
}

public void setNamedWriteableRegistry(NamedWriteableRegistry namedWriteableRegistry) {
this.namedWriteableRegistry = namedWriteableRegistry;
}
}
116 changes: 116 additions & 0 deletions src/test/java/org/opensearch/sdk/TestSDKNamedWriteableRegistry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.sdk;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.opensearch.common.io.stream.NamedWriteable;
import org.opensearch.common.io.stream.NamedWriteableRegistry;
import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.common.io.stream.StreamOutput;
import org.opensearch.common.io.stream.Writeable;
import org.opensearch.common.settings.Settings;
import org.opensearch.test.OpenSearchTestCase;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class TestSDKNamedWriteableRegistry extends OpenSearchTestCase {
private TestSDKNamedWriteableRegistry.ExampleRunnerForTest runner;

private static class DummyNamedWriteable implements NamedWriteable {
DummyNamedWriteable(StreamInput in) {}

@Override
public String getWriteableName() {
return "test";
}

@Override
public void writeTo(StreamOutput out) throws IOException {}
}

private static class Example implements NamedWriteable {
public static final String NAME = "Example";
public static final NamedWriteableRegistry.Entry WRITEABLE_REGISTRY = new NamedWriteableRegistry.Entry(
NamedWriteable.class,
NAME,
DummyNamedWriteable::new
);

private final String name;

public Example(String name) {
this.name = name;
}

@Override
public String getWriteableName() {
return name;
}

@Override
public void writeTo(StreamOutput out) throws IOException {}
}

private static class ExampleRunnerForTest extends ExtensionsRunnerForTest {

private List<NamedWriteableRegistry.Entry> testNamedWriteables = Collections.emptyList();
private final SDKNamedWriteableRegistry sdkNamedWriteableRegistry = new SDKNamedWriteableRegistry(this);

public ExampleRunnerForTest() throws IOException {
super();
}

@Override
public Settings getEnvironmentSettings() {
return Settings.EMPTY;
}

@Override
public List<NamedWriteableRegistry.Entry> getCustomNamedWriteables() {
return this.testNamedWriteables;
}

@Override
public void updateNamedWriteableRegistry() {
this.testNamedWriteables = Collections.singletonList(Example.WRITEABLE_REGISTRY);
this.sdkNamedWriteableRegistry.updateNamedWriteableRegistry(this);
}
}

@Override
@BeforeEach
public void setUp() throws IOException {
this.runner = new TestSDKNamedWriteableRegistry.ExampleRunnerForTest();
}

@Test
public void testDefaultNamedWriteableRegistry() throws IOException {
NamedWriteableRegistry registry = runner.sdkNamedWriteableRegistry.getRegistry();

IllegalArgumentException ex = assertThrows(
IllegalArgumentException.class,
() -> registry.getReader(TestSDKNamedWriteableRegistry.Example.class, TestSDKNamedWriteableRegistry.Example.NAME)
);
assertEquals("Unknown NamedWriteable category [" + TestSDKNamedWriteableRegistry.Example.class.getName() + "]", ex.getMessage());
}

@Test
public void testCustomNamedWriteableRegistry() throws IOException {
// Update the runner before testing
runner.updateNamedWriteableRegistry();
NamedWriteableRegistry registry = runner.sdkNamedWriteableRegistry.getRegistry();

Writeable.Reader<? extends NamedWriteable> reader = registry.getReader(NamedWriteable.class, Example.NAME);
assertNotNull(reader.read(null));
}
}

0 comments on commit e13aed8

Please sign in to comment.