diff --git a/src/Bootloader/TemporalBridgeBootloader.php b/src/Bootloader/TemporalBridgeBootloader.php index 126ed46..7399464 100644 --- a/src/Bootloader/TemporalBridgeBootloader.php +++ b/src/Bootloader/TemporalBridgeBootloader.php @@ -37,6 +37,9 @@ use Temporal\Worker\WorkerFactoryInterface as TemporalWorkerFactoryInterface; use Temporal\Worker\WorkerOptions; use Temporal\WorkerFactory as TemporalWorkerFactory; +use Temporal\Client\ScheduleClient; +use Temporal\Client\ScheduleClientInterface; +use Temporal\Client\GRPC\ServiceClientInterface; class TemporalBridgeBootloader extends Bootloader { @@ -57,8 +60,10 @@ public function defineSingletons(): array DeclarationLocatorInterface::class => [self::class, 'initDeclarationLocator'], WorkflowClientInterface::class => [self::class, 'initWorkflowClient'], WorkersRegistryInterface::class => WorkersRegistry::class, + ScheduleClientInterface::class => [self::class, 'initScheduleClient'], DataConverterInterface::class => [self::class, 'initDataConverter'], PipelineProvider::class => [self::class, 'initPipelineProvider'], + ServiceClientInterface::class => [self::class, 'initServiceClient'], ]; } @@ -89,8 +94,12 @@ protected function initConfig(EnvironmentInterface $env): void [ 'address' => $env->get('TEMPORAL_ADDRESS', '127.0.0.1:7233'), 'namespace' => 'App\\Endpoint\\Temporal\\Workflow', - 'defaultWorker' => (string)$env->get('TEMPORAL_TASK_QUEUE', TemporalWorkerFactoryInterface::DEFAULT_TASK_QUEUE), + 'defaultWorker' => (string)$env->get( + 'TEMPORAL_TASK_QUEUE', + TemporalWorkerFactoryInterface::DEFAULT_TASK_QUEUE, + ), 'workers' => [], + 'clientOptions' => null, ], ); } @@ -99,10 +108,11 @@ protected function initWorkflowClient( TemporalConfig $config, DataConverterInterface $dataConverter, PipelineProvider $pipelineProvider, + ServiceClientInterface $serviceClient, ): WorkflowClientInterface { return new WorkflowClient( - serviceClient: ServiceClient::create($config->getAddress()), - options: (new ClientOptions())->withNamespace($config->getTemporalNamespace()), + serviceClient: $serviceClient, + options: $config->getClientOptions(), converter: $dataConverter, interceptorProvider: $pipelineProvider, ); @@ -143,4 +153,21 @@ protected function initPipelineProvider(TemporalConfig $config, FactoryInterface return new SimplePipelineProvider($interceptors); } + + protected function initServiceClient(TemporalConfig $config): ServiceClientInterface + { + return ServiceClient::create($config->getAddress()); + } + + protected function initScheduleClient( + TemporalConfig $config, + DataConverterInterface $dataConverter, + ServiceClientInterface $serviceClient, + ): ScheduleClientInterface { + return new ScheduleClient( + serviceClient: $serviceClient, + options: $config->getClientOptions(), + converter: $dataConverter, + ); + } } diff --git a/src/Config/TemporalConfig.php b/src/Config/TemporalConfig.php index 4c68faa..9853921 100644 --- a/src/Config/TemporalConfig.php +++ b/src/Config/TemporalConfig.php @@ -6,6 +6,7 @@ use Spiral\Core\Container\Autowire; use Spiral\Core\InjectableConfig; +use Temporal\Client\ClientOptions; use Temporal\Exception\ExceptionInterceptorInterface; use Temporal\Internal\Interceptor\Interceptor; use Temporal\Worker\WorkerFactoryInterface; @@ -25,7 +26,8 @@ * temporalNamespace: non-empty-string, * defaultWorker: non-empty-string, * workers: array, - * interceptors?: TInterceptor[] + * interceptors?: TInterceptor[], + * clientOptions?: ClientOptions * } $config */ final class TemporalConfig extends InjectableConfig @@ -39,6 +41,7 @@ final class TemporalConfig extends InjectableConfig 'defaultWorker' => WorkerFactoryInterface::DEFAULT_TASK_QUEUE, 'workers' => [], 'interceptors' => [], + 'clientOptions' => null, ]; /** @@ -88,4 +91,9 @@ public function getInterceptors(): array { return $this->config['interceptors'] ?? []; } + + public function getClientOptions(): ClientOptions + { + return $this->config['clientOptions'] ?? (new ClientOptions())->withNamespace($this->getTemporalNamespace()); + } } diff --git a/tests/src/Attribute/AssignWorkerTest.php b/tests/src/Attribute/AssignWorkerTest.php index 86754bf..f5f9ec6 100644 --- a/tests/src/Attribute/AssignWorkerTest.php +++ b/tests/src/Attribute/AssignWorkerTest.php @@ -4,6 +4,7 @@ namespace Spiral\TemporalBridge\Tests\Attribute; +use PHPUnit\Framework\Attributes\DataProvider; use Spiral\Attributes\Factory; use Spiral\TemporalBridge\Attribute\AssignWorker; use Spiral\TemporalBridge\Tests\App\SomeActivity; @@ -13,7 +14,7 @@ final class AssignWorkerTest extends TestCase { - /** @dataProvider assignWorkerDataProvider */ + #[DataProvider(methodName: "assignWorkerDataProvider")] public function testAssignWorkerAttribute(\ReflectionClass $class, ?AssignWorker $expected = null): void { $reader = (new Factory())->create(); @@ -21,7 +22,7 @@ public function testAssignWorkerAttribute(\ReflectionClass $class, ?AssignWorker $this->assertEquals($expected, $reader->firstClassMetadata($class, AssignWorker::class)); } - public function assignWorkerDataProvider(): \Traversable + public static function assignWorkerDataProvider(): \Traversable { yield [new \ReflectionClass(SomeActivity::class), new AssignWorker('worker1')]; yield [new \ReflectionClass(SomeWorkflow::class), new AssignWorker('worker2')]; diff --git a/tests/src/Bootloader/TemporalBridgeBootloaderTest.php b/tests/src/Bootloader/TemporalBridgeBootloaderTest.php index 7c87d1d..9a15c46 100644 --- a/tests/src/Bootloader/TemporalBridgeBootloaderTest.php +++ b/tests/src/Bootloader/TemporalBridgeBootloaderTest.php @@ -15,6 +15,10 @@ use Spiral\TemporalBridge\WorkerFactoryInterface; use Spiral\TemporalBridge\WorkersRegistry; use Spiral\TemporalBridge\WorkersRegistryInterface; +use Temporal\Client\GRPC\ServiceClient; +use Temporal\Client\GRPC\ServiceClientInterface; +use Temporal\Client\ScheduleClient; +use Temporal\Client\ScheduleClientInterface; use Temporal\Client\WorkflowClient; use Temporal\Client\WorkflowClientInterface; use Temporal\DataConverter\DataConverter; @@ -27,6 +31,22 @@ class TemporalBridgeBootloaderTest extends TestCase { + public function testServiceClient(): void + { + $this->assertContainerBoundAsSingleton( + ServiceClientInterface::class, + ServiceClient::class, + ); + } + + public function testScheduleClient(): void + { + $this->assertContainerBoundAsSingleton( + ScheduleClientInterface::class, + ScheduleClient::class, + ); + } + public function testTemporalWorkerFactory(): void { $this->assertContainerBoundAsSingleton( diff --git a/tests/src/Config/TemporalConfigTest.php b/tests/src/Config/TemporalConfigTest.php index f7bb05f..67bf00a 100644 --- a/tests/src/Config/TemporalConfigTest.php +++ b/tests/src/Config/TemporalConfigTest.php @@ -6,6 +6,7 @@ use Spiral\TemporalBridge\Config\TemporalConfig; use Spiral\TemporalBridge\Tests\TestCase; +use Temporal\Client\ClientOptions; use Temporal\Worker\WorkerFactoryInterface; use Temporal\Worker\WorkerOptions; @@ -113,4 +114,24 @@ public function testGetsWorkersIfItNotSet(): void $this->assertSame([], $config->getWorkers()); } + + public function testGetsUndefinedClientOptions(): void + { + $config = new TemporalConfig([ + 'temporalNamespace' => 'foo', + ]); + + $options = $config->getClientOptions(); + + $this->assertSame('foo', $options->namespace); + } + + public function testGetsClientOptions(): void + { + $config = new TemporalConfig([ + 'clientOptions' => $options = new ClientOptions(), + ]); + + $this->assertSame($options, $config->getClientOptions()); + } } diff --git a/tests/src/WorkerFactoryTest.php b/tests/src/WorkerFactoryTest.php index 813a6e8..f195017 100644 --- a/tests/src/WorkerFactoryTest.php +++ b/tests/src/WorkerFactoryTest.php @@ -4,6 +4,7 @@ namespace Spiral\TemporalBridge\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Spiral\Boot\FinalizerInterface; use Spiral\Core\Container; @@ -66,9 +67,7 @@ public function testCreateWithOptionsInArray(): void $this->assertSame($worker, $factory->create('with-options-in-array')); } - /** - * @dataProvider exceptionInterceptorsDataProvider - */ + #[DataProvider(methodName: 'exceptionInterceptorsDataProvider')] public function testCreateWithExceptionInterceptor(string $name): void { $this->temporalWorkerFactory @@ -125,7 +124,7 @@ public function testCreateWithAllOptions(): void $this->assertSame($worker, $factory->create('all')); } - public function exceptionInterceptorsDataProvider(): \Traversable + public static function exceptionInterceptorsDataProvider(): \Traversable { yield ['with-exception-interceptor-as-string']; yield ['with-exception-interceptor-as-autowire'];