Merge remote-tracking branch 'origin/main' into feature/use_tasks_as_logs
This commit is contained in:
commit
3461056beb
|
@ -156,7 +156,7 @@ jobs:
|
|||
- name: Upload coverage data
|
||||
# pin to upload coverage from only one matrix entry, otherwise coverage gets confused later
|
||||
if: always() && matrix.session == 'tests' && matrix.python == '3.11' && matrix.os == 'ubuntu-latest' && matrix.database == 'mysql'
|
||||
uses: "actions/upload-artifact@v3.0.0"
|
||||
uses: "actions/upload-artifact@v3"
|
||||
# this action doesn't seem to respect working-directory so include working-directory value in path
|
||||
with:
|
||||
name: coverage-data
|
||||
|
@ -164,14 +164,14 @@ jobs:
|
|||
|
||||
- name: Upload documentation
|
||||
if: matrix.session == 'docs-build'
|
||||
uses: actions/upload-artifact@v3.0.0
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docs
|
||||
path: docs/_build
|
||||
|
||||
- name: Upload logs
|
||||
if: failure() && matrix.session == 'tests'
|
||||
uses: "actions/upload-artifact@v3.0.0"
|
||||
uses: "actions/upload-artifact@v3"
|
||||
with:
|
||||
name: logs-${{matrix.python}}-${{matrix.os}}-${{matrix.database}}
|
||||
path: "./log/*.log"
|
||||
|
|
|
@ -108,21 +108,21 @@ jobs:
|
|||
run: ./bin/get_logs_from_docker_compose >./log/docker_compose.log
|
||||
- name: Upload logs
|
||||
if: failure()
|
||||
uses: "actions/upload-artifact@v3.0.0"
|
||||
uses: "actions/upload-artifact@v3"
|
||||
with:
|
||||
name: spiffworkflow-backend-logs
|
||||
path: "./spiffworkflow-backend/log/*.log"
|
||||
|
||||
# https://github.com/cypress-io/github-action#artifacts
|
||||
- name: upload_screenshots
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: cypress-screenshots
|
||||
path: ./spiffworkflow-frontend/cypress/screenshots
|
||||
# Test run video was always captured, so this action uses "always()" condition
|
||||
- name: upload_videos
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: cypress-videos
|
||||
|
|
|
@ -396,7 +396,7 @@
|
|||
"otpPolicyLookAheadWindow" : 1,
|
||||
"otpPolicyPeriod" : 30,
|
||||
"otpPolicyCodeReusable" : false,
|
||||
"otpSupportedApplications" : [ "totpAppGoogleName", "totpAppFreeOTPName" ],
|
||||
"otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName" ],
|
||||
"webAuthnPolicyRpEntityName" : "keycloak",
|
||||
"webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
|
||||
"webAuthnPolicyRpId" : "",
|
||||
|
@ -991,6 +991,29 @@
|
|||
"realmRoles" : [ "default-roles-spiffworkflow" ],
|
||||
"notBefore" : 0,
|
||||
"groups" : [ ]
|
||||
}, {
|
||||
"id" : "7b86b997-de98-478c-8550-cfca65e40c33",
|
||||
"createdTimestamp" : 1679060366901,
|
||||
"username" : "core18.contributor",
|
||||
"enabled" : true,
|
||||
"totp" : false,
|
||||
"emailVerified" : false,
|
||||
"email" : "core18.contributor@status.im",
|
||||
"attributes" : {
|
||||
"spiffworkflow-employeeid" : [ "233" ]
|
||||
},
|
||||
"credentials" : [ {
|
||||
"id" : "55ca2bd7-6f60-4f04-be21-df6300ca9442",
|
||||
"type" : "password",
|
||||
"createdDate" : 1679060366954,
|
||||
"secretData" : "{\"value\":\"hC/O8LJ8/y/nXLmRFgRazOX9PXMHkowYH1iHUB4Iw9jzc8IMMv8dFrxu7XBklfyz7CPc1bmgl0k29jygRZYHlg==\",\"salt\":\"4R17tmLrHWyFAMvrfLMETQ==\",\"additionalParameters\":{}}",
|
||||
"credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
|
||||
} ],
|
||||
"disableableCredentialTypes" : [ ],
|
||||
"requiredActions" : [ ],
|
||||
"realmRoles" : [ "default-roles-spiffworkflow" ],
|
||||
"notBefore" : 0,
|
||||
"groups" : [ ]
|
||||
}, {
|
||||
"id" : "3b81b45e-759b-4d7a-aa90-adf7b447208c",
|
||||
"createdTimestamp" : 1676302140358,
|
||||
|
@ -1505,6 +1528,29 @@
|
|||
"realmRoles" : [ "default-roles-spiffworkflow" ],
|
||||
"notBefore" : 0,
|
||||
"groups" : [ ]
|
||||
}, {
|
||||
"id" : "d123d384-66a4-4db5-9dbb-d73c12047001",
|
||||
"createdTimestamp" : 1678997616280,
|
||||
"username" : "finance.project-lead",
|
||||
"enabled" : true,
|
||||
"totp" : false,
|
||||
"emailVerified" : false,
|
||||
"email" : "finance.project-lead@status.im",
|
||||
"attributes" : {
|
||||
"spiffworkflow-employeeid" : [ "128" ]
|
||||
},
|
||||
"credentials" : [ {
|
||||
"id" : "b680f5c5-c2de-4255-9d23-7e18cff3ac4e",
|
||||
"type" : "password",
|
||||
"createdDate" : 1678997616336,
|
||||
"secretData" : "{\"value\":\"4kasmb11Sv62rInh8eFUhS3rGYNymzsvxzfsEIWGYhnlisYuo1iTS2opv/kET/NyJlsYrfwc7yrIqSHvkUHkkA==\",\"salt\":\"q/ees3a4K+3K11olnfPzCQ==\",\"additionalParameters\":{}}",
|
||||
"credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
|
||||
} ],
|
||||
"disableableCredentialTypes" : [ ],
|
||||
"requiredActions" : [ ],
|
||||
"realmRoles" : [ "default-roles-spiffworkflow" ],
|
||||
"notBefore" : 0,
|
||||
"groups" : [ ]
|
||||
}, {
|
||||
"id" : "f6d2488a-446c-493b-bbe8-210ede6f3e42",
|
||||
"createdTimestamp" : 1674148694899,
|
||||
|
@ -4578,7 +4624,7 @@
|
|||
"subType" : "authenticated",
|
||||
"subComponents" : { },
|
||||
"config" : {
|
||||
"allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-address-mapper" ]
|
||||
"allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "saml-user-property-mapper" ]
|
||||
}
|
||||
}, {
|
||||
"id" : "d68e938d-dde6-47d9-bdc8-8e8523eb08cd",
|
||||
|
@ -4596,7 +4642,7 @@
|
|||
"subType" : "anonymous",
|
||||
"subComponents" : { },
|
||||
"config" : {
|
||||
"allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "saml-user-property-mapper" ]
|
||||
"allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper" ]
|
||||
}
|
||||
}, {
|
||||
"id" : "3854361d-3fe5-47fb-9417-a99592e3dc5c",
|
||||
|
@ -4686,7 +4732,7 @@
|
|||
"internationalizationEnabled" : false,
|
||||
"supportedLocales" : [ ],
|
||||
"authenticationFlows" : [ {
|
||||
"id" : "04b09640-f53c-4c1b-b2b1-8cac25afc2bb",
|
||||
"id" : "38a6b336-b026-46be-a8be-e8ff7b9da407",
|
||||
"alias" : "Account verification options",
|
||||
"description" : "Method with which to verity the existing account",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4708,7 +4754,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "e7c246f4-71c3-4a48-9037-72438bdcfcbb",
|
||||
"id" : "eb9fe753-cd35-4e65-bb34-e83ba7059566",
|
||||
"alias" : "Authentication Options",
|
||||
"description" : "Authentication options.",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4737,7 +4783,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "6e9d415e-98f7-4459-b10b-45b08302c681",
|
||||
"id" : "aa9c74f7-0426-4440-907f-4aa0f999eb1e",
|
||||
"alias" : "Browser - Conditional OTP",
|
||||
"description" : "Flow to determine if the OTP is required for the authentication",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4759,7 +4805,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "c86b0fad-f7dd-4c58-974e-25eb83c1dacf",
|
||||
"id" : "eb2a0849-c316-46bc-8b06-fd0cc50e3f32",
|
||||
"alias" : "Direct Grant - Conditional OTP",
|
||||
"description" : "Flow to determine if the OTP is required for the authentication",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4781,7 +4827,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "cb7f4c87-a8fa-445a-a8d4-53869cdfed12",
|
||||
"id" : "8f064003-823b-4be1-aa66-7324bf38c741",
|
||||
"alias" : "First broker login - Conditional OTP",
|
||||
"description" : "Flow to determine if the OTP is required for the authentication",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4803,7 +4849,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "8fa87954-bc65-4f1e-bc55-f5bb49f59fbb",
|
||||
"id" : "eef22678-b09c-4ca8-bdcf-90ea44ff0120",
|
||||
"alias" : "Handle Existing Account",
|
||||
"description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4825,7 +4871,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "e617d826-c654-4c35-96ad-8381bd1e2298",
|
||||
"id" : "4367f263-ef2c-426e-b5cd-49fff868ea1a",
|
||||
"alias" : "Reset - Conditional OTP",
|
||||
"description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4847,7 +4893,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "2e4a46ae-2813-4b71-9386-c08b2f063fa6",
|
||||
"id" : "b2e9c608-1779-4c03-b32a-03c77450abae",
|
||||
"alias" : "User creation or linking",
|
||||
"description" : "Flow for the existing/non-existing user alternatives",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4870,7 +4916,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "8fa69de0-13cf-4252-899b-c59a30ebd132",
|
||||
"id" : "a8c79324-1881-4bb0-a8a2-83dfd54cacd1",
|
||||
"alias" : "Verify Existing Account by Re-authentication",
|
||||
"description" : "Reauthentication of existing account",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4892,7 +4938,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "204d20f6-d9a7-49ff-a7a3-45386fb884f4",
|
||||
"id" : "d1aa83c6-da36-4cb6-b6ed-f6ec556df614",
|
||||
"alias" : "browser",
|
||||
"description" : "browser based authentication",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4928,7 +4974,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "3c0c2987-65db-4920-ae44-34aba220c3fb",
|
||||
"id" : "2afecfef-4bfb-4842-b338-7ed032a618d2",
|
||||
"alias" : "clients",
|
||||
"description" : "Base authentication for clients",
|
||||
"providerId" : "client-flow",
|
||||
|
@ -4964,7 +5010,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "68a92113-be75-4e63-a322-8076d6c67650",
|
||||
"id" : "34dc1854-4969-4065-90e6-fef38b0dea98",
|
||||
"alias" : "direct grant",
|
||||
"description" : "OpenID Connect Resource Owner Grant",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -4993,7 +5039,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "a630d78f-4fe1-4350-a19d-d091d1af514d",
|
||||
"id" : "40557323-dbbc-48ee-9ed1-748b11c9628d",
|
||||
"alias" : "docker auth",
|
||||
"description" : "Used by Docker clients to authenticate against the IDP",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -5008,7 +5054,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "f73b4437-8e82-4788-be69-e437b09b500c",
|
||||
"id" : "d18b5c50-39fa-4b11-a7d2-0e6768e275c1",
|
||||
"alias" : "first broker login",
|
||||
"description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -5031,7 +5077,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "b7c8cc6d-bc1f-446e-b263-72214b2f5c56",
|
||||
"id" : "976be80d-a88b-412c-8ad2-9ebe427793d4",
|
||||
"alias" : "forms",
|
||||
"description" : "Username, password, otp and other auth forms.",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -5053,7 +5099,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "a3bdf79f-8c7d-4bff-807d-76fa61093446",
|
||||
"id" : "83b3a411-ff7c-4cba-845a-9554c536d6b1",
|
||||
"alias" : "http challenge",
|
||||
"description" : "An authentication flow based on challenge-response HTTP Authentication Schemes",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -5075,7 +5121,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "ada41b4e-5a12-496d-aa1e-d31cf8c08226",
|
||||
"id" : "1cb835a6-b38c-4f29-a6d8-d04d0a84d05e",
|
||||
"alias" : "registration",
|
||||
"description" : "registration flow",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -5091,7 +5137,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "1c858bcd-2031-4056-bbf0-1fbaecdd7068",
|
||||
"id" : "7ec06c82-6802-4ff4-a3ab-9b6a0b8dbc4b",
|
||||
"alias" : "registration form",
|
||||
"description" : "registration form",
|
||||
"providerId" : "form-flow",
|
||||
|
@ -5127,7 +5173,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "ff91e251-d85e-450b-bff7-d45be26777d5",
|
||||
"id" : "f3bc2f7b-2074-4d93-9578-3abf648a6681",
|
||||
"alias" : "reset credentials",
|
||||
"description" : "Reset credentials for a user if they forgot their password or something",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -5163,7 +5209,7 @@
|
|||
"userSetupAllowed" : false
|
||||
} ]
|
||||
}, {
|
||||
"id" : "7b0680a2-99b9-454c-b145-f286e9d60c58",
|
||||
"id" : "e62e031b-9922-4682-b867-bc5c3a4a7e99",
|
||||
"alias" : "saml ecp",
|
||||
"description" : "SAML ECP Profile Authentication Flow",
|
||||
"providerId" : "basic-flow",
|
||||
|
@ -5179,13 +5225,13 @@
|
|||
} ]
|
||||
} ],
|
||||
"authenticatorConfig" : [ {
|
||||
"id" : "aa1e4f55-3e7f-445a-a432-7a972776d719",
|
||||
"id" : "c449f0aa-5f3c-4107-9f04-3222fa93a486",
|
||||
"alias" : "create unique user config",
|
||||
"config" : {
|
||||
"require.password.update.after.registration" : "false"
|
||||
}
|
||||
}, {
|
||||
"id" : "fd69765e-309b-4c5d-bdd5-51343427cd27",
|
||||
"id" : "f7a6ed54-0ab8-4f29-9877-960bd65bf394",
|
||||
"alias" : "review profile config",
|
||||
"config" : {
|
||||
"update.profile.on.first.login" : "missing"
|
||||
|
|
|
@ -21,6 +21,7 @@ core14.contributor@status.im,229
|
|||
core15.contributor@status.im,230
|
||||
core16.contributor@status.im,231
|
||||
core17.contributor@status.im,232
|
||||
core18.contributor@status.im,233
|
||||
core2.contributor@status.im,156
|
||||
core3.contributor@status.im,157
|
||||
core4.contributor@status.im,158
|
||||
|
@ -42,6 +43,7 @@ desktop3.sme@status.im,196
|
|||
desktop4.sme@status.im,197
|
||||
desktop5.sme@status.im,198
|
||||
fin@status.im,118
|
||||
finance.project-lead@status.im,128
|
||||
finance_user1@status.im
|
||||
fluffy.project-lead@status.im,162
|
||||
harmeet@status.im,109
|
||||
|
|
|
@ -129,5 +129,13 @@ SPIFFWORKFLOW_BACKEND_ENGINE_STEP_DEFAULT_STRATEGY_WEB = environ.get(
|
|||
"SPIFFWORKFLOW_BACKEND_ENGINE_STEP_DEFAULT_STRATEGY_WEB", default="greedy"
|
||||
)
|
||||
|
||||
SPIFFWORKFLOW_BACKEND_USER_INPUT_REQUIRED_LOCK_RETRY_TIMES = int(
|
||||
environ.get("SPIFFWORKFLOW_BACKEND_USER_INPUT_REQUIRED_LOCK_RETRY_TIMES", default="3")
|
||||
)
|
||||
|
||||
SPIFFWORKFLOW_BACKEND_USER_INPUT_REQUIRED_LOCK_RETRY_INTERVAL_IN_SECONDS = int(
|
||||
environ.get("SPIFFWORKFLOW_BACKEND_USER_INPUT_REQUIRED_LOCK_RETRY_INTERVAL_IN_SECONDS", default="1")
|
||||
)
|
||||
|
||||
# this is only used in CI. use SPIFFWORKFLOW_BACKEND_DATABASE_URI instead for real configuration
|
||||
SPIFFWORKFLOW_BACKEND_DATABASE_PASSWORD = environ.get("SPIFFWORKFLOW_BACKEND_DATABASE_PASSWORD", default=None)
|
||||
|
|
|
@ -173,7 +173,17 @@ def process_instance_terminate(
|
|||
"""Process_instance_run."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.terminate()
|
||||
|
||||
try:
|
||||
processor.lock_process_instance("Web")
|
||||
processor.terminate()
|
||||
except (ProcessInstanceIsNotEnqueuedError, ProcessInstanceIsAlreadyLockedError) as e:
|
||||
ErrorHandlingService().handle_error(processor, e)
|
||||
raise e
|
||||
finally:
|
||||
if ProcessInstanceLockService.has_lock(process_instance.id):
|
||||
processor.unlock_process_instance("Web")
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
|
@ -183,7 +193,18 @@ def process_instance_suspend(
|
|||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_suspend."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
ProcessInstanceProcessor.suspend(process_instance)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
|
||||
try:
|
||||
processor.lock_process_instance("Web")
|
||||
processor.suspend()
|
||||
except (ProcessInstanceIsNotEnqueuedError, ProcessInstanceIsAlreadyLockedError) as e:
|
||||
ErrorHandlingService().handle_error(processor, e)
|
||||
raise e
|
||||
finally:
|
||||
if ProcessInstanceLockService.has_lock(process_instance.id):
|
||||
processor.unlock_process_instance("Web")
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
|
@ -193,7 +214,18 @@ def process_instance_resume(
|
|||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_resume."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
ProcessInstanceProcessor.resume(process_instance)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
|
||||
try:
|
||||
processor.lock_process_instance("Web")
|
||||
processor.resume()
|
||||
except (ProcessInstanceIsNotEnqueuedError, ProcessInstanceIsAlreadyLockedError) as e:
|
||||
ErrorHandlingService().handle_error(processor, e)
|
||||
raise e
|
||||
finally:
|
||||
if ProcessInstanceLockService.has_lock(process_instance.id):
|
||||
processor.unlock_process_instance("Web")
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
|
|
|
@ -378,8 +378,13 @@ def task_submit_shared(
|
|||
only_tasks_that_can_be_completed=True,
|
||||
)
|
||||
|
||||
retry_times = current_app.config["SPIFFWORKFLOW_BACKEND_USER_INPUT_REQUIRED_LOCK_RETRY_TIMES"]
|
||||
retry_interval_in_seconds = current_app.config[
|
||||
"SPIFFWORKFLOW_BACKEND_USER_INPUT_REQUIRED_LOCK_RETRY_INTERVAL_IN_SECONDS"
|
||||
]
|
||||
|
||||
with sentry_sdk.start_span(op="task", description="complete_form_task"):
|
||||
processor.lock_process_instance("Web")
|
||||
processor.lock_process_instance("Web", retry_times, retry_interval_in_seconds)
|
||||
ProcessInstanceService.complete_form_task(
|
||||
processor=processor,
|
||||
spiff_task=spiff_task,
|
||||
|
|
|
@ -91,9 +91,8 @@ from spiffworkflow_backend.services.file_system_service import FileSystemService
|
|||
from spiffworkflow_backend.services.process_instance_lock_service import (
|
||||
ProcessInstanceLockService,
|
||||
)
|
||||
from spiffworkflow_backend.services.process_instance_queue_service import (
|
||||
ProcessInstanceQueueService,
|
||||
)
|
||||
from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceIsAlreadyLockedError
|
||||
from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceQueueService
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||
from spiffworkflow_backend.services.service_task_service import ServiceTaskDelegate
|
||||
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
||||
|
@ -1276,7 +1275,7 @@ class ProcessInstanceProcessor:
|
|||
self.add_step()
|
||||
self.save()
|
||||
# Saving the workflow seems to reset the status
|
||||
self.suspend(self.process_instance_model)
|
||||
self.suspend()
|
||||
|
||||
def reset_process(self, spiff_step: int) -> None:
|
||||
"""Reset a process to an earlier state."""
|
||||
|
@ -1319,7 +1318,7 @@ class ProcessInstanceProcessor:
|
|||
db.session.delete(row)
|
||||
|
||||
self.save()
|
||||
self.suspend(self.process_instance_model)
|
||||
self.suspend()
|
||||
|
||||
@staticmethod
|
||||
def get_parser() -> MyCustomParser:
|
||||
|
@ -1485,8 +1484,23 @@ class ProcessInstanceProcessor:
|
|||
return the_status
|
||||
|
||||
# TODO: replace with implicit/more granular locking in workflow execution service
|
||||
def lock_process_instance(self, lock_prefix: str) -> None:
|
||||
ProcessInstanceQueueService.dequeue(self.process_instance_model)
|
||||
# TODO: remove the retry logic once all user_input_required's don't need to be locked to check timers
|
||||
def lock_process_instance(
|
||||
self, lock_prefix: str, retry_count: int = 0, retry_interval_in_seconds: int = 0
|
||||
) -> None:
|
||||
try:
|
||||
ProcessInstanceQueueService.dequeue(self.process_instance_model)
|
||||
except ProcessInstanceIsAlreadyLockedError as e:
|
||||
if retry_count > 0:
|
||||
current_app.logger.info(
|
||||
f"process_instance_id {self.process_instance_model.id} is locked. "
|
||||
f"will retry {retry_count} times with delay of {retry_interval_in_seconds}."
|
||||
)
|
||||
if retry_interval_in_seconds > 0:
|
||||
time.sleep(retry_interval_in_seconds)
|
||||
self.lock_process_instance(lock_prefix, retry_count - 1, retry_interval_in_seconds)
|
||||
else:
|
||||
raise e
|
||||
|
||||
# TODO: replace with implicit/more granular locking in workflow execution service
|
||||
def unlock_process_instance(self, lock_prefix: str) -> None:
|
||||
|
@ -1923,16 +1937,14 @@ class ProcessInstanceProcessor:
|
|||
db.session.add(self.process_instance_model)
|
||||
db.session.commit()
|
||||
|
||||
@classmethod
|
||||
def suspend(cls, process_instance: ProcessInstanceModel) -> None:
|
||||
def suspend(self) -> None:
|
||||
"""Suspend."""
|
||||
process_instance.status = ProcessInstanceStatus.suspended.value
|
||||
db.session.add(process_instance)
|
||||
self.process_instance_model.status = ProcessInstanceStatus.suspended.value
|
||||
db.session.add(self.process_instance_model)
|
||||
db.session.commit()
|
||||
|
||||
@classmethod
|
||||
def resume(cls, process_instance: ProcessInstanceModel) -> None:
|
||||
def resume(self) -> None:
|
||||
"""Resume."""
|
||||
process_instance.status = ProcessInstanceStatus.waiting.value
|
||||
db.session.add(process_instance)
|
||||
self.process_instance_model.status = ProcessInstanceStatus.waiting.value
|
||||
db.session.add(self.process_instance_model)
|
||||
db.session.commit()
|
||||
|
|
|
@ -25,6 +25,7 @@ from spiffworkflow_backend.models.process_instance_file_data import (
|
|||
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
||||
from spiffworkflow_backend.models.task import Task
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
from spiffworkflow_backend.services.assertion_service import safe_assertion
|
||||
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||
from spiffworkflow_backend.services.git_service import GitCommandError
|
||||
from spiffworkflow_backend.services.git_service import GitService
|
||||
|
@ -95,6 +96,13 @@ class ProcessInstanceService:
|
|||
)
|
||||
process_instance_lock_prefix = "Background"
|
||||
for process_instance in records:
|
||||
with safe_assertion(process_instance.status == status_value) as false_assumption:
|
||||
if false_assumption:
|
||||
raise AssertionError(
|
||||
f"Queue assumed process instance {process_instance.id} has status of {status_value} "
|
||||
f"when it really is {process_instance.status}"
|
||||
)
|
||||
|
||||
locked = False
|
||||
processor = None
|
||||
try:
|
||||
|
|
|
@ -1419,7 +1419,7 @@ class TestProcessApi(BaseTest):
|
|||
)
|
||||
processor.save()
|
||||
|
||||
processor.suspend(process_instance)
|
||||
processor.suspend()
|
||||
payload["description"] = "Message To Suspended"
|
||||
response = client.post(
|
||||
f"/v1.0/messages/{message_model_identifier}",
|
||||
|
@ -1431,7 +1431,7 @@ class TestProcessApi(BaseTest):
|
|||
assert response.json
|
||||
assert response.json["error_code"] == "message_not_accepted"
|
||||
|
||||
processor.resume(process_instance)
|
||||
processor.resume()
|
||||
payload["description"] = "Message To Resumed"
|
||||
response = client.post(
|
||||
f"/v1.0/messages/{message_model_identifier}",
|
||||
|
|
Loading…
Reference in New Issue