opensearch-project / opensearch-java

Java Client for OpenSearch
Apache License 2.0
124 stars 183 forks source link

[FEATURE] Migrating from OpenSearch High Level Rest client to Java Client - XContent support #297

Open owaiskazi19 opened 1 year ago

owaiskazi19 commented 1 year ago

Is your feature request related to a problem?

For the purpose of creating extensions, we are migrating AnomalyDetector Plugin to AnomalyDetector Extension. The way High level rest client uses IndexRequest to index a document is:

 IndexRequest indexRequest = new IndexRequest(ANOMALY_DETECTORS_INDEX)
            .setRefreshPolicy(refreshPolicy)
            .source(detector.toXContent(XContentFactory.jsonBuilder(), XCONTENT_WITH_TYPE))
            .setIfSeqNo(seqNo)
            .setIfPrimaryTerm(primaryTerm)
            .timeout(requestTimeout);

It has source which requires a type XContentBuilder to parse the model object.

Whereas Java Client uses IndexRequest in a builder model like:

 IndexRequest<AnomalyDetector> indexRequest = new IndexRequest.Builder<AnomalyDetector>()
            .index(ANOMALY_DETECTORS_INDEX)
            .document(detector)
            .build();

It has document which requires a type TDocument. Parsing the model class AnomalyDetector creates the below response for IndexRequest

"featureAttributes": [
            {
                "id": "5EO8LIUBBpwdv5HXa-s5",
                "name": "test",
                "enabled": true,
                "aggregation": {
                    "name": "test",
                    "factoriesBuilder": {
                        "names": [],
                        "aggregationBuilders": [],
                        "pipelineAggregatorBuilders": [],
                        "aggregatorFactories": [],
                        "pipelineAggregatorFactories": [],
                        "fragment": false
                    },
                    "metadata": {},
                    "field": "value",
                    "type": "sum",
                    "registryKey": {
                        "name": "sum",
                        "supplierType": "org.opensearch.search.aggregations.metrics.MetricAggregatorSupplier"
                    },
                    "writeableName": "sum",
                    "pipelineAggregations": [],
                    "subAggregations": [],
                    "fragment": true
                },
                "fragment": false
            }
        ],
        "filterQuery": {
            "boost": 1.0,
            "mustClauses": [],
            "mustNotClauses": [],
            "filterClauses": [
                {
                    "boost": 1.0,
                    "fieldName": "value",
                    "from": 1,
                    "includeLower": false,
                    "includeUpper": true,
                    "writeableName": "range",
                    "name": "range",
                    "fragment": false
                }
            ],
            "shouldClauses": [],
            "adjustPureNegative": true,
            "writeableName": "bool",
            "name": "bool",
            "fragment": false
        },

This is because of the JSON parsing instead of XContent in the java client.

Whereas high level rest client creates it like:

"feature_attributes" : [
      {
        "feature_id" : "jSAH9IQBQKHn24uRc-zn",
        "feature_name" : "test",
        "feature_enabled" : true,
        "aggregation_query" : {
          "test" : {
            "sum" : {
              "field" : "value"
            }
          }
        }
      }
    ],
    "filter_query" : {
      "bool" : {
        "filter" : [
          {
            "range" : {
              "value" : {
                "from" : 1,
                "to" : null,
                "include_lower" : false,
                "include_upper" : true,
                "boost" : 1.0
              }
            }
          }
        ],
        "adjust_pure_negative" : true,
        "boost" : 1.0
      }
    },

What solution would you like?

  1. A support for XContent as a easier way to migrate from High level rest client to Java Client.
  2. A serializer/deserializer for document to parse JSON to XContent

What alternatives have you considered?

A clear and concise description of any alternative solutions or features you've considered.

Do you have any additional context?

Mapping for the index can be find here. Request body is present here

dblock commented 1 year ago

Please note #182. I think you could port XContent as is here.

Xtansia commented 1 year ago

Not sure if I'm misunderstanding something here, but I believe the equivalent here is to implement JsonpSerializable on the document type or provide a explicit serializer to the builder? Used here which goes through to here. I realise this means rewriting your serializers and isn't drop-in ready, but I believe what you want to achieve is doable.

owaiskazi19 commented 1 year ago

Not sure if I'm misunderstanding something here, but I believe the equivalent here is to implement JsonpSerializable on the document type or provide a explicit serializer to the builder? Used here which goes through to here. I realise this means rewriting your serializers and isn't drop-in ready, but I believe what you want to achieve is doable

This makes sense. Trying to understand the reason behind not supporting XContent type here. Having the support will definitely help plugins to migrate from High Level Rest Client to Java Client without rewriting the serializers.