diff --git a/CHANGELOG.md b/CHANGELOG.md index c9ee8d63d..3cbca08b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,10 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added missing `status` to `/_search/template` response ([#702](https://github.com/opensearch-project/opensearch-api-specification/pull/702)) - Added `_type` to `rank_eval` API specs ([#704](https://github.com/opensearch-project/opensearch-api-specification/pull/704)) - Added request body to `_search_shards` API specs ([#709](https://github.com/opensearch-project/opensearch-api-specification/pull/709)) +- Added NodeAttributes as additional property in `shard_stores` API specs ([#715](https://github.com/opensearch-project/opensearch-api-specification/pull/715)) +- Added missing `repository` query parameter to `/_cat/snapshots` ([#700](https://github.com/opensearch-project/opensearch-api-specification/pull/700)) +- Added `sm` namespace API specifications ([#701](https://github.com/opensearch-project/opensearch-api-specification/pull/701)) +- Added schema for `/_plugins/_knn/stats`, `/_plugins/_knn/models/{model_id}`, `_train` and `_search` ([#704](https://github.com/opensearch-project/opensearch-api-specification/pull/704)) - Added `retry` support in `prologues` and `epilogues` ([#713](https://github.com/opensearch-project/opensearch-api-specification/pull/713)) ### Removed @@ -52,9 +56,10 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Fixed `/_ingest/pipeline/{id}/_simulate` response `docs/_source` field schema ([#689](https://github.com/opensearch-project/opensearch-api-specification/pull/689)) - Fixed `/_scripts/painless/_execute` request and response schema ([#699](https://github.com/opensearch-project/opensearch-api-specification/pull/699)) - Fixed `fields` in `Hit` allowing primitive arrays ([#699](https://github.com/opensearch-project/opensearch-api-specification/pull/699)) -- Added missing `repository` query parameter to `/_cat/snapshots` ([#700](https://github.com/opensearch-project/opensearch-api-specification/pull/700)) - Fixed `hits` in `rank_eval` allowing numbers ([#704](https://github.com/opensearch-project/opensearch-api-specification/pull/704)) - Fixed query DSL schemas ([#706](https://github.com/opensearch-project/opensearch-api-specification/pull/706)) +- Fixed content-type of `GET /_plugins/_observability/_local/stats` ([#711](https://github.com/opensearch-project/opensearch-api-specification/pull/711)) +- Fixed `tenant` in `ObservabilityObject` request body to not be required ([#711](https://github.com/opensearch-project/opensearch-api-specification/pull/711)) ### Changed - Changed `tasks._common:TaskInfo` and `tasks._common:TaskGroup` to be composed of a `tasks._common:TaskInfoBase` ([#683](https://github.com/opensearch-project/opensearch-api-specification/pull/683)) @@ -165,7 +170,6 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added API spec for `adjust_pure_negative` for bool queries ([#641](https://github.com/opensearch-project/opensearch-api-specification/pull/641)) - Added a spec style checker [#620](https://github.com/opensearch-project/opensearch-api-specification/pull/620). - Added `remote_store` to node `Stats` ([#643](https://github.com/opensearch-project/opensearch-api-specification/pull/643)) -- Added `sm` namespace API specifications ([#701](https://github.com/opensearch-project/opensearch-api-specification/pull/701)) ### Changed diff --git a/spec/namespaces/_core.yaml b/spec/namespaces/_core.yaml index 3b71f9287..d48733fd5 100644 --- a/spec/namespaces/_core.yaml +++ b/spec/namespaces/_core.yaml @@ -2710,7 +2710,7 @@ components: additionalProperties: type: object indices_boost: - description: Allows increasing the relevance of specific indices in the search. + description: Allows increasing the relevance of specific indexes in the search. type: object additionalProperties: type: number diff --git a/spec/namespaces/knn.yaml b/spec/namespaces/knn.yaml index 563f4f783..d7156d4b9 100644 --- a/spec/namespaces/knn.yaml +++ b/spec/namespaces/knn.yaml @@ -251,45 +251,28 @@ components: content: application/json: schema: - type: object - properties: - training_index: - type: string - training_field: - type: string - dimension: - type: integer - format: int32 - max_training_vector_count: - type: integer - format: int32 - search_size: - type: integer - format: int32 - description: - type: string - mode: - type: string - compression_level: - type: string - method: - type: string - spaceType: - type: string - required: - - dimension - - training_field - - training_index - required: true + $ref: '../schemas/knn._common.yaml#/components/schemas/TrainedModel' responses: - knn.delete_model@200: {} + knn.delete_model@200: + content: + application/json: + schema: + $ref: '../schemas/knn._common.yaml#/components/schemas/DeletedModel' knn.get_model@200: content: application/json: schema: type: object - knn.search_models@200: {} - knn.stats@200: {} + knn.search_models@200: + content: + application/json: + schema: + $ref: '../schemas/_core.search.yaml#/components/schemas/ResponseBody' + knn.stats@200: + content: + application/json: + schema: + $ref: '../schemas/knn._common.yaml#/components/schemas/Stats' knn.train_model@200: content: application/json: @@ -681,12 +664,19 @@ components: - graph_memory_usage_percentage - graph_query_errors - graph_query_requests + - graph_stats - hit_count - indexing_from_model_degraded - indices_in_cache - knn_query_requests + - knn_query_with_filter_requests - load_exception_count - load_success_count + - lucene_initialized + - max_distance_query_requests + - max_distance_query_with_filter_requests + - min_score_query_requests + - min_score_query_with_filter_requests - miss_count - model_index_status - nmslib_initialized diff --git a/spec/namespaces/observability.yaml b/spec/namespaces/observability.yaml index 62cca3dfd..1b34a9241 100644 --- a/spec/namespaces/observability.yaml +++ b/spec/namespaces/observability.yaml @@ -8,8 +8,8 @@ paths: get: operationId: observability.get_localstats.0 x-operation-group: observability.get_localstats - x-version-added: '1.1' - description: Retrieves Local Stats of all observability objects. + x-version-added: '2.5' + description: Retrieves local stats of all observability objects. responses: '200': $ref: '#/components/responses/observability.get_localstats@200' @@ -177,7 +177,7 @@ components: observability.get_localstats@200: description: Retrieves content: - application/json: + text/plain: schema: type: string parameters: diff --git a/spec/schemas/indices.shard_stores.yaml b/spec/schemas/indices.shard_stores.yaml index 0745101db..9b76b9027 100644 --- a/spec/schemas/indices.shard_stores.yaml +++ b/spec/schemas/indices.shard_stores.yaml @@ -40,6 +40,8 @@ components: $ref: '_common.yaml#/components/schemas/Id' store_exception: $ref: '#/components/schemas/ShardStoreException' + additionalProperties: + $ref: '_common.yaml#/components/schemas/NodeAttributes' required: - allocation ShardStoreAllocation: diff --git a/spec/schemas/knn._common.yaml b/spec/schemas/knn._common.yaml index b4cbeaa36..6a71753ae 100644 --- a/spec/schemas/knn._common.yaml +++ b/spec/schemas/knn._common.yaml @@ -25,3 +25,164 @@ components: - always - missing - popular + Stats: + type: object + properties: + _nodes: + $ref: '_common.yaml#/components/schemas/NodeStatistics' + cluster_name: + $ref: '_common.yaml#/components/schemas/Name' + circuit_breaker_triggered: + type: boolean + model_index_status: + oneOf: + - $ref: '_common.yaml#/components/schemas/HealthStatusCapitalized' + - type: 'null' + nodes: + type: object + additionalProperties: + $ref: '#/components/schemas/NodeStats' + NodeStats: + type: object + properties: + max_distance_query_with_filter_requests: + type: number + graph_memory_usage_percentage: + $ref: '_common.yaml#/components/schemas/PercentageNumber' + graph_query_requests: + type: number + graph_memory_usage: + type: number + cache_capacity_reached: + type: boolean + load_success_count: + type: number + training_memory_usage: + type: number + indices_in_cache: + type: object + additionalProperties: true + script_query_errors: + type: number + hit_count: + type: number + knn_query_requests: + type: number + total_load_time: + type: number + miss_count: + type: number + min_score_query_requests: + type: number + knn_query_with_filter_requests: + type: number + training_memory_usage_percentage: + $ref: '_common.yaml#/components/schemas/PercentageNumber' + max_distance_query_requests: + type: number + lucene_initialized: + type: boolean + graph_index_requests: + type: number + faiss_initialized: + type: boolean + load_exception_count: + type: number + training_errors: + type: number + min_score_query_with_filter_requests: + type: number + eviction_count: + type: number + nmslib_initialized: + type: boolean + script_compilations: + type: number + script_query_requests: + type: number + graph_stats: + $ref: '#/components/schemas/GraphStats' + graph_query_errors: + type: number + indexing_from_model_degraded: + type: boolean + graph_index_errors: + type: number + training_requests: + type: number + script_compilation_errors: + type: number + GraphStats: + type: object + properties: + merge: + $ref: '#/components/schemas/GraphMergeStats' + refresh: + $ref: '#/components/schemas/GraphRefreshStats' + GraphRefreshStats: + type: object + properties: + total: + type: number + total_time_in_millis: + $ref: '_common.yaml#/components/schemas/DurationValueUnitMillis' + GraphMergeStats: + type: object + properties: + current: + type: number + total: + type: number + total_time_in_millis: + $ref: '_common.yaml#/components/schemas/DurationValueUnitMillis' + current_docs: + type: number + total_docs: + type: number + total_size_in_bytes: + $ref: '_common.yaml#/components/schemas/ByteCount' + current_size_in_bytes: + $ref: '_common.yaml#/components/schemas/ByteCount' + TrainedModel: + type: object + properties: + training_index: + type: string + training_field: + type: string + dimension: + type: integer + format: int32 + max_training_vector_count: + type: integer + format: int32 + search_size: + type: integer + format: int32 + description: + type: string + mode: + type: string + compression_level: + type: string + method: + type: string + spaceType: + type: string + required: + - dimension + - training_field + - training_index + DeletedModel: + type: object + properties: + model_id: + type: string + result: + type: string + enum: + - deleted + - error + required: + - model_id + - result diff --git a/spec/schemas/observability._common.yaml b/spec/schemas/observability._common.yaml index 08b7fbce6..bc7c56d87 100644 --- a/spec/schemas/observability._common.yaml +++ b/spec/schemas/observability._common.yaml @@ -44,7 +44,6 @@ components: $ref: '#/components/schemas/SavedQuery' required: - objectId - - tenant OperationalPanel: type: object diff --git a/tests/default/_core/shard_stores.yaml b/tests/default/_core/shard_stores.yaml new file mode 100644 index 000000000..d425f9b73 --- /dev/null +++ b/tests/default/_core/shard_stores.yaml @@ -0,0 +1,26 @@ +$schema: ../../../json_schemas/test_story.schema.yaml + +description: Test _shard_stores API. +prologues: + - path: /_bulk + method: POST + parameters: + refresh: true + request: + content_type: application/x-ndjson + payload: + - {create: {_index: movies, _id: movie1}} + - {director: Quentin Tarantino, title: Pulp Fiction, year: 1994} + - {create: {_index: movies, _id: movie2}} + - {director: Christopher Nolan, title: Inception, year: 2010} +epilogues: + - path: /movies + method: DELETE + status: [200, 404] + +chapters: + - synopsis: Verify shard store information across all indices. + path: /_shard_stores + method: GET + response: + status: 200 diff --git a/tests/default/indices/shard_stores.yaml b/tests/default/indices/shard_stores.yaml new file mode 100644 index 000000000..07ca4f8fc --- /dev/null +++ b/tests/default/indices/shard_stores.yaml @@ -0,0 +1,28 @@ +$schema: ../../../json_schemas/test_story.schema.yaml + +description: Test _shard_stores API. +prologues: + - path: /_bulk + method: POST + parameters: + refresh: true + request: + content_type: application/x-ndjson + payload: + - {create: {_index: movies, _id: movie1}} + - {director: Quentin Tarantino, title: Pulp Fiction, year: 1994} + - {create: {_index: movies, _id: movie2}} + - {director: Christopher Nolan, title: Inception, year: 2010} +epilogues: + - path: /movies + method: DELETE + status: [200, 404] + +chapters: + - synopsis: Verify shard store information for a specific index. + path: /{index}/_shard_stores + parameters: + index: movies + method: GET + response: + status: 200 diff --git a/tests/default/knn/models.yaml b/tests/default/knn/models.yaml new file mode 100644 index 000000000..3589fc162 --- /dev/null +++ b/tests/default/knn/models.yaml @@ -0,0 +1,61 @@ +$schema: ../../../json_schemas/test_story.schema.yaml + +description: Delete a k-NN model. +version: '>= 2.17' +prologues: + - method: PUT + path: /movies + request: + payload: + settings: + index: + knn: true + mappings: + properties: + recommendation_vector: + type: knn_vector + dimension: 8 + status: [200] + - method: POST + path: /_bulk + parameters: + refresh: true + request: + content_type: application/x-ndjson + payload: + - {index: {_index: movies, _id: '1'}} + - {recommendation_vector: [1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5], duration: 12.2} + - {index: {_index: movies, _id: '2'}} + - {recommendation_vector: [2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5], duration: 7.1} + status: [200] + - method: POST + path: /_plugins/_knn/models/model-1/_train + request: + payload: + training_index: movies + training_field: recommendation_vector + dimension: 8 + max_training_vector_count: 1200 + search_size: 100 + description: Test model + mode: on_disk + compression_level: 32x + spaceType: l2 + status: [200] +epilogues: + - path: /movies + method: DELETE + status: [200, 404] + - path: /_plugins/_knn/models/model-1 + method: DELETE + status: [200, 404] +chapters: + - synopsis: Delete a trained model. + method: DELETE + path: /_plugins/_knn/models/{model_id} + parameters: + model_id: model-1 + retry: + count: 3 + response: + status: 200 diff --git a/tests/default/knn/models/search.yaml b/tests/default/knn/models/search.yaml new file mode 100644 index 000000000..52711b0f5 --- /dev/null +++ b/tests/default/knn/models/search.yaml @@ -0,0 +1,70 @@ +$schema: ../../../../json_schemas/test_story.schema.yaml + +description: Search for a k-NN model. +version: '>= 2.17' +prologues: + - method: PUT + path: /movies + request: + payload: + settings: + index: + knn: true + mappings: + properties: + recommendation_vector: + type: knn_vector + dimension: 8 + status: [200] + - method: POST + path: /_bulk + parameters: + refresh: true + request: + content_type: application/x-ndjson + payload: + - {index: {_index: movies, _id: '1'}} + - {recommendation_vector: [1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5], duration: 12.2} + - {index: {_index: movies, _id: '2'}} + - {recommendation_vector: [2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5], duration: 7.1} + status: [200] + - method: POST + path: /_plugins/_knn/models/model-1/_train + request: + payload: + training_index: movies + training_field: recommendation_vector + dimension: 8 + max_training_vector_count: 1200 + search_size: 100 + description: Test model + mode: on_disk + compression_level: 32x + spaceType: l2 + status: [200] +epilogues: + - path: /movies + method: DELETE + status: [200, 404] + - path: /_plugins/_knn/models/model-1 + method: DELETE + status: [200, 404] +chapters: + - synopsis: Search models (GET). + method: GET + path: /_plugins/_knn/models/_search + request: + payload: + query: + match_all: {} + response: + status: 200 + - synopsis: Search models (POST). + method: POST + path: /_plugins/_knn/models/_search + request: + payload: + query: + match_all: {} + response: + status: 200 diff --git a/tests/default/knn/train_model.yaml b/tests/default/knn/models/train.yaml similarity index 77% rename from tests/default/knn/train_model.yaml rename to tests/default/knn/models/train.yaml index cb58ed97c..fbcfb19d5 100644 --- a/tests/default/knn/train_model.yaml +++ b/tests/default/knn/models/train.yaml @@ -1,8 +1,7 @@ -$schema: ../../../json_schemas/test_story.schema.yaml +$schema: ../../../../json_schemas/test_story.schema.yaml -description: Test training k-NN model with disk-based parameters. +description: Train a k-NN model with disk-based parameters. version: '>= 2.17' - prologues: - method: PUT path: /movies @@ -19,6 +18,8 @@ prologues: status: [200] - method: POST path: /_bulk + parameters: + refresh: true request: content_type: application/x-ndjson payload: @@ -41,9 +42,6 @@ prologues: - {index: {_index: movies, _id: '9'}} - {recommendation_vector: [9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5], duration: 8.9} status: [200] - - method: POST - path: /_refresh - status: [200] epilogues: - path: /movies method: DELETE @@ -53,9 +51,11 @@ epilogues: model_id: ${train_model.test_model_id} method: DELETE status: [200, 404] - + - path: /_plugins/_knn/models/model-1 + method: DELETE + status: [200, 404] chapters: - - synopsis: Test training a model with disk-based parameters. + - synopsis: Train a new model with disk-based parameters. id: train_model method: POST path: /_plugins/_knn/models/_train @@ -88,3 +88,21 @@ chapters: payload: model_id: ${train_model.test_model_id} state: created + - synopsis: Train a model with a given ID. + method: POST + path: /_plugins/_knn/models/{model_id}/_train + parameters: + model_id: model-1 + request: + payload: + training_index: movies + training_field: recommendation_vector + dimension: 8 + max_training_vector_count: 2400 + search_size: 100 + description: Test model + mode: on_disk + compression_level: 32x + spaceType: l2 + response: + status: 200 diff --git a/tests/default/knn/stats.yaml b/tests/default/knn/stats.yaml new file mode 100644 index 000000000..f1fb9c5c9 --- /dev/null +++ b/tests/default/knn/stats.yaml @@ -0,0 +1,35 @@ +$schema: ../../../json_schemas/test_story.schema.yaml + +description: Get k-NN stats. +chapters: + - synopsis: Get k-NN stats. + method: GET + path: /_plugins/_knn/stats + response: + status: 200 + - synopsis: Get k-NN stat. + method: GET + path: /_plugins/_knn/stats/{stat} + parameters: + stat: + - hit_count + response: + status: 200 + - synopsis: Get all k-NN stat for all nodes. + method: GET + path: /_plugins/_knn/{node_id}/stats + parameters: + node_id: + - _all + response: + status: 200 + - synopsis: Get `hit_count` k-NN stat for all nodes. + method: GET + path: /_plugins/_knn/{node_id}/stats/{stat} + parameters: + node_id: + - _all + stat: + - hit_count + response: + status: 200 diff --git a/tests/default/notifications/configs.yaml b/tests/default/notifications/configs.yaml index 3a1523f1e..b89256418 100644 --- a/tests/default/notifications/configs.yaml +++ b/tests/default/notifications/configs.yaml @@ -91,7 +91,33 @@ chapters: config_id: webhook-configuration response: status: 200 + - synopsis: Create another channel configuration. + path: /_plugins/_notifications/configs + method: POST + request: + payload: + config_id: second-configuration + config: + name: Notifications Channel + description: Second notifications channel. + config_type: webhook + is_enabled: true + webhook: + url: http://webhook:8080/ + response: + status: 200 + - synopsis: Delete multiple channel configurations. + version: '>= 2.2' + path: /_plugins/_notifications/configs + method: DELETE + parameters: + config_id_list: second-configuration + response: + status: 200 epilogues: - path: /_plugins/_notifications/configs/webhook-configuration method: DELETE status: [200,404] + - path: /_plugins/_notifications/configs/second-configuration + method: DELETE + status: [200,404] diff --git a/tests/default/observability/local/stats.yaml b/tests/default/observability/local/stats.yaml new file mode 100644 index 000000000..024cfdf02 --- /dev/null +++ b/tests/default/observability/local/stats.yaml @@ -0,0 +1,12 @@ +$schema: ../../../../json_schemas/test_story.schema.yaml + +description: Test backend stats. +version: '>= 2.5' + +chapters: + - synopsis: Get observability stats. + path: /_plugins/_observability/_local/stats + method: GET + response: + status: 200 + content_type: text/plain \ No newline at end of file diff --git a/tests/default/observability/observability.yaml b/tests/default/observability/object.yaml similarity index 84% rename from tests/default/observability/observability.yaml rename to tests/default/observability/object.yaml index e27b2be5e..16f01f772 100644 --- a/tests/default/observability/observability.yaml +++ b/tests/default/observability/object.yaml @@ -2,13 +2,9 @@ $schema: ../../../json_schemas/test_story.schema.yaml description: Test various operations of the OpenSearch Observability Object API. -prologues: - - path: /_plugins/_observability/object/{object_id} - method: DELETE - parameters: - object_id: test_object - status: [200, 404] - - path: /_plugins/_observability/object +chapters: + - synopsis: Create an observability object. + path: /_plugins/_observability/object method: POST request: payload: @@ -56,12 +52,12 @@ prologues: tokens: - name: field1 type: text - status: [200] - - path: /_refresh + - synopsis: Refresh index. + path: /_refresh method: POST - status: [200] -chapters: - - synopsis: Retrieve specific Observability object after creation. + warnings: + multiple-paths-detected: false + - synopsis: Retrieve an observability object. path: /_plugins/_observability/object/{object_id} id: observatory_object method: GET @@ -74,7 +70,7 @@ chapters: totalHits: 1 totalHitRelation: eq observabilityObjectList: [] - - synopsis: Update specific Observability object. + - synopsis: Update an observability object. path: /_plugins/_observability/object/{object_id} method: PUT parameters: @@ -82,7 +78,6 @@ chapters: request: payload: objectId: test_object - tenant: '' operationalPanel: name: updated_test_panel visualizations: [] @@ -128,19 +123,7 @@ chapters: status: 200 payload: objectId: test_object - - synopsis: Retrieve specific Observability object after update. - path: /_plugins/_observability/object/{object_id} - method: GET - parameters: - object_id: test_object - response: - status: 200 - payload: - startIndex: 0 - totalHits: 1 - totalHitRelation: eq - observabilityObjectList: [] - - synopsis: Retrieve list of Observability objects. + - synopsis: Retrieve all observability objects. path: /_plugins/_observability/object method: GET response: @@ -150,6 +133,11 @@ chapters: totalHits: 1 totalHitRelation: eq observabilityObjectList: [] + - synopsis: Delete an observability object. + path: /_plugins/_observability/object/{object_id} + method: DELETE + parameters: + object_id: test_object epilogues: - path: /_plugins/_observability/object/{object_id} method: DELETE diff --git a/tests/default/ppl/stats.yaml b/tests/default/ppl/stats.yaml index fafba95ec..eba2073f3 100644 --- a/tests/default/ppl/stats.yaml +++ b/tests/default/ppl/stats.yaml @@ -3,7 +3,13 @@ $schema: ../../../json_schemas/test_story.schema.yaml description: Test get SQL Queries stats. chapters: - - synopsis: Get stats from PPL Query. + - synopsis: Get stats from PPL query (GET). + path: /_plugins/_ppl/stats + method: GET + response: + status: 200 + content_type: text/plain + - synopsis: Get stats from PPL query (POST). path: /_plugins/_ppl/stats method: POST response: diff --git a/tests/plugins/notifications/notifications/feature/test.yaml b/tests/plugins/notifications/notifications/feature/test.yaml index e889155e1..084aa8b78 100644 --- a/tests/plugins/notifications/notifications/feature/test.yaml +++ b/tests/plugins/notifications/notifications/feature/test.yaml @@ -17,7 +17,7 @@ prologues: url: http://webhook:8080/ status: [200] chapters: - - synopsis: Test sending a notification. + - synopsis: Test sending a notification (GET). path: /_plugins/_notifications/feature/test/{config_id} method: GET parameters: @@ -31,6 +31,20 @@ chapters: delivery_status: status_code: '200' status_text: '{"ok":"true"}' + - synopsis: Test sending a notification (POST). + path: /_plugins/_notifications/feature/test/{config_id} + method: POST + parameters: + config_id: custom-webhook-configuration + response: + status: 200 + payload: + status_list: + - config_id: custom-webhook-configuration + config_type: webhook + delivery_status: + status_code: '200' + status_text: '{"ok":"true"}' epilogues: - path: /_plugins/_notifications/configs/custom-webhook-configuration method: DELETE