mirror of
https://github.com/sartography/spiff-arena.git
synced 2025-02-04 13:45:13 +00:00
Feature/pin form schemas to revision (#526)
* task show loads the correct revision of the json schema form w/ burnettk * display error if form cannot be found at revision w/ burnettk --------- Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
parent
dbbf14fe58
commit
b12af9f3bc
@ -89,13 +89,15 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
|
|||||||
start_in_seconds: int | None = db.Column(db.Integer, index=True)
|
start_in_seconds: int | None = db.Column(db.Integer, index=True)
|
||||||
end_in_seconds: int | None = db.Column(db.Integer, index=True)
|
end_in_seconds: int | None = db.Column(db.Integer, index=True)
|
||||||
task_updated_at_in_seconds: int = db.Column(db.Integer, nullable=True)
|
task_updated_at_in_seconds: int = db.Column(db.Integer, nullable=True)
|
||||||
updated_at_in_seconds: int = db.Column(db.Integer)
|
|
||||||
created_at_in_seconds: int = db.Column(db.Integer)
|
|
||||||
status: str = db.Column(db.String(50), index=True)
|
status: str = db.Column(db.String(50), index=True)
|
||||||
|
|
||||||
bpmn_version_control_type: str = db.Column(db.String(50))
|
updated_at_in_seconds: int = db.Column(db.Integer)
|
||||||
bpmn_version_control_identifier: str = db.Column(db.String(255))
|
created_at_in_seconds: int = db.Column(db.Integer)
|
||||||
last_milestone_bpmn_name: str = db.Column(db.String(255))
|
|
||||||
|
bpmn_version_control_type: str | None = db.Column(db.String(50))
|
||||||
|
# this could also be a blank string for older instances since we were putting blank strings in here as well
|
||||||
|
bpmn_version_control_identifier: str | None = db.Column(db.String(255))
|
||||||
|
last_milestone_bpmn_name: str | None = db.Column(db.String(255))
|
||||||
|
|
||||||
bpmn_xml_file_contents: str | None = None
|
bpmn_xml_file_contents: str | None = None
|
||||||
bpmn_xml_file_contents_retrieval_error: str | None = None
|
bpmn_xml_file_contents_retrieval_error: str | None = None
|
||||||
|
@ -46,7 +46,6 @@ from spiffworkflow_backend.services.process_instance_queue_service import Proces
|
|||||||
from spiffworkflow_backend.services.process_instance_report_service import ProcessInstanceReportService
|
from spiffworkflow_backend.services.process_instance_report_service import ProcessInstanceReportService
|
||||||
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
|
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
|
||||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||||
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
|
||||||
from spiffworkflow_backend.services.task_service import TaskService
|
from spiffworkflow_backend.services.task_service import TaskService
|
||||||
|
|
||||||
# from spiffworkflow_backend.services.process_instance_report_service import (
|
# from spiffworkflow_backend.services.process_instance_report_service import (
|
||||||
@ -682,10 +681,6 @@ def _get_process_instance(
|
|||||||
process_identifier: str | None = None,
|
process_identifier: str | None = None,
|
||||||
) -> flask.wrappers.Response:
|
) -> flask.wrappers.Response:
|
||||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||||
try:
|
|
||||||
current_version_control_revision = GitService.get_current_revision()
|
|
||||||
except GitCommandError:
|
|
||||||
current_version_control_revision = ""
|
|
||||||
|
|
||||||
process_model_with_diagram = None
|
process_model_with_diagram = None
|
||||||
name_of_file_with_diagram = None
|
name_of_file_with_diagram = None
|
||||||
@ -706,19 +701,14 @@ def _get_process_instance(
|
|||||||
|
|
||||||
if process_model_with_diagram and name_of_file_with_diagram:
|
if process_model_with_diagram and name_of_file_with_diagram:
|
||||||
bpmn_xml_file_contents = None
|
bpmn_xml_file_contents = None
|
||||||
if process_instance.bpmn_version_control_identifier == current_version_control_revision:
|
try:
|
||||||
bpmn_xml_file_contents = SpecFileService.get_data(
|
bpmn_xml_file_contents = GitService.get_file_contents_for_revision_if_git_revision(
|
||||||
process_model_with_diagram, name_of_file_with_diagram
|
process_model=process_model_with_diagram,
|
||||||
).decode("utf-8")
|
revision=process_instance.bpmn_version_control_identifier,
|
||||||
else:
|
file_name=name_of_file_with_diagram,
|
||||||
try:
|
)
|
||||||
bpmn_xml_file_contents = GitService.get_instance_file_contents_for_revision(
|
except GitCommandError as ex:
|
||||||
process_model_with_diagram,
|
process_instance.bpmn_xml_file_contents_retrieval_error = str(ex)
|
||||||
process_instance.bpmn_version_control_identifier,
|
|
||||||
file_name=name_of_file_with_diagram,
|
|
||||||
)
|
|
||||||
except GitCommandError as ex:
|
|
||||||
process_instance.bpmn_xml_file_contents_retrieval_error = str(ex)
|
|
||||||
process_instance.bpmn_xml_file_contents = bpmn_xml_file_contents
|
process_instance.bpmn_xml_file_contents = bpmn_xml_file_contents
|
||||||
|
|
||||||
process_instance_as_dict = process_instance.serialized_with_metadata()
|
process_instance_as_dict = process_instance.serialized_with_metadata()
|
||||||
|
@ -54,6 +54,8 @@ from spiffworkflow_backend.services.authorization_service import HumanTaskNotFou
|
|||||||
from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError
|
from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError
|
||||||
from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService
|
from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService
|
||||||
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
||||||
|
from spiffworkflow_backend.services.git_service import GitCommandError
|
||||||
|
from spiffworkflow_backend.services.git_service import GitService
|
||||||
from spiffworkflow_backend.services.jinja_service import JinjaService
|
from spiffworkflow_backend.services.jinja_service import JinjaService
|
||||||
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
|
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
|
||||||
from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceIsAlreadyLockedError
|
from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceIsAlreadyLockedError
|
||||||
@ -452,9 +454,10 @@ def task_show(
|
|||||||
)
|
)
|
||||||
|
|
||||||
form_dict = _prepare_form_data(
|
form_dict = _prepare_form_data(
|
||||||
form_schema_file_name,
|
form_file=form_schema_file_name,
|
||||||
task_model,
|
task_model=task_model,
|
||||||
process_model_with_form,
|
process_model=process_model_with_form,
|
||||||
|
revision=process_instance.bpmn_version_control_identifier,
|
||||||
)
|
)
|
||||||
|
|
||||||
_update_form_schema_with_task_data_as_needed(form_dict, task_model.data)
|
_update_form_schema_with_task_data_as_needed(form_dict, task_model.data)
|
||||||
@ -464,9 +467,10 @@ def task_show(
|
|||||||
|
|
||||||
if form_ui_schema_file_name:
|
if form_ui_schema_file_name:
|
||||||
ui_form_contents = _prepare_form_data(
|
ui_form_contents = _prepare_form_data(
|
||||||
form_ui_schema_file_name,
|
form_file=form_ui_schema_file_name,
|
||||||
task_model,
|
task_model=task_model,
|
||||||
process_model_with_form,
|
process_model=process_model_with_form,
|
||||||
|
revision=process_instance.bpmn_version_control_identifier,
|
||||||
)
|
)
|
||||||
if ui_form_contents:
|
if ui_form_contents:
|
||||||
task_model.form_ui_schema = ui_form_contents
|
task_model.form_ui_schema = ui_form_contents
|
||||||
@ -940,31 +944,51 @@ def _get_tasks(
|
|||||||
return make_response(jsonify(response_json), 200)
|
return make_response(jsonify(response_json), 200)
|
||||||
|
|
||||||
|
|
||||||
def _prepare_form_data(form_file: str, task_model: TaskModel, process_model: ProcessModelInfo) -> dict:
|
def _prepare_form_data(
|
||||||
|
form_file: str, task_model: TaskModel, process_model: ProcessModelInfo, revision: str | None = None
|
||||||
|
) -> dict:
|
||||||
if task_model.data is None:
|
if task_model.data is None:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
file_contents = SpecFileService.get_data(process_model, form_file).decode("utf-8")
|
try:
|
||||||
|
file_contents = GitService.get_file_contents_for_revision_if_git_revision(
|
||||||
|
process_model=process_model,
|
||||||
|
revision=revision,
|
||||||
|
file_name=form_file,
|
||||||
|
)
|
||||||
|
except GitCommandError as exception:
|
||||||
|
raise (
|
||||||
|
ApiError(
|
||||||
|
error_code="git_error_loading_form",
|
||||||
|
message=(
|
||||||
|
f"Could not load form schema from: {form_file}. Was git history rewritten such that revision"
|
||||||
|
f" '{revision}' no longer exists? Error was: {str(exception)}"
|
||||||
|
),
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
) from exception
|
||||||
|
|
||||||
try:
|
try:
|
||||||
form_contents = JinjaService.render_jinja_template(file_contents, task=task_model)
|
form_contents = JinjaService.render_jinja_template(file_contents, task=task_model)
|
||||||
try:
|
|
||||||
# form_contents is a str
|
|
||||||
hot_dict: dict = json.loads(form_contents)
|
|
||||||
return hot_dict
|
|
||||||
except Exception as exception:
|
|
||||||
raise (
|
|
||||||
ApiError(
|
|
||||||
error_code="error_loading_form",
|
|
||||||
message=f"Could not load form schema from: {form_file}. Error was: {str(exception)}",
|
|
||||||
status_code=400,
|
|
||||||
)
|
|
||||||
) from exception
|
|
||||||
except TaskModelError as wfe:
|
except TaskModelError as wfe:
|
||||||
wfe.add_note(f"Error in Json Form File '{form_file}'")
|
wfe.add_note(f"Error in Json Form File '{form_file}'")
|
||||||
api_error = ApiError.from_workflow_exception("instructions_error", str(wfe), exp=wfe)
|
api_error = ApiError.from_workflow_exception("instructions_error", str(wfe), exp=wfe)
|
||||||
api_error.file_name = form_file
|
api_error.file_name = form_file
|
||||||
raise api_error
|
raise api_error
|
||||||
|
|
||||||
|
try:
|
||||||
|
# form_contents is a str
|
||||||
|
hot_dict: dict = json.loads(form_contents)
|
||||||
|
return hot_dict
|
||||||
|
except Exception as exception:
|
||||||
|
raise (
|
||||||
|
ApiError(
|
||||||
|
error_code="error_loading_form",
|
||||||
|
message=f"Could not load form schema from: {form_file}. Error was: {str(exception)}",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
) from exception
|
||||||
|
|
||||||
|
|
||||||
def _get_spiff_task_from_process_instance(
|
def _get_spiff_task_from_process_instance(
|
||||||
task_guid: str,
|
task_guid: str,
|
||||||
|
@ -10,6 +10,7 @@ from spiffworkflow_backend.config import ConfigurationError
|
|||||||
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
||||||
from spiffworkflow_backend.services.data_setup_service import DataSetupService
|
from spiffworkflow_backend.services.data_setup_service import DataSetupService
|
||||||
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
||||||
|
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
||||||
|
|
||||||
|
|
||||||
class MissingGitConfigsError(Exception):
|
class MissingGitConfigsError(Exception):
|
||||||
@ -47,19 +48,43 @@ class GitService:
|
|||||||
cls,
|
cls,
|
||||||
process_model: ProcessModelInfo,
|
process_model: ProcessModelInfo,
|
||||||
revision: str,
|
revision: str,
|
||||||
file_name: str | None = None,
|
file_name: str,
|
||||||
) -> str:
|
) -> str:
|
||||||
bpmn_spec_absolute_dir = current_app.config["SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR"]
|
bpmn_spec_absolute_dir = current_app.config["SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR"]
|
||||||
process_model_relative_path = FileSystemService.process_model_relative_path(process_model)
|
process_model_relative_path = FileSystemService.process_model_relative_path(process_model)
|
||||||
file_name_to_use = file_name
|
|
||||||
if file_name_to_use is None:
|
|
||||||
file_name_to_use = process_model.primary_file_name
|
|
||||||
shell_command = [
|
shell_command = [
|
||||||
"show",
|
"show",
|
||||||
f"{revision}:{process_model_relative_path}/{file_name_to_use}",
|
f"{revision}:{process_model_relative_path}/{file_name}",
|
||||||
]
|
]
|
||||||
return cls.run_shell_command_to_get_stdout(shell_command, context_directory=bpmn_spec_absolute_dir)
|
return cls.run_shell_command_to_get_stdout(shell_command, context_directory=bpmn_spec_absolute_dir)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_file_contents_for_revision_if_git_revision(
|
||||||
|
cls,
|
||||||
|
process_model: ProcessModelInfo,
|
||||||
|
file_name: str,
|
||||||
|
revision: str | None = None,
|
||||||
|
) -> str:
|
||||||
|
try:
|
||||||
|
current_version_control_revision = cls.get_current_revision()
|
||||||
|
except GitCommandError:
|
||||||
|
current_version_control_revision = None
|
||||||
|
file_contents = None
|
||||||
|
if (
|
||||||
|
revision is None
|
||||||
|
or revision == ""
|
||||||
|
or current_version_control_revision is None
|
||||||
|
or revision == current_version_control_revision
|
||||||
|
):
|
||||||
|
file_contents = SpecFileService.get_data(process_model, file_name).decode("utf-8")
|
||||||
|
else:
|
||||||
|
file_contents = GitService.get_instance_file_contents_for_revision(
|
||||||
|
process_model,
|
||||||
|
revision,
|
||||||
|
file_name=file_name,
|
||||||
|
)
|
||||||
|
return file_contents
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def commit(
|
def commit(
|
||||||
cls,
|
cls,
|
||||||
@ -92,7 +117,7 @@ class GitService:
|
|||||||
if raise_on_missing:
|
if raise_on_missing:
|
||||||
raise MissingGitConfigsError(
|
raise MissingGitConfigsError(
|
||||||
"Missing config for SPIFFWORKFLOW_BACKEND_GIT_SOURCE_BRANCH. "
|
"Missing config for SPIFFWORKFLOW_BACKEND_GIT_SOURCE_BRANCH. "
|
||||||
"This is required for publishing process models"
|
"This is required for committing and publishing process models"
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
@ -94,7 +94,7 @@ class ProcessInstanceService:
|
|||||||
try:
|
try:
|
||||||
current_git_revision = GitService.get_current_revision()
|
current_git_revision = GitService.get_current_revision()
|
||||||
except GitCommandError:
|
except GitCommandError:
|
||||||
current_git_revision = ""
|
current_git_revision = None
|
||||||
process_instance_model = ProcessInstanceModel(
|
process_instance_model = ProcessInstanceModel(
|
||||||
status=ProcessInstanceStatus.not_started.value,
|
status=ProcessInstanceStatus.not_started.value,
|
||||||
process_initiator_id=user.id,
|
process_initiator_id=user.id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user