-
Notifications
You must be signed in to change notification settings - Fork 58
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] Add util class for parsing ExtensionAction bytes #607
Comments
Hello @dbwiddis, I would like to take this issue |
Assigning it to you, @Kuanysh-kst but let's make sure we prioritize finishing up your currently open parsing validator PR. |
@dbwiddis can I redo this code like this :
|
@Kuanysh-kst I'm missing what comment this is in a reply to, but generally speaking:
I suspect there is a bigger question here that I'm missing because this comment seems disconnected. |
@Kuanysh-kst I think I got an email about a comment here but it may have been deleted. Let me try to clarify all the places where I think a util is useful. I'm going to use the Hello World Creating the request: this is already handled with the constructor syntax, no util needed. RemoteExtensionActionRequest proxyActionRequest = new RemoteExtensionActionRequest(SampleAction.INSTANCE, sampleRequest); This is passed to the RemoteExtensionActionResponse response = sdkTransportService.sendRemoteExtensionActionRequest(request); The Upon receipt at the target extension, we have to deserialize, that is handled in
They aren't exactly in sequence in the above snippet but the pieces are there. Separating the stream and bytes is int nullPos = indexOf(request.getRequestBytes(), RemoteExtensionActionRequest.UNIT_SEPARATOR);
String requestClassName = new String(Arrays.copyOfRange(request.getRequestBytes(), 0, nullPos + 1),
StandardCharsets.UTF_8).stripTrailing();
StreamInput requestByteStream = StreamInput.wrap(
Arrays.copyOfRange(request.getRequestBytes(), nullPos + 1, request.getRequestBytes().length)
); (Note the And then instantiating the class is: Class<?> clazz = Class.forName(requestClassName);
Constructor<?> constructor = clazz.getConstructor(StreamInput.class);
actionRequest = (ActionRequest) constructor.newInstance(requestByteStream); That's all we need, since the next thing we do is SO in this sequence there are 3 distinct util methods:
Ideally the two methods in part 3 would be separate methods, but since we are returning two bits of information that complicates things, so a single method returning an ActionRequest works. |
In addition to the above 3 methods which work for Extension-to-Extension, we have the Plugin-to-Extension version. I noted that opensearch-project/job-scheduler#349 contained many of the same methods:
It has a new method to convert a private static <T extends Writeable> byte[] convertParamsToBytes(T actionParams) This isn't obvious but in the Extension case (Hello World) we implemented similar code in the constructor taking the sample request. It could be made shorter using that public RemoteExtensionActionRequest(ActionType<? extends ActionResponse> instance, ActionRequest request) {
this.action = instance.getClass().getName();
this.requestClass = request.getClass().getName();
byte[] bytes = new byte[0];
try (BytesStreamOutput out = new BytesStreamOutput()) {
request.writeTo(out);
bytes = BytesReference.toBytes(out.bytes());
} catch (IOException e) {
throw new IllegalStateException("Writing an OutputStream to memory should never result in an IOException.");
}
this.requestBytes = bytes;
} So this conversion of |
So to sum up the above 2 comments, the 4 methods needed are:
|
The Util PR is getting a bit confusing with the naming. Let's be clear on the pieces of information we have here. Ultimately we want to enable calling Step 1: turn action (extends ActionType) into a class name (this is easily done, no util needed) |
@dbwiddis can I open a new PR again , there are a lot of problems in the old one |
You can, but it's generally a better idea to try to fix the old one. Usually a rebase commit and resolving conflicts fixes a lot of the issues. git checkout main
git pull upstream main
git checkout yourprbranch
git rebase main This will show any conflicting files. Resolve conflicts, then Once you're done, force push the result. Then fix any compile errors and push the fix. |
@dbwiddis can you check the new commit |
@dbwiddis can we close this issue since the PR associated with this issue: opensearch-project/OpenSearch#6969 is merged? |
Is your feature request related to a problem?
Don't Repeat Yourself
While reviewing JS #349 I noticed a lot of repetition of some of the same code as in #588.
This is all general code for the common pattern we've chosen of appending a request class name as a string to its parameters in bytes.
What solution would you like?
Copy these repeated features to a class in the same package as the ExtensionAction / ExtensionTransportAction / ExtensionActionRequest and related classes. They might fit well in an existing class (ExtensionAction possibly) or in a new class (ExtensionActionUtil). These include:
Basically, all the functions needed to do this:
opensearch-sdk-java/src/main/java/org/opensearch/sdk/SDKTransportService.java
Lines 81 to 86 in ebc684a
and this:
opensearch-sdk-java/src/main/java/org/opensearch/sdk/handlers/ExtensionActionRequestHandler.java
Lines 86 to 96 in ebc684a
Plus there's one more method I see in JS #349 that converts a
Writeable
tobytes
, and that's also useful.What alternatives have you considered?
Repeating ourselves.
Do you have any additional context?
This somewhat doubles down on using Writeable and if we're considering switching to protobuf, then we may consider a different approach.
The text was updated successfully, but these errors were encountered: