diff --git a/Tests/Transport/GpsConfigurationTest.php b/Tests/Transport/GpsConfigurationTest.php index 15d1686..64e59ea 100644 --- a/Tests/Transport/GpsConfigurationTest.php +++ b/Tests/Transport/GpsConfigurationTest.php @@ -39,7 +39,9 @@ public static function dataProvider(): array 'options' => [], 'expectedConfiguration' => new GpsConfiguration( GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, [], [], [], @@ -51,7 +53,9 @@ public static function dataProvider(): array 'options' => [], 'expectedConfiguration' => new GpsConfiguration( 'something', + true, 'something', + true, [], [], [], @@ -63,7 +67,9 @@ public static function dataProvider(): array 'options' => [], 'expectedConfiguration' => new GpsConfiguration( 'topic_name', + true, 'subscription_name', + true, [], [], [], @@ -75,7 +81,9 @@ public static function dataProvider(): array 'options' => [], 'expectedConfiguration' => new GpsConfiguration( 'topic_name', + true, 'subscription_name', + true, ['apiEndpoint' => 'https://europe-west3-pubsub.googleapis.com'], ['labels' => ['label_topic1']], ['labels' => ['label_subscription1'], 'enableMessageOrdering' => true, 'ackDeadlineSeconds' => 100], @@ -89,7 +97,9 @@ public static function dataProvider(): array ], 'expectedConfiguration' => new GpsConfiguration( 'something', + true, 'something', + true, [], [], [], @@ -104,7 +114,9 @@ public static function dataProvider(): array ], 'expectedConfiguration' => new GpsConfiguration( 'topic_name', + true, 'subscription_name', + true, [], [], [], @@ -135,7 +147,9 @@ public static function dataProvider(): array ], 'expectedConfiguration' => new GpsConfiguration( 'topic_name1', + true, 'subscription_name', + true, ['apiEndpoint' => 'https://europe-west3-pubsub.googleapis.com'], ['labels' => ['label_topic1']], ['labels' => ['label_subscription1'], 'enableMessageOrdering' => true, 'ackDeadlineSeconds' => 100], @@ -147,7 +161,9 @@ public static function dataProvider(): array 'options' => [], 'expectedConfiguration' => new GpsConfiguration( GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, [], [], [], @@ -159,7 +175,9 @@ public static function dataProvider(): array 'options' => [], 'expectedConfiguration' => new GpsConfiguration( GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, [], [], [], @@ -178,7 +196,9 @@ public static function dataProvider(): array ], 'expectedConfiguration' => new GpsConfiguration( GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, [], [], [], @@ -197,13 +217,121 @@ public static function dataProvider(): array ], 'expectedConfiguration' => new GpsConfiguration( GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, [], [], [], ['maxMessages' => 5, 'returnImmediately' => true] ), ], + 'Subscription is not created' => [ + 'dsn' => 'gps://default', + 'options' => [ + 'subscription' => [ + 'createIfNotExist' => false + ], + ], + 'expectedConfiguration' => new GpsConfiguration( + GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, + GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + false, + [], + [], + [], + ['maxMessages' => 10, 'returnImmediately' => false] + ), + ], + 'Topic is not created' => [ + 'dsn' => 'gps://default', + 'options' => [ + 'topic' => [ + 'createIfNotExist' => false + ], + ], + 'expectedConfiguration' => new GpsConfiguration( + GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + false, + GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME, + true, + [], + [], + [], + ['maxMessages' => 10, 'returnImmediately' => false] + ), + ], + 'DSN: Subscription is not created' => [ + 'dsn' => 'gps://default?topic[name]=foo&subscription[name]=bar&subscription[createIfNotExist]=false', + 'options' => [], + 'expectedConfiguration' => new GpsConfiguration( + 'foo', + true, + 'bar', + false, + [], + [], + [], + ['maxMessages' => 10, 'returnImmediately' => false] + ), + ], + 'DSN: Subscription is not created #2' => [ + 'dsn' => 'gps://default?topic[name]=foo&topic[createIfNotExist]=true&subscription[name]=bar&subscription[createIfNotExist]=false', + 'options' => [], + 'expectedConfiguration' => new GpsConfiguration( + 'foo', + true, + 'bar', + false, + [], + [], + [], + ['maxMessages' => 10, 'returnImmediately' => false] + ), + ], + 'DSN: Topic is not created' => [ + 'dsn' => 'gps://default?topic[name]=foo&topic[createIfNotExist]=false&subscription[name]=bar&subscription[createIfNotExist]=true', + 'options' => [], + 'expectedConfiguration' => new GpsConfiguration( + 'foo', + false, + 'bar', + true, + [], + [], + [], + ['maxMessages' => 10, 'returnImmediately' => false] + ), + ], + 'DSN: Topic is not created #2' => [ + 'dsn' => 'gps://default?topic[name]=foo&topic[createIfNotExist]=false&subscription[name]=bar', + 'options' => [], + 'expectedConfiguration' => new GpsConfiguration( + 'foo', + false, + 'bar', + true, + [], + [], + [], + ['maxMessages' => 10, 'returnImmediately' => false] + ), + ], + 'DSN: createIfNotExist contains invalid value' => [ + 'dsn' => 'gps://default?topic[name]=foo&topic[createIfNotExist]=quux&subscription[name]=bar', + 'options' => [], + 'expectedConfiguration' => new GpsConfiguration( + 'foo', + true, + 'bar', + true, + [], + [], + [], + ['maxMessages' => 10, 'returnImmediately' => false] + ), + ], ]; } } diff --git a/Tests/Transport/GpsTransportTest.php b/Tests/Transport/GpsTransportTest.php index 16ac378..9c3040d 100644 --- a/Tests/Transport/GpsTransportTest.php +++ b/Tests/Transport/GpsTransportTest.php @@ -134,6 +134,16 @@ public function testSetup() ->method('getSubscriptionName') ->willReturn($queue); + $this->gpsConfiguration + ->expects($this->atLeast(1)) + ->method('isTopicCreationEnabled') + ->willReturn(true); + + $this->gpsConfiguration + ->expects($this->atLeast(1)) + ->method('isSubscriptionCreationEnabled') + ->willReturn(true); + $topicMock = $this->createMock(Topic::class); $topicMock ->expects($this->once()) diff --git a/Transport/GpsConfiguration.php b/Transport/GpsConfiguration.php index ce910b5..d5a51ed 100644 --- a/Transport/GpsConfiguration.php +++ b/Transport/GpsConfiguration.php @@ -10,22 +10,28 @@ final class GpsConfiguration implements GpsConfigurationInterface { private string $topicName; + private bool $topicCreationEnabled; private string $subscriptionName; - private array $clientConfig; - private array $topicOptions; - private array $subscriptionOptions; - private array $subscriptionPullOptions; + private bool $subscriptionCreationEnabled; + private array $clientConfig; + private array $topicOptions; + private array $subscriptionOptions; + private array $subscriptionPullOptions; public function __construct( string $queueName, + bool $topicCreationEnabled, string $subscriptionName, + bool $subscriptionCreationEnabled, array $clientConfig, array $topicOptions, array $subscriptionOptions, array $subscriptionPullOptions ) { $this->topicName = $queueName; + $this->topicCreationEnabled = $topicCreationEnabled; $this->subscriptionName = $subscriptionName; + $this->subscriptionCreationEnabled = $subscriptionCreationEnabled; $this->clientConfig = $clientConfig; $this->topicOptions = $topicOptions; $this->subscriptionOptions = $subscriptionOptions; @@ -37,11 +43,21 @@ public function getTopicName(): string return $this->topicName; } + public function isTopicCreationEnabled(): bool + { + return $this->topicCreationEnabled; + } + public function getSubscriptionName(): string { return $this->subscriptionName; } + public function isSubscriptionCreationEnabled(): bool + { + return $this->subscriptionCreationEnabled; + } + public function getClientConfig(): array { return $this->clientConfig; diff --git a/Transport/GpsConfigurationInterface.php b/Transport/GpsConfigurationInterface.php index 52ac104..d0236e5 100644 --- a/Transport/GpsConfigurationInterface.php +++ b/Transport/GpsConfigurationInterface.php @@ -15,8 +15,12 @@ interface GpsConfigurationInterface { public function getTopicName(): string; + public function isTopicCreationEnabled(): bool; + public function getSubscriptionName(): string; + public function isSubscriptionCreationEnabled(): bool; + /** * @see PubSubClient constructor options */ diff --git a/Transport/GpsConfigurationResolver.php b/Transport/GpsConfigurationResolver.php index cae3f37..af493b1 100644 --- a/Transport/GpsConfigurationResolver.php +++ b/Transport/GpsConfigurationResolver.php @@ -108,8 +108,10 @@ function (OptionsResolver $resolver, Options $parentOptions) use ($subscriptionO ->setDefault('topic', function (OptionsResolver $topicResolver): void { $topicResolver ->setDefault('name', self::DEFAULT_TOPIC_NAME) + ->setDefault('createIfNotExist', true) ->setDefault('options', []) ->setAllowedTypes('name', 'string') + ->setAllowedTypes('createIfNotExist', 'bool') ->setAllowedTypes('options', 'array') ; }) @@ -119,6 +121,7 @@ function (OptionsResolver $resolver, Options $parentOptions) use ($subscriptionO if ($parentOptions->offsetExists('queue')) { $resolver ->setDefault('name', $parentOptions['queue']['name']) + ->setDefault('createIfNotExist', true) ->setDefault('options', $parentOptions['queue']['options']) ->setDefault( 'pull', @@ -130,6 +133,7 @@ function (OptionsResolver $pullResolver) use ($parentOptions): void { } ) ->setAllowedTypes('name', 'string') + ->setAllowedTypes('createIfNotExist', 'bool') ->setAllowedTypes('options', 'array') ->setAllowedTypes('pull', 'array') ->setNormalizer('pull', $subscriptionPullOptionsNormalizer) @@ -140,6 +144,7 @@ function (OptionsResolver $pullResolver) use ($parentOptions): void { $resolver ->setDefault('name', $parentOptions['topic']['name']) + ->setDefault('createIfNotExist', true) ->setDefault('options', []) ->setDefault( 'pull', @@ -151,6 +156,7 @@ function (OptionsResolver $pullResolver) use ($parentOptions): void { } ) ->setAllowedTypes('name', 'string') + ->setAllowedTypes('createIfNotExist', 'bool') ->setAllowedTypes('options', 'array') ->setAllowedTypes('pull', 'array') ->setNormalizer('options', $subscriptionOptionsNormalizer) @@ -165,7 +171,9 @@ function (OptionsResolver $pullResolver) use ($parentOptions): void { return new GpsConfiguration( $resolvedOptions['topic']['name'], + $resolvedOptions['topic']['createIfNotExist'], $resolvedOptions['subscription']['name'], + $resolvedOptions['subscription']['createIfNotExist'], $resolvedOptions['client_config'], $resolvedOptions['topic']['options'], $resolvedOptions['subscription']['options'], @@ -188,6 +196,21 @@ private function getMergedOptions(string $dsn, array $options): array $dnsOptions['topic']['name'] = substr($dnsPathOption, 1); } + if (isset($dnsOptions['topic']['createIfNotExist'])) { + $dnsOptions['topic']['createIfNotExist'] = $this->toBool($dnsOptions['topic']['createIfNotExist'], true); + } + + if (isset($dnsOptions['subscription']['createIfNotExist'])) { + $dnsOptions['subscription']['createIfNotExist'] = $this->toBool($dnsOptions['subscription']['createIfNotExist'], true); + } + return array_merge($dnsOptions, $options); } + + private function toBool(string $value, bool $default): bool + { + $result = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + + return $result ?? $default; + } } diff --git a/Transport/GpsTransport.php b/Transport/GpsTransport.php index 72a3b83..20b88ac 100644 --- a/Transport/GpsTransport.php +++ b/Transport/GpsTransport.php @@ -91,7 +91,7 @@ public function setup(): void { $topic = $this->pubSubClient->topic($this->gpsConfiguration->getTopicName()); - if (false === $topic->exists()) { + if (true === $this->gpsConfiguration->isTopicCreationEnabled() && false === $topic->exists()) { $topic = $this->pubSubClient->createTopic( $this->gpsConfiguration->getTopicName(), $this->gpsConfiguration->getTopicOptions() @@ -100,7 +100,7 @@ public function setup(): void $subscription = $topic->subscription($this->gpsConfiguration->getSubscriptionName()); - if (false === $subscription->exists()) { + if (true === $this->gpsConfiguration->isSubscriptionCreationEnabled() && false === $subscription->exists()) { $topic->subscribe( $this->gpsConfiguration->getSubscriptionName(), $this->gpsConfiguration->getSubscriptionOptions()