Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/extensions] First draft of adding support for dynamically registering actions #4460

Conversation

saratvemulapalli
Copy link
Member

Description

With extensions, we would like to register actions during runtime of OpenSearch and not only during bootstrap.
This PR enables ActionModule in OpenSearch core to register transport actions dynamically.

Issues Resolved

opensearch-project/opensearch-sdk-java#107

Check List

  • New functionality includes testing.
    • All tests pass
  • New functionality has been documented.
    • New functionality has javadoc added
  • Commits are signed per the DCO using --signoff
  • Commit changes are listed out in CHANGELOG.md file (See: Changelog)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
@saratvemulapalli saratvemulapalli requested review from a team and reta as code owners September 8, 2022 17:51
@github-actions
Copy link
Contributor

github-actions bot commented Sep 8, 2022

Gradle Check (Jenkins) Run Completed with:

  • RESULT: null ❌
  • URL: null
  • CommitID: c1301cd

@saratvemulapalli saratvemulapalli marked this pull request as draft September 8, 2022 17:57
Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
@saratvemulapalli saratvemulapalli marked this pull request as ready for review September 13, 2022 16:32
Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
@saratvemulapalli
Copy link
Member Author

ChangeLog action failing, I'll wait for #4479 to merge and then rebase. Because it will eventually end up in conflicts.

Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@saratvemulapalli
Copy link
Member Author

1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':server:spotlessJavaCheck'.
> The following files had format violations:
      src/main/java/org/opensearch/node/Node.java
          @@ -1022,7 +1022,8 @@
           ············resourcesToClose.add(injector.getInstance(PeerRecoverySourceService.class));
           ············this.pluginLifecycleComponents·=·Collections.unmodifiableList(pluginLifecycleComponents);
           ············client.initialize(injector.getInstance(new·Key<Map<ActionType,·TransportAction>>()·{
          -················}),·injector.getInstance(ActionRegistry.class),
          +············}),
          +················injector.getInstance(ActionRegistry.class),
           ················()·->·clusterService.localNode().getId(),
           ················transportService.getRemoteClusterService(),
           ················namedWriteableRegistry
      src/test/java/org/opensearch/client/node/NodeClientHeadersTests.java
          @@ -32,7 +32,6 @@
           
           package·org.opensearch.client.node;
           
          -import·org.opensearch.action.ActionModule;
           import·org.opensearch.action.ActionType;
           import·org.opensearch.action.ActionListener;
           import·org.opensearch.action.ActionRequest;
      src/test/java/org/opensearch/snapshots/SnapshotResiliencyTests.java
          @@ -38,7 +38,6 @@
           import·org.opensearch.ExceptionsHelper;
           import·org.opensearch.Version;
           import·org.opensearch.action.ActionListener;
          -import·org.opensearch.action.ActionModule;
           import·org.opensearch.action.ActionType;
           import·org.opensearch.action.RequestValidators;
           import·org.opensearch.action.StepListener;
  Run './gradlew :server:spotlessApply' to fix these violations.

Signed-off-by: Sarat Vemulapalli <vemulapallisarat@gmail.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@saratvemulapalli
Copy link
Member Author

saratvemulapalli commented Sep 13, 2022

Gradle check failures:


1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':example-plugins:custom-suggester:yamlRestTest'.
> process was found dead while waiting for ports files, node{:example-plugins:custom-suggester:yamlRestTest-0}

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
==============================================================================

2: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':plugins:discovery-gce:qa:gce:yamlRestTest'.
> process was found dead while waiting for ports files, node{:plugins:discovery-gce:qa:gce:yamlRestTest-0}

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
==============================================================================

3: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':plugins:discovery-ec2:qa:amazon-ec2:yamlRestTestContainerCredentials'.
> process was found dead while waiting for ports files, node{:plugins:discovery-ec2:qa:amazon-ec2:yamlRestTestContainerCredentials-0}

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
==============================================================================

4: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':rest-api-spec:yamlRestTest'.
> process was found dead while waiting for ports files, node{:rest-api-spec:yamlRestTest-0}

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
==============================================================================

import java.io.IOException;

