diff --git a/CHANGELOG.md b/CHANGELOG.md index 3687ac3d..23e37961 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,6 +94,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added `xy_shape` query ([#531](https://github.com/opensearch-project/opensearch-api-specification/pull/531)) - Added `/_plugins/_flow_framework/` ,`_search`,`state/_search`,`_provision`,`_deprovision`,`_steps`,`_status`([#508](https://github.com/opensearch-project/opensearch-api-specification/issues/508)) - Added `/_plugins/_ism/policies`, `add`, `remove`, `change_policy`, `explain` ([#568](https://github.com/opensearch-project/opensearch-api-specification/pull/568)) +- Added more 4xx errors to `/_plugins/_flow_framework/` and added sample template test ([#833](https://github.com/opensearch-project/flow-framework/issues/833) ### Changed diff --git a/spec/namespaces/flow_framework.yaml b/spec/namespaces/flow_framework.yaml index e3a3e005..feed463e 100644 --- a/spec/namespaces/flow_framework.yaml +++ b/spec/namespaces/flow_framework.yaml @@ -412,6 +412,10 @@ components: - $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: @@ -423,6 +427,9 @@ components: - $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: diff --git a/spec/schemas/flow_framework.common.yaml b/spec/schemas/flow_framework.common.yaml index a8d7d7c0..d3ab4ae9 100644 --- a/spec/schemas/flow_framework.common.yaml +++ b/spec/schemas/flow_framework.common.yaml @@ -65,6 +65,8 @@ components: use_case: type: string description: A use case, which can be used with the Search Workflow API to find related workflows. + workflows: + type: object version: $ref: '#/components/schemas/version' minProperties: 1 diff --git a/spec/schemas/flow_framework.errors.yaml b/spec/schemas/flow_framework.errors.yaml index 6f46f243..879cf7fe 100644 --- a/spec/schemas/flow_framework.errors.yaml +++ b/spec/schemas/flow_framework.errors.yaml @@ -11,7 +11,7 @@ components: application/json: type: object properties: - message: + error: type: string example: This API is disabled. To enable it, set [flow_framework.enabled] to true. status: @@ -21,7 +21,7 @@ components: application/json: type: object properties: - message: + error: type: string example: Only the parameters [param1, param2] are permitted unless the provision parameter is set to true. status: @@ -31,7 +31,7 @@ components: application/json: type: object properties: - message: + error: type: string example: You cannot use both the 'provision_workflow' and 'update_workflow_fields' parameters in the same request. status: @@ -41,7 +41,7 @@ components: application/json: type: object properties: - message: + error: type: string example: You cannot use the 'reprovision_workflow' parameter to create a new template. status: @@ -51,7 +51,7 @@ components: application/json: type: object properties: - message: + error: type: string example: You cannot use the 'reprovision_workflow' and 'use_case' parameters in the same request. status: @@ -61,7 +61,7 @@ components: application/json: type: object properties: - message: + error: type: string example: Workflow ID can not be null status: @@ -100,7 +100,7 @@ components: application/json: type: object properties: - message: + error: type: string example: Failed to save workflow state status: @@ -110,27 +110,60 @@ components: application/json: type: object properties: - message: + error: type: string example: Maximum workflows limit reached 50 code: type: integer + TemplateNameRequiredError: + type: object + properties: + error: + type: string + description: Error message when the template name is missing. TemplateNotFoundError: content: application/json: type: object properties: - message: + 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. + 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. + 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. WorkflowStepsRetrieveError: content: application/json: type: object properties: - message: + error: type: string example: Failed to retrieve workflow step json. code: diff --git a/tests/default/flow_framework/deprovision.yaml b/tests/default/flow_framework/deprovision.yaml index 43babeeb..dada6f1f 100644 --- a/tests/default/flow_framework/deprovision.yaml +++ b/tests/default/flow_framework/deprovision.yaml @@ -25,16 +25,6 @@ epilogues: parameters: workflow_id: ${create_flow_framework.test_workflow_id} chapters: - - synopsis: Check the provision status before calling the deprovision API. - path: /_plugins/_flow_framework/workflow/{workflow_id}/_status - method: GET - parameters: - workflow_id: ${create_flow_framework.test_workflow_id} - response: - status: 200 - payload: - workflow_id: ${create_flow_framework.test_workflow_id} - state: PROVISIONING - synopsis: Deprovision workflow. path: /_plugins/_flow_framework/workflow/{workflow_id}/_deprovision method: POST @@ -42,16 +32,6 @@ chapters: workflow_id: ${create_flow_framework.test_workflow_id} response: status: 200 - - synopsis: Check the provision status after calling the deprovision API. - path: /_plugins/_flow_framework/workflow/{workflow_id}/_status - method: GET - parameters: - workflow_id: ${create_flow_framework.test_workflow_id} - response: - status: 200 - payload: - workflow_id: ${create_flow_framework.test_workflow_id} - state: NOT_STARTED - synopsis: Deprovision workflow using an invalid ID. path: /_plugins/_flow_framework/workflow/{workflow_id}/_deprovision method: POST diff --git a/tests/default/flow_framework/provision.yaml b/tests/default/flow_framework/provision.yaml index 2d52e83e..fb1e41a0 100644 --- a/tests/default/flow_framework/provision.yaml +++ b/tests/default/flow_framework/provision.yaml @@ -23,16 +23,6 @@ epilogues: parameters: workflow_id: ${create_flow_framework.test_workflow_id} chapters: - - synopsis: Check the status before calling provision API. - path: /_plugins/_flow_framework/workflow/{workflow_id}/_status - method: GET - parameters: - workflow_id: ${create_flow_framework.test_workflow_id} - response: - status: 200 - payload: - workflow_id: ${create_flow_framework.test_workflow_id} - state: NOT_STARTED - synopsis: Provision workflow. path: /_plugins/_flow_framework/workflow/{workflow_id}/_provision method: POST @@ -42,14 +32,4 @@ chapters: payload: openai_key: '1234556' response: - status: 200 - - synopsis: Check the provision status after calling provision API. - path: /_plugins/_flow_framework/workflow/{workflow_id}/_status - method: GET - parameters: - workflow_id: ${create_flow_framework.test_workflow_id} - response: - status: 200 - payload: - workflow_id: ${create_flow_framework.test_workflow_id} - state: PROVISIONING \ No newline at end of file + status: 200 \ No newline at end of file diff --git a/tests/default/flow_framework/template.yaml b/tests/default/flow_framework/template.yaml new file mode 100644 index 00000000..c7ac780c --- /dev/null +++ b/tests/default/flow_framework/template.yaml @@ -0,0 +1,237 @@ +$schema: ../../../json_schemas/test_story.schema.yaml +description: Test flow_framework endpoints using sample template. +version: '>= 2.12' +epilogues: + - path: /_plugins/_flow_framework/workflow/{workflow_id} + method: DELETE + status: [200, 404] + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} +chapters: + - synopsis: Create workflow with openAI model. + id: create_flow_framework + path: /_plugins/_flow_framework/workflow + method: POST + request: + payload: + name: Deploy OpenAI Model + description: Deploy a model using a connector to OpenAI + use_case: PROVISION + version: + template: 1.0.0 + compatibility: + - 2.12.0 + - 3.0.0 + workflows: + provision: + nodes: + - id: create_openai_connector + type: create_connector + user_inputs: + name: OpenAI Chat Connector + description: The connector to public OpenAI model service for GPT 3.5 + version: '1' + protocol: http + parameters: + endpoint: api.openai.com + model: gpt-3.5-turbo + response_filter: '$.choices[0].message.content' + credential: + openAI_key: '1234556' + actions: + - action_type: predict + method: POST + url: example_url + - id: register_openai_model + type: register_remote_model + previous_node_inputs: + create_openai_connector: connector_id + user_inputs: + name: openAI-gpt-3.5-turbo + - id: deploy_openai_model + type: deploy_model + previous_node_inputs: + register_openai_model: model_id + response: + status: 201 + output: + test_workflow_id: payload.workflow_id + - synopsis: Update workflow. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: PUT + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + update_fields: true + request: + payload: + name: test_update_name + response: + status: 201 + - synopsis: Update workflow field fail without updating the whole template. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: PUT + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + update_fields: true + request: + payload: + workflows: + name: test + response: + status: 400 + - synopsis: Update workflow with updating the whole template. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: PUT + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + request: + payload: + name: Deploy OpenAI Model + description: Deploy a model using a connector to OpenAI + use_case: PROVISION + version: + template: 1.0.0 + compatibility: + - 2.12.0 + - 3.0.0 + workflows: + provision: + nodes: + - id: create_openai_connector + type: create_connector + user_inputs: + name: OpenAI Chat Connector + description: The connector to public OpenAI model service for GPT 3.5 update + version: '1' + protocol: http + parameters: + endpoint: api.openai.com + model: gpt-3.5-turbo + response_filter: '$.choices[0].message.content' + credential: + openAI_key: '1234556' + actions: + - action_type: predict + method: POST + url: example_url + - id: register_openai_model + type: register_remote_model + previous_node_inputs: + create_openai_connector: connector_id + user_inputs: + name: openAI-gpt-3.5-turbo + - id: deploy_openai_model + type: deploy_model + previous_node_inputs: + register_openai_model: model_id + response: + status: 201 + - synopsis: Provision workflow. + path: /_plugins/_flow_framework/workflow/{workflow_id}/_provision + method: POST + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + response: + status: 200 + - synopsis: Update workflow fail With provision and update_fields set true. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: PUT + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + provision: true + update_fields: true + request: + payload: + name: test_create_work_flow + response: + status: 400 + - synopsis: Update workflow fail With Reprovision and updateFields set true. + version: '>= 2.17' + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: PUT + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + reprovision: true + update_fields: true + request: + payload: + name: test_create_work_flow + response: + status: 400 + - synopsis: Create workflow fail With Reprovision set true. + version: '>= 2.17' + path: /_plugins/_flow_framework/workflow + method: POST + parameters: + reprovision: true + request: + payload: + name: test_create_work_flow + response: + status: 400 + - synopsis: Create workflow fail With Reprovision set true and UseCase Not null. + version: '>= 2.17' + path: /_plugins/_flow_framework/workflow + method: POST + parameters: + reprovision: true + use_case: test_use_case + request: + payload: + name: test_create_work_flow + response: + status: 400 + - synopsis: Update workflow fail With Reprovision set true and UseCase Not null. + version: '>= 2.17' + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: PUT + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + reprovision: true + use_case: test_use_case + request: + payload: + name: test_create_work_flow + response: + status: 400 + - synopsis: Get workflow. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: GET + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + response: + status: 200 + - synopsis: Get workflow fail. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: GET + parameters: + workflow_id: invalid + response: + status: 404 + - synopsis: Update workflow with a non-existent workflow ID. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: PUT + parameters: + workflow_id: invalid + request: + payload: + name: test_update_work_flow + response: + status: 404 + - synopsis: Search workflow state. + path: /_plugins/_flow_framework/workflow/state/_search + method: POST + request: + payload: + query: + match: + state: PROVISIONING + response: + status: 200 + - synopsis: Delete workflow. + path: /_plugins/_flow_framework/workflow/{workflow_id} + method: DELETE + parameters: + workflow_id: ${create_flow_framework.test_workflow_id} + response: + status: 200 \ No newline at end of file diff --git a/tests/default/flow_framework/workflow.yaml b/tests/default/flow_framework/workflow.yaml index d136c804..4f50a012 100644 --- a/tests/default/flow_framework/workflow.yaml +++ b/tests/default/flow_framework/workflow.yaml @@ -118,16 +118,6 @@ chapters: name: test_update_work_flow response: status: 404 - - synopsis: Search workflow state. - path: /_plugins/_flow_framework/workflow/state/_search - method: POST - request: - payload: - query: - match: - state: test - response: - status: 200 - synopsis: Delete workflow. path: /_plugins/_flow_framework/workflow/{workflow_id} method: DELETE