Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ProcessMaker/Facades/WorkflowManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*
* @method static mixed callProcess($filename, $processId)
* @method static mixed triggerStartEvent($definitions, $event, array $data)
* @method static mixed completeTask(\ProcessMaker\Models\Process $definitions, \ProcessMaker\Nayra\Contracts\Bpmn\ExecutionInstanceInterface $instance, \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface $token, array $data)
* @method static mixed taskFailed(\ProcessMaker\Nayra\Contracts\Bpmn\ExecutionInstanceInterface $instance, \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface $token, string $error)
* @method static mixed runScripTask(\ProcessMaker\Nayra\Contracts\Bpmn\ScriptTaskInterface $scriptTask, Token $token)
* @method static mixed runServiceTask(\ProcessMaker\Nayra\Contracts\Bpmn\ServiceTaskInterface $serviceTask, Token $token)
* @method static void throwSignalEventDefinition(\ProcessMaker\Nayra\Contracts\Bpmn\EventDefinitionInterface $sourceEventDefinition, \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface $token)
Expand Down
129 changes: 129 additions & 0 deletions ProcessMaker/Jobs/RunNayraScriptTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace ProcessMaker\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use ProcessMaker\Exception\ScriptException;
use ProcessMaker\Facades\WorkflowManager;
use ProcessMaker\Managers\DataManager;
use ProcessMaker\Models\ProcessRequestToken;
use ProcessMaker\Models\Script;
use ProcessMaker\Models\ScriptExecutor;
use ProcessMaker\Nayra\Contracts\Bpmn\ScriptTaskInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface;
use Throwable;

/**
* This job runs a script task with custom language like nodejs
*/
class RunNayraScriptTask implements ShouldQueue
{
use Dispatchable,
InteractsWithQueue,
Queueable,
SerializesModels;

public $tokenId;

public $userId;

/**
* Create a new job instance.
*
* @param \ProcessMaker\Models\ProcessRequestToken $token
* @param array $data
*/
public function __construct(TokenInterface $token)
{
$this->tokenId = $token->getKey();
}

/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// Get token
$token = ProcessRequestToken::find($this->tokenId);
$token->loadTokenProperties();
$instance = $token->processRequest;
$processModel = $token->process;
$instance->loadProcessRequestInstance();
$token->setInstance($instance);
$element = $token->getDefinition(true);

// Exit if the task was completed or closed
if (!$token || !$element) {
return;
}
$scriptRef = $element->getProperty('scriptRef');
$configuration = json_decode($element->getProperty('config'), true);
$errorHandling = json_decode($element->getProperty('errorHandling'), true);
if ($errorHandling === null) {
$errorHandling = [];
}

// Check to see if we've failed parsing. If so, let's convert to empty array.
if ($configuration === null) {
$configuration = [];
}
try {
if (empty($scriptRef)) {
$code = $element->getScript();
if (empty($code)) {
throw new ScriptException(__('No code or script assigned to ":name"', ['name' => $element->getName()]));
}
$language = Script::scriptFormat2Language($element->getProperty('scriptFormat', 'application/x-php'));
$script = new Script([
'code' => $code,
'language' => $language,
'run_as_user_id' => Script::defaultRunAsUser()->id,
'script_executor_id' => ScriptExecutor::initialExecutor($language)->id,
]);
} else {
$script = Script::findOrFail($scriptRef)->versionFor($instance);
}

$dataManager = new DataManager();
$data = $dataManager->getData($token);
$response = $script->runScript($data, $configuration, $token->getId(), $errorHandling);

// Dispatch complete task action
WorkflowManager::completeTask($processModel, $instance, $token, $response['output']);
} catch (Throwable $exception) {
Log::error('Script failed: ' . $scriptRef . ' - ' . $exception->getMessage());
Log::error($exception->getTraceAsString());
WorkflowManager::taskFailed($instance, $token, $exception->getMessage());
}
}

