diff --git a/config/services/http_value_resolver.yaml b/config/services/http_value_resolver.yaml index 21b40f2..3f59048 100644 --- a/config/services/http_value_resolver.yaml +++ b/config/services/http_value_resolver.yaml @@ -5,6 +5,7 @@ services: public: false arguments: - '%upload_directory%' + - '@serializer' cleverage_ui_process.http_value_resolver.process_configuration: class: CleverAge\UiProcessBundle\Http\ValueResolver\ProcessConfigurationValueResolver diff --git a/docs/index.md b/docs/index.md index db90d03..5297d9e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -52,12 +52,25 @@ That's all, now you can launch a process via http post request ***Curl sample*** ```bash make bash -curl --location 'http://apache2/http/process/execute?code=demo.die' \ ---header 'Authorization: Bearer 3da8409b5f5b640fb0c43d68e8ac8d23' \ ---form 'input=@"/file.csv"' \ ---form 'context[context_1]="FOO"' \ ---form 'context[context_2]="BAR"' +curl --location 'http://localhost/http/process/execute' \ +--header 'Authorization: Bearer myBearerToken' \ +--form 'input=@"/path/to/your/file.csv"' \ +--form 'code="demo.dummy"' \ +--form 'context="{\"foo\": \"bar\"}"' ``` + +```bash +make bash +curl --location 'http://localhost/http/process/execute' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer d641d254aed12733758a3a4247559868' \ +--header 'Cookie: PHPSESSID=m8l9s5sniknv1b0jb798f8sri7; main_auth_profile_token=2f3d24' \ +--data '{ +"code": "demo.die", +"context": {"foo": "bar"} +}' +``` + * Query string code parameter must be a valid process code * Header Authorization: Bearer is the previously generated token * input could be string or file representation diff --git a/src/Controller/ProcessExecuteController.php b/src/Controller/ProcessExecuteController.php index 5de49d2..21c351b 100644 --- a/src/Controller/ProcessExecuteController.php +++ b/src/Controller/ProcessExecuteController.php @@ -17,7 +17,7 @@ use CleverAge\UiProcessBundle\Message\ProcessExecuteMessage; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; +use Symfony\Component\HttpKernel\Attribute\ValueResolver; use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Attribute\Route; @@ -27,7 +27,7 @@ class ProcessExecuteController extends AbstractController { public function __invoke( - #[MapRequestPayload] HttpProcessExecution $httpProcessExecution, + #[ValueResolver('http_process_execution')] HttpProcessExecution $httpProcessExecution, ValidatorInterface $validator, MessageBusInterface $bus, ): JsonResponse { @@ -43,7 +43,9 @@ public function __invoke( new ProcessExecuteMessage( $httpProcessExecution->code ?? '', $httpProcessExecution->input, - $httpProcessExecution->context + \is_string($httpProcessExecution->context) + ? json_decode($httpProcessExecution->context, true) + : $httpProcessExecution->context ) ); diff --git a/src/Http/Model/HttpProcessExecution.php b/src/Http/Model/HttpProcessExecution.php index fc4272f..fd9f62b 100644 --- a/src/Http/Model/HttpProcessExecution.php +++ b/src/Http/Model/HttpProcessExecution.php @@ -14,8 +14,11 @@ namespace CleverAge\UiProcessBundle\Http\Model; use CleverAge\UiProcessBundle\Validator\IsValidProcessCode; +use Symfony\Component\Validator\Constraints\AtLeastOneOf; +use Symfony\Component\Validator\Constraints\Json; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Sequentially; +use Symfony\Component\Validator\Constraints\Type; final readonly class HttpProcessExecution { @@ -26,7 +29,8 @@ public function __construct( #[Sequentially(constraints: [new NotNull(message: 'Process code is required.'), new IsValidProcessCode()])] public ?string $code = null, public ?string $input = null, - public array $context = [], + #[AtLeastOneOf(constraints: [new Json(), new Type('array')])] + public string|array $context = [], ) { } } diff --git a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php index 5e2aafe..411f0cc 100644 --- a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php +++ b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php @@ -20,11 +20,12 @@ use Symfony\Component\HttpKernel\Attribute\AsTargetedValueResolver; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; +use Symfony\Component\Serializer\SerializerInterface; #[AsTargetedValueResolver('http_process_execution')] readonly class HttpProcessExecuteValueResolver implements ValueResolverInterface { - public function __construct(private string $storageDir) + public function __construct(private string $storageDir, private SerializerInterface $serializer) { } @@ -33,13 +34,31 @@ public function __construct(private string $storageDir) */ public function resolve(Request $request, ArgumentMetadata $argument): iterable { - $input = $request->get('input', $request->files->get('input')); - if ($input instanceof UploadedFile) { - $uploadFileName = $this->storageDir.\DIRECTORY_SEPARATOR.date('YmdHis').'_'.uniqid().'_'.$input->getClientOriginalName(); - (new Filesystem())->dumpFile($uploadFileName, $input->getContent()); - $input = $uploadFileName; - } + $all = $request->request->all(); + try { + if ([] === $all) { + $httpProcessExecution = $this->serializer->deserialize( + $request->getContent(), + HttpProcessExecution::class, + 'json' + ); + } else { + $input = $request->get('input', $request->files->get('input')); + if ($input instanceof UploadedFile) { + $uploadFileName = $this->storageDir.\DIRECTORY_SEPARATOR.date('YmdHis').'_'.uniqid().'_'.$input->getClientOriginalName(); + (new Filesystem())->dumpFile($uploadFileName, $input->getContent()); + $input = $uploadFileName; + } + $httpProcessExecution = new HttpProcessExecution( + $request->get('code'), + $input, + $request->get('context', []) + ); + } - return [new HttpProcessExecution($request->get('code'), $input, $request->get('context', []))]; + return [$httpProcessExecution]; + } catch (\Throwable) { + return [new HttpProcessExecution()]; + } } }