Feature/service task part deux (#91)

This commit is contained in:
jbirddog 2022-09-16 15:37:20 -04:00 committed by GitHub
parent 439f9e55ed
commit 112fe1a0eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 2 deletions

View File

@ -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:

View File

@ -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"
)

View File

@ -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,

View File

@ -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,

View File

@ -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}