unique bpmn process ids (#927)
* remove SpecReferenceCache * make sure strings are sometimes unique * lint * more random Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: burnettk <burnettk@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
parent
4cb1f33ac9
commit
711da2b048
|
@ -23,9 +23,6 @@ from spiffworkflow_backend.models.principal import PrincipalModel # noqa: F401
|
|||
|
||||
|
||||
from spiffworkflow_backend.models.human_task import HumanTaskModel # noqa: F401
|
||||
from spiffworkflow_backend.models.spec_reference import (
|
||||
SpecReferenceCache,
|
||||
) # noqa: F401
|
||||
from spiffworkflow_backend.models.cache_generation import (
|
||||
CacheGenerationModel,
|
||||
) # noqa: F401
|
||||
|
|
|
@ -59,7 +59,6 @@ class Reference:
|
|||
return os.path.join(self.relative_location, self.file_name).replace("/", os.sep)
|
||||
|
||||
|
||||
# SpecReferenceCache
|
||||
class ReferenceCacheModel(SpiffworkflowBaseDBModel):
|
||||
"""A cache of information about all the Processes and Decisions defined in all files."""
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
from flask_marshmallow import Schema # type: ignore
|
||||
from marshmallow import INCLUDE
|
||||
from sqlalchemy import UniqueConstraint
|
||||
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
|
||||
class SpecReferenceNotFoundError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass()
|
||||
class SpecReference:
|
||||
"""File Reference Information.
|
||||
|
||||
Includes items such as the process id and name for a BPMN,
|
||||
or the Decision id and Decision name for a DMN file. There may be more than
|
||||
one reference that points to a particular file - if for instance, there are
|
||||
three executable processes in a collaboration within a BPMN Diagram.
|
||||
"""
|
||||
|
||||
identifier: str # The id of the process or decision. "Process_1234"
|
||||
display_name: str # The name of the process or decision. "Invoice Submission"
|
||||
process_model_id: str
|
||||
type: str # can be 'process' or 'decision'
|
||||
file_name: str # The name of the file where this process or decision is defined.
|
||||
relative_path: str # The path to the file.
|
||||
has_lanes: bool # If this is a process, whether it has lanes or not.
|
||||
is_executable: bool # Whether this process or decision is designated as executable.
|
||||
is_primary: bool # Whether this is the primary process of a process model
|
||||
messages: dict # Any messages defined in the same file where this process is defined.
|
||||
correlations: dict # Any correlations defined in the same file with this process.
|
||||
start_messages: list # The names of any messages that would start this process.
|
||||
called_element_ids: list # The element ids of any called elements
|
||||
|
||||
|
||||
class SpecReferenceCache(SpiffworkflowBaseDBModel):
|
||||
"""A cache of information about all the Processes and Decisions defined in all files."""
|
||||
|
||||
__tablename__ = "spec_reference_cache"
|
||||
__table_args__ = (UniqueConstraint("identifier", "type", name="_identifier_type_unique"),)
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
identifier = db.Column(db.String(255), index=True)
|
||||
display_name = db.Column(db.String(255), index=True)
|
||||
process_model_id = db.Column(db.String(255), index=True)
|
||||
type = db.Column(db.String(255), index=True) # either 'process' or 'decision'
|
||||
file_name = db.Column(db.String(255))
|
||||
relative_path = db.Column(db.String(255))
|
||||
has_lanes = db.Column(db.Boolean())
|
||||
is_executable = db.Column(db.Boolean())
|
||||
is_primary = db.Column(db.Boolean())
|
||||
|
||||
@classmethod
|
||||
def from_spec_reference(cls, ref: SpecReference) -> "SpecReferenceCache":
|
||||
return cls(
|
||||
identifier=ref.identifier,
|
||||
display_name=ref.display_name,
|
||||
process_model_id=ref.process_model_id,
|
||||
type=ref.type,
|
||||
file_name=ref.file_name,
|
||||
has_lanes=ref.has_lanes,
|
||||
is_executable=ref.is_executable,
|
||||
is_primary=ref.is_primary,
|
||||
relative_path=ref.relative_path,
|
||||
)
|
||||
|
||||
|
||||
class SpecReferenceSchema(Schema): # type: ignore
|
||||
class Meta:
|
||||
model = SpecReference
|
||||
fields = [
|
||||
"identifier",
|
||||
"display_name",
|
||||
"process_group_id",
|
||||
"process_model_id",
|
||||
"type",
|
||||
"file_name",
|
||||
"has_lanes",
|
||||
"is_executable",
|
||||
"is_primary",
|
||||
]
|
||||
unknown = INCLUDE
|
|
@ -1,7 +1,9 @@
|
|||
"""APIs for dealing with process groups, process models, and process instances."""
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import string
|
||||
from hashlib import sha256
|
||||
from typing import Any
|
||||
|
||||
|
@ -83,6 +85,15 @@ def process_model_create(
|
|||
with open(template_file) as f:
|
||||
contents = f.read()
|
||||
process_model_id_for_bpmn_file = process_model_info.id.split("/")[-1]
|
||||
|
||||
# convert dashes to underscores for process id
|
||||
underscored_process_id = process_model_id_for_bpmn_file.replace("-", "_")
|
||||
|
||||
# make process id unique by adding random string to add
|
||||
fuzz = "".join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(7))
|
||||
process_id_with_fuzz = f"Process_{underscored_process_id}_{fuzz}"
|
||||
contents = contents.replace("Process_replace_me_just_for_template", process_id_with_fuzz)
|
||||
|
||||
SpecFileService.update_file(process_model_info, f"{process_model_id_for_bpmn_file}.bpmn", contents.encode())
|
||||
|
||||
_commit_and_push_to_git(f"User: {g.user.username} created process model {process_model_info.id}")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
|
||||
<bpmn:process id="Process_ynixgwm" isExecutable="true">
|
||||
<bpmn:process id="Process_replace_me_just_for_template" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_17db3yp</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
|
@ -27,7 +27,7 @@ You can also change the text you are reading here by updating the *Instructions*
|
|||
</bpmn:manualTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_ynixgwm">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_replace_me_just_for_template">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
|
|
@ -166,7 +166,7 @@ class TestNestedGroups(BaseTest):
|
|||
data=json.dumps(ProcessGroupSchema().dump(process_group_c)),
|
||||
)
|
||||
|
||||
def test_process_model_create(
|
||||
def test_process_model_create_nested(
|
||||
self,
|
||||
app: Flask,
|
||||
client: FlaskClient,
|
||||
|
|
|
@ -173,6 +173,9 @@ class TestProcessApi(BaseTest):
|
|||
assert model_display_name == process_model.display_name
|
||||
assert 0 == process_model.display_order
|
||||
assert 1 == len(ProcessModelService.get_process_groups())
|
||||
assert process_model.primary_file_name == f"{process_model_id}.bpmn"
|
||||
assert process_model.primary_process_id
|
||||
assert process_model.primary_process_id.startswith(f"Process_{process_model_id}")
|
||||
|
||||
# add bpmn file to the model
|
||||
bpmn_file_name = "sample.bpmn"
|
||||
|
|
Loading…
Reference in New Issue