prepare workflows

This commit is contained in:
Dennis Eichhorn 2023-04-21 19:13:03 +00:00
parent fe21c97c5f
commit 94f57e6121
5 changed files with 128 additions and 26 deletions

View File

@ -21,8 +21,9 @@
"en": "Check condition",
"de": "Überprüfe Bedingung"
},
"function_type": "API",
"function_type": "Api",
"function": "apiValidateCondition",
"module": "Workflow",
"inputs": [
"field_name",
"field_value",
@ -181,8 +182,9 @@
"en": "Takes input data and forwards the data to another action. Check the outputs and inputs of the actions to create the correct mapping.",
"de": "Übernimmt Eingangsdaten und leitet diese an eine andere Aktion weiter. Überprüfe die Ausgaben und Eingaben der jeweiligen Aktionen um die korrekten Verknüpfungen zu erstellen."
},
"function_type": "API",
"function_type": "Api",
"function": "apiAdapter",
"module": "Workflow",
"inputs": [
"map",
"{*}"
@ -217,8 +219,9 @@
"en": "Listens to trigger",
"de": "Wartet auf Trigger"
},
"function_type": "API",
"function_type": "Api",
"function": "apiListenToTrigger",
"module": "Workflow",
"inputs": [
"type",
"trigger",
@ -328,8 +331,9 @@
"en": "Takes input data and forwards the data to another action. Check the outputs and inputs of the actions to create the correct mapping.",
"de": "Übernimmt Eingangsdaten und leitet diese an eine andere Aktion weiter. Überprüfe die Ausgaben und Eingaben der jeweiligen Aktionen um die korrekten Verknüpfungen zu erstellen."
},
"function_type": "API",
"function_type": "Api",
"function": "apiRun",
"module": "Workflow",
"inputs": [
"map",
"{*}"
@ -359,13 +363,18 @@
}
},
"1005500005": {
"name": "Timed Trigger",
"name": "Timed Trigger (Job/Task)",
"description": {
"en": "Timed trigger",
"de": "Wartet auf Trigger"
"en": "Timed trigger (Job/Task)",
"de": "Zeitgesteuerter Trigger (Job/Task)"
},
"function_type": "API",
"function_type": "Api",
"function": "apiRun",
"module": "Workflow",
"function_install": {
"module": "Workflow",
"function": "installTimedTrigger"
},
"inputs": [
"interval",
"{*}"
@ -398,8 +407,9 @@
"en": "Cli action",
"de": "Konsolenbefehl"
},
"function_type": "API",
"function_type": "Api",
"function": "apiRun",
"module": "Workflow",
"inputs": [
"cmd",
"{*}"
@ -432,8 +442,9 @@
"en": "Workflow script",
"de": "Workflow Script"
},
"function_type": "API",
"function_type": "Api",
"function": "apiRun",
"module": "Workflow",
"inputs": [
"{*}"
],

View File

@ -35,9 +35,12 @@ use phpOMS\Message\NotificationLevel;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Model\Message\FormValidation;
use phpOMS\System\File\FileUtils;
use phpOMS\System\MimeType;
use phpOMS\Utils\Parser\Markdown\Markdown;
use phpOMS\Utils\StringUtils;
use phpOMS\Utils\TaskSchedule\SchedulerFactory;
use phpOMS\Utils\TaskSchedule\TaskFactory;
use phpOMS\Views\View;
/**
@ -495,9 +498,49 @@ final class ApiController extends Controller
$this->createDatabaseForTemplate($template);
}
// perform other workflow installation actions
$actions = \json_decode(\file_get_contents(__DIR__ . '/../Definitions/actions.json'), true);
$this->installWorkflowModel($template, $actions);
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Template', 'Template successfully created', $template);
}
private function installWorkflowModel(WorkflowTemplate $template, array $actions) : void
{
$schema = $template->schema;
foreach ($schema as $primary) {
$id = $primary['id'] ?? '';
if (!isset($actions[$id]['function_install'])) {
continue;
}
$this->app->moduleManager->get($actions[$id]['function_install']['module'])->{$actions[$id]['function_install']['function_install_function']}($template);
}
}
public function installTimedTrigger(WorkflowTemplate $template) : void
{
$id = 'Workflow-' . $template->getId();
$scheduler = SchedulerFactory::create();
if (!empty($scheduler->getAllByName($id))) {
return;
}
$job = TaskFactory::create($id);
$job->interval = $template->schema['settings']['interval'] ?? '';
$job->command = 'php '
. FileUtils::absolute(__DIR__ . '/../../../Cli/cli.php')
. ' /workflow/instance -id '
. $template->getId()
. ' -trigger 1005500005';
$scheduler->create($job);
$scheduler->reload();
}
/**
* Parse and replace placeholder elements
*

View File

@ -14,7 +14,9 @@ declare(strict_types=1);
namespace Modules\Workflow\Controller;
use Modules\Workflow\Models\WorkflowInstance;
use Modules\Workflow\Models\WorkflowInstanceAbstract;
use Modules\Workflow\Models\WorkflowInstanceAbstractMapper;
use Modules\Workflow\Models\WorkflowStatus;
use Modules\Workflow\Models\WorkflowTemplate;
use Modules\Workflow\Models\WorkflowTemplateMapper;
@ -122,6 +124,21 @@ final class CliController extends Controller
return $view;
}
public function runWorkflowElement(array $actions, WorkflowTemplate $template, WorkflowInstanceAbstract $instance, array $element) : void
{
if (isset($actions[$element['id']])) {
$result = $this->app->moduleManager
->get($actions[$element['id']]['modules'], $actions[$element['id']]['function_type'])
->{$actions[$element['id']]['function']}($template);
}
// @todo: currently all children are executed one after another, maybe consider parallel execution
foreach ($element['children'] as $child) {
// @todo: pass previous results (probably needs a populator for input variables based on previous output variables)
$this->runWorkflowElement($actions, $template, $instance, $child);
}
}
/**
* Validate template create request
*
@ -134,7 +151,7 @@ final class CliController extends Controller
private function validateInstanceCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['j'] = !$request->hasData('j'))) {
if (($val['id'] = !$request->hasData('id'))) {
return $val;
}
@ -147,6 +164,8 @@ final class CliController extends Controller
* @param RequestAbstract $request Request
*
* @return WorkflowInstanceAbstract
*
* @todo: How to handle workflow instances which are not saved in the database and are continued?
*
* @since 1.0.0
*/
@ -154,28 +173,21 @@ final class CliController extends Controller
{
/** @var \Modules\Workflow\Models\WorkflowTemplate $template */
$template = WorkflowTemplateMapper::get()
->where('id', (int) $request->getData('j'))
->where('id', (int) $request->getData('id'))
->execute();
$controller = null;
$instance = new WorkflowInstance();
$files = $template->source->getSources();
foreach ($files as $tMedia) {
$lowerPath = \strtolower($tMedia->getPath());
$actions = \json_decode(\file_get_contents(__DIR__ . '/../Definitions/actions.json'), true);
switch (true) {
case StringUtils::endsWith($lowerPath, 'WorkflowController.php'):
require_once $lowerPath;
foreach ($template->schema as $e) {
if ($e['id'] === $request->getDataString('trigger')) {
$this->runWorkflowElement($actions, $template, $instance, $e);
$controller = new WorkflowController($this->app, $template);
break;
break;
}
}
/** @var \Modules\Workflow\Models\WorkflowControllerInterface $controller */
$instance = $controller->createInstanceFromRequest($request, $template);
$controller->createInstanceDbModel($instance);
return $instance;
}
}

View File

@ -14,4 +14,13 @@ A `States.php` file contains all workflow states. This is especially important i
The `Workflow.php` file is the heart of every workflow. This file is responsible for executing state driven actions and it can also be seen as the API for a workflow. All workflow related actions will be forwarded to this file and can be handled inside including database queries.
##
##
1. Workflow gets installed with a trigger (either hook or cron job)
2. Trigger is fired
3. Hook loads CliApplication::installWorkflowTemplate with template ID, action ID and Hook
4. Installer creates WorkflowInstance Model
5. Installer calls CliApplication::runWorkflow with template, action ID, Hook, instance, and element for every element on this level.
6. runWorkflow executes the element by calling the respective function
7. runWorkflow calls itself with all child elements

View File

@ -0,0 +1,27 @@
<?php
/**
* Karaka
*
* PHP Version 8.1
*
* @package Modules\Workflow\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Workflow\Models;
/**
* Workflow instance model
*
* @package Modules\Workflow\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class WorkflowInstance extends WorkflowInstanceAbstract
{
}