diff --git a/.cspell b/.cspell index 274d2da09..eb1d955ba 100644 --- a/.cspell +++ b/.cspell @@ -63,6 +63,7 @@ geotile gsub Gsub haasephonetik +hashcode heteroscedastic hnsw homoscedastic @@ -134,6 +135,7 @@ Oversample performanceanalyzer permissionsinfo pipefail +pipenv preconfigure preconfigured prefilter diff --git a/.github/workflows/validate-spec.yml b/.github/workflows/validate-spec-lint.yml similarity index 100% rename from .github/workflows/validate-spec.yml rename to .github/workflows/validate-spec-lint.yml diff --git a/.github/workflows/validate-spec-py.yml b/.github/workflows/validate-spec-py.yml new file mode 100644 index 000000000..9e33a5aaf --- /dev/null +++ b/.github/workflows/validate-spec-py.yml @@ -0,0 +1,34 @@ +name: Validate Spec (Python) + +on: [pull_request,push] + +jobs: + validate-spec-py: + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Build + run: npm ci && npm run merge + + - name: Set Up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install Dependencies + working-directory: tools/src/validate-spec-py + run: | + pip install --user pipenv + pipenv install + + - name: Validate Spec + working-directory: tools/src/validate-spec-py + run: | + pipenv run python validate.py ../../../build/opensearch-openapi.yaml diff --git a/.github/workflows/validate-spec-ruby.yml b/.github/workflows/validate-spec-ruby.yml new file mode 100644 index 000000000..de0e1e200 --- /dev/null +++ b/.github/workflows/validate-spec-ruby.yml @@ -0,0 +1,30 @@ +name: Validate Spec (Ruby) + +on: [pull_request, push] + +jobs: + validate-spec-ruby: + runs-on: ubuntu-latest + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/tools/src/validate-spec-ruby/Gemfile + steps: + - name: Checkout the repo + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Build + run: npm ci && npm run merge + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' + bundler-cache: true + + - name: Validate Spec + working-directory: tools/src/validate-spec-ruby + run: | + bundle exec ruby validate.rb ../../../build/opensearch-openapi.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bc71eaeb..811c2cb21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,22 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Added - Added API specs for query groups lifecycle APIs ([#649](https://github.com/opensearch-project/opensearch-api-specification/pull/649)) +- Added Python and Ruby spec validators ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Added verbose output of the story being evaluated ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) ### Removed - Removed unsupported `_common.mapping:SourceField`'s `mode` field and associated `_common.mapping:SourceFieldMode` enum ([#652](https://github.com/opensearch-project/opensearch-api-specification/pull/652)) +### Fixed +- Spec passes OpenAPI 3.1.0 validations ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Disallowed characters (`::`, `@`, and `:`) in key names are replaced with `___` on merge ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Added missing `required` to `path` parameters ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Added missing `schema` parent to response types ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Removed invalid `externalDocs` from `flow_framework.create/update::query.use_case` ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Fixed incorrect `style` in `indices.get_mapping::query.index` ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Removed invalid `required` from `ppl` responses ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) +- Added schema for security API error responses ([#646](https://github.com/opensearch-project/opensearch-api-specification/pull/646)) + ## [0.1.0] - 2024-10-25 ### Added diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index b46319eb6..7ff326560 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -26,7 +26,9 @@ - [Comment on PR](#comment-on-pr) - [Test Tools (Unit)](#test-tools-unit) - [Test Tools (Integration)](#test-tools-integration) - - [Validate Spec](#validate-spec) + - [Validate Spec (Lint)](#validate-spec-lint) + - [Validate Spec (Python)](#validate-spec-python) + - [Validate Spec (Ruby)](#validate-spec-ruby) # Developer Guide @@ -375,6 +377,30 @@ This workflow runs on PRs to invoke the [tools' unit tests](tools/tests), upload This workflow runs on PRs to invoke the [tools' integration tests](tools/tests) that require a running instance of OpenSearch to ensure there are no breakages in behavior. -### [Validate Spec](.github/workflows/validate-spec.yml) +### [Validate Spec (Lint)](.github/workflows/validate-spec-lint.yml) This workflow runs on PRs to invoke the [spec linter](#spec-linter) and ensure the multi-file spec is correct and follows the design guidelines. + +### [Validate Spec (Python)](.github/workflows/validate-spec-py.yml) + +This workflow runs on PRs to invoke the [Python openapi-spec-validator](https://pypi.org/project/openapi-spec-validator/) to ensure that the resulting spec can be loaded by Python tools. + +You can run the validator locally as follows after installing [pipenv](https://pipenv.pypa.io/en/latest/installation.html). + +``` +cd tools/src/validate-spec-py +pipenv install +npm run merge ; pipenv run python validate.py ../../../build/opensearch-openapi.yaml +``` + +### [Validate Spec (Ruby)](.github/workflows/validate-spec-ruby.yml) + +This workflow runs on PRs to invoke the Ruby [Json Schemer](https://github.com/davishmcclurg/json_schemer/) to ensure that the resulting spec can be loaded by Ruby tools. + +You can run the validator locally as follows. + +``` +cd tools/src/validate-spec-ruby +bundle install +npm run merge ; bundle exec ruby validate.rb ../../../build/opensearch-openapi.yaml +``` diff --git a/spec/_global_parameters.yaml b/spec/_global_parameters.yaml index 91ddbfe8f..160d1d241 100644 --- a/spec/_global_parameters.yaml +++ b/spec/_global_parameters.yaml @@ -10,21 +10,21 @@ components: description: Whether to pretty format the returned JSON response. schema: type: boolean - default: false + default: false human: name: human in: query description: Whether to return human readable values for statistics. schema: type: boolean - default: true + default: true error_trace: name: error_trace in: query description: Whether to include the stack trace of returned errors. schema: type: boolean - default: false + default: false source: name: source in: query diff --git a/spec/_superseded_operations.yaml b/spec/_superseded_operations.yaml index 80e556067..fbc54730f 100644 --- a/spec/_superseded_operations.yaml +++ b/spec/_superseded_operations.yaml @@ -201,7 +201,7 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml - GET - PUT /_opendistro/_ism/policies/{policyID}: - superseded_by: /_plugins/_ism/policies/{policyID} + superseded_by: /_plugins/_ism/policies/{policy_id} operations: - GET - HEAD @@ -240,7 +240,7 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml operations: - GET /_opendistro/_knn/{nodeId}/stats/{stat}: - superseded_by: /_plugins/_knn/{nodeId}/stats/{stat} + superseded_by: /_plugins/_knn/{node_id}/stats/{stat} operations: - GET /_opendistro/_performanceanalyzer/_agent/{redirectEndpoint}: @@ -354,22 +354,22 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml - GET - PUT /_opendistro/_rollup/jobs/{rollupID}: - superseded_by: /_plugins/_rollup/jobs/{rollupID} + superseded_by: /_plugins/_rollup/jobs/{id} operations: - GET - HEAD - PUT - DELETE /_opendistro/_rollup/jobs/{rollupID}/_explain: - superseded_by: /_plugins/_rollup/jobs/{rollupID}/_explain + superseded_by: /_plugins/_rollup/jobs/{id}/_explain operations: - GET /_opendistro/_rollup/jobs/{rollupID}/_start: - superseded_by: /_plugins/_rollup/jobs/{rollupID}/_start + superseded_by: /_plugins/_rollup/jobs/{id}/_start operations: - POST /_opendistro/_rollup/jobs/{rollupID}/_stop: - superseded_by: /_plugins/_rollup/jobs/{rollupID}/_stop + superseded_by: /_plugins/_rollup/jobs/{id}/_stop operations: - POST /_opendistro/_security/api/_upgrade_check/: @@ -401,7 +401,7 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml - GET - PATCH /_opendistro/_security/api/actiongroups/{name}: - superseded_by: /_plugins/_security/api/actiongroups/{name} + superseded_by: /_plugins/_security/api/actiongroups/{action_group} operations: - GET - PUT @@ -433,14 +433,14 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml - GET - PATCH /_opendistro/_security/api/internalusers/{name}: - superseded_by: /_plugins/_security/api/internalusers/{name} + superseded_by: /_plugins/_security/api/internalusers/{username} operations: - GET - PUT - PATCH - DELETE /_opendistro/_security/api/internalusers/{name}/authtoken: - superseded_by: /_plugins/_security/api/internalusers/{name}/authtoken + superseded_by: /_plugins/_security/api/internalusers/{username}/authtoken operations: - POST /_opendistro/_security/api/migrate: @@ -457,7 +457,7 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml - GET - PATCH /_opendistro/_security/api/roles/{name}: - superseded_by: /_plugins/_security/api/roles/{name} + superseded_by: /_plugins/_security/api/roles/{role} operations: - GET - PUT @@ -469,7 +469,7 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml - GET - PATCH /_opendistro/_security/api/rolesmapping/{name}: - superseded_by: /_plugins/_security/api/rolesmapping/{name} + superseded_by: /_plugins/_security/api/rolesmapping/{role} operations: - GET - PUT @@ -519,7 +519,7 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml - GET - PATCH /_opendistro/_security/api/tenants/{name}: - superseded_by: /_plugins/_security/api/tenants/{name} + superseded_by: /_plugins/_security/api/tenants/{tenant} operations: - GET - PUT @@ -529,14 +529,14 @@ $schema: ./json_schemas/_superseded_operations.schema.yaml superseded_by: /_plugins/_security/api/user operations: - GET -/_opendistro/_security/api/user/{name}: - superseded_by: /_plugins/_security/api/user/{name} +/_opendistro/_security/api/user/{username}: + superseded_by: /_plugins/_security/api/user/{username} operations: - GET - PUT - DELETE /_opendistro/_security/api/user/{name}/authtoken: - superseded_by: /_plugins/_security/api/user/{name}/authtoken + superseded_by: /_plugins/_security/api/user/{username}/authtoken operations: - POST /_opendistro/_security/api/validate: diff --git a/spec/namespaces/asynchronous_search.yaml b/spec/namespaces/asynchronous_search.yaml index 863cd33d6..9153257a9 100644 --- a/spec/namespaces/asynchronous_search.yaml +++ b/spec/namespaces/asynchronous_search.yaml @@ -90,11 +90,13 @@ components: in: path schema: type: string + required: true asynchronous_search.delete::path.id: name: id in: path schema: type: string + required: true requestBodies: asynchronous_search.search: content: diff --git a/spec/namespaces/cat.yaml b/spec/namespaces/cat.yaml index 9e6f27684..c89368e5b 100644 --- a/spec/namespaces/cat.yaml +++ b/spec/namespaces/cat.yaml @@ -792,7 +792,8 @@ components: cat.aliases@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -801,7 +802,8 @@ components: cat.all_pit_segments@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -810,7 +812,8 @@ components: cat.allocation@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -819,7 +822,8 @@ components: cat.cluster_manager@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -828,7 +832,8 @@ components: cat.count@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -837,7 +842,8 @@ components: cat.fielddata@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -846,7 +852,8 @@ components: cat.health@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -875,7 +882,8 @@ components: cat.indices@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -899,7 +907,8 @@ components: cat.master@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -908,7 +917,8 @@ components: cat.nodeattrs@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -917,7 +927,8 @@ components: cat.nodes@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -926,7 +937,8 @@ components: cat.pending_tasks@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -935,7 +947,8 @@ components: cat.pit_segments@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -944,7 +957,8 @@ components: cat.plugins@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -953,7 +967,8 @@ components: cat.recovery@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -962,7 +977,8 @@ components: cat.repositories@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -971,7 +987,8 @@ components: cat.segment_replication@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -980,7 +997,8 @@ components: cat.segments@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -989,7 +1007,8 @@ components: cat.shards@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -998,7 +1017,8 @@ components: cat.snapshots@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -1007,7 +1027,8 @@ components: cat.tasks@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -1016,7 +1037,8 @@ components: cat.templates@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array @@ -1025,7 +1047,8 @@ components: cat.thread_pool@200: content: text/plain: - type: string + schema: + type: string application/json: schema: type: array diff --git a/spec/namespaces/flow_framework.yaml b/spec/namespaces/flow_framework.yaml index feed463e6..7d3616220 100644 --- a/spec/namespaces/flow_framework.yaml +++ b/spec/namespaces/flow_framework.yaml @@ -302,8 +302,6 @@ components: $ref: '../schemas/flow_framework.common.yaml#/components/schemas/Reprovision' flow_framework.create::query.use_case: description: To use a workflow template, specify it in the use_case query parameter when creating a workflow. - externalDocs: - url: https://opensearch.org/docs/latest/automating-configurations/workflow-templates/#supported-workflow-templates in: query name: use_case schema: @@ -316,8 +314,6 @@ components: $ref: '../schemas/flow_framework.common.yaml#/components/schemas/All' flow_framework.update::query.use_case: description: To use a workflow template, specify it in the use_case query parameter when creating a workflow. - externalDocs: - url: https://opensearch.org/docs/latest/automating-configurations/workflow-templates/#supported-workflow-templates in: query name: use_case schema: @@ -400,36 +396,39 @@ components: flow_framework.create@403: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' flow_framework.create@400: description: Bad Request - Multiple possible reasons content: application/json: - oneOf: - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidParameterError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ConflictError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MissingParameterError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ParameterConflictError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MaxWorkflowsLimitError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowSaveError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowParsingError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/UnsupportedFieldUpdateError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidTemplateVersionError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNameRequiredError' + schema: + anyOf: + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidParameterError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ConflictError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MissingParameterError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ParameterConflictError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MaxWorkflowsLimitError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowSaveError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowParsingError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/UnsupportedFieldUpdateError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidTemplateVersionError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNameRequiredError' flow_framework.update@400: description: Bad Request - Multiple possible reasons content: application/json: - oneOf: - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidParameterError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ConflictError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MissingParameterError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ParameterConflictError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MaxWorkflowsLimitError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowSaveError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidTemplateVersionError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/UnsupportedFieldUpdateError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowParsingError' + schema: + anyOf: + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidParameterError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ConflictError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MissingParameterError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/ParameterConflictError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/MaxWorkflowsLimitError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowSaveError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidTemplateVersionError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/UnsupportedFieldUpdateError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowParsingError' flow_framework.update@201: content: application/json: @@ -444,121 +443,148 @@ components: flow_framework.delete@200: content: application/json: - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/FlowFrameworkDeleteResponse' + schema: + $ref: '../schemas/flow_framework.common.yaml#/components/schemas/FlowFrameworkDeleteResponse' flow_framework.get@200: content: application/json: - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/FlowFrameworkGetResponse' + schema: + $ref: '../schemas/flow_framework.common.yaml#/components/schemas/FlowFrameworkGetResponse' flow_framework.update@404: description: Template Not Found Error content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' flow_framework.delete@400: description: Work Flow Id Null Error content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkFlowIdNullError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkFlowIdNullError' flow_framework.delete@403: description: Flow Framework API Disabled Error content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' flow_framework.get@404: description: Template Not Found Error content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' flow_framework.get_steps@200: content: application/json: - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowStep' + schema: + $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowSteps' flow_framework.get_steps@403: description: Flow Framework API Disabled Error content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' flow_framework.get_steps@400: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowStepsRetrieveError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkflowStepsRetrieveError' flow_framework.get_status@403: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' flow_framework.get_status@404: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' flow_framework.get_status@200: content: application/json: - oneOf: - - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkFlowStatusFullResponse' - - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkFlowStatusDefaultResponse' + schema: + anyOf: + - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkFlowStatusFullResponse' + - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkFlowStatusDefaultResponse' flow_framework.deprovision@200: content: application/json: - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowID' + schema: + $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowIDResponse' flow_framework.provision@200: content: application/json: - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowID' + schema: + $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowIDResponse' flow_framework.deprovision@202: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/DeprovisioningError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/DeprovisioningError' flow_framework.deprovision@403: content: application/json: - oneOf: - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/DeprovisioningForbiddenError' + schema: + oneOf: + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/DeprovisioningForbiddenError' flow_framework.deprovision@404: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/TemplateNotFoundError' flow_framework.provision@403: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' flow_framework.provision@400: content: application/json: - oneOf: - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkFlowIdNullError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/RequestBodyParsingFailedError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidRequestBodyFieldError' - - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/DuplicateKeyError' + schema: + oneOf: + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/WorkFlowIdNullError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/RequestBodyParsingFailedError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/InvalidRequestBodyFieldError' + - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/DuplicateKeyError' flow_framework.search@200: content: application/json: - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowSearchResponse' + schema: + $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowSearchResponse' flow_framework.search@403: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' flow_framework.search@408: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/RequestTimeoutError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/RequestTimeoutError' flow_framework.search@400: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/BadRequestError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/BadRequestError' flow_framework.search_state@200: content: application/json: - $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowSearchStateResponse' + schema: + $ref: '../schemas/flow_framework.common.yaml#/components/schemas/WorkflowSearchStateResponse' flow_framework.search_state@403: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/FlowFrameworkAPIDisabledError' flow_framework.search_state@408: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/RequestTimeoutError' + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/RequestTimeoutError' flow_framework.search_state@400: content: application/json: - $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/BadRequestError' \ No newline at end of file + schema: + $ref: '../schemas/flow_framework.errors.yaml#/components/schemas/BadRequestError' \ No newline at end of file diff --git a/spec/namespaces/indices.yaml b/spec/namespaces/indices.yaml index cbe075a6d..fcf676adf 100644 --- a/spec/namespaces/indices.yaml +++ b/spec/namespaces/indices.yaml @@ -2404,7 +2404,7 @@ components: content: application/json: schema: - $ref: '../schemas/indices._common.yaml#/components/schemas/IndexErrorCause' + $ref: '../schemas/indices._common.yaml#/components/schemas/IndexError' indices.delete_alias@200: content: application/json: @@ -3965,7 +3965,7 @@ components: To target all data streams and indices, omit this parameter or use `*` or `_all`. schema: $ref: '../schemas/_common.yaml#/components/schemas/Indices' - style: simple + style: form indices.get_mapping::query.local: in: query name: local diff --git a/spec/namespaces/ism.yaml b/spec/namespaces/ism.yaml index 334bc69f7..9e91d84c7 100644 --- a/spec/namespaces/ism.yaml +++ b/spec/namespaces/ism.yaml @@ -178,7 +178,7 @@ paths: '200': $ref: '#/components/responses/ism.explain_policy@200' post: - operationId: ism.explain_policy.0 + operationId: ism.explain_policy.1 x-operation-group: ism.explain_policy description: Gets the currently applied policy on indices. externalDocs: @@ -190,7 +190,7 @@ paths: $ref: '#/components/responses/ism.explain_policy@200' /_plugins/_ism/explain/{index}: get: - operationId: ism.explain_policy.1 + operationId: ism.explain_policy.3 x-operation-group: ism.explain_policy description: Gets the currently applied policy on indices. externalDocs: @@ -203,7 +203,7 @@ paths: '200': $ref: '#/components/responses/ism.explain_policy@200' post: - operationId: ism.explain_policy.1 + operationId: ism.explain_policy.4 x-operation-group: ism.explain_policy description: Gets the currently applied policy on indices. externalDocs: diff --git a/spec/namespaces/observability.yaml b/spec/namespaces/observability.yaml index a8553dbe1..62cca3dfd 100644 --- a/spec/namespaces/observability.yaml +++ b/spec/namespaces/observability.yaml @@ -150,7 +150,6 @@ components: type: object additionalProperties: type: string - example: OK observability.delete_object@404: description: Not Found content: @@ -168,7 +167,7 @@ components: type: object additionalProperties: type: string - example: OK + # example: OK observability.delete_objects@404: description: Not Found content: diff --git a/spec/namespaces/ppl.yaml b/spec/namespaces/ppl.yaml index 0794fd32d..02ef9e2bb 100644 --- a/spec/namespaces/ppl.yaml +++ b/spec/namespaces/ppl.yaml @@ -150,16 +150,13 @@ components: application/json: schema: $ref: '../schemas/sql._common.yaml#/components/schemas/ExplainResponse' - required: true ppl.get_stats@200: content: text/plain: schema: type: string - required: true ppl.post_stats@200: content: text/plain: schema: type: string - required: true \ No newline at end of file diff --git a/spec/namespaces/search_pipeline.yaml b/spec/namespaces/search_pipeline.yaml index 05d16fbdd..a2b5bd5fd 100644 --- a/spec/namespaces/search_pipeline.yaml +++ b/spec/namespaces/search_pipeline.yaml @@ -106,6 +106,7 @@ components: description: Comma-separated list of search pipeline ids. Wildcards supported. schema: type: string + required: true search_pipeline.get::query.cluster_manager_timeout: name: cluster_manager_timeout in: query diff --git a/spec/namespaces/security.yaml b/spec/namespaces/security.yaml index 5900516f5..77dc0c6f6 100644 --- a/spec/namespaces/security.yaml +++ b/spec/namespaces/security.yaml @@ -1558,7 +1558,8 @@ components: security.cache@501: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.change_password@200: content: application/json: @@ -1567,7 +1568,8 @@ components: security.change_password@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.config_upgrade_check@200: content: application/json: @@ -1581,7 +1583,8 @@ components: security.config_upgrade_perform@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.create_action_group@200: content: application/json: @@ -1600,7 +1603,8 @@ components: security.create_allowlist@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.create_role@200: content: application/json: @@ -1634,7 +1638,8 @@ components: security.create_tenant@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.create_update_tenancy_config@200: content: application/json: @@ -1643,7 +1648,8 @@ components: security.create_update_tenancy_config@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.create_user@200: content: application/json: @@ -1672,11 +1678,13 @@ components: security.delete_distinguished_name@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.delete_distinguished_name@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.delete_role@200: content: application/json: @@ -1695,7 +1703,8 @@ components: security.delete_tenant@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.delete_user@200: content: application/json: @@ -1719,9 +1728,11 @@ components: security.generate_obo_token@400: content: text/plain: - type: string + schema: + type: string application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.generate_user_token@200: content: application/json: @@ -1730,11 +1741,13 @@ components: security.generate_user_token@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.generate_user_token_legacy@501: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_account_details@200: content: application/json: @@ -1758,7 +1771,8 @@ components: security.get_allowlist@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_audit_configuration@200: content: application/json: @@ -1777,7 +1791,8 @@ components: security.get_all_certificates@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_all_certificates@500: content: application/json: @@ -1791,15 +1806,18 @@ components: security.get_node_certificates@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_certificates@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_certificates@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_node_certificates@500: content: application/json: @@ -1829,11 +1847,13 @@ components: security.get_distinguished_name@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_distinguished_name@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_distinguished_names@200: content: application/json: @@ -1843,11 +1863,13 @@ components: description: Show nodesDn setting for given cluster. content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_distinguished_names@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_permissions_info@200: content: application/json: @@ -1901,7 +1923,8 @@ components: security.get_tenancy_config@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_tenants@200: content: application/json: @@ -1910,7 +1933,8 @@ components: security.get_tenants@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.get_user@200: content: application/json: @@ -1944,7 +1968,8 @@ components: security.migrate@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_action_group@200: content: application/json: @@ -1963,7 +1988,8 @@ components: security.patch_allowlist@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_audit_configuration@200: content: application/json: @@ -1977,7 +2003,8 @@ components: security.patch_configuration@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_distinguished_name@200: content: application/json: @@ -1986,11 +2013,13 @@ components: security.patch_distinguished_name@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_distinguished_name@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_distinguished_names@200: content: application/json: @@ -1999,11 +2028,13 @@ components: security.patch_distinguished_names@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_distinguished_names@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_role@200: content: application/json: @@ -2012,7 +2043,8 @@ components: security.patch_role@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_role_mapping@200: content: application/json: @@ -2021,7 +2053,8 @@ components: security.patch_role_mapping@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_role_mappings@200: content: application/json: @@ -2030,7 +2063,8 @@ components: security.patch_role_mappings@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_roles@200: content: application/json: @@ -2039,7 +2073,8 @@ components: security.patch_roles@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_tenant@200: content: application/json: @@ -2048,7 +2083,8 @@ components: security.patch_tenant@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_tenants@200: content: application/json: @@ -2057,7 +2093,8 @@ components: security.patch_tenants@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.patch_user@200: content: application/json: @@ -2086,11 +2123,13 @@ components: security.reload_http_certificates@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.reload_http_certificates@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.reload_transport_certificates@200: content: application/json: @@ -2099,11 +2138,13 @@ components: security.reload_transport_certificates@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.reload_transport_certificates@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.tenant_info@200: content: application/json: @@ -2112,9 +2153,11 @@ components: security.tenant_info@403: content: text/plain: - type: string + schema: + type: string application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.tenant_info@500: content: application/json: @@ -2133,7 +2176,8 @@ components: security.update_configuration@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.update_distinguished_name@200: content: application/json: @@ -2142,11 +2186,13 @@ components: security.update_distinguished_name@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.update_distinguished_name@403: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.validate@200: content: application/json: @@ -2155,7 +2201,8 @@ components: security.validate@400: content: application/json: - schema: null + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Error' security.who_am_i@200: content: application/json: diff --git a/spec/namespaces/sql.yaml b/spec/namespaces/sql.yaml index a54c6cc39..053ebead0 100644 --- a/spec/namespaces/sql.yaml +++ b/spec/namespaces/sql.yaml @@ -177,31 +177,26 @@ components: anyOf: - $ref: '../schemas/sql._common.yaml#/components/schemas/SqlSettingsPlain' - $ref: '../schemas/sql._common.yaml#/components/schemas/SqlSettings' - required: true sql.query: content: application/json: schema: $ref: '../schemas/sql._common.yaml#/components/schemas/Query' - required: true sql.explain: content: application/json: schema: $ref: '../schemas/sql._common.yaml#/components/schemas/Explain' - required: true sql.close: content: application/json: schema: $ref: '../schemas/sql._common.yaml#/components/schemas/SqlClose' - required: true sql.post_stats: content: application/json: schema: $ref: '../schemas/sql._common.yaml#/components/schemas/Stats' - required: true responses: sql.settings@200: content: @@ -218,22 +213,18 @@ components: application/json: schema: $ref: '../schemas/sql._common.yaml#/components/schemas/ExplainResponse' - required: true sql.close@200: content: application/json: schema: $ref: '../schemas/sql._common.yaml#/components/schemas/SqlCloseResponse' - required: true sql.get_stats@200: content: text/plain: schema: type: string - required: true sql.post_stats@200: content: text/plain: schema: type: string - required: true \ No newline at end of file diff --git a/spec/schemas/cluster.allocation_explain.yaml b/spec/schemas/cluster.allocation_explain.yaml index f7141a328..97b36f6ef 100644 --- a/spec/schemas/cluster.allocation_explain.yaml +++ b/spec/schemas/cluster.allocation_explain.yaml @@ -177,7 +177,6 @@ components: - node_id - node_name - transport_address - - weight_ranking AllocationStore: type: object properties: diff --git a/spec/schemas/flow_framework.common.yaml b/spec/schemas/flow_framework.common.yaml index d3ab4ae9b..2c3678921 100644 --- a/spec/schemas/flow_framework.common.yaml +++ b/spec/schemas/flow_framework.common.yaml @@ -11,6 +11,12 @@ components: type: string WorkflowID: type: string + WorkflowIDResponse: + type: object + properties: + workflow_id: + type: string + description: The ID of the workflow WorkflowStepName: type: string Provision: @@ -99,6 +105,8 @@ components: properties: name: type: string + version: + $ref: '#/components/schemas/version' description: type: string use_case: @@ -111,6 +119,8 @@ components: type: integer last_updated_time: type: integer + last_provisioned_time: + type: number version: type: object description: A key-value map with two fields, template, which identifies the template version, and compatibility, which identifies a list of minimum required OpenSearch versions. @@ -135,6 +145,9 @@ components: failed: type: integer description: The number of shards where the deletion failed. + skipped: + type: integer + description: The number of shards where the deletion was skipped. query: type: object description: The search query to match workflows. Use `match_all` to retrieve all workflows, or `match` to search by specific fields like `use_case`. @@ -237,9 +250,11 @@ components: total: $ref: '#/components/schemas/total' max_score: - type: number - format: float - description: The maximum score of the search hits. + oneOf: + - type: 'null' + - type: number + format: float + description: The maximum score of the search hits. hits: type: array items: @@ -250,13 +265,19 @@ components: total: $ref: '#/components/schemas/total' max_score: - type: number - format: float - description: The maximum score of the search hits. + oneOf: + - type: 'null' + - type: number + format: float + description: The maximum score of the search hits. hits: type: array items: $ref: '#/components/schemas/StateItems' + WorkflowSteps: + type: object + additionalProperties: + $ref: '#/components/schemas/WorkflowStep' WorkflowStep: type: object properties: @@ -275,6 +296,8 @@ components: items: type: string description: The list of plugins required for the workflow step + timeout: + $ref: '_common.yaml#/components/schemas/Duration' WorkFlowStatusDefaultResponse: type: object properties: diff --git a/spec/schemas/flow_framework.errors.yaml b/spec/schemas/flow_framework.errors.yaml index 879cf7fe5..c91ed0e1d 100644 --- a/spec/schemas/flow_framework.errors.yaml +++ b/spec/schemas/flow_framework.errors.yaml @@ -7,65 +7,53 @@ paths: {} components: schemas: FlowFrameworkAPIDisabledError: - content: - application/json: - type: object - properties: - error: - type: string - example: This API is disabled. To enable it, set [flow_framework.enabled] to true. - status: - type: integer + type: object + properties: + error: + type: string + # example: This API is disabled. To enable it, set [flow_framework.enabled] to true. + status: + type: integer InvalidParameterError: - content: - application/json: - type: object - properties: - error: - type: string - example: Only the parameters [param1, param2] are permitted unless the provision parameter is set to true. - status: - type: integer + type: object + properties: + error: + type: string + # example: Only the parameters [param1, param2] are permitted unless the provision parameter is set to true. + status: + type: integer ConflictError: - content: - application/json: - type: object - properties: - error: - type: string - example: You cannot use both the 'provision_workflow' and 'update_workflow_fields' parameters in the same request. - status: - type: integer + type: object + properties: + error: + type: string + # example: You cannot use both the 'provision_workflow' and 'update_workflow_fields' parameters in the same request. + status: + type: integer MissingParameterError: - content: - application/json: - type: object - properties: - error: - type: string - example: You cannot use the 'reprovision_workflow' parameter to create a new template. - status: - type: integer + type: object + properties: + error: + type: string + # example: You cannot use the 'reprovision_workflow' parameter to create a new template. + status: + type: integer ParameterConflictError: - content: - application/json: - type: object - properties: - error: - type: string - example: You cannot use the 'reprovision_workflow' and 'use_case' parameters in the same request. - status: - type: integer + type: object + properties: + error: + type: string + # example: You cannot use the 'reprovision_workflow' and 'use_case' parameters in the same request. + status: + type: integer WorkFlowIdNullError: - content: - application/json: - type: object - properties: - error: - type: string - example: Workflow ID can not be null - status: - type: integer + type: object + properties: + error: + type: string + # example: Workflow ID can not be null + status: + type: integer DuplicateKeyError: type: object properties: @@ -75,7 +63,7 @@ components: status: type: integer description: HTTP status code for the error. - example: 400 + # example: 400 InvalidRequestBodyFieldError: type: object properties: @@ -94,27 +82,23 @@ components: status: type: integer description: HTTP status code for the error. - example: 400 + # example: 400 WorkflowSaveError: - content: - application/json: - type: object - properties: - error: - type: string - example: Failed to save workflow state - status: - type: integer + type: object + properties: + error: + type: string + # example: Failed to save workflow state + status: + type: integer MaxWorkflowsLimitError: - content: - application/json: - type: object - properties: - error: - type: string - example: Maximum workflows limit reached 50 - code: - type: integer + type: object + properties: + error: + type: string + # example: Maximum workflows limit reached 50 + code: + type: integer TemplateNameRequiredError: type: object properties: @@ -122,59 +106,49 @@ components: type: string description: Error message when the template name is missing. TemplateNotFoundError: - content: - application/json: - type: object - properties: - error: - type: string - example: Failed to retrieve template (12345) from global context. - code: - type: integer + type: object + properties: + error: + type: string + # example: Failed to retrieve template (12345) from global context. + code: + type: integer InvalidTemplateVersionError: - content: - application/json: - type: object - properties: - error: - type: string - description: Error message when the template version is invalid or missing. - example: Unable to parse field [version] in a version object. + type: object + properties: + error: + type: string + description: Error message when the template version is invalid or missing. + # example: Unable to parse field [version] in a version object. UnsupportedFieldUpdateError: - content: - application/json: - type: object - properties: - error: - type: string - description: Error message when trying to update an unsupported field in a template. - example: You can not update the field [fieldName] without updating the whole template. + type: object + properties: + error: + type: string + description: Error message when trying to update an unsupported field in a template. + # example: You can not update the field [fieldName] without updating the whole template. WorkflowParsingError: - content: - application/json: - type: object - properties: - error: - type: string - description: Error message when workflow parsing fails. - example: Unable to parse field [workflow] in a template object. + type: object + properties: + error: + type: string + description: Error message when workflow parsing fails. + # example: Unable to parse field [workflow] in a template object. WorkflowStepsRetrieveError: - content: - application/json: - type: object - properties: - error: - type: string - example: Failed to retrieve workflow step json. - code: - type: integer + type: object + properties: + error: + type: string + # example: Failed to retrieve workflow step json. + code: + type: integer DeprovisioningError: type: object properties: error: type: string description: Describes the deprovisioning error and identifies resources that were not deprovisioned - example: Failed to deprovision some resources [connector_id Lw7PX4wBfVtHp98y06wV]. + # example: Failed to deprovision some resources [connector_id Lw7PX4wBfVtHp98y06wV]. required: - error DeprovisioningForbiddenError: @@ -183,7 +157,7 @@ components: error: type: string description: Describes the resources that require the allow_delete parameter for deprovisioning - example: These resources require the allow_delete parameter to deprovision [index_name my-index]. + # example: These resources require the allow_delete parameter to deprovision [index_name my-index]. required: - error RequestTimeoutError: @@ -195,15 +169,15 @@ components: status: type: integer description: HTTP status code for the error. - example: 408 + # example: 408 BadRequestError: type: object properties: error: type: string description: Error message when the request body or parameters are invalid. - example: Invalid request body or query parameters. + # example: Invalid request body or query parameters. status: type: integer description: HTTP status code for the error. - example: 400 \ No newline at end of file + # example: 400 \ No newline at end of file diff --git a/spec/schemas/indices._common.yaml b/spec/schemas/indices._common.yaml index 2e3763cc4..10386d1ea 100644 --- a/spec/schemas/indices._common.yaml +++ b/spec/schemas/indices._common.yaml @@ -983,6 +983,13 @@ components: - mappings - order - settings + IndexError: + type: object + properties: + error: + $ref: '#/components/schemas/IndexErrorCause' + status: + type: number IndexErrorCause: type: object properties: diff --git a/spec/schemas/insights._common.yaml b/spec/schemas/insights._common.yaml index b4a700360..66b0bbe47 100644 --- a/spec/schemas/insights._common.yaml +++ b/spec/schemas/insights._common.yaml @@ -30,7 +30,7 @@ components: items: type: object $ref: '#/components/schemas/TaskResourceUsages' - # eslint-disable-next-line @cspell/spellchecker + query_hashcode: type: string description: The hash code of the query. diff --git a/spec/schemas/observability._common.yaml b/spec/schemas/observability._common.yaml index fc8018f55..08b7fbce6 100644 --- a/spec/schemas/observability._common.yaml +++ b/spec/schemas/observability._common.yaml @@ -218,7 +218,7 @@ components: $ref: '#/components/schemas/ErrorResponse' status: type: integer - example: 404 + # example: 404 required: - error - status @@ -232,10 +232,10 @@ components: $ref: '#/components/schemas/RootCause' type: type: string - example: status_exception + # example: status_exception reason: type: string - example: 'ObservabilityObject {objectId} not found' + # example: 'ObservabilityObject {objectId} not found' required: - reason - root_cause @@ -246,10 +246,10 @@ components: properties: type: type: string - example: status_exception + # example: status_exception reason: type: string - example: 'ObservabilityObject {objectId} not found' + # example: 'ObservabilityObject {objectId} not found' required: - reason - type diff --git a/spec/schemas/query._common.yaml b/spec/schemas/query._common.yaml index 40277b8b0..ef4e315f4 100644 --- a/spec/schemas/query._common.yaml +++ b/spec/schemas/query._common.yaml @@ -71,6 +71,14 @@ components: - error ErrorResponse: + type: object + properties: + error: + $ref: '#/components/schemas/Error' + status: + type: number + + Error: type: object properties: root_cause: diff --git a/spec/schemas/security._common.yaml b/spec/schemas/security._common.yaml index d98618758..fde8ffb39 100644 --- a/spec/schemas/security._common.yaml +++ b/spec/schemas/security._common.yaml @@ -454,6 +454,22 @@ components: items: type: string + Error: + type: object + properties: + status: + type: string + enum: + - BAD_REQUEST + - CONFLICT + - FORBIDDEN + - INTERNAL_SERVER_ERROR + - NOT_FOUND + - NOT_IMPLEMENTED + - UNAUTHORIZED + message: + type: string + InternalServerError: type: object properties: diff --git a/tests/default/flow_framework/template.yaml b/tests/default/flow_framework/template.yaml index c7ac780c9..84ecd8638 100644 --- a/tests/default/flow_framework/template.yaml +++ b/tests/default/flow_framework/template.yaml @@ -7,6 +7,8 @@ epilogues: status: [200, 404] parameters: workflow_id: ${create_flow_framework.test_workflow_id} +warnings: + multiple-paths-detected: false chapters: - synopsis: Create workflow with openAI model. id: create_flow_framework diff --git a/tests/default/security/api/nodesdn.yaml b/tests/default/security/api/nodesdn.yaml deleted file mode 100644 index 43b3991d4..000000000 --- a/tests/default/security/api/nodesdn.yaml +++ /dev/null @@ -1,65 +0,0 @@ -$schema: ../../../../json_schemas/test_story.schema.yaml - -description: Test nodesdn endpoints. -distributions: - excluded: - - amazon-managed - - amazon-serverless - -# ADMIN-CERT only. These tests require explicit rest api admin privileges. -# The setting `plugins. security. nodes_dn_dynamic_config_enabled` must be enabled. -chapters: - - synopsis: Get distinguished names. - path: /_plugins/_security/api/nodesdn - method: GET - parameters: - show_all: true - response: - status: 400 - - synopsis: Patch distinguished names. - path: /_plugins/_security/api/nodesdn - method: PATCH - request: - payload: - - op: replace - path: /cluster1/nodes_dn/0 - value: [''] - response: - status: 400 - - synopsis: Create distinguished name. - path: /_plugins/_security/api/nodesdn/{cluster_name} - method: PUT - parameters: - cluster_name: test - request: - payload: - nodes_dn: - - CN=cluster3.example.com - response: - status: 400 - - synopsis: Get distinguished name. - path: /_plugins/_security/api/nodesdn/{cluster_name} - method: GET - parameters: - cluster_name: test - response: - status: 400 - - synopsis: Patch distinguished name. - path: /_plugins/_security/api/nodesdn/{cluster_name} - method: PATCH - parameters: - cluster_name: test - request: - payload: - op: replace - path: /test/nodes_dn/0 - value: [CN=cluster2.example.com] - response: - status: 400 - - synopsis: Delete distinguished name. - path: /_plugins/_security/api/nodesdn/{cluster_name} - method: DELETE - parameters: - cluster_name: test - response: - status: 400 diff --git a/tests/plugins/ml/ingest/pipeline/neural_search.yaml b/tests/plugins/ml/ingest/pipeline/neural_search.yaml index ca2fdd60a..5e68f5995 100644 --- a/tests/plugins/ml/ingest/pipeline/neural_search.yaml +++ b/tests/plugins/ml/ingest/pipeline/neural_search.yaml @@ -183,23 +183,6 @@ chapters: title: Moneyball script: source: _score * 1.7 - - synopsis: Search by Image - Invalid Model. - path: /{index}/_search - method: POST - parameters: - index: movies - request: - payload: - _source: - excludes: [passage_embedding] - query: - neural: - passage_embedding: - query_image: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII= - model_id: invalid # This makes the test fail with a 404 but will still validate the query_image. - k: 100 - response: - status: 404 - synopsis: Undeploy a model. path: /_plugins/_ml/models/{model_id}/_undeploy method: POST diff --git a/tests/plugins/ml/ingest/pipeline/search_by_image.yaml b/tests/plugins/ml/ingest/pipeline/search_by_image.yaml new file mode 100644 index 000000000..e4fc46e61 --- /dev/null +++ b/tests/plugins/ml/ingest/pipeline/search_by_image.yaml @@ -0,0 +1,26 @@ +$schema: ../../../../../json_schemas/test_story.schema.yaml + +description: Test search by image. +distributions: + excluded: + - amazon-managed + - amazon-serverless +version: '>= 2.11' +chapters: + - synopsis: Search by Image - Invalid Model. + path: /{index}/_search + method: POST + parameters: + index: movies + request: + payload: + _source: + excludes: [passage_embedding] + query: + neural: + passage_embedding: + query_image: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII= + model_id: invalid # This makes the test fail with a 404 but will still validate the query_image. + k: 100 + response: + status: 404 diff --git a/tools/src/linter/SchemasValidator.ts b/tools/src/linter/SchemasValidator.ts index c463e49d9..9e8418688 100644 --- a/tools/src/linter/SchemasValidator.ts +++ b/tools/src/linter/SchemasValidator.ts @@ -50,8 +50,8 @@ export default class SchemasValidator { const message = this.json_validator.validate_schema(_schema) if (message == null) return - const file = `schemas/${key.split(':')[0]}.yaml` - const location = `#/components/schemas/${key.split(':')[1]}` + const file = `schemas/${key.split('___')[0]}.yaml` + const location = `#/components/schemas/${key.split('___')[1]}` return this.error(file, location, message) }).filter((error) => error != null) as ValidationError[] } @@ -61,9 +61,9 @@ export default class SchemasValidator { const message = this.json_validator.validate_schema(param.schema) if (message == null) return - const namespace = this.group_to_namespace(key.split('::')[0]) + const namespace = this.group_to_namespace(key.split('___')[0]) const file = namespace === '_global' ? '_global_parameters.yaml' : `namespaces/${namespace}.yaml` - const location = namespace === '_global' ? param.name as string : `#/components/parameters/${key}` + const location = namespace === '_global' ? param.name as string : `#/components/parameters/${key}`.replace('___', '::') return this.error(file, location, message) }).filter((error) => error != null) as ValidationError[] } @@ -78,9 +78,9 @@ export default class SchemasValidator { validate_response_schemas (): ValidationError[] { return Object.entries(this.spec.responses as Record).flatMap(([key, response]) => { - const namespace = this.group_to_namespace(key.split('@')[0]) + const namespace = this.group_to_namespace(key.split('___')[0]) const file = `namespaces/${namespace}.yaml` - const location = `#/components/responses/${key}` + const location = `#/components/responses/${key}`.replace('___', '@') const content = response.content as Record return this.validate_content_schemas(file, location, content) }) diff --git a/tools/src/merger/OpenApiMerger.ts b/tools/src/merger/OpenApiMerger.ts index ff8cd7d06..9ea66265d 100644 --- a/tools/src/merger/OpenApiMerger.ts +++ b/tools/src/merger/OpenApiMerger.ts @@ -53,8 +53,11 @@ export default class OpenApiMerger { this.#merge_schemas() this.#merge_namespaces() this.#sort_spec_keys() + this.#add_defaults() + this.#fix_refs() this.#generate_global_params() this.#generate_superseded_ops() + this.#normalize_fields() this._merged = true } @@ -134,6 +137,58 @@ export default class OpenApiMerger { }) } + #fix_refs(obj: any = this._spec.components): void { + if (obj?.$ref !== undefined) { + if (obj?.description !== undefined) { + delete obj?.description + } + } + + for (const key in obj) { + var item = obj[key] + if (_.isObject(item) || _.isArray(item)) { + this.#fix_refs(item) + } + } + } + + #normalize_key(key: string): string { + return key + .replaceAll('::', '___') + .replaceAll('@', '___') + .replaceAll(':', '___') + } + + #normalize_fields(obj: any = this._spec): void { + for (const key in obj) { + var item = obj[key] + + if (item?.$ref !== undefined) { + var renamed_ref = this.#normalize_key(item.$ref as string) + if (renamed_ref != item.$ref) { + item.$ref = renamed_ref + } + } + + var renamed_key = this.#normalize_key(key) + if (renamed_key != key) { + obj[renamed_key] = obj[key] + delete obj[key] + } + + if (_.isObject(item) || _.isArray(item)) { + this.#normalize_fields(item) + } + } + } + + #add_defaults(): void { + // Add default descriptions + Object.entries(this._spec.components.responses as Document).forEach(([_path, response_item]) => { + if (response_item.description === undefined) response_item.description = '' + }) + } + // Generate global parameters from _global_params.yaml file. #generate_global_params (): void { const gen = new GlobalParamsGenerator(this.root_folder) diff --git a/tools/src/tester/ChapterReader.ts b/tools/src/tester/ChapterReader.ts index f85e6fdc6..ad34d715b 100644 --- a/tools/src/tester/ChapterReader.ts +++ b/tools/src/tester/ChapterReader.ts @@ -61,9 +61,8 @@ export default class ChapterReader { } else { response.status = e.response.status response.content_type = e.response.headers['content-type']?.split(';')[0] - const payload = this.#deserialize_payload(e.response.data, response.content_type) - if (payload !== undefined) response.payload = payload.error ?? payload - response.message = payload.error?.reason ?? e.response.statusText + response.payload = this.#deserialize_payload(e.response.data, response.content_type) + response.message = response.payload.error?.reason ?? e.response.statusText this.logger.info(`<= ${response.status} (${response.content_type}) | ${response.payload !== undefined ? to_json(response.payload) : response.message}`) } }) diff --git a/tools/src/tester/TestRunner.ts b/tools/src/tester/TestRunner.ts index 6317ef392..77fe2df6d 100644 --- a/tools/src/tester/TestRunner.ts +++ b/tools/src/tester/TestRunner.ts @@ -19,6 +19,7 @@ import type StoryValidator from "./StoryValidator"; import { OpenSearchHttpClient } from 'OpenSearchHttpClient' import * as ansi from './Ansi' import _ from 'lodash' +import { Logger } from 'Logger' export default class TestRunner { private readonly _http_client: OpenSearchHttpClient @@ -26,12 +27,14 @@ export default class TestRunner { private readonly _story_evaluator: StoryEvaluator private readonly _result_logger: ResultLogger private readonly _story_files: Record = {} + private readonly _logger: Logger - constructor (http_client: OpenSearchHttpClient, story_validator: StoryValidator, story_evaluator: StoryEvaluator, result_logger: ResultLogger) { + constructor (http_client: OpenSearchHttpClient, story_validator: StoryValidator, story_evaluator: StoryEvaluator, result_logger: ResultLogger, logger: Logger) { this._http_client = http_client this._story_validator = story_validator this._story_evaluator = story_evaluator this._result_logger = result_logger + this._logger = logger } async run (story_path: string, version?: string, distribution?: string, dry_run: boolean = false): Promise<{ results: StoryEvaluations, failed: boolean }> { @@ -52,6 +55,7 @@ export default class TestRunner { } for (const story_file of story_files) { + this._logger.info(`Evaluating ${story_file.display_path} ...`) const evaluation = this._story_validator.validate(story_file) ?? await this._story_evaluator.evaluate(story_file, version, distribution, dry_run) results.evaluations.push(evaluation) this._result_logger.log(evaluation) diff --git a/tools/src/tester/test.ts b/tools/src/tester/test.ts index e781e343c..77351fe75 100644 --- a/tools/src/tester/test.ts +++ b/tools/src/tester/test.ts @@ -75,7 +75,7 @@ const supplemental_chapter_evaluator = new SupplementalChapterEvaluator(chapter_ const story_validator = new StoryValidator() const story_evaluator = new StoryEvaluator(chapter_evaluator, supplemental_chapter_evaluator) const result_logger = new ConsoleResultLogger(opts.tabWidth, opts.verbose) -const runner = new TestRunner(http_client, story_validator, story_evaluator, result_logger) +const runner = new TestRunner(http_client, story_validator, story_evaluator, result_logger, logger) runner.run(opts.testsPath, spec.api_version(), opts.opensearchDistribution, opts.dryRun) .then( diff --git a/tools/src/validate-spec-py/Pipfile b/tools/src/validate-spec-py/Pipfile new file mode 100644 index 000000000..fa5bb05f6 --- /dev/null +++ b/tools/src/validate-spec-py/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +openapi_spec_validator = "*" + +[dev-packages] + +[requires] +python_version = "3" \ No newline at end of file diff --git a/tools/src/validate-spec-py/Pipfile.lock b/tools/src/validate-spec-py/Pipfile.lock new file mode 100644 index 000000000..cbb761748 --- /dev/null +++ b/tools/src/validate-spec-py/Pipfile.lock @@ -0,0 +1,455 @@ +{ + "_meta": { + "hash": { + "sha256": "8b96bf24637f13e9b0dd9a291f35f43962b4918dd76e52d5e7459c5ac620cdc4" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "attrs": { + "hashes": [ + "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", + "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2" + ], + "markers": "python_version >= '3.7'", + "version": "==24.2.0" + }, + "certifi": { + "hashes": [ + "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + ], + "markers": "python_version >= '3.6'", + "version": "==2024.8.30" + }, + "charset-normalizer": { + "hashes": [ + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.4.0" + }, + "idna": { + "hashes": [ + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" + ], + "markers": "python_version >= '3.6'", + "version": "==3.10" + }, + "jsonschema": { + "hashes": [ + "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", + "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566" + ], + "markers": "python_version >= '3.8'", + "version": "==4.23.0" + }, + "jsonschema-path": { + "hashes": [ + "sha256:203aff257f8038cd3c67be614fe6b2001043408cb1b4e36576bc4921e09d83c4", + "sha256:f02e5481a4288ec062f8e68c808569e427d905bedfecb7f2e4c69ef77957c382" + ], + "markers": "python_full_version >= '3.8.0' and python_full_version < '4.0.0'", + "version": "==0.3.3" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", + "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.12.1" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56", + "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4", + "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8", + "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282", + "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757", + "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424", + "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b", + "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255", + "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70", + "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94", + "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074", + "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c", + "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee", + "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9", + "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9", + "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69", + "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f", + "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3", + "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9", + "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d", + "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977", + "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b", + "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43", + "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658", + "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a", + "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd", + "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83", + "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4", + "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696", + "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05", + "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3", + "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6", + "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895", + "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4", + "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba", + "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03", + "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c" + ], + "markers": "python_version >= '3.8'", + "version": "==1.10.0" + }, + "openapi-schema-validator": { + "hashes": [ + "sha256:11a95c9c9017912964e3e5f2545a5b11c3814880681fcacfb73b1759bb4f2804", + "sha256:c4887c1347c669eb7cded9090f4438b710845cd0f90d1fb9e1b3303fb37339f8" + ], + "markers": "python_full_version >= '3.8.0' and python_full_version < '4.0.0'", + "version": "==0.6.2" + }, + "openapi-spec-validator": { + "hashes": [ + "sha256:3c81825043f24ccbcd2f4b149b11e8231abce5ba84f37065e14ec947d8f4e959", + "sha256:8577b85a8268685da6f8aa30990b83b7960d4d1117e901d451b5d572605e5ec7" + ], + "markers": "python_full_version >= '3.8.0' and python_full_version < '4.0.0'", + "version": "==0.7.1" + }, + "pathable": { + "hashes": [ + "sha256:5c869d315be50776cc8a993f3af43e0c60dc01506b399643f919034ebf4cdcab", + "sha256:cdd7b1f9d7d5c8b8d3315dbf5a86b2596053ae845f056f57d97c0eefff84da14" + ], + "markers": "python_full_version >= '3.7.0' and python_full_version < '4.0.0'", + "version": "==0.4.3" + }, + "pyyaml": { + "hashes": [ + "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", + "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", + "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", + "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", + "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", + "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", + "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", + "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", + "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", + "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", + "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a", + "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", + "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", + "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", + "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", + "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", + "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", + "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a", + "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", + "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", + "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", + "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", + "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", + "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", + "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", + "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", + "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", + "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", + "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", + "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706", + "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", + "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", + "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", + "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083", + "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", + "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", + "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", + "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", + "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", + "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", + "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", + "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", + "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", + "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", + "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5", + "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d", + "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", + "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", + "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", + "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", + "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", + "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", + "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.2" + }, + "referencing": { + "hashes": [ + "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", + "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de" + ], + "markers": "python_version >= '3.8'", + "version": "==0.35.1" + }, + "requests": { + "hashes": [ + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" + ], + "markers": "python_version >= '3.8'", + "version": "==2.32.3" + }, + "rfc3339-validator": { + "hashes": [ + "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", + "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.1.4" + }, + "rpds-py": { + "hashes": [ + "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", + "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", + "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5", + "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6", + "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef", + "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2", + "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29", + "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318", + "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b", + "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399", + "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739", + "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee", + "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", + "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a", + "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344", + "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2", + "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03", + "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5", + "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22", + "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e", + "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96", + "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", + "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752", + "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075", + "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253", + "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee", + "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad", + "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5", + "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce", + "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7", + "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b", + "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", + "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", + "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3", + "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec", + "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209", + "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921", + "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", + "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074", + "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580", + "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", + "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5", + "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3", + "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0", + "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", + "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", + "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db", + "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", + "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789", + "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f", + "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", + "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c", + "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232", + "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6", + "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c", + "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", + "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489", + "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94", + "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751", + "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", + "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda", + "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", + "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51", + "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c", + "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8", + "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989", + "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511", + "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1", + "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2", + "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150", + "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c", + "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965", + "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f", + "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58", + "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b", + "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", + "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d", + "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821", + "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de", + "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121", + "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855", + "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272", + "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60", + "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", + "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1", + "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140", + "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", + "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940", + "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364", + "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4", + "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e", + "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420", + "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5", + "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24", + "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c", + "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf", + "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f", + "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e", + "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab", + "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08", + "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92", + "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", + "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8" + ], + "markers": "python_version >= '3.8'", + "version": "==0.20.0" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.16.0" + }, + "urllib3": { + "hashes": [ + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.3" + } + }, + "develop": {} +} diff --git a/tools/src/validate-spec-py/validate.py b/tools/src/validate-spec-py/validate.py new file mode 100644 index 000000000..9739c51f6 --- /dev/null +++ b/tools/src/validate-spec-py/validate.py @@ -0,0 +1,20 @@ +import sys + +from openapi_spec_validator import validate +from openapi_spec_validator.readers import read_from_filename +from openapi_spec_validator.validation.exceptions import OpenAPIValidationError + +if len(sys.argv) < 2: + print("syntax: validate.py [spec]") + exit(1) + +spec = sys.argv[1] +print(f'Validating {spec} ...') + +spec_dict, base_uri = read_from_filename(spec) + +try: + validate(spec_dict) +except OpenAPIValidationError as err: + print(err) + exit(2) diff --git a/tools/src/validate-spec-ruby/Gemfile b/tools/src/validate-spec-ruby/Gemfile new file mode 100644 index 000000000..a7a8f3b53 --- /dev/null +++ b/tools/src/validate-spec-ruby/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'json_schemer' diff --git a/tools/src/validate-spec-ruby/Gemfile.lock b/tools/src/validate-spec-ruby/Gemfile.lock new file mode 100644 index 000000000..f6926e79f --- /dev/null +++ b/tools/src/validate-spec-ruby/Gemfile.lock @@ -0,0 +1,22 @@ +GEM + remote: https://rubygems.org/ + specs: + bigdecimal (3.1.8) + hana (1.3.7) + json_schemer (2.3.0) + bigdecimal + hana (~> 1.3) + regexp_parser (~> 2.0) + simpleidn (~> 0.2) + regexp_parser (2.9.2) + simpleidn (0.2.3) + +PLATFORMS + arm64-darwin-21 + ruby + +DEPENDENCIES + json_schemer + +BUNDLED WITH + 2.5.2 diff --git a/tools/src/validate-spec-ruby/validate.rb b/tools/src/validate-spec-ruby/validate.rb new file mode 100644 index 000000000..261cfd360 --- /dev/null +++ b/tools/src/validate-spec-ruby/validate.rb @@ -0,0 +1,20 @@ +require 'json_schemer' +require 'yaml' + +raise 'syntax: validate [spec]' unless ARGV.length >= 1 + +spec = ARGV[0] +puts "Validating #{spec} ..." + +schemer = JSONSchemer.openapi(YAML.load_file(spec)) +schemer.validate + +total_errors = 0 +schemer.validate.each do |error| + puts "#{error['data']}: #{error['error']}" if total_errors < 10 + total_errors += 1 +end + +puts total_errors > 0 ? " .... #{total_errors} total." : "Done." + +exit total_errors == 0 ? 0 : 1 diff --git a/tools/tests/merger/fixtures/extractor/opensearch/expected_1.3.yaml b/tools/tests/merger/fixtures/extractor/opensearch/expected_1.3.yaml index 24d08aa4d..eafc740f0 100644 --- a/tools/tests/merger/fixtures/extractor/opensearch/expected_1.3.yaml +++ b/tools/tests/merger/fixtures/extractor/opensearch/expected_1.3.yaml @@ -12,33 +12,33 @@ paths: x-version-added: '1.0' description: Returns information about nodes in the cluster. parameters: - - $ref: '#/components/parameters/nodes.info::path.id' + - $ref: '#/components/parameters/nodes.info___path.id' responses: '200': - $ref: '#/components/responses/nodes.info@200' + $ref: '#/components/responses/nodes.info___200' /index: get: operationId: get.0 responses: '200': - $ref: '#/components/responses/info@200' + $ref: '#/components/responses/info___200' '201': - $ref: '#/components/responses/info@201' + $ref: '#/components/responses/info___201' '404': - $ref: '#/components/responses/info@404' + $ref: '#/components/responses/info___404' '500': - $ref: '#/components/responses/info@500' + $ref: '#/components/responses/info___500' '503': - $ref: '#/components/responses/info@503' + $ref: '#/components/responses/info___503' removed-2.0: - $ref: '#/components/responses/info@removed-2.0' + $ref: '#/components/responses/info___removed-2.0' x-version-removed: '2.0' removed-2.0-refs: - $ref: '#/components/responses/info@removed-2.0-refs' + $ref: '#/components/responses/info___removed-2.0-refs' added-1.3-removed-2.0: - $ref: '#/components/responses/info@added-1.3-removed-2.0' + $ref: '#/components/responses/info___added-1.3-removed-2.0' distributed-excluded-amazon-serverless: - $ref: '#/components/responses/info@distributed-all' + $ref: '#/components/responses/info___distributed-all' x-distributions-excluded: - amazon-serverless parameters: [] @@ -47,11 +47,11 @@ paths: operationId: nodes.0 responses: '200': - $ref: '#/components/responses/nodes.info@200' + $ref: '#/components/responses/nodes.info___200' parameters: [] components: parameters: - nodes.info::path.id: + nodes.info___path.id: in: path name: id description: Node ID. @@ -60,19 +60,20 @@ components: type: string requestBodies: {} responses: - info@200: + info___200: content: application/json: schema: type: object properties: _type: - $ref: '#/components/schemas/_common:Type' + $ref: '#/components/schemas/_common___Type' tagline: type: string required: - tagline - info@201: + description: '' + info___201: content: application/json: schema: @@ -83,7 +84,8 @@ components: required: - tagline unevaluatedProperties: true - info@404: + description: '' + info___404: content: application/json: schema: @@ -95,7 +97,8 @@ components: - tagline unevaluatedProperties: type: object - info@500: + description: '' + info___500: content: application/json: schema: @@ -103,34 +106,36 @@ components: properties: tagline: type: string - info@503: + description: '' + info___503: content: application/json: schema: type: object - info@added-1.3-removed-2.0: + description: '' + info___added-1.3-removed-2.0: description: Added in 1.3, removed in 2.0 via attribute in response body. x-version-added: '1.3' x-version-removed: '2.0' - info@distributed-all: + info___distributed-all: description: Distributed in opensearch.org, AOS and AOSS. - info@removed-2.0: + info___removed-2.0: description: Removed in 2.0 via attribute next to ref. - info@removed-2.0-refs: + info___removed-2.0-refs: description: One of the ref values removed in 2.0. schema: oneOf: - - $ref: '#/components/schemas/_common:Type' - - $ref: '#/components/schemas/_common:OldId' - nodes.info@200: + - $ref: '#/components/schemas/_common___Type' + - $ref: '#/components/schemas/_common___OldId' + nodes.info___200: description: All nodes. content: application/json: schema: type: object schemas: - _common:OldId: + _common___OldId: type: string - _common:Type: + _common___Type: type: string x-version-removed: '2.0' diff --git a/tools/tests/merger/fixtures/extractor/opensearch/expected_2.0.yaml b/tools/tests/merger/fixtures/extractor/opensearch/expected_2.0.yaml index a824f4787..b287d6982 100644 --- a/tools/tests/merger/fixtures/extractor/opensearch/expected_2.0.yaml +++ b/tools/tests/merger/fixtures/extractor/opensearch/expected_2.0.yaml @@ -12,25 +12,25 @@ paths: x-version-added: '1.0' description: Returns information about nodes in the cluster. parameters: - - $ref: '#/components/parameters/nodes.info::path.id' + - $ref: '#/components/parameters/nodes.info___path.id' responses: '200': - $ref: '#/components/responses/nodes.info@200' + $ref: '#/components/responses/nodes.info___200' post: operationId: nodes.info.1 x-operation-group: nodes.info x-version-added: '2.0' description: Returns information about nodes in the cluster. parameters: - - $ref: '#/components/parameters/nodes.info::path.id' - - $ref: '#/components/parameters/nodes.info::query.flag' + - $ref: '#/components/parameters/nodes.info___path.id' + - $ref: '#/components/parameters/nodes.info___query.flag' requestBody: $ref: '#/components/requestBodies/nodes.info' responses: '200': - $ref: '#/components/responses/nodes.info@200' + $ref: '#/components/responses/nodes.info___200' '201': - $ref: '#/components/responses/nodes.info@201' + $ref: '#/components/responses/nodes.info___201' /cluster_manager: get: operationId: cluster_manager.0 @@ -45,22 +45,22 @@ paths: operationId: get.0 responses: '200': - $ref: '#/components/responses/info@200' + $ref: '#/components/responses/info___200' '201': - $ref: '#/components/responses/info@201' + $ref: '#/components/responses/info___201' '404': - $ref: '#/components/responses/info@404' + $ref: '#/components/responses/info___404' '500': - $ref: '#/components/responses/info@500' + $ref: '#/components/responses/info___500' '503': - $ref: '#/components/responses/info@503' + $ref: '#/components/responses/info___503' added-2.0: - $ref: '#/components/responses/info@added-2.0' + $ref: '#/components/responses/info___added-2.0' x-version-added: '2.0' removed-2.0-refs: - $ref: '#/components/responses/info@removed-2.0-refs' + $ref: '#/components/responses/info___removed-2.0-refs' distributed-excluded-amazon-serverless: - $ref: '#/components/responses/info@distributed-all' + $ref: '#/components/responses/info___distributed-all' x-distributions-excluded: - amazon-serverless parameters: [] @@ -69,18 +69,18 @@ paths: operationId: nodes.0 responses: '200': - $ref: '#/components/responses/nodes.info@200' + $ref: '#/components/responses/nodes.info___200' parameters: [] components: parameters: - nodes.info::path.id: + nodes.info___path.id: in: path name: id description: Node ID. required: true schema: type: string - nodes.info::query.flag: + nodes.info___query.flag: in: query name: flag description: Flag. @@ -98,11 +98,11 @@ components: _all: type: boolean ids: - $ref: '#/components/schemas/_common:Ids' + $ref: '#/components/schemas/_common___Ids' x-version-added: '2.0' description: Nodes options. responses: - info@200: + info___200: content: application/json: schema: @@ -112,7 +112,8 @@ components: type: string required: - tagline - info@201: + description: '' + info___201: content: application/json: schema: @@ -123,7 +124,8 @@ components: required: - tagline unevaluatedProperties: true - info@404: + description: '' + info___404: content: application/json: schema: @@ -135,7 +137,8 @@ components: - tagline unevaluatedProperties: type: object - info@500: + description: '' + info___500: content: application/json: schema: @@ -143,38 +146,40 @@ components: properties: tagline: type: string - info@503: + description: '' + info___503: content: application/json: schema: type: object - info@added-2.0: + description: '' + info___added-2.0: description: Added in 2.0 via attribute next to ref. - info@distributed-all: + info___distributed-all: description: Distributed in opensearch.org, AOS and AOSS. - info@removed-2.0-refs: + info___removed-2.0-refs: description: One of the ref values removed in 2.0. schema: oneOf: - - $ref: '#/components/schemas/_common:OldId' - nodes.info@200: + - $ref: '#/components/schemas/_common___OldId' + nodes.info___200: description: All nodes. content: application/json: schema: type: object - nodes.info@201: + nodes.info___201: description: All nodes. content: application/json: schema: type: object schemas: - _common:Ids: + _common___Ids: oneOf: - - $ref: '#/components/schemas/_common:OldId' + - $ref: '#/components/schemas/_common___OldId' - type: array items: - $ref: '#/components/schemas/_common:Ids' - _common:OldId: + $ref: '#/components/schemas/_common___Ids' + _common___OldId: type: string diff --git a/tools/tests/merger/fixtures/merger/animals/expected.yaml b/tools/tests/merger/fixtures/merger/animals/expected.yaml index 789d1f203..a28b20af2 100644 --- a/tools/tests/merger/fixtures/merger/animals/expected.yaml +++ b/tools/tests/merger/fixtures/merger/animals/expected.yaml @@ -7,54 +7,54 @@ paths: /{index}: post: parameters: - - $ref: '#/components/parameters/indices.create::path.index' - - $ref: '#/components/parameters/indices.create::query.pretty' - - $ref: '#/components/parameters/indices.create::query.wait_for_active_shards' - - $ref: '#/components/parameters/_global::query.human' + - $ref: '#/components/parameters/indices.create___path.index' + - $ref: '#/components/parameters/indices.create___query.pretty' + - $ref: '#/components/parameters/indices.create___query.wait_for_active_shards' + - $ref: '#/components/parameters/_global___query.human' requestBody: $ref: '#/components/requestBodies/indices.create' responses: '200': - $ref: '#/components/responses/indices.create@200' + $ref: '#/components/responses/indices.create___200' '201': - $ref: '#/components/responses/indices.create@201' + $ref: '#/components/responses/indices.create___201' x-version-added: '2.0' /adopt/{animal}/dockets/{docket}: get: operationId: adopt.0 parameters: - - $ref: '#/components/parameters/adopt::path.animal' - - $ref: '#/components/parameters/adopt::path.docket' - - $ref: '#/components/parameters/_global::query.human' + - $ref: '#/components/parameters/adopt___path.animal' + - $ref: '#/components/parameters/adopt___path.docket' + - $ref: '#/components/parameters/_global___query.human' responses: '200': - $ref: '#/components/responses/adopt@200' + $ref: '#/components/responses/adopt___200' post: operationId: adopt.1 parameters: - - $ref: '#/components/parameters/adopt::path.animal' - - $ref: '#/components/parameters/adopt::path.docket' - - $ref: '#/components/parameters/_global::query.human' + - $ref: '#/components/parameters/adopt___path.animal' + - $ref: '#/components/parameters/adopt___path.docket' + - $ref: '#/components/parameters/_global___query.human' requestBody: $ref: '#/components/requestBodies/adopt' responses: '200': - $ref: '#/components/responses/adopt@200' + $ref: '#/components/responses/adopt___200' /replaced/adopting/{animal}/something/{docket}: get: operationId: adopt.0_superseded parameters: - - $ref: '#/components/parameters/adopt::path.animal' - - $ref: '#/components/parameters/adopt::path.docket' - - $ref: '#/components/parameters/_global::query.human' + - $ref: '#/components/parameters/adopt___path.animal' + - $ref: '#/components/parameters/adopt___path.docket' + - $ref: '#/components/parameters/_global___query.human' responses: '200': - $ref: '#/components/responses/adopt@200' + $ref: '#/components/responses/adopt___200' deprecated: true x-ignorable: true components: parameters: - _global::query.human: + _global___query.human: name: human in: query description: Whether to return human readable values for statistics. @@ -62,27 +62,27 @@ components: type: boolean default: true x-global: true - adopt::path.animal: + adopt___path.animal: name: animal in: path schema: - $ref: '#/components/schemas/animals:Animal' - adopt::path.docket: + $ref: '#/components/schemas/animals___Animal' + adopt___path.docket: name: docket in: path schema: type: number - indices.create::path.index: + indices.create___path.index: name: index in: path schema: type: string - indices.create::query.pretty: + indices.create___query.pretty: name: pretty in: query schema: type: boolean - indices.create::query.wait_for_active_shards: + indices.create___query.wait_for_active_shards: name: pretty in: query x-version-added: '2.0' @@ -94,35 +94,37 @@ components: name: type: string responses: - adopt@200: + adopt___200: application/json: schema: type: object - indices.create@200: + description: '' + indices.create___200: application/json: schema: type: object - indices.create@201: + description: '' + indices.create___201: description: Added in 2.0. application/json: schema: type: object schemas: - actions:Bark: + actions___Bark: type: string - actions:Meow: + actions___Meow: type: string - animals:Animal: + animals___Animal: oneOf: - - $ref: '#/components/schemas/animals:Dog' - - $ref: '#/components/schemas/animals:Cat' - animals:Cat: + - $ref: '#/components/schemas/animals___Dog' + - $ref: '#/components/schemas/animals___Cat' + animals___Cat: type: object properties: meow: - $ref: '#/components/schemas/actions:Meow' - animals:Dog: + $ref: '#/components/schemas/actions___Meow' + animals___Dog: type: object properties: bark: - $ref: '#/components/schemas/actions:Bark' + $ref: '#/components/schemas/actions___Bark' diff --git a/tools/tests/tester/ChapterReader.test.ts b/tools/tests/tester/ChapterReader.test.ts index 38a0b82fc..2b0c2eb42 100644 --- a/tools/tests/tester/ChapterReader.test.ts +++ b/tools/tests/tester/ChapterReader.test.ts @@ -248,6 +248,35 @@ describe('ChapterReader', () => { message: 'Not Found' }); }); + + it('sets payload to entire response when payload.error is present', async () => { + const mock_payload = { '_data': '1', 'result': 'updated', 'error': 'error' }; + const mock_error = { + response: { + status: 404, + headers: { + 'content-type': 'application/json' + }, + data: JSON.stringify(mock_payload), + statusText: 'Not Found' + } + }; + + mocked_axios.request.mockRejectedValue(mock_error); + + const result = await reader.read({ + id: 'id', + path: 'path', + method: 'POST' + }, new StoryOutputs()); + + expect(result).toStrictEqual({ + status: 404, + content_type: 'application/json', + payload: mock_payload, + message: 'Not Found' + }); + }); }) describe('deserialize_payload', () => { diff --git a/tools/tests/tester/MergedOpenApiSpec.test.ts b/tools/tests/tester/MergedOpenApiSpec.test.ts index 3857cae52..54d65b60e 100644 --- a/tools/tests/tester/MergedOpenApiSpec.test.ts +++ b/tools/tests/tester/MergedOpenApiSpec.test.ts @@ -40,27 +40,27 @@ describe('merged API spec', () => { const responses: any = spec.spec().components?.responses test('is added with required fields', () => { - const schema = responses['info@200'].content['application/json'].schema + const schema = responses.info___200.content['application/json'].schema expect(schema.unevaluatedProperties).toEqual({ not: true, errorMessage: 'property is not defined in the spec' }) }) test('is added when no required fields', () => { - const schema = responses['info@500'].content['application/json'].schema + const schema = responses.info___500.content['application/json'].schema expect(schema.unevaluatedProperties).toEqual({ not: true, errorMessage: 'property is not defined in the spec' }) }) test('is not added to empty object schema', () => { - const schema = responses['info@503'].content['application/json'].schema + const schema = responses.info___503.content['application/json'].schema expect(schema.unevaluatedProperties).toBeUndefined() }) test('is not added when true', () => { - const schema = responses['info@201'].content['application/json'].schema + const schema = responses.info___201.content['application/json'].schema expect(schema.unevaluatedProperties).toEqual(true) }) test('is not added when object', () => { - const schema = responses['info@404'].content['application/json'].schema + const schema = responses.info___404.content['application/json'].schema expect(schema.unevaluatedProperties).toEqual({ type: 'object' }) }) }) diff --git a/tools/tests/tester/helpers.ts b/tools/tests/tester/helpers.ts index 354fcabe4..399c1359e 100644 --- a/tools/tests/tester/helpers.ts +++ b/tools/tests/tester/helpers.ts @@ -54,7 +54,7 @@ export function construct_tester_components (spec_path: string): { const story_validator = new StoryValidator() const story_evaluator = new StoryEvaluator(chapter_evaluator, supplemental_chapter_evaluator) const result_logger = new NoOpResultLogger() - const test_runner = new TestRunner(opensearch_http_client, story_validator, story_evaluator, result_logger) + const test_runner = new TestRunner(opensearch_http_client, story_validator, story_evaluator, result_logger, logger) return { specification, operation_locator,