Feature/service task part deux (#91)
This commit is contained in:
parent
439f9e55ed
commit
112fe1a0eb
|
@ -847,6 +847,20 @@ paths:
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/Task"
|
$ref: "#/components/schemas/Task"
|
||||||
|
|
||||||
|
/service_tasks:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Service Tasks
|
||||||
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.service_tasks_show
|
||||||
|
summary: Gets all available service task connectors
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: All service task connectors
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ServiceTask"
|
||||||
|
|
||||||
/tasks/{process_instance_id}/{task_id}:
|
/tasks/{process_instance_id}/{task_id}:
|
||||||
parameters:
|
parameters:
|
||||||
- name: task_id
|
- name: task_id
|
||||||
|
@ -1654,6 +1668,32 @@ components:
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: 5
|
example: 5
|
||||||
|
ServiceTask:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
type: array
|
||||||
|
$ref: "#/components/schemas/ServiceTaskConnector"
|
||||||
|
readOnly: true
|
||||||
|
ServiceTaskConnector:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
example: xero/CreateInvoice
|
||||||
|
parameters:
|
||||||
|
type: array
|
||||||
|
$ref: "#/components/schemas/ServiceTaskOperatorParameter"
|
||||||
|
readOnly: true
|
||||||
|
ServiceTaskOperatorParameter:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
example: client_id
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
example: str
|
||||||
|
required:
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
GitRepo:
|
GitRepo:
|
||||||
properties:
|
properties:
|
||||||
# remote:
|
# remote:
|
||||||
|
|
|
@ -34,3 +34,8 @@ OPEN_ID_CLIENT_SECRET_KEY = environ.get(
|
||||||
SPIFFWORKFLOW_BACKEND_LOG_TO_FILE = (
|
SPIFFWORKFLOW_BACKEND_LOG_TO_FILE = (
|
||||||
environ.get("SPIFFWORKFLOW_BACKEND_LOG_TO_FILE", default="false") == "true"
|
environ.get("SPIFFWORKFLOW_BACKEND_LOG_TO_FILE", default="false") == "true"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# service task connector proxy
|
||||||
|
CONNECTOR_PROXY_URL = environ.get(
|
||||||
|
"CONNECTOR_PROXY_URL", default="http://localhost:7004"
|
||||||
|
)
|
||||||
|
|
|
@ -54,6 +54,7 @@ from spiffworkflow_backend.services.process_instance_service import (
|
||||||
ProcessInstanceService,
|
ProcessInstanceService,
|
||||||
)
|
)
|
||||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||||
|
from spiffworkflow_backend.services.service_task_service import ServiceTaskService
|
||||||
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
||||||
|
|
||||||
process_api_blueprint = Blueprint("process_api", __name__)
|
process_api_blueprint = Blueprint("process_api", __name__)
|
||||||
|
@ -652,6 +653,16 @@ def process_instance_report_delete(
|
||||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||||
|
|
||||||
|
|
||||||
|
def service_tasks_show() -> flask.wrappers.Response:
|
||||||
|
"""service_tasks_show."""
|
||||||
|
available_connectors = ServiceTaskService.available_connectors()
|
||||||
|
print(available_connectors)
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
json.dumps(available_connectors), status=200, mimetype="application/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def process_instance_report_show(
|
def process_instance_report_show(
|
||||||
process_group_id: str,
|
process_group_id: str,
|
||||||
process_model_id: str,
|
process_model_id: str,
|
||||||
|
|
|
@ -41,6 +41,7 @@ from SpiffWorkflow.spiff.serializer import ManualTaskConverter
|
||||||
from SpiffWorkflow.spiff.serializer import NoneTaskConverter
|
from SpiffWorkflow.spiff.serializer import NoneTaskConverter
|
||||||
from SpiffWorkflow.spiff.serializer import ReceiveTaskConverter
|
from SpiffWorkflow.spiff.serializer import ReceiveTaskConverter
|
||||||
from SpiffWorkflow.spiff.serializer import SendTaskConverter
|
from SpiffWorkflow.spiff.serializer import SendTaskConverter
|
||||||
|
from SpiffWorkflow.spiff.serializer import ServiceTaskConverter
|
||||||
from SpiffWorkflow.spiff.serializer import StartEventConverter
|
from SpiffWorkflow.spiff.serializer import StartEventConverter
|
||||||
from SpiffWorkflow.spiff.serializer import SubWorkflowTaskConverter
|
from SpiffWorkflow.spiff.serializer import SubWorkflowTaskConverter
|
||||||
from SpiffWorkflow.spiff.serializer import TransactionSubprocessConverter
|
from SpiffWorkflow.spiff.serializer import TransactionSubprocessConverter
|
||||||
|
@ -69,6 +70,7 @@ from spiffworkflow_backend.models.task_event import TaskEventModel
|
||||||
from spiffworkflow_backend.models.user import UserModelSchema
|
from spiffworkflow_backend.models.user import UserModelSchema
|
||||||
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
||||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||||
|
from spiffworkflow_backend.services.service_task_service import ServiceTaskService
|
||||||
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
||||||
from spiffworkflow_backend.services.user_service import UserService
|
from spiffworkflow_backend.services.user_service import UserService
|
||||||
|
|
||||||
|
@ -111,15 +113,21 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
|
||||||
"'%s', %s" % (expression, str(exception)),
|
"'%s', %s" % (expression, str(exception)),
|
||||||
) from exception
|
) from exception
|
||||||
|
|
||||||
def execute(self, task: SpiffTask, script: str) -> None:
|
def execute(
|
||||||
|
self, task: SpiffTask, script: str, external_methods: Any = None
|
||||||
|
) -> None:
|
||||||
"""Execute."""
|
"""Execute."""
|
||||||
try:
|
try:
|
||||||
super().execute(task, script)
|
super().execute(task, script, external_methods)
|
||||||
except WorkflowException as e:
|
except WorkflowException as e:
|
||||||
raise e
|
raise e
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise WorkflowTaskExecException(task, f" {script}, {e}", e) from e
|
raise WorkflowTaskExecException(task, f" {script}, {e}", e) from e
|
||||||
|
|
||||||
|
def available_service_task_external_methods(self) -> Dict[str, Any]:
|
||||||
|
"""Returns available service task external methods."""
|
||||||
|
return ServiceTaskService.scripting_additions()
|
||||||
|
|
||||||
|
|
||||||
class MyCustomParser(BpmnDmnParser): # type: ignore
|
class MyCustomParser(BpmnDmnParser): # type: ignore
|
||||||
"""A BPMN and DMN parser that can also parse spiffworkflow-specific extensions."""
|
"""A BPMN and DMN parser that can also parse spiffworkflow-specific extensions."""
|
||||||
|
@ -150,6 +158,7 @@ class ProcessInstanceProcessor:
|
||||||
NoneTaskConverter,
|
NoneTaskConverter,
|
||||||
ReceiveTaskConverter,
|
ReceiveTaskConverter,
|
||||||
SendTaskConverter,
|
SendTaskConverter,
|
||||||
|
ServiceTaskConverter,
|
||||||
StartEventConverter,
|
StartEventConverter,
|
||||||
SubWorkflowTaskConverter,
|
SubWorkflowTaskConverter,
|
||||||
TransactionSubprocessConverter,
|
TransactionSubprocessConverter,
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
"""ServiceTask_service."""
|
||||||
|
import json
|
||||||
|
from typing import Any
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from flask import current_app
|
||||||
|
|
||||||
|
|
||||||
|
def connector_proxy_url() -> Any:
|
||||||
|
"""Returns the connector proxy url."""
|
||||||
|
return current_app.config["CONNECTOR_PROXY_URL"]
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceTaskDelegate:
|
||||||
|
"""ServiceTaskDelegate."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def call_connector(
|
||||||
|
name: str, bpmn_params: Any
|
||||||
|
) -> None: # TODO what is the return/type
|
||||||
|
"""Calls a connector via the configured proxy."""
|
||||||
|
|
||||||
|
def normalize_value(v: Any) -> Any:
|
||||||
|
value = v["value"]
|
||||||
|
secret_prefix = "secret:" # noqa: S105
|
||||||
|
if value.startswith(secret_prefix):
|
||||||
|
key = value.removeprefix(secret_prefix)
|
||||||
|
# TODO replace with call to secret store
|
||||||
|
value = key
|
||||||
|
return value
|
||||||
|
|
||||||
|
params = {k: normalize_value(v) for k, v in bpmn_params.items()}
|
||||||
|
proxied_response = requests.get(f"{connector_proxy_url()}/v1/do/{name}", params)
|
||||||
|
|
||||||
|
if proxied_response.status_code != 200:
|
||||||
|
print("got error from connector proxy")
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceTaskService:
|
||||||
|
"""ServiceTaskService."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def available_connectors() -> Any:
|
||||||
|
"""Returns a list of available connectors."""
|
||||||
|
try:
|
||||||
|
print(connector_proxy_url)
|
||||||
|
response = requests.get(f"{connector_proxy_url()}/v1/commands")
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
return []
|
||||||
|
|
||||||
|
parsed_response = json.loads(response.text)
|
||||||
|
return parsed_response
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def scripting_additions() -> Dict[str, Any]:
|
||||||
|
"""Allows the ServiceTaskDelegate to be available to script engine instances."""
|
||||||
|
return {"ServiceTaskDelegate": ServiceTaskDelegate}
|
Loading…
Reference in New Issue