public class ExtensionsActionResponse extends ActionResponse implements ToXContentObject {
String myFirstResponse;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like leftover from draft PR?

@@ -96,7 +96,7 @@ protected void doExecute(Task task, ActionRequest request, ActionListener listen
final Map<ActionType, TransportAction> actions = new HashMap<>();
actions.put(ValidateQueryAction.INSTANCE, transportAction);

client.initialize(actions, () -> "local", null, new NamedWriteableRegistry(Collections.emptyList()));
client.initialize(actions, null, () -> "local", null, new NamedWriteableRegistry(Collections.emptyList()));
Copy link
Member

@owaiskazi19 owaiskazi19 Sep 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we create a dummy obj of actionsRegistry instead of passing null?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

import org.opensearch.action.ActionType;

public class ExtensionsAction extends ActionType<ExtensionsActionResponse> {
public static final String NAME = "cluster:monitor/extension";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be keep the action name in the same format as internal...?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure makes sense.

import java.io.IOException;

public class ExtensionsActionRequest extends ActionRequest {
String firstRequest;
Copy link
Member

@owaiskazi19 owaiskazi19 Sep 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover from draft PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is this a draft PR?

Why is the first request so important to preserve?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, looks like I missed a commit during the rebase.
This is moved to action which the extension would like to register.

@@ -137,6 +141,7 @@ public String getLocalNodeId() {
private <Request extends ActionRequest, Response extends ActionResponse> TransportAction<Request, Response> transportAction(
ActionType<Response> action
) {
/* TODO add support to read actionsRegistry along with actions */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have an issue to track this TODO?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha I've taken care of this as part of SDK#106.

@@ -1101,6 +1110,8 @@ public Node start() throws NodeValidationException {
nodeService.getMonitorService().start();

final ClusterService clusterService = injector.getInstance(ClusterService.class);
final ActionModule actionModule = injector.getInstance(ActionModule.class);
actionModule.registerAction(ExtensionsAction.INSTANCE, TransportExtensionsAction.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have tests for registerActions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats a good point.
Sure.

Copy link
Member

@dbwiddis dbwiddis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks generally good with comments inline. I'm confused whether this is a draft PR (per subject line) or intended to be merged. Would be helpful to have more comments indicating future functionality.

The word "Action" is overused in the codebase and at least one of these classes (probably ExtensionsAction) should describe just what we are talking about.

import java.io.IOException;

public class ExtensionsActionResponse extends ActionResponse implements ToXContentObject {
String myFirstResponse;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In #4519 I merged multiple similar "string response" classes into an ExtensionStringResponse class. This looks very similar in that it's just a basic "string response" but extending ActionResponse rather than TransportResponse.

I don't think the name ExtensionsActionResponse is meaningful for the simplicity of this object.

I am also thinking we need to figure out a consistent naming convention.

I am also seeing that we are very inconsistent in pluralization of Extension in these class names.

Naming things is hard.


@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(myFirstResponse);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't dug into the implementation details, but when I see a super(in) I expect to see a matching super(out). I know the super is required for transport requests but not responses, and in the latter case the super call is a noop.

All that to say, either add a super(out) here or delete the super(in) above.


@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will eventually go here? I don't like seeing null returns, but a comment suggesting future usage would make me happier.


public class ExtensionsActionTests extends OpenSearchSingleNodeTestCase {

public void testExtensionAction() throws ExecutionException, InterruptedException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usually tests contain assertions of some sort. :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup I just realized I missed a commit :D

import java.io.IOException;

public class ExtensionsActionRequest extends ActionRequest {
String firstRequest;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is this a draft PR?

Why is the first request so important to preserve?

@@ -449,6 +449,7 @@ public class ActionModule extends AbstractModule {
private final SettingsFilter settingsFilter;
private final List<ActionPlugin> actionPlugins;
private final Map<String, ActionHandler<?, ?>> actions;
private ActionRegistry actionRegistryMap;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything around this is final. Should this also be?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats a good point. I was debating but it can be a final because the instance would not change.
Will update.

@saratvemulapalli
Copy link
Member Author

Thanks for the feedback @dbwiddis, @owaiskazi19 !
Conflicts causing problems. Im sending out a clean PR and closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants