Merge branch 'main' into feature/secrets

# Conflicts:
#	.gitignore
#	migrations/versions/774ff3b4b328_.py
#	migrations/versions/ab77f4ccb4d6_.py
#	migrations/versions/d4922c5cd32d_.py
#	src/spiffworkflow_backend/load_database_models.py
This commit is contained in:
mike cullerton 2022-09-15 11:42:47 -04:00
commit ee29df7268
9 changed files with 85 additions and 39 deletions

1
.gitignore vendored
View File

@ -16,4 +16,5 @@ node_modules
/tests/files/tickets.csv
/log/*.log
/tests/spiffworkflow_backend/files
/bin/import_secrets.py
/src/spiffworkflow_backend/config/secrets.py

View File

@ -1,8 +1,8 @@
"""empty message
Revision ID: d4922c5cd32d
Revision ID: 70d52c39fdda
Revises:
Create Date: 2022-09-15 11:08:25.133655
Create Date: 2022-09-15 11:40:42.072748
"""
from alembic import op
@ -10,7 +10,7 @@ import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd4922c5cd32d'
revision = '70d52c39fdda'
down_revision = None
branch_labels = None
depends_on = None
@ -46,15 +46,6 @@ def upgrade():
)
op.create_index(op.f('ix_message_model_identifier'), 'message_model', ['identifier'], unique=True)
op.create_index(op.f('ix_message_model_name'), 'message_model', ['name'], unique=True)
op.create_table('spiff_logging',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('process_instance_id', sa.Integer(), nullable=False),
sa.Column('bpmn_process_identifier', sa.String(length=50), nullable=False),
sa.Column('task', sa.String(length=50), nullable=False),
sa.Column('timestamp', sa.Float(), nullable=False),
sa.Column('message', sa.String(length=50), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_table('user',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('username', sa.String(length=255), nullable=False),
@ -230,6 +221,17 @@ def upgrade():
sa.ForeignKeyConstraint(['secret_id'], ['secret.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('spiff_logging',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('process_instance_id', sa.Integer(), nullable=False),
sa.Column('bpmn_process_identifier', sa.String(length=50), nullable=False),
sa.Column('bpmn_task_identifier', sa.String(length=50), nullable=False),
sa.Column('spiff_task_guid', sa.String(length=50), nullable=False),
sa.Column('timestamp', sa.DECIMAL(precision=17, scale=6), nullable=False),
sa.Column('message', sa.String(length=50), nullable=True),
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('task_event',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
@ -286,6 +288,7 @@ def downgrade():
op.drop_table('message_correlation_message_instance')
op.drop_table('data_store')
op.drop_table('task_event')
op.drop_table('spiff_logging')
op.drop_table('secret_allowed_process')
op.drop_table('message_instance')
op.drop_index(op.f('ix_message_correlation_value'), table_name='message_correlation')
@ -311,7 +314,6 @@ def downgrade():
op.drop_index(op.f('ix_message_correlation_property_identifier'), table_name='message_correlation_property')
op.drop_table('message_correlation_property')
op.drop_table('user')
op.drop_table('spiff_logging')
op.drop_index(op.f('ix_message_model_name'), table_name='message_model')
op.drop_index(op.f('ix_message_model_identifier'), table_name='message_model')
op.drop_table('message_model')

View File

@ -32,6 +32,9 @@ from spiffworkflow_backend.models.secret_model import (
) # noqa: F401
from spiffworkflow_backend.models.secret_model import SecretModel # noqa: F401
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel # noqa: F401
from spiffworkflow_backend.models.spiff_logging import (
SpiffLoggingModel,
) # noqa: F401
from spiffworkflow_backend.models.task_event import TaskEventModel # noqa: F401
from spiffworkflow_backend.models.user import UserModel # noqa: F401
from spiffworkflow_backend.models.user_group_assignment import (

View File

@ -93,6 +93,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
active_tasks = relationship("ActiveTaskModel", cascade="delete") # type: ignore
task_events = relationship("TaskEventModel", cascade="delete") # type: ignore
spiff_logs = relationship("SpiffLoggingModel", cascade="delete") # type: ignore
bpmn_json: str | None = deferred(db.Column(db.JSON)) # type: ignore
start_in_seconds: int | None = db.Column(db.Integer)

View File

@ -4,6 +4,9 @@ from typing import Optional
from flask_bpmn.models.db import db
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
@dataclass
@ -12,13 +15,9 @@ class SpiffLoggingModel(SpiffworkflowBaseDBModel):
__tablename__ = "spiff_logging"
id: int = db.Column(db.Integer, primary_key=True)
process_instance_id: int = db.Column(
db.Integer, nullable=False
) # record.process_instance_id
bpmn_process_identifier: str = db.Column(
db.String(50), nullable=False
) # record.workflow
task: str = db.Column(db.String(50), nullable=False) # record.task_id
timestamp: float = db.Column(db.Float(), nullable=False) # record.created
message: Optional[str] = db.Column(db.String(50), nullable=True) # record.msg
process_instance_id: int = db.Column(ForeignKey(ProcessInstanceModel.id), nullable=False) # type: ignore
bpmn_process_identifier: str = db.Column(db.String(50), nullable=False)
bpmn_task_identifier: str = db.Column(db.String(50), nullable=False)
spiff_task_guid: str = db.Column(db.String(50), nullable=False)
timestamp: float = db.Column(db.DECIMAL(17, 6), nullable=False)
message: Optional[str] = db.Column(db.String(50), nullable=True)

View File

@ -9,7 +9,6 @@ from flask_bpmn.models.db import SpiffworkflowBaseDBModel
from marshmallow import fields
from marshmallow import INCLUDE
from marshmallow import Schema
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
from sqlalchemy import func
@ -58,18 +57,6 @@ class TaskEventModel(SpiffworkflowBaseDBModel):
date = db.Column(db.DateTime(timezone=True), default=func.now())
class TaskEventModelSchema(SQLAlchemyAutoSchema):
"""TaskEventModelSchema."""
class Meta:
"""Meta."""
model = TaskEventModel
load_instance = True
include_relationships = True
include_fk = True # Includes foreign keys
class TaskEvent:
"""TaskEvent."""

View File

@ -170,13 +170,15 @@ class DBHandler(logging.Handler):
"""Emit."""
if record:
bpmn_process_identifier = record.workflow # type: ignore
task = str(record.task_id) # type: ignore
spiff_task_guid = str(record.task_id) # type: ignore
bpmn_task_identifier = str(record.task_spec) # type: ignore
timestamp = record.created
message = record.msg if hasattr(record, "msg") else None
spiff_log = SpiffLoggingModel(
process_instance_id=record.process_instance_id, # type: ignore
bpmn_process_identifier=bpmn_process_identifier,
task=task,
spiff_task_guid=spiff_task_guid,
bpmn_task_identifier=bpmn_task_identifier,
message=message,
timestamp=timestamp,
)

View File

@ -36,5 +36,11 @@ class TestLoggingService(BaseTest):
assert len(logs) > 0
for log in logs:
assert log["process_instance_id"] == process_instance_id
for key in ["timestamp", "task", "bpmn_process_identifier", "message"]:
for key in [
"timestamp",
"spiff_task_guid",
"bpmn_task_identifier",
"bpmn_process_identifier",
"message",
]:
assert key in log.keys()

View File

@ -0,0 +1,45 @@
"""Process Model."""
from flask.app import Flask
from decimal import Decimal
from flask_bpmn.models.db import db
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
class TestSpiffLogging(BaseTest):
"""TestSpiffLogging."""
def test_timestamps_are_stored_correctly(
self, app: Flask, with_db_and_bpmn_file_cleanup: None
) -> None:
"""Test_timestamps_are_stored_correctly."""
process_model = load_test_spec(
"call_activity_test",
process_model_source_directory="call_activity_same_directory",
)
process_instance = self.create_process_instance_from_process_model(
process_model
)
bpmn_process_identifier = "test_process_identifier"
spiff_task_guid = "test_spiff_task_guid"
bpmn_task_identifier = "test_bpmn_task_identifier"
timestamp = 1663250624.664887 # actual timestamp from spiff logs
message = "test_message"
spiff_log = SpiffLoggingModel(
process_instance_id=process_instance.id,
bpmn_process_identifier=bpmn_process_identifier,
spiff_task_guid=spiff_task_guid,
bpmn_task_identifier=bpmn_task_identifier,
message=message,
timestamp=timestamp,
)
assert spiff_log.timestamp == timestamp
db.session.add(spiff_log)
db.session.commit()
assert spiff_log.timestamp == Decimal(str(timestamp))