/**
* When Job fails
*/
public function failed(Throwable $exception)
{
if (!$this->tokenId) {
Log::error('Script failed: ' . $exception->getMessage());

return;
}
Log::error('Script (#' . $this->tokenId . ') failed: ' . $exception->getMessage());
$token = ProcessRequestToken::find($this->tokenId);
if ($token) {
$element = $token->getBpmnDefinition();
$token->setStatus(ScriptTaskInterface::TOKEN_STATE_FAILING);
$error = $element->getRepository()->createError();
$error->setName($exception->getMessage());
$token->setProperty('error', $error);
Log::error($exception->getTraceAsString());
$token->save();
}
}
}
44 changes: 37 additions & 7 deletions ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class WorkflowManagerRabbitMq extends WorkflowManagerDefault implements Workflow

const ACTION_TRIGGER_SIGNAL_EVENT = 'TRIGGER_SIGNAL_EVENT';

const ACTION_TASK_FAILED = 'TASK_FAILED';

/**
* Trigger a start event and return the process request instance.
*
Expand Down Expand Up @@ -113,7 +115,7 @@ public function triggerStartEvent(Definitions $definitions, StartEventInterface
*
* @param Definitions $definitions
* @param ExecutionInstanceInterface $instance
* @param TokenInterface $token
* @param TokenInterface|ProcessRequestToken $token
* @param array $data
*
* @return void
Expand Down Expand Up @@ -146,6 +148,39 @@ public function completeTask(Definitions $definitions, ExecutionInstanceInterfac
]);
}

/**
* Fail a task.
*
* @param ExecutionInstanceInterface $instance
* @param TokenInterface|ProcessRequestToken $token
* @param string $error
*
* @return void
*/
public function taskFailed(ExecutionInstanceInterface $instance, TokenInterface $token, string $error)
{
// Get complementary information
$version = $instance->process_version_id;
$userId = $this->getCurrentUserId();
$state = $this->serializeState($instance);

// Dispatch complete task action
$this->dispatchAction([
'bpmn' => $version,
'action' => self::ACTION_TASK_FAILED,
'params' => [
'request_id' => $token->process_request_id,
'token_id' => $token->uuid,
'element_id' => $token->element_id,
'error' => $error,
],
'state' => $state,
'session' => [
'user_id' => $userId,
],
]);
}

/**
* Complete a catch event.
*
Expand Down Expand Up @@ -312,15 +347,10 @@ public function handleServiceTask(ProcessRequestToken $token)
],
]);
} catch (Throwable $exception) {
// Change to error status
$token->setStatus(ServiceTaskInterface::TOKEN_STATE_FAILING);
$error = $element->getRepository()->createError();
$error->setName($exception->getMessage());
$token->setProperty('error', $error);

// Log message errors
Log::info('Service task failed: ' . $implementation . ' - ' . $exception->getMessage());
Log::error($exception->getTraceAsString());
$this->taskFailed($instance, $token, $exception->getMessage());
}
}

Expand Down
8 changes: 8 additions & 0 deletions ProcessMaker/Nayra/Repositories/PersistenceHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use ProcessMaker\Jobs\RunNayraScriptTask;
use ProcessMaker\Listeners\BpmnSubscriber;
use ProcessMaker\Managers\TaskSchedulerManager;
use ProcessMaker\Models\ProcessRequest;
Expand Down Expand Up @@ -137,6 +138,13 @@ public function save(array $transaction)
$subscriber = new BpmnSubscriber();
$subscriber->onServiceTaskActivated($serviceTask, $token);
break;
case 'script_task_executor':
// Get object instances
$token = $this->deserializer->unserializeToken($transaction['token']);

// Trigger script task executor
RunNayraScriptTask::dispatch($token)->onQueue('bpmn');
break;
default:
throw new Exception('Unknown transaction type ' . $transaction['type']);
}
Expand Down