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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Yokai\Batch\Bridge\Symfony\Console\CommandRunner;
use Yokai\Batch\Bridge\Symfony\Console\RunCommandJobLauncher;
use Yokai\Batch\Factory\JobExecutionFactory;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\NullJobExecutionParametersBuilder;
use Yokai\Batch\Factory\UniqidJobExecutionIdGenerator;
use Yokai\Batch\Test\Storage\InMemoryJobExecutionStorage;

Expand All @@ -29,7 +30,7 @@ public function testLaunch(): void
->shouldBeCalledTimes(1);

$launcher = new RunCommandJobLauncher(
new JobExecutionFactory(new UniqidJobExecutionIdGenerator()),
new JobExecutionFactory(new UniqidJobExecutionIdGenerator(), new NullJobExecutionParametersBuilder()),
$commandRunner->reveal(),
$storage = new InMemoryJobExecutionStorage(),
'test.log'
Expand Down
3 changes: 2 additions & 1 deletion src/batch-symfony-console/tests/RunJobCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Yokai\Batch\Bridge\Symfony\Console\RunJobCommand;
use Yokai\Batch\Exception\UnexpectedValueException;
use Yokai\Batch\Factory\JobExecutionFactory;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\NullJobExecutionParametersBuilder;
use Yokai\Batch\Factory\UniqidJobExecutionIdGenerator;
use Yokai\Batch\Job\JobExecutionAccessor;
use Yokai\Batch\Job\JobExecutor;
Expand All @@ -38,7 +39,7 @@ protected function setUp(): void
$this->job = $this->prophesize(JobInterface::class);

$this->accessor = new JobExecutionAccessor(
new JobExecutionFactory(new UniqidJobExecutionIdGenerator()),
new JobExecutionFactory(new UniqidJobExecutionIdGenerator(), new NullJobExecutionParametersBuilder()),
new InMemoryJobExecutionStorage(),
);
$this->executor = new JobExecutor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* @phpstan-type Config array{
* storage: StorageConfig,
* launcher: LauncherConfig,
* parameters: ParametersConfig,
* ui: UserInterfaceConfig,
* }
* @phpstan-type StorageConfig array{
Expand All @@ -31,6 +32,10 @@
* default: string|null,
* launchers: array<string, string>,
* }
* @phpstan-type ParametersConfig array{
* global: array<string, mixed>,
* per_job: array<string, array<string, mixed>>,
* }
* @phpstan-type UserInterfaceConfig array{
* enabled: bool,
* security: array{
Expand Down Expand Up @@ -59,6 +64,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->children()
->append($this->storage())
->append($this->launcher())
->append($this->parameters())
->append($this->ui())
->end()
;
Expand Down Expand Up @@ -131,6 +137,47 @@ private function launcher(): ArrayNodeDefinition
return $node;
}

private function parameters(): ArrayNodeDefinition
{
/** @var ArrayNodeDefinition $node */
$node = (new TreeBuilder('parameters'))->getRootNode();

$isStringAssociativeArray = function (mixed $value): bool {
if (!\is_array($value)) {
return false;
}

foreach ($value as $key => $unused) {
if (!\is_string($key)) {
return false;
}
}

return true;
};

$node
->addDefaultsIfNotSet()
->children()
->arrayNode('global')
->useAttributeAsKey('name')
->variablePrototype()
->end()
->end()
->arrayNode('per_job')
->useAttributeAsKey('name')
->variablePrototype()
->validate()
->ifTrue(fn(mixed $value) => !$isStringAssociativeArray($value))
->thenInvalid('Should be an array<string, mixed>.')
->end()
->end()
->end()
;

return $node;
}

private function ui(): ArrayNodeDefinition
{
/** @var ArrayNodeDefinition $node */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\ConfigurableTemplating;
use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\SonataAdminTemplating;
use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\TemplatingInterface;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\PerJobJobExecutionParametersBuilder;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\StaticJobExecutionParametersBuilder;
use Yokai\Batch\Launcher\JobLauncherInterface;
use Yokai\Batch\Storage\FilesystemJobExecutionStorage;
use Yokai\Batch\Storage\JobExecutionStorageInterface;
Expand All @@ -34,6 +36,7 @@
* @phpstan-import-type Config from Configuration
* @phpstan-import-type StorageConfig from Configuration
* @phpstan-import-type LauncherConfig from Configuration
* @phpstan-import-type ParametersConfig from Configuration
* @phpstan-import-type UserInterfaceConfig from Configuration
*/
final class YokaiBatchExtension extends Extension
Expand Down Expand Up @@ -64,6 +67,7 @@ public function load(array $configs, ContainerBuilder $container): void

$this->configureStorage($container, $config['storage']);
$this->configureLauncher($container, $config['launcher']);
$this->configureParameters($container, $config['parameters']);
$this->configureUserInterface($container, $loader, $config['ui']);

$container->registerAliasForArgument('yokai_batch.logger', LoggerInterface::class, 'yokaiBatchLogger');
Expand Down Expand Up @@ -189,6 +193,25 @@ private function configureLauncher(ContainerBuilder $container, array $config):
);
}

/**
* @param ParametersConfig $config
*/
private function configureParameters(ContainerBuilder $container, array $config): void
{
if ($config['global'] !== []) {
$container->register('yokai_batch.job_execution_parameters_builder.global')
->setClass(StaticJobExecutionParametersBuilder::class)
->setArgument('$parameters', $config['global'])
->addTag('yokai_batch.job_execution_parameters_builder');
}
if ($config['per_job'] !== []) {
$container->register('yokai_batch.job_execution_parameters_builder.per_job')
->setClass(PerJobJobExecutionParametersBuilder::class)
->setArgument('$perJobParameters', $config['per_job'])
->addTag('yokai_batch.job_execution_parameters_builder');
}
}

/**
* @param UserInterfaceConfig $config
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@

<service id="Yokai\Batch\Factory\JobExecutionIdGeneratorInterface"
alias="yokai_batch.job_execution_id_generator.uniqid"/>

<service id="Yokai\Batch\Factory\JobExecutionParametersBuilderInterface"
alias="yokai_batch.job_execution_parameters_builder.chain"/>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<service id="yokai_batch.job_execution_factory"
class="Yokai\Batch\Factory\JobExecutionFactory">
<argument type="service" id="Yokai\Batch\Factory\JobExecutionIdGeneratorInterface"/>
<argument type="service" id="Yokai\Batch\Factory\JobExecutionParametersBuilderInterface"/>
</service>

<service id="yokai_batch.job_registry"
Expand All @@ -32,5 +33,10 @@

<service id="yokai_batch.job_execution_id_generator.uniqid"
class="Yokai\Batch\Factory\UniqidJobExecutionIdGenerator"/>

<service id="yokai_batch.job_execution_parameters_builder.chain"
class="Yokai\Batch\Factory\JobExecutionParametersBuilder\ChainJobExecutionParametersBuilder">
<argument type="tagged_iterator" tag="yokai_batch.job_execution_parameters_builder"/>
</service>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Exception;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\LogicException;
Expand All @@ -17,6 +18,10 @@
use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\SonataAdminTemplating;
use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\TemplatingInterface;
use Yokai\Batch\Bridge\Symfony\Messenger\DispatchMessageJobLauncher;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\ChainJobExecutionParametersBuilder;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\PerJobJobExecutionParametersBuilder;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\StaticJobExecutionParametersBuilder;
use Yokai\Batch\Factory\JobExecutionParametersBuilderInterface;
use Yokai\Batch\Launcher\JobLauncherInterface;
use Yokai\Batch\Launcher\SimpleJobLauncher;
use Yokai\Batch\Storage\JobExecutionStorageInterface;
Expand Down Expand Up @@ -387,4 +392,111 @@ public function errors(): \Generator
new ServiceNotFoundException('app.unknown'),
];
}

/**
* @dataProvider parameters
*/
public function testParameters(array $config, array|null $global, array|null $perJob): void
{
$container = $this->createContainer($config);

$globalService = $this->getDefinition($container, 'yokai_batch.job_execution_parameters_builder.global');
if ($global !== null) {
self::assertNotNull($globalService);
self::assertSame(StaticJobExecutionParametersBuilder::class, $globalService->getClass());
self::assertTrue($globalService->hasTag('yokai_batch.job_execution_parameters_builder'));
self::assertSame($global, $globalService->getArgument('$parameters'));
} else {
self::assertNull($globalService);
}
$perJobService = $this->getDefinition($container, 'yokai_batch.job_execution_parameters_builder.per_job');
if ($perJob !== null) {
self::assertNotNull($perJobService);
self::assertSame(PerJobJobExecutionParametersBuilder::class, $perJobService->getClass());
self::assertTrue($perJobService->hasTag('yokai_batch.job_execution_parameters_builder'));
self::assertSame($perJob, $perJobService->getArgument('$perJobParameters'));
} else {
self::assertNull($perJobService);
}
$defaultService = $this->getDefinition($container, JobExecutionParametersBuilderInterface::class);
self::assertNotNull($defaultService);
self::assertSame(ChainJobExecutionParametersBuilder::class, $defaultService->getClass());
$defaultServiceBuilders = $defaultService->getArgument(0);
self::assertTrue($defaultServiceBuilders instanceof TaggedIteratorArgument);
/** @var TaggedIteratorArgument $defaultServiceBuilders */
self::assertSame('yokai_batch.job_execution_parameters_builder', $defaultServiceBuilders->getTag());
}

public function parameters(): \Generator
{
yield 'Global parameters' => [
['parameters' => ['global' => ['global' => true]]],
['global' => true],
null,
];
yield 'Per job parameters' => [
['parameters' => ['per_job' => ['job.foo' => ['foo' => true], 'job.bar' => ['bar' => true]]]],
null,
['job.foo' => ['foo' => true], 'job.bar' => ['bar' => true]],
];
yield 'Global AND per job parameters' => [
['parameters' => [
'global' => ['global' => true],
'per_job' => ['job.foo' => ['foo' => true], 'job.bar' => ['bar' => true]],
]],
['global' => true],
['job.foo' => ['foo' => true], 'job.bar' => ['bar' => true]],
];
}

/**
* @dataProvider invalidParameters
*/
public function testInvalidParameters(array $config, \Exception $error): void
{
$this->expectExceptionObject($error);
$this->createContainer($config);
}

public function invalidParameters(): \Generator
{
yield 'Per job parameters value must be an array' => [
['parameters' => ['per_job' => ['job.foo' => 'string']]],
new InvalidConfigurationException(
'Invalid configuration for path "yokai_batch.parameters.per_job.job.foo": Should be an array<string, mixed>.'
),
];
yield 'Per job parameters value must be a string indexed array' => [
['parameters' => ['per_job' => ['job.foo' => [1, 2, 3]]]],
new InvalidConfigurationException(
'Invalid configuration for path "yokai_batch.parameters.per_job.job.foo": Should be an array<string, mixed>.'
),
];
}

private function createContainer(array $config, \Closure|null $configure = null): ContainerBuilder
{
$container = new ContainerBuilder();
if ($configure !== null) {
$configure($container);
}
$container->registerExtension(new YokaiBatchExtension());
$container->loadFromExtension('yokai_batch', $config);

$container->getCompilerPassConfig()->setOptimizationPasses([]);
$container->getCompilerPassConfig()->setRemovingPasses([]);
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
$container->compile();

return $container;
}

private function getDefinition(ContainerBuilder $container, string $id): Definition|null
{
try {
return $container->findDefinition($id);
} catch (ServiceNotFoundException) {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Yokai\Batch\Bridge\Symfony\Messenger\DispatchMessageJobLauncher;
use Yokai\Batch\Bridge\Symfony\Messenger\LaunchJobMessage;
use Yokai\Batch\Factory\JobExecutionFactory;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\NullJobExecutionParametersBuilder;
use Yokai\Batch\Factory\UniqidJobExecutionIdGenerator;
use Yokai\Batch\Test\Factory\SequenceJobExecutionIdGenerator;
use Yokai\Batch\Test\Storage\InMemoryJobExecutionStorage;
Expand All @@ -21,7 +22,7 @@ final class DispatchMessageJobLauncherTest extends TestCase
public function testLaunch(): void
{
$jobLauncher = new DispatchMessageJobLauncher(
new JobExecutionFactory(new UniqidJobExecutionIdGenerator()),
new JobExecutionFactory(new UniqidJobExecutionIdGenerator(), new NullJobExecutionParametersBuilder()),
$storage = new InMemoryJobExecutionStorage(),
$messageBus = new BufferingMessageBus()
);
Expand All @@ -41,9 +42,12 @@ public function testLaunch(): void
public function testLaunchWithNoId(): void
{
$jobLauncher = new DispatchMessageJobLauncher(
new JobExecutionFactory(new SequenceJobExecutionIdGenerator(['123456789'])),
new JobExecutionFactory(
new SequenceJobExecutionIdGenerator(['123456789']),
new NullJobExecutionParametersBuilder(),
),
$storage = new InMemoryJobExecutionStorage(),
$messageBus = new BufferingMessageBus()
$messageBus = new BufferingMessageBus(),
);

$jobExecutionFromLauncher = $jobLauncher->launch('testing');
Expand All @@ -60,7 +64,7 @@ public function testLaunchWithNoId(): void
public function testLaunchAndMessengerFail(): void
{
$jobLauncher = new DispatchMessageJobLauncher(
new JobExecutionFactory(new UniqidJobExecutionIdGenerator()),
new JobExecutionFactory(new UniqidJobExecutionIdGenerator(), new NullJobExecutionParametersBuilder()),
$storage = new InMemoryJobExecutionStorage(),
new FailingMessageBus(new TransportException('This is a test'))
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Yokai\Batch\Bridge\Symfony\Messenger\LaunchJobMessage;
use Yokai\Batch\Bridge\Symfony\Messenger\LaunchJobMessageHandler;
use Yokai\Batch\Factory\JobExecutionFactory;
use Yokai\Batch\Factory\JobExecutionParametersBuilder\NullJobExecutionParametersBuilder;
use Yokai\Batch\Job\JobExecutionAccessor;
use Yokai\Batch\Job\JobExecutor;
use Yokai\Batch\Job\JobInterface;
Expand All @@ -35,7 +36,10 @@ public function execute(JobExecution $jobExecution): void
$jobExecutionStorage = new InMemoryJobExecutionStorage();
$handler = new LaunchJobMessageHandler(
new JobExecutionAccessor(
new JobExecutionFactory(new SequenceJobExecutionIdGenerator(['123456'])),
new JobExecutionFactory(
new SequenceJobExecutionIdGenerator(['123456']),
new NullJobExecutionParametersBuilder(),
),
$jobExecutionStorage,
),
new JobExecutor(
Expand Down
2 changes: 2 additions & 0 deletions src/batch/src/Factory/JobExecutionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class JobExecutionFactory
{
public function __construct(
private JobExecutionIdGeneratorInterface $idGenerator,
private JobExecutionParametersBuilderInterface $parametersBuilder,
) {
}

Expand All @@ -24,6 +25,7 @@ public function __construct(
*/
public function create(string $name, array $configuration = []): JobExecution
{
$configuration = $configuration + $this->parametersBuilder->build($name);
/** @var string $id */
$id = $configuration['_id'] ??= $this->idGenerator->generate();

Expand Down
Loading
Loading