forked from opensearch-project/OpenSearch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SearchExtBuilders to SearchResponse (opensearch-project#9379)
* Add SearchExtBuilders to SearchResponse. [Issue opensearch-project#9328](opensearch-project#9328) Signed-off-by: Austin Lee <austin@aryn.ai> * Keep SearchResponse immutable, add a constructor to take a List of SearchExtBuilders. Signed-off-by: Austin Lee <austin@aryn.ai> * Fix spotlessJavaCheck findings. Signed-off-by: Austin Lee <austin@aryn.ai> * Move SearchExtBuilders into SearchResponseSections, fix indenting in SearchRequest. Signed-off-by: Austin Lee <austin@aryn.ai> * Updated changelog (mixed minor formatting issues), added version checks on serialization/deserialization, added a Builder for making copies of SearchResponse easier. Signed-off-by: Austin Lee <austin@aryn.ai> * Add GenericSearchExtBuilder as a catch-all for SearchExtBuilders not registered in xcontent registry. Signed-off-by: Austin Lee <austin@aryn.ai> * Simplify GenericSearchExtBuilder using a single Object member. Signed-off-by: Austin Lee <austin@aryn.ai> * Address additional review comments. Signed-off-by: Austin Lee <austin@aryn.ai> * Add Javadocs. Signed-off-by: Austin Lee <austin@aryn.ai> --------- Signed-off-by: Austin Lee <austin@aryn.ai> Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
- Loading branch information
1 parent
eeedb83
commit eb72e68
Showing
7 changed files
with
893 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
165 changes: 165 additions & 0 deletions
165
server/src/main/java/org/opensearch/search/GenericSearchExtBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
* 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.search; | ||
|
||
import org.opensearch.core.ParseField; | ||
import org.opensearch.core.common.io.stream.StreamInput; | ||
import org.opensearch.core.common.io.stream.StreamOutput; | ||
import org.opensearch.core.xcontent.XContentBuilder; | ||
import org.opensearch.core.xcontent.XContentParseException; | ||
import org.opensearch.core.xcontent.XContentParser; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
/** | ||
* This is a catch-all SearchExtBuilder implementation that is used when an appropriate SearchExtBuilder | ||
* is not found during SearchResponse's fromXContent operation. | ||
*/ | ||
public final class GenericSearchExtBuilder extends SearchExtBuilder { | ||
|
||
public final static ParseField EXT_BUILDER_NAME = new ParseField("generic_ext"); | ||
|
||
private final Object genericObj; | ||
private final ValueType valueType; | ||
|
||
enum ValueType { | ||
SIMPLE(0), | ||
MAP(1), | ||
LIST(2); | ||
|
||
private final int value; | ||
|
||
ValueType(int value) { | ||
this.value = value; | ||
} | ||
|
||
public int getValue() { | ||
return value; | ||
} | ||
|
||
static ValueType fromInt(int value) { | ||
switch (value) { | ||
case 0: | ||
return SIMPLE; | ||
case 1: | ||
return MAP; | ||
case 2: | ||
return LIST; | ||
default: | ||
throw new IllegalArgumentException("Unsupported value: " + value); | ||
} | ||
} | ||
} | ||
|
||
public GenericSearchExtBuilder(Object genericObj, ValueType valueType) { | ||
this.genericObj = genericObj; | ||
this.valueType = valueType; | ||
} | ||
|
||
public GenericSearchExtBuilder(StreamInput in) throws IOException { | ||
valueType = ValueType.fromInt(in.readInt()); | ||
switch (valueType) { | ||
case SIMPLE: | ||
genericObj = in.readGenericValue(); | ||
break; | ||
case MAP: | ||
genericObj = in.readMap(); | ||
break; | ||
case LIST: | ||
genericObj = in.readList(r -> r.readGenericValue()); | ||
break; | ||
default: | ||
throw new IllegalStateException("Unable to construct GenericSearchExtBuilder from incoming stream."); | ||
} | ||
} | ||
|
||
public static GenericSearchExtBuilder fromXContent(XContentParser parser) throws IOException { | ||
// Look at the parser's next token. | ||
// If it's START_OBJECT, parse as map, if it's START_ARRAY, parse as list, else | ||
// parse as simpleVal | ||
XContentParser.Token token = parser.currentToken(); | ||
ValueType valueType; | ||
Object genericObj; | ||
if (token == XContentParser.Token.START_OBJECT) { | ||
genericObj = parser.map(); | ||
valueType = ValueType.MAP; | ||
} else if (token == XContentParser.Token.START_ARRAY) { | ||
genericObj = parser.list(); | ||
valueType = ValueType.LIST; | ||
} else if (token.isValue()) { | ||
genericObj = parser.objectText(); | ||
valueType = ValueType.SIMPLE; | ||
} else { | ||
throw new XContentParseException("Unknown token: " + token); | ||
} | ||
|
||
return new GenericSearchExtBuilder(genericObj, valueType); | ||
} | ||
|
||
@Override | ||
public String getWriteableName() { | ||
return EXT_BUILDER_NAME.getPreferredName(); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
out.writeInt(valueType.getValue()); | ||
switch (valueType) { | ||
case SIMPLE: | ||
out.writeGenericValue(genericObj); | ||
break; | ||
case MAP: | ||
out.writeMap((Map<String, Object>) genericObj); | ||
break; | ||
case LIST: | ||
out.writeCollection((List<Object>) genericObj, StreamOutput::writeGenericValue); | ||
break; | ||
default: | ||
throw new IllegalStateException("Unknown valueType: " + valueType); | ||
} | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
switch (valueType) { | ||
case SIMPLE: | ||
return builder.field(EXT_BUILDER_NAME.getPreferredName(), genericObj); | ||
case MAP: | ||
return builder.field(EXT_BUILDER_NAME.getPreferredName(), (Map<String, Object>) genericObj); | ||
case LIST: | ||
return builder.field(EXT_BUILDER_NAME.getPreferredName(), (List<Object>) genericObj); | ||
default: | ||
return null; | ||
} | ||
} | ||
|
||
// We need this for the equals method. | ||
Object getValue() { | ||
return genericObj; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(this.valueType, this.genericObj); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj == null) { | ||
return false; | ||
} | ||
if (!(obj instanceof GenericSearchExtBuilder)) { | ||
return false; | ||
} | ||
return Objects.equals(getValue(), ((GenericSearchExtBuilder) obj).getValue()) | ||
&& Objects.equals(valueType, ((GenericSearchExtBuilder) obj).valueType); | ||
} | ||
} |
Oops, something went wrong.