From af6676b27117398bf28b8582a88b9438aa4be501 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 15 Oct 2026 11:49:48 +0200 Subject: [PATCH 1/2] feat(task) #46 #45 Give a code to the task and the transformer, class name as service id - RequestTask: tagged { name: cleverage.task, code: soap_request } (cleverage/process-bundle#91), referenced with "task: soap_request". - RequestTransformer: tagged { name: cleverage.transformer, code: soap_request } (the code returned by getCode()), loaded lazily by cleverage/process-bundle 5.4 (cleverage/process-bundle#276). - Class name as service id for both, public with the container.private tag: fetching them directly from the service container is deprecated since 3.3, private in 4.0. Arguments, non-shared task and monolog.logger tags unchanged. - Former ids cleverage_soap_process.task.request and cleverage_soap_process.transformer.request: private deprecated aliases of the class names (since 3.3, removed in 4.0). - Tests: extension test for the ids, codes, container.private tags and the deprecated aliases. - Docs: code on the task reference page and template, examples switched to "task: ", configuration paragraph in docs/index.md; CHANGELOG. Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 2 + config/services/task.yaml | 21 +++-- config/services/transformer.yaml | 22 ++++-- docs/cookbooks/soap_call_and_export.md | 8 +- docs/cookbooks/soap_enrich_csv.md | 14 ++-- docs/index.md | 13 ++++ docs/reference/tasks/_template.md | 3 +- docs/reference/tasks/request_task.md | 5 +- .../CleverAgeSoapProcessExtensionTest.php | 78 +++++++++++++++---- 9 files changed, 125 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c03f39..eabba73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ Latest ------ ### Changes +* [#46](https://github.com/cleverage/soap-process-bundle/issues/46) Give a code to the task ([cleverage/process-bundle#91](https://github.com/cleverage/process-bundle/issues/91)): `soap_request` (`task: soap_request`, with `cleverage/process-bundle` 5.4 or later, referencing it by `service` being deprecated there). The task has its class name as service id; fetching it directly from the service container is deprecated (`container.private`), it will be private in 4.0. The former id `cleverage_soap_process.task.request` is a deprecated alias, removed in 4.0. Update documentation, add tests. +* [#45](https://github.com/cleverage/soap-process-bundle/issues/45) Tag the `RequestTransformer` with its code, `soap_request`, for its lazy loading by `cleverage/process-bundle` 5.4 or later ([cleverage/process-bundle#276](https://github.com/cleverage/process-bundle/issues/276)). The transformer has its class name as service id; fetching it directly from the service container is deprecated (`container.private`), it will be private in 4.0. The former id `cleverage_soap_process.transformer.request` is a deprecated alias, removed in 4.0. Update documentation, add tests. * [#43](https://github.com/cleverage/soap-process-bundle/issues/43) CI: test the lowest versions allowed by `composer.json` (`--prefer-lowest`, PHP 8.2). Require `psr/log` `^2|^3`: the loggers (of the tests, and `TaskLogger` of `cleverage/process-bundle`) use the typed `LoggerInterface` signatures of `psr/log` 2+, a fatal error with `psr/log` 1. * [#41](https://github.com/cleverage/soap-process-bundle/issues/41) Add a `.gitattributes`: the development files (`.docker/`, `.github/`, `tests/`, quality tools and PHPUnit configurations, `Makefile`) are no longer part of the archive installed by Composer (`dist`). * [#38](https://github.com/cleverage/soap-process-bundle/issues/38) Require `psr/log`, used directly by `Client` and `RequestTask` but only installed through `cleverage/process-bundle`. diff --git a/config/services/task.yaml b/config/services/task.yaml index 3a9ddb6..1dcb17d 100644 --- a/config/services/task.yaml +++ b/config/services/task.yaml @@ -1,13 +1,22 @@ services: - cleverage_soap_process.task.request: - class: CleverAge\SoapProcessBundle\Task\RequestTask - public: false + _defaults: + # Public for the direct access from the service container, deprecated since 3.3: private in 4.0 + public: true + tags: + - { name: container.private, package: cleverage/soap-process-bundle, version: '3.3' } + + CleverAge\SoapProcessBundle\Task\RequestTask: shared: false arguments: - '@logger' - '@cleverage_soap_process.registry.client' tags: + - { name: cleverage.task, code: soap_request } - { name: monolog.logger, channel: cleverage_process_task } - CleverAge\SoapProcessBundle\Task\RequestTask: - alias: cleverage_soap_process.task.request - public: true + cleverage_soap_process.task.request: + alias: CleverAge\SoapProcessBundle\Task\RequestTask + public: false + deprecated: + package: cleverage/soap-process-bundle + version: '3.3' + message: 'The "%alias_id%" service alias is deprecated, use the "soap_request" task code or the class name of the task instead. It will be removed in 4.0.' diff --git a/config/services/transformer.yaml b/config/services/transformer.yaml index c84d641..1cdaa8b 100644 --- a/config/services/transformer.yaml +++ b/config/services/transformer.yaml @@ -1,11 +1,21 @@ services: - cleverage_soap_process.transformer.request: - class: CleverAge\SoapProcessBundle\Transformer\RequestTransformer - public: false + _defaults: + # Public for the direct access from the service container, deprecated since 3.3: private in 4.0 + public: true + tags: + - { name: container.private, package: cleverage/soap-process-bundle, version: '3.3' } + + CleverAge\SoapProcessBundle\Transformer\RequestTransformer: arguments: - '@cleverage_soap_process.registry.client' tags: - - { name: cleverage.transformer } + # The code is the one returned by RequestTransformer::getCode(): the transformer is loaded lazily + - { name: cleverage.transformer, code: soap_request } - { name: monolog.logger, channel: cleverage_process_transformer } - CleverAge\SoapProcessBundle\Transformer\RequestTransformer: - alias: cleverage_soap_process.transformer.request + cleverage_soap_process.transformer.request: + alias: CleverAge\SoapProcessBundle\Transformer\RequestTransformer + public: false + deprecated: + package: cleverage/soap-process-bundle + version: '3.3' + message: 'The "%alias_id%" service alias is deprecated, use the "soap_request" transformer code or the class name of the transformer instead. It will be removed in 4.0.' diff --git a/docs/cookbooks/soap_call_and_export.md b/docs/cookbooks/soap_call_and_export.md index 3766643..0a41511 100644 --- a/docs/cookbooks/soap_call_and_export.md +++ b/docs/cookbooks/soap_call_and_export.md @@ -12,7 +12,7 @@ clever_age_process: description: 'Export the European countries from the CountryInfoService' tasks: list_countries: - service: '@CleverAge\SoapProcessBundle\Task\RequestTask' + task: soap_request error_strategy: stop options: client: country_info @@ -20,7 +20,7 @@ clever_age_process: outputs: [extract] extract: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: property_accessor: # Get the list of countries from the stdClass response @@ -48,11 +48,11 @@ clever_age_process: outputs: [iterate] iterate: - service: '@CleverAge\ProcessBundle\Task\InputIteratorTask' + task: input_iterator outputs: [write] write: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/exports/european_countries_{date}.csv' headers: [iso_code, name, capital, phone_code, currency] diff --git a/docs/cookbooks/soap_enrich_csv.md b/docs/cookbooks/soap_enrich_csv.md index 2b7c73d..aafa920 100644 --- a/docs/cookbooks/soap_enrich_csv.md +++ b/docs/cookbooks/soap_enrich_csv.md @@ -21,13 +21,13 @@ clever_age_process: description: 'Add the capital city and currency of each country' tasks: read: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvReaderTask' + task: csv_reader options: file_path: '%kernel.project_dir%/var/data/countries.csv' outputs: [build_arguments] build_arguments: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: # { parameters: { sCountryISOCode: FR } } @@ -40,7 +40,7 @@ clever_age_process: outputs: [get_country] get_country: - service: '@CleverAge\SoapProcessBundle\Task\RequestTask' + task: soap_request error_strategy: skip options: client: country_info @@ -49,13 +49,13 @@ clever_age_process: error_outputs: [log_error] log_error: - service: '@CleverAge\ProcessBundle\Task\Reporting\LoggerTask' + task: logger options: level: warning message: 'FullCountryInfo call failed, line skipped' map_response: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: property_accessor: @@ -75,7 +75,7 @@ clever_age_process: outputs: [write] write: - service: '@CleverAge\ProcessBundle\Task\File\Csv\CsvWriterTask' + task: csv_writer options: file_path: '%kernel.project_dir%/var/exports/countries_enriched_{date}.csv' headers: [iso, name, capital, currency] @@ -109,7 +109,7 @@ To add a single value to the line instead of replacing it, the SOAP call can als ```yaml # Task configuration level add_country_name: - service: '@CleverAge\ProcessBundle\Task\TransformerTask' + task: transformer options: transformers: mapping: diff --git a/docs/index.md b/docs/index.md index a59b596..410e6c3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -41,6 +41,19 @@ services: - { name: cleverage.soap.client } ``` +The task is registered as a service (non-shared) and is used in your processes by its code, `soap_request` (e.g. +`task: soap_request`, requires `cleverage/process-bundle` 5.4 or later, see its +[task definition](https://github.com/cleverage/process-bundle/blob/main/docs/reference/02-task_definition.md)). +Referencing it by its class name (`service: '@CleverAge\SoapProcessBundle\Task\RequestTask'`) is deprecated since +`cleverage/process-bundle` 5.4. + +The transformer is tagged with its code, `soap_request` (the transformers and the tasks have separate codes): with +`cleverage/process-bundle` 5.4 or later, it is loaded lazily, only when a process uses it. + +The service id of the task and of the transformer is their class name. Fetching them directly from the service container +is deprecated since 3.3 (they will be private in 4.0); their former ids, `cleverage_soap_process.task.request` and +`cleverage_soap_process.transformer.request`, are deprecated aliases since 3.3, removed in 4.0. + ## Reference - [Client](reference/client.md) diff --git a/docs/reference/tasks/_template.md b/docs/reference/tasks/_template.md index 919390a..4e8ea00 100644 --- a/docs/reference/tasks/_template.md +++ b/docs/reference/tasks/_template.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `Fully\Qualified\ClassName` +* **Code**: `soap_task_code` (`task: soap_task_code`) * **Iterable task** _(only if it implements `IterableTaskInterface`)_ * **Blocking task** _(only if it implements `BlockingTaskInterface`)_ * **Flushable task** _(only if it implements `FlushableTaskInterface`)_ @@ -39,7 +40,7 @@ Examples ```yaml # Task configuration level code: - service: '@Fully\Qualified\ClassName' + task: soap_task_code options: a: 1 b: 2 diff --git a/docs/reference/tasks/request_task.md b/docs/reference/tasks/request_task.md index 0aebd3f..0b0cbe5 100644 --- a/docs/reference/tasks/request_task.md +++ b/docs/reference/tasks/request_task.md @@ -7,6 +7,7 @@ Task reference -------------- * **Service**: `CleverAge\SoapProcessBundle\Task\RequestTask` +* **Code**: `soap_request` (`task: soap_request`) Accepted inputs --------------- @@ -54,7 +55,7 @@ Examples ```yaml # Task configuration level list_countries: - service: '@CleverAge\SoapProcessBundle\Task\RequestTask' + task: soap_request options: client: country_info method: FullCountryInfoAllCountries @@ -67,7 +68,7 @@ list_countries: ```yaml # Task configuration level get_order: - service: '@CleverAge\SoapProcessBundle\Task\RequestTask' + task: soap_request error_strategy: skip options: client: legacy_erp diff --git a/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php b/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php index d9839df..ff1815f 100644 --- a/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php +++ b/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php @@ -20,7 +20,6 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; #[CoversClass(CleverAgeSoapProcessExtension::class)] @@ -32,15 +31,22 @@ public function testServices(): void (new CleverAgeSoapProcessExtension())->load([], $container); self::assertSame(ClientRegistry::class, $container->getDefinition('cleverage_soap_process.registry.client')->getClass()); + } + + public function testTaskIsRegistered(): void + { + $container = new ContainerBuilder(); + (new CleverAgeSoapProcessExtension())->load([], $container); - $taskIds = array_keys(array_filter($container->getDefinitions(), static fn ($definition): bool => RequestTask::class === $definition->getClass())); - self::assertCount(1, $taskIds); - $task = $container->getDefinition($taskIds[0]); + // The class name is the service id + $task = $container->getDefinition(RequestTask::class); // Tasks are stateful: each process execution must get its own instance self::assertFalse($task->isShared()); - // Referenced as '@' in process configurations - self::assertSame($taskIds[0], (string) $container->getAlias(RequestTask::class)); - self::assertTrue($container->getAlias(RequestTask::class)->isPublic()); + // Referenced by its code in the process configurations (task: soap_request) + self::assertSame([['code' => 'soap_request']], $task->getTag('cleverage.task')); + // Public for the direct access from the service container, deprecated + self::assertTrue($task->isPublic()); + self::assertSame([['package' => 'cleverage/soap-process-bundle', 'version' => '3.3']], $task->getTag('container.private')); // Logged in the process tasks channel: the "channel" of the "monolog.logger" tag only applies to a reference to // the "logger" service self::assertSame([['channel' => 'cleverage_process_task']], $task->getTag('monolog.logger')); @@ -50,13 +56,55 @@ public function testServices(): void $references[] = (string) $argument; } } - self::assertContains('logger', $references); - self::assertNotContains('monolog.logger', $references); - - $transformers = array_filter($container->getDefinitions(), static fn ($definition): bool => RequestTransformer::class === $definition->getClass()); - self::assertCount(1, $transformers); - $transformer = current($transformers); - self::assertInstanceOf(Definition::class, $transformer); - self::assertTrue($transformer->hasTag('cleverage.transformer')); + self::assertSame(['logger', 'cleverage_soap_process.registry.client'], $references); + + // Former id, deprecated + $this->assertDeprecatedAlias( + $container, + 'cleverage_soap_process.task.request', + RequestTask::class, + 'The "cleverage_soap_process.task.request" service alias is deprecated, use the "soap_request" task code or the class name of the task instead. It will be removed in 4.0.', + ); + } + + public function testTransformerIsRegistered(): void + { + $container = new ContainerBuilder(); + (new CleverAgeSoapProcessExtension())->load([], $container); + + // The class name is the service id + $transformer = $container->getDefinition(RequestTransformer::class); + // Loaded lazily by its code, which must be the one returned by getCode() + $code = (new RequestTransformer(new ClientRegistry()))->getCode(); + self::assertSame('soap_request', $code); + self::assertSame([['code' => $code]], $transformer->getTag('cleverage.transformer')); + // Public for the direct access from the service container, deprecated + self::assertTrue($transformer->isPublic()); + self::assertSame([['package' => 'cleverage/soap-process-bundle', 'version' => '3.3']], $transformer->getTag('container.private')); + self::assertSame([['channel' => 'cleverage_process_transformer']], $transformer->getTag('monolog.logger')); + $arguments = $transformer->getArguments(); + self::assertCount(1, $arguments); + self::assertInstanceOf(Reference::class, $arguments[0]); + self::assertSame('cleverage_soap_process.registry.client', (string) $arguments[0]); + + // Former id, deprecated + $this->assertDeprecatedAlias( + $container, + 'cleverage_soap_process.transformer.request', + RequestTransformer::class, + 'The "cleverage_soap_process.transformer.request" service alias is deprecated, use the "soap_request" transformer code or the class name of the transformer instead. It will be removed in 4.0.', + ); + } + + private function assertDeprecatedAlias(ContainerBuilder $container, string $id, string $target, string $message): void + { + $alias = $container->getAlias($id); + self::assertSame($target, (string) $alias); + self::assertFalse($alias->isPublic()); + self::assertTrue($alias->isDeprecated()); + self::assertSame( + ['package' => 'cleverage/soap-process-bundle', 'version' => '3.3', 'message' => $message], + $alias->getDeprecation($id) + ); } } From 52c92d1e02f7dc6d936d6576367fa2660692ddac Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 15 Oct 2026 11:53:21 +0200 Subject: [PATCH 2/2] test #46 #45 Declare the RequestTransformer as used by the extension test The transformer test instantiates RequestTransformer to compare the tag code with getCode(): with a coverage driver, the test was risky (code executed but not listed as covered or used). Co-Authored-By: Claude Opus 5.5 (1M context) --- tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php b/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php index ff1815f..0418d55 100644 --- a/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php +++ b/tests/DependencyInjection/CleverAgeSoapProcessExtensionTest.php @@ -18,11 +18,13 @@ use CleverAge\SoapProcessBundle\Task\RequestTask; use CleverAge\SoapProcessBundle\Transformer\RequestTransformer; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; #[CoversClass(CleverAgeSoapProcessExtension::class)] +#[UsesClass(RequestTransformer::class)] class CleverAgeSoapProcessExtensionTest extends TestCase { public function testServices(): void