From e0a045f3ce668224e8a4ab359b6478d7812df3a6 Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sun, 14 Jan 2024 17:36:13 +0700 Subject: [PATCH 1/7] Rewrite middlewares --- src/Debug/QueueDecorator.php | 9 +- ...pterPushHandler.php => AdapterHandler.php} | 6 +- .../Consume/ConsumeMiddlewareDispatcher.php | 100 --------- src/Middleware/Consume/ConsumeRequest.php | 41 ---- .../MessageHandlerConsumeInterface.php | 10 - .../Consume/MiddlewareConsumeInterface.php | 10 - .../Consume/MiddlewareConsumeStack.php | 75 ------- .../Consume/MiddlewareFactoryConsume.php | 155 -------------- .../MiddlewareFactoryConsumeInterface.php | 22 -- .../{Consume => }/ConsumeFinalHandler.php | 6 +- .../DelayMiddlewareInterface.php | 6 +- .../FailureHandlingRequest.php | 2 +- .../ExponentialDelayMiddleware.php | 3 +- src/Middleware/MessageHandlerInterface.php | 10 + ...ispatcher.php => MiddlewareDispatcher.php} | 32 +-- ...eFactoryPush.php => MiddlewareFactory.php} | 46 ++-- src/Middleware/MiddlewareFactoryInterface.php | 22 ++ src/Middleware/MiddlewareInterface.php | 10 + ...ewarePushStack.php => MiddlewareStack.php} | 28 +-- .../Push/MessageHandlerPushInterface.php | 10 - .../Push/MiddlewareFactoryPushInterface.php | 22 -- .../Push/MiddlewarePushInterface.php | 10 - .../{Push/PushRequest.php => Request.php} | 4 +- src/Queue.php | 51 +++-- src/QueueInterface.php | 8 +- src/Worker/Worker.php | 16 +- tests/App/DummyQueue.php | 9 +- tests/Integration/MessageConsumingTest.php | 4 +- tests/Integration/MiddlewareTest.php | 17 +- tests/Integration/QueueFactoryTest.php | 6 +- tests/Integration/Support/TestMiddleware.php | 21 +- tests/TestCase.php | 26 +-- .../Middleware/Consume/ConsumeRequestTest.php | 23 -- ...validMiddlewareDefinitionExceptionTest.php | 64 ------ .../Consume/MiddlewareDispatcherTest.php | 185 ---------------- .../Consume/MiddlewareFactoryTest.php | 200 ------------------ .../Consume/Support/FailMiddleware.php | 18 -- .../Consume/Support/InvalidController.php | 13 -- .../Support/TestCallableMiddleware.php | 16 -- .../Consume/Support/TestMiddleware.php | 22 -- .../ExponentialDelayMiddlewareTest.php | 3 +- .../SendAgainMiddlewareTest.php | 3 +- ...validMiddlewareDefinitionExceptionTest.php | 10 +- .../{Push => }/MiddlewareDispatcherTest.php | 56 ++--- .../{Push => }/MiddlewareFactoryTest.php | 86 ++++---- .../Unit/Middleware/Push/PushRequestTest.php | 22 -- .../Push/Support/TestMiddleware.php | 22 -- tests/Unit/Middleware/PushRequestTest.php | 22 ++ .../{Push => }/Support/InvalidController.php | 2 +- .../Support/TestCallableMiddleware.php | 6 +- .../Middleware/Support/TestMiddleware.php | 22 ++ tests/Unit/WorkerTest.php | 7 +- 52 files changed, 324 insertions(+), 1275 deletions(-) rename src/Middleware/{Push/AdapterPushHandler.php => AdapterHandler.php} (66%) delete mode 100644 src/Middleware/Consume/ConsumeMiddlewareDispatcher.php delete mode 100644 src/Middleware/Consume/ConsumeRequest.php delete mode 100644 src/Middleware/Consume/MessageHandlerConsumeInterface.php delete mode 100644 src/Middleware/Consume/MiddlewareConsumeInterface.php delete mode 100644 src/Middleware/Consume/MiddlewareConsumeStack.php delete mode 100644 src/Middleware/Consume/MiddlewareFactoryConsume.php delete mode 100644 src/Middleware/Consume/MiddlewareFactoryConsumeInterface.php rename src/Middleware/{Consume => }/ConsumeFinalHandler.php (57%) rename src/Middleware/{Push/Implementation => }/DelayMiddlewareInterface.php (69%) create mode 100644 src/Middleware/MessageHandlerInterface.php rename src/Middleware/{Push/PushMiddlewareDispatcher.php => MiddlewareDispatcher.php} (67%) rename src/Middleware/{Push/MiddlewareFactoryPush.php => MiddlewareFactory.php} (77%) create mode 100644 src/Middleware/MiddlewareFactoryInterface.php create mode 100644 src/Middleware/MiddlewareInterface.php rename src/Middleware/{Push/MiddlewarePushStack.php => MiddlewareStack.php} (59%) delete mode 100644 src/Middleware/Push/MessageHandlerPushInterface.php delete mode 100644 src/Middleware/Push/MiddlewareFactoryPushInterface.php delete mode 100644 src/Middleware/Push/MiddlewarePushInterface.php rename src/Middleware/{Push/PushRequest.php => Request.php} (92%) delete mode 100644 tests/Unit/Middleware/Consume/ConsumeRequestTest.php delete mode 100644 tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php delete mode 100644 tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php delete mode 100644 tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php delete mode 100644 tests/Unit/Middleware/Consume/Support/FailMiddleware.php delete mode 100644 tests/Unit/Middleware/Consume/Support/InvalidController.php delete mode 100644 tests/Unit/Middleware/Consume/Support/TestCallableMiddleware.php delete mode 100644 tests/Unit/Middleware/Consume/Support/TestMiddleware.php rename tests/Unit/Middleware/{Push => }/InvalidMiddlewareDefinitionExceptionTest.php (82%) rename tests/Unit/Middleware/{Push => }/MiddlewareDispatcherTest.php (72%) rename tests/Unit/Middleware/{Push => }/MiddlewareFactoryTest.php (65%) delete mode 100644 tests/Unit/Middleware/Push/PushRequestTest.php delete mode 100644 tests/Unit/Middleware/Push/Support/TestMiddleware.php create mode 100644 tests/Unit/Middleware/PushRequestTest.php rename tests/Unit/Middleware/{Push => }/Support/InvalidController.php (68%) rename tests/Unit/Middleware/{Push => }/Support/TestCallableMiddleware.php (53%) create mode 100644 tests/Unit/Middleware/Support/TestMiddleware.php diff --git a/src/Debug/QueueDecorator.php b/src/Debug/QueueDecorator.php index 4ebee030..556357e4 100644 --- a/src/Debug/QueueDecorator.php +++ b/src/Debug/QueueDecorator.php @@ -7,7 +7,7 @@ use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Enum\JobStatus; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewarePushInterface; +use Yiisoft\Queue\Middleware\MiddlewareInterface; use Yiisoft\Queue\QueueInterface; final class QueueDecorator implements QueueInterface @@ -28,7 +28,7 @@ public function status(string|int $id): JobStatus public function push( MessageInterface $message, - string|array|callable|MiddlewarePushInterface ...$middlewareDefinitions + string|array|callable|MiddlewareInterface ...$middlewareDefinitions ): MessageInterface { $message = $this->queue->push($message, ...$middlewareDefinitions); $this->collector->collectPush($this->queue->getChannelName(), $message, ...$middlewareDefinitions); @@ -61,4 +61,9 @@ public function withChannelName(string $channel): QueueInterface $new->queue = $this->queue->withChannelName($channel); return $new; } + + public function getAdapter(): ?AdapterInterface + { + // TODO: Implement getAdapter() method. + } } diff --git a/src/Middleware/Push/AdapterPushHandler.php b/src/Middleware/AdapterHandler.php similarity index 66% rename from src/Middleware/Push/AdapterPushHandler.php rename to src/Middleware/AdapterHandler.php index be4b1e67..7564016b 100644 --- a/src/Middleware/Push/AdapterPushHandler.php +++ b/src/Middleware/AdapterHandler.php @@ -2,16 +2,16 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Middleware\Push; +namespace Yiisoft\Queue\Middleware; use Yiisoft\Queue\Exception\AdapterConfiguration\AdapterNotConfiguredException; /** * @internal */ -final class AdapterPushHandler implements MessageHandlerPushInterface +final class AdapterHandler implements MessageHandlerInterface { - public function handlePush(PushRequest $request): PushRequest + public function handle(Request $request): Request { if (($adapter = $request->getAdapter()) === null) { throw new AdapterNotConfiguredException(); diff --git a/src/Middleware/Consume/ConsumeMiddlewareDispatcher.php b/src/Middleware/Consume/ConsumeMiddlewareDispatcher.php deleted file mode 100644 index be8de7df..00000000 --- a/src/Middleware/Consume/ConsumeMiddlewareDispatcher.php +++ /dev/null @@ -1,100 +0,0 @@ -middlewareDefinitions = array_reverse($middlewareDefinitions); - } - - /** - * Dispatch request through middleware to get response. - * - * @param ConsumeRequest $request Request to pass to middleware. - * @param MessageHandlerConsumeInterface $finishHandler Handler to use in case no middleware produced response. - */ - public function dispatch( - ConsumeRequest $request, - MessageHandlerConsumeInterface $finishHandler - ): ConsumeRequest { - if ($this->stack === null) { - $this->stack = new MiddlewareConsumeStack($this->buildMiddlewares(), $finishHandler); - } - - return $this->stack->handleConsume($request); - } - - /** - * Returns new instance with middleware handlers replaced with the ones provided. - * Last specified handler will be executed first. - * - * @param array[]|callable[]|MiddlewareConsumeInterface[]|string[] $middlewareDefinitions Each array element is: - * - * - A name of a middleware class. The middleware instance will be obtained from container executed. - * - A callable with `function(ServerRequestInterface $request, RequestHandlerInterface $handler): - * ResponseInterface` signature. - * - A "callable-like" array in format `[FooMiddleware::class, 'index']`. `FooMiddleware` instance will - * be created and `index()` method will be executed. - * - A function returning a middleware. The middleware returned will be executed. - * - * For callables typed parameters are automatically injected using dependency injection container. - * - * @return self New instance of the {@see ConsumeMiddlewareDispatcher} - */ - public function withMiddlewares(array $middlewareDefinitions): self - { - $instance = clone $this; - $instance->middlewareDefinitions = array_reverse($middlewareDefinitions); - - // Fixes a memory leak. - unset($instance->stack); - $instance->stack = null; - - return $instance; - } - - /** - * @return bool Whether there are middleware defined in the dispatcher. - */ - public function hasMiddlewares(): bool - { - return $this->middlewareDefinitions !== []; - } - - /** - * @return Closure[] - */ - private function buildMiddlewares(): array - { - $middlewares = []; - $factory = $this->middlewareFactory; - - foreach ($this->middlewareDefinitions as $middlewareDefinition) { - $middlewares[] = static fn (): MiddlewareConsumeInterface => $factory->createConsumeMiddleware( - $middlewareDefinition - ); - } - - return $middlewares; - } -} diff --git a/src/Middleware/Consume/ConsumeRequest.php b/src/Middleware/Consume/ConsumeRequest.php deleted file mode 100644 index 489c7d5a..00000000 --- a/src/Middleware/Consume/ConsumeRequest.php +++ /dev/null @@ -1,41 +0,0 @@ -message; - } - - public function getQueue(): QueueInterface - { - return $this->queue; - } - - public function withMessage(MessageInterface $message): self - { - $instance = clone $this; - $instance->message = $message; - - return $instance; - } - - public function withQueue(QueueInterface $queue): self - { - $instance = clone $this; - $instance->queue = $queue; - - return $instance; - } -} diff --git a/src/Middleware/Consume/MessageHandlerConsumeInterface.php b/src/Middleware/Consume/MessageHandlerConsumeInterface.php deleted file mode 100644 index 832d5896..00000000 --- a/src/Middleware/Consume/MessageHandlerConsumeInterface.php +++ /dev/null @@ -1,10 +0,0 @@ -stack === null) { - $this->build(); - } - - /** @psalm-suppress PossiblyNullReference */ - return $this->stack->handleConsume($request); - } - - private function build(): void - { - $handler = $this->finishHandler; - - foreach ($this->middlewares as $middleware) { - $handler = $this->wrap($middleware, $handler); - } - - $this->stack = $handler; - } - - /** - * Wrap handler by middlewares. - */ - private function wrap(Closure $middlewareFactory, MessageHandlerConsumeInterface $handler): MessageHandlerConsumeInterface - { - return new class ($middlewareFactory, $handler) implements MessageHandlerConsumeInterface { - private ?MiddlewareConsumeInterface $middleware = null; - - public function __construct( - private Closure $middlewareFactory, - private MessageHandlerConsumeInterface $handler, - ) { - } - - public function handleConsume(ConsumeRequest $request): ConsumeRequest - { - if ($this->middleware === null) { - $this->middleware = ($this->middlewareFactory)(); - } - - return $this->middleware->processConsume($request, $this->handler); - } - }; - } -} diff --git a/src/Middleware/Consume/MiddlewareFactoryConsume.php b/src/Middleware/Consume/MiddlewareFactoryConsume.php deleted file mode 100644 index e5561b37..00000000 --- a/src/Middleware/Consume/MiddlewareFactoryConsume.php +++ /dev/null @@ -1,155 +0,0 @@ -getFromContainer($middlewareDefinition); - } - - return $this->tryGetFromCallable($middlewareDefinition) - ?? $this->tryGetFromArrayDefinition($middlewareDefinition) - ?? throw new InvalidMiddlewareDefinitionException($middlewareDefinition); - } - - private function getFromContainer(string $middlewareDefinition): MiddlewareConsumeInterface - { - if (class_exists($middlewareDefinition)) { - if (is_subclass_of($middlewareDefinition, MiddlewareConsumeInterface::class)) { - /** @var MiddlewareConsumeInterface */ - return $this->container->get($middlewareDefinition); - } - } elseif ($this->container->has($middlewareDefinition)) { - $middleware = $this->container->get($middlewareDefinition); - if ($middleware instanceof MiddlewareConsumeInterface) { - return $middleware; - } - } - - throw new InvalidMiddlewareDefinitionException($middlewareDefinition); - } - - private function wrapCallable(callable $callback): MiddlewareConsumeInterface - { - return new class ($callback, $this->container) implements MiddlewareConsumeInterface { - private $callback; - - public function __construct(callable $callback, private ContainerInterface $container) - { - $this->callback = $callback; - } - - public function processConsume(ConsumeRequest $request, MessageHandlerConsumeInterface $handler): ConsumeRequest - { - $response = (new Injector($this->container))->invoke($this->callback, [$request, $handler]); - if ($response instanceof ConsumeRequest) { - return $response; - } - - if ($response instanceof MiddlewareConsumeInterface) { - return $response->processConsume($request, $handler); - } - - throw new InvalidMiddlewareDefinitionException($this->callback); - } - }; - } - - private function tryGetFromCallable( - callable|MiddlewareConsumeInterface|array|string $definition - ): ?MiddlewareConsumeInterface { - if ($definition instanceof Closure) { - return $this->wrapCallable($definition); - } - - if ( - is_array($definition) - && array_keys($definition) === [0, 1] - ) { - try { - return $this->wrapCallable($this->callableFactory->create($definition)); - } catch (InvalidCallableConfigurationException $exception) { - throw new InvalidMiddlewareDefinitionException($definition, previous: $exception); - } - } else { - return null; - } - } - - private function tryGetFromArrayDefinition( - callable|MiddlewareConsumeInterface|array|string $definition - ): ?MiddlewareConsumeInterface { - if (!is_array($definition)) { - return null; - } - - try { - DefinitionValidator::validateArrayDefinition($definition); - - $middleware = ArrayDefinition::fromConfig($definition)->resolve($this->container); - if ($middleware instanceof MiddlewareConsumeInterface) { - return $middleware; - } - - throw new InvalidMiddlewareDefinitionException($definition); - } catch (InvalidConfigException) { - } - - throw new InvalidMiddlewareDefinitionException($definition); - } -} diff --git a/src/Middleware/Consume/MiddlewareFactoryConsumeInterface.php b/src/Middleware/Consume/MiddlewareFactoryConsumeInterface.php deleted file mode 100644 index 70f20cf2..00000000 --- a/src/Middleware/Consume/MiddlewareFactoryConsumeInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -handler; $handler($request->getMessage()); diff --git a/src/Middleware/Push/Implementation/DelayMiddlewareInterface.php b/src/Middleware/DelayMiddlewareInterface.php similarity index 69% rename from src/Middleware/Push/Implementation/DelayMiddlewareInterface.php rename to src/Middleware/DelayMiddlewareInterface.php index bd52a52e..6f99d4cc 100644 --- a/src/Middleware/Push/Implementation/DelayMiddlewareInterface.php +++ b/src/Middleware/DelayMiddlewareInterface.php @@ -2,14 +2,12 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Middleware\Push\Implementation; - -use Yiisoft\Queue\Middleware\Push\MiddlewarePushInterface; +namespace Yiisoft\Queue\Middleware; /** * A middleware interface for message delaying. It must be implemented in an adapter package or in a project. */ -interface DelayMiddlewareInterface extends MiddlewarePushInterface +interface DelayMiddlewareInterface extends MiddlewareInterface { /** * Set a new delay value into the middleware object diff --git a/src/Middleware/FailureHandling/FailureHandlingRequest.php b/src/Middleware/FailureHandling/FailureHandlingRequest.php index 43de7433..7d350684 100644 --- a/src/Middleware/FailureHandling/FailureHandlingRequest.php +++ b/src/Middleware/FailureHandling/FailureHandlingRequest.php @@ -10,7 +10,7 @@ final class FailureHandlingRequest { - public function __construct(private MessageInterface $message, private Throwable $exception, private QueueInterface $queue) + public function __construct(private MessageInterface $message, private ?Throwable $exception, private QueueInterface $queue) { } diff --git a/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php b/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php index 1997367f..5beeb099 100644 --- a/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php +++ b/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php @@ -5,12 +5,11 @@ namespace Yiisoft\Queue\Middleware\FailureHandling\Implementation; use InvalidArgumentException; -use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; +use Yiisoft\Queue\Middleware\DelayMiddlewareInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface; use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFailureInterface; -use Yiisoft\Queue\Middleware\Push\Implementation\DelayMiddlewareInterface; use Yiisoft\Queue\QueueInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureEnvelope; diff --git a/src/Middleware/MessageHandlerInterface.php b/src/Middleware/MessageHandlerInterface.php new file mode 100644 index 00000000..1191b63f --- /dev/null +++ b/src/Middleware/MessageHandlerInterface.php @@ -0,0 +1,10 @@ +middlewareDefinitions = array_reverse($middlewareDefinitions); } @@ -29,25 +29,25 @@ public function __construct( /** * Dispatch request through middleware to get response. * - * @param PushRequest $request Request to pass to middleware. - * @param MessageHandlerPushInterface $finishHandler Handler to use in case no middleware produced response. + * @param Request $request Request to pass to middleware. + * @param MessageHandlerInterface $finishHandler Handler to use in case no middleware produced response. */ public function dispatch( - PushRequest $request, - MessageHandlerPushInterface $finishHandler - ): PushRequest { + Request $request, + MessageHandlerInterface $finishHandler + ): Request { if ($this->stack === null) { - $this->stack = new MiddlewarePushStack($this->buildMiddlewares(), $finishHandler); + $this->stack = new MiddlewareStack($this->buildMiddlewares(), $finishHandler); } - return $this->stack->handlePush($request); + return $this->stack->handle($request); } /** * Returns new instance with middleware handlers replaced with the ones provided. * Last specified handler will be executed first. * - * @param array[]|callable[]|MiddlewarePushInterface[]|string[] $middlewareDefinitions Each array element is: + * @param array[]|callable[]|MiddlewareInterface[]|string[] $middlewareDefinitions Each array element is: * * - A name of a middleware class. The middleware instance will be obtained from container executed. * - A callable with `function(ServerRequestInterface $request, RequestHandlerInterface $handler): @@ -89,7 +89,7 @@ private function buildMiddlewares(): array $factory = $this->middlewareFactory; foreach ($this->middlewareDefinitions as $middlewareDefinition) { - $middlewares[] = static fn (): MiddlewarePushInterface => $factory->createPushMiddleware( + $middlewares[] = static fn (): MiddlewareInterface => $factory->createMiddleware( $middlewareDefinition ); } diff --git a/src/Middleware/Push/MiddlewareFactoryPush.php b/src/Middleware/MiddlewareFactory.php similarity index 77% rename from src/Middleware/Push/MiddlewareFactoryPush.php rename to src/Middleware/MiddlewareFactory.php index 8e235b36..e02d621b 100644 --- a/src/Middleware/Push/MiddlewareFactoryPush.php +++ b/src/Middleware/MiddlewareFactory.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Middleware\Push; +namespace Yiisoft\Queue\Middleware; use Closure; use Psr\Container\ContainerInterface; @@ -19,7 +19,7 @@ /** * Creates a middleware based on the definition provided. */ -final class MiddlewareFactoryPush implements MiddlewareFactoryPushInterface +final class MiddlewareFactory implements MiddlewareFactoryInterface { /** * @param ContainerInterface $container Container to use for resolving definitions. @@ -31,7 +31,7 @@ public function __construct( } /** - * @param array|callable|MiddlewarePushInterface|string $middlewareDefinition Middleware definition in one of the + * @param array|callable|MiddlewareInterface|string $middlewareDefinition Middleware definition in one of the * following formats: * * - A middleware object. @@ -49,12 +49,12 @@ public function __construct( * * @throws InvalidMiddlewareDefinitionException * - * @return MiddlewarePushInterface + * @return MiddlewareInterface */ - public function createPushMiddleware( - MiddlewarePushInterface|callable|array|string $middlewareDefinition - ): MiddlewarePushInterface { - if ($middlewareDefinition instanceof MiddlewarePushInterface) { + public function createMiddleware( + MiddlewareInterface|callable|array|string $middlewareDefinition + ): MiddlewareInterface { + if ($middlewareDefinition instanceof MiddlewareInterface) { return $middlewareDefinition; } @@ -67,16 +67,16 @@ public function createPushMiddleware( ?? throw new InvalidMiddlewareDefinitionException($middlewareDefinition); } - private function getFromContainer(string $middlewareDefinition): MiddlewarePushInterface + private function getFromContainer(string $middlewareDefinition): MiddlewareInterface { if (class_exists($middlewareDefinition)) { - if (is_subclass_of($middlewareDefinition, MiddlewarePushInterface::class)) { - /** @var MiddlewarePushInterface */ + if (is_subclass_of($middlewareDefinition, MiddlewareInterface::class)) { + /** @var MiddlewareInterface */ return $this->container->get($middlewareDefinition); } } elseif ($this->container->has($middlewareDefinition)) { $middleware = $this->container->get($middlewareDefinition); - if ($middleware instanceof MiddlewarePushInterface) { + if ($middleware instanceof MiddlewareInterface) { return $middleware; } } @@ -84,9 +84,9 @@ private function getFromContainer(string $middlewareDefinition): MiddlewarePushI throw new InvalidMiddlewareDefinitionException($middlewareDefinition); } - private function wrapCallable(callable $callback): MiddlewarePushInterface + private function wrapCallable(callable $callback): MiddlewareInterface { - return new class ($callback, $this->container) implements MiddlewarePushInterface { + return new class ($callback, $this->container) implements MiddlewareInterface { private $callback; public function __construct(callable $callback, private ContainerInterface $container) @@ -94,15 +94,15 @@ public function __construct(callable $callback, private ContainerInterface $cont $this->callback = $callback; } - public function processPush(PushRequest $request, MessageHandlerPushInterface $handler): PushRequest + public function process(Request $request, MessageHandlerInterface $handler): Request { $response = (new Injector($this->container))->invoke($this->callback, [$request, $handler]); - if ($response instanceof PushRequest) { + if ($response instanceof Request) { return $response; } - if ($response instanceof MiddlewarePushInterface) { - return $response->processPush($request, $handler); + if ($response instanceof MiddlewareInterface) { + return $response->process($request, $handler); } throw new InvalidMiddlewareDefinitionException($this->callback); @@ -111,8 +111,8 @@ public function processPush(PushRequest $request, MessageHandlerPushInterface $h } private function tryGetFromCallable( - callable|MiddlewarePushInterface|array|string $definition - ): ?MiddlewarePushInterface { + callable|MiddlewareInterface|array|string $definition + ): ?MiddlewareInterface { if ($definition instanceof Closure) { return $this->wrapCallable($definition); } @@ -132,8 +132,8 @@ private function tryGetFromCallable( } private function tryGetFromArrayDefinition( - callable|MiddlewarePushInterface|array|string $definition - ): ?MiddlewarePushInterface { + callable|MiddlewareInterface|array|string $definition + ): ?MiddlewareInterface { if (!is_array($definition)) { return null; } @@ -142,7 +142,7 @@ private function tryGetFromArrayDefinition( DefinitionValidator::validateArrayDefinition($definition); $middleware = ArrayDefinition::fromConfig($definition)->resolve($this->container); - if ($middleware instanceof MiddlewarePushInterface) { + if ($middleware instanceof MiddlewareInterface) { return $middleware; } diff --git a/src/Middleware/MiddlewareFactoryInterface.php b/src/Middleware/MiddlewareFactoryInterface.php new file mode 100644 index 00000000..6a445062 --- /dev/null +++ b/src/Middleware/MiddlewareFactoryInterface.php @@ -0,0 +1,22 @@ +stack === null) { $this->build(); } /** @psalm-suppress PossiblyNullReference */ - return $this->stack->handlePush($request); + return $this->stack->handle($request); } private function build(): void @@ -51,24 +51,24 @@ private function build(): void /** * Wrap handler by middlewares. */ - private function wrap(Closure $middlewareFactory, MessageHandlerPushInterface $handler): MessageHandlerPushInterface + private function wrap(Closure $middlewareFactory, MessageHandlerInterface $handler): MessageHandlerInterface { - return new class ($middlewareFactory, $handler) implements MessageHandlerPushInterface { - private ?MiddlewarePushInterface $middleware = null; + return new class ($middlewareFactory, $handler) implements MessageHandlerInterface { + private ?MiddlewareInterface $middleware = null; public function __construct( private Closure $middlewareFactory, - private MessageHandlerPushInterface $handler, + private MessageHandlerInterface $handler, ) { } - public function handlePush(PushRequest $request): PushRequest + public function handle(Request $request): Request { if ($this->middleware === null) { $this->middleware = ($this->middlewareFactory)(); } - return $this->middleware->processPush($request, $this->handler); + return $this->middleware->process($request, $this->handler); } }; } diff --git a/src/Middleware/Push/MessageHandlerPushInterface.php b/src/Middleware/Push/MessageHandlerPushInterface.php deleted file mode 100644 index 8db45bff..00000000 --- a/src/Middleware/Push/MessageHandlerPushInterface.php +++ /dev/null @@ -1,10 +0,0 @@ -middlewareDefinitions = $middlewareDefinitions; - $this->adapterPushHandler = new AdapterPushHandler(); + $this->adapterHandler = new AdapterHandler(); } public function getChannelName(): string @@ -46,21 +46,21 @@ public function getChannelName(): string public function push( MessageInterface $message, - MiddlewarePushInterface|callable|array|string ...$middlewareDefinitions + MiddlewareInterface|callable|array|string ...$middlewareDefinitions ): MessageInterface { $this->logger->debug( 'Preparing to push message with handler name "{handlerName}".', ['handlerName' => $message->getHandlerName()] ); - $request = new PushRequest($message, $this->adapter); + $request = new Request($message, $this->adapter); $message = $this->pushMiddlewareDispatcher - ->dispatch($request, $this->createPushHandler($middlewareDefinitions)) + ->dispatch($request, $this->createHandler($middlewareDefinitions)) ->getMessage(); $messageId = $message->getMetadata()[IdEnvelope::MESSAGE_ID_KEY] ?? 'null'; $this->logger->info( - 'Pushed message with handler name "{handlerName}" to the queue. Assigned ID #{id}.', + 'ed message with handler name "{handlerName}" to the queue. Assigned ID #{id}.', ['handlerName' => $message->getHandlerName(), 'id' => $messageId] ); @@ -118,7 +118,12 @@ public function withAdapter(AdapterInterface $adapter): self return $new; } - public function withMiddlewares(MiddlewarePushInterface|callable|array|string ...$middlewareDefinitions): self + public function getAdapter(): ?AdapterInterface + { + return $this->adapter; + } + + public function withMiddlewares(MiddlewareInterface|callable|array|string ...$middlewareDefinitions): self { $instance = clone $this; $instance->middlewareDefinitions = $middlewareDefinitions; @@ -126,7 +131,7 @@ public function withMiddlewares(MiddlewarePushInterface|callable|array|string .. return $instance; } - public function withMiddlewaresAdded(MiddlewarePushInterface|callable|array|string ...$middlewareDefinitions): self + public function withMiddlewaresAdded(MiddlewareInterface|callable|array|string ...$middlewareDefinitions): self { $instance = clone $this; $instance->middlewareDefinitions = [...array_values($instance->middlewareDefinitions), ...array_values($middlewareDefinitions)]; @@ -156,25 +161,25 @@ private function checkAdapter(): void } } - private function createPushHandler(array $middlewares): MessageHandlerPushInterface + private function createHandler(array $middlewares): MessageHandlerInterface { return new class ( - $this->adapterPushHandler, + $this->adapterHandler, $this->pushMiddlewareDispatcher, array_merge($this->middlewareDefinitions, $middlewares) - ) implements MessageHandlerPushInterface { + ) implements MessageHandlerInterface { public function __construct( - private AdapterPushHandler $adapterPushHandler, - private PushMiddlewareDispatcher $dispatcher, + private AdapterHandler $adapterHandler, + private MiddlewareDispatcher $dispatcher, private array $middlewares, ) { } - public function handlePush(PushRequest $request): PushRequest + public function handle(Request $request): Request { return $this->dispatcher ->withMiddlewares($this->middlewares) - ->dispatch($request, $this->adapterPushHandler); + ->dispatch($request, $this->adapterHandler); } }; } diff --git a/src/QueueInterface.php b/src/QueueInterface.php index 2fa93fb3..e04e0033 100644 --- a/src/QueueInterface.php +++ b/src/QueueInterface.php @@ -8,7 +8,7 @@ use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Enum\JobStatus; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewarePushInterface; +use Yiisoft\Queue\Middleware\MiddlewareInterface; /** * @internal Please don't use this interface. It is only used here to make tests simpler and will be removed @@ -20,11 +20,11 @@ interface QueueInterface * Pushes a message into the queue. * * @param MessageInterface $message - * @param array|callable|MiddlewarePushInterface|string ...$middlewareDefinitions + * @param array|callable|MiddlewareInterface|string ...$middlewareDefinitions * * @return MessageInterface */ - public function push(MessageInterface $message, MiddlewarePushInterface|callable|array|string ...$middlewareDefinitions): MessageInterface; + public function push(MessageInterface $message, MiddlewareInterface|callable|array|string ...$middlewareDefinitions): MessageInterface; /** * Execute all existing jobs and exit @@ -49,6 +49,8 @@ public function status(string|int $id): JobStatus; public function withAdapter(AdapterInterface $adapter): self; + public function getAdapter(): ?AdapterInterface; + public function getChannelName(): string; public function withChannelName(string $channel): self; diff --git a/src/Worker/Worker.php b/src/Worker/Worker.php index a42f0c75..46bf645d 100644 --- a/src/Worker/Worker.php +++ b/src/Worker/Worker.php @@ -16,14 +16,14 @@ use Yiisoft\Injector\Injector; use Yiisoft\Queue\Exception\JobFailureException; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Consume\ConsumeFinalHandler; -use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\Consume\ConsumeRequest; -use Yiisoft\Queue\Middleware\Consume\MessageHandlerConsumeInterface; +use Yiisoft\Queue\Middleware\ConsumeFinalHandler; use Yiisoft\Queue\Middleware\FailureHandling\FailureFinalHandler; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher; use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface; +use Yiisoft\Queue\Middleware\MessageHandlerInterface; +use Yiisoft\Queue\Middleware\MiddlewareDispatcher; +use Yiisoft\Queue\Middleware\Request; use Yiisoft\Queue\QueueInterface; use Yiisoft\Queue\Message\IdEnvelope; @@ -36,7 +36,7 @@ public function __construct( private LoggerInterface $logger, private Injector $injector, private ContainerInterface $container, - private ConsumeMiddlewareDispatcher $consumeMiddlewareDispatcher, + private MiddlewareDispatcher $consumeMiddlewareDispatcher, private FailureMiddlewareDispatcher $failureMiddlewareDispatcher, ) { } @@ -54,12 +54,12 @@ public function process(MessageInterface $message, QueueInterface $queue): Messa throw new RuntimeException("Queue handler with name $name doesn't exist"); } - $request = new ConsumeRequest($message, $queue); + $request = new Request($message, $queue->getAdapter()); $closure = fn (MessageInterface $message): mixed => $this->injector->invoke($handler, [$message]); try { return $this->consumeMiddlewareDispatcher->dispatch($request, $this->createConsumeHandler($closure))->getMessage(); } catch (Throwable $exception) { - $request = new FailureHandlingRequest($request->getMessage(), $exception, $request->getQueue()); + $request = new FailureHandlingRequest($request->getMessage(), $exception, $queue); try { $result = $this->failureMiddlewareDispatcher->dispatch($request, $this->createFailureHandler()); @@ -141,7 +141,7 @@ private function prepare(callable|object|array|string|null $definition): callabl return $definition; } - private function createConsumeHandler(Closure $handler): MessageHandlerConsumeInterface + private function createConsumeHandler(Closure $handler): MessageHandlerInterface { return new ConsumeFinalHandler($handler); } diff --git a/tests/App/DummyQueue.php b/tests/App/DummyQueue.php index dc8eceb4..1a89d097 100644 --- a/tests/App/DummyQueue.php +++ b/tests/App/DummyQueue.php @@ -8,7 +8,7 @@ use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Enum\JobStatus; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewarePushInterface; +use Yiisoft\Queue\Middleware\MiddlewareInterface; use Yiisoft\Queue\QueueInterface; final class DummyQueue implements QueueInterface @@ -19,7 +19,7 @@ public function __construct(private string $channelName) public function push( MessageInterface $message, - string|array|callable|MiddlewarePushInterface ...$middlewareDefinitions + string|array|callable|MiddlewareInterface ...$middlewareDefinitions ): MessageInterface { return $message; } @@ -51,4 +51,9 @@ public function withChannelName(string $channel): QueueInterface { throw new Exception('`withChannelName()` method is not implemented yet.'); } + + public function getAdapter(): ?AdapterInterface + { + return null; + } } diff --git a/tests/Integration/MessageConsumingTest.php b/tests/Integration/MessageConsumingTest.php index 6c30ba92..7c4eeeaa 100644 --- a/tests/Integration/MessageConsumingTest.php +++ b/tests/Integration/MessageConsumingTest.php @@ -13,6 +13,8 @@ use Yiisoft\Queue\Middleware\Consume\MiddlewareFactoryConsumeInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher; use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFactoryFailureInterface; +use Yiisoft\Queue\Middleware\MiddlewareDispatcher; +use Yiisoft\Queue\Middleware\MiddlewareFactoryInterface; use Yiisoft\Queue\Tests\TestCase; use Yiisoft\Queue\Worker\Worker; @@ -30,7 +32,7 @@ public function testMessagesConsumed(): void new NullLogger(), new Injector($container), $container, - new ConsumeMiddlewareDispatcher($this->createMock(MiddlewareFactoryConsumeInterface::class)), + new MiddlewareDispatcher($this->createMock(MiddlewareFactoryInterface::class)), new FailureMiddlewareDispatcher($this->createMock(MiddlewareFactoryFailureInterface::class), []) ); diff --git a/tests/Integration/MiddlewareTest.php b/tests/Integration/MiddlewareTest.php index ed8f6ad3..2c5e7997 100644 --- a/tests/Integration/MiddlewareTest.php +++ b/tests/Integration/MiddlewareTest.php @@ -9,6 +9,8 @@ use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Yiisoft\Injector\Injector; +use Yiisoft\Queue\AMQP\Middleware\DelayMiddleware; +use Yiisoft\Queue\Middleware\DelayMiddlewareInterface; use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Test\Support\Log\SimpleLogger; use Yiisoft\Queue\Adapter\SynchronousAdapter; @@ -16,17 +18,14 @@ use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; use Yiisoft\Queue\Middleware\CallableFactory; -use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\Consume\MiddlewareFactoryConsume; +use Yiisoft\Queue\Middleware\MiddlewareDispatcher; use Yiisoft\Queue\Middleware\FailureHandling\FailureFinalHandler; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher; use Yiisoft\Queue\Middleware\FailureHandling\Implementation\ExponentialDelayMiddleware; use Yiisoft\Queue\Middleware\FailureHandling\Implementation\SendAgainMiddleware; use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFactoryFailure; -use Yiisoft\Queue\Middleware\Push\Implementation\DelayMiddlewareInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewareFactoryPush; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareDispatcher; +use Yiisoft\Queue\Middleware\MiddlewareFactory; use Yiisoft\Queue\Queue; use Yiisoft\Queue\QueueInterface; use Yiisoft\Queue\Tests\Integration\Support\TestMiddleware; @@ -48,8 +47,8 @@ public function testFullStackPush(): void 'message 2', ]; - $pushMiddlewareDispatcher = new PushMiddlewareDispatcher( - new MiddlewareFactoryPush( + $pushMiddlewareDispatcher = new MiddlewareDispatcher( + new MiddlewareFactory( $this->createMock(ContainerInterface::class), new CallableFactory( $this->createMock(ContainerInterface::class) @@ -93,8 +92,8 @@ public function testFullStackConsume(): void $container = new SimpleContainer(); $callableFactory = new CallableFactory($container); - $consumeMiddlewareDispatcher = new ConsumeMiddlewareDispatcher( - new MiddlewareFactoryConsume( + $consumeMiddlewareDispatcher = new MiddlewareDispatcher( + new MiddlewareFactory( $this->createMock(ContainerInterface::class), new CallableFactory( $this->createMock(ContainerInterface::class) diff --git a/tests/Integration/QueueFactoryTest.php b/tests/Integration/QueueFactoryTest.php index 50076896..0a3dc936 100644 --- a/tests/Integration/QueueFactoryTest.php +++ b/tests/Integration/QueueFactoryTest.php @@ -11,8 +11,8 @@ use Yiisoft\Queue\Adapter\SynchronousAdapter; use Yiisoft\Queue\Cli\LoopInterface; use Yiisoft\Queue\Middleware\CallableFactory; -use Yiisoft\Queue\Middleware\Push\MiddlewareFactoryPushInterface; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareDispatcher; +use Yiisoft\Queue\Middleware\MiddlewareFactoryInterface; +use Yiisoft\Queue\Middleware\MiddlewareDispatcher; use Yiisoft\Queue\Queue; use Yiisoft\Queue\QueueFactory; use Yiisoft\Queue\QueueFactoryInterface; @@ -76,7 +76,7 @@ private function getDefaultQueue(WorkerInterface $worker): Queue $worker, $this->createMock(LoopInterface::class), $this->createMock(LoggerInterface::class), - new PushMiddlewareDispatcher($this->createMock(MiddlewareFactoryPushInterface::class)), + new MiddlewareDispatcher($this->createMock(MiddlewareFactoryInterface::class)), ); } } diff --git a/tests/Integration/Support/TestMiddleware.php b/tests/Integration/Support/TestMiddleware.php index 54ea46bb..8662b4bb 100644 --- a/tests/Integration/Support/TestMiddleware.php +++ b/tests/Integration/Support/TestMiddleware.php @@ -5,36 +5,33 @@ namespace Yiisoft\Queue\Tests\Integration\Support; use Yiisoft\Queue\Message\Message; -use Yiisoft\Queue\Middleware\Consume\ConsumeRequest; -use Yiisoft\Queue\Middleware\Consume\MessageHandlerConsumeInterface; -use Yiisoft\Queue\Middleware\Consume\MiddlewareConsumeInterface; -use Yiisoft\Queue\Middleware\Push\MessageHandlerPushInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewarePushInterface; -use Yiisoft\Queue\Middleware\Push\PushRequest; - -final class TestMiddleware implements MiddlewarePushInterface, MiddlewareConsumeInterface +use Yiisoft\Queue\Middleware\MessageHandlerInterface; +use Yiisoft\Queue\Middleware\MiddlewareInterface; +use Yiisoft\Queue\Middleware\Request; + +final class TestMiddleware implements MiddlewareInterface { public function __construct(private string $stage) { } - public function processPush(PushRequest $request, MessageHandlerPushInterface $handler): PushRequest + public function process(Request $request, MessageHandlerInterface $handler): Request { $message = $request->getMessage(); $stack = $message->getData(); $stack[] = $this->stage; $messageNew = new Message($message->getHandlerName(), $stack); - return $handler->handlePush($request->withMessage($messageNew)); + return $handler->handle($request->withMessage($messageNew)); } - public function processConsume(ConsumeRequest $request, MessageHandlerConsumeInterface $handler): ConsumeRequest + public function process2(Request $request, MessageHandlerInterface $handler): Request { $message = $request->getMessage(); $stack = $message->getData(); $stack[] = $this->stage; $messageNew = new Message($message->getHandlerName(), $stack); - return $handler->handleConsume($request->withMessage($messageNew)); + return $handler->handle($request->withMessage($messageNew)); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index d9f09e8b..c15eccd0 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -10,18 +10,16 @@ use Psr\Log\NullLogger; use RuntimeException; use Yiisoft\Injector\Injector; +use Yiisoft\Queue\Middleware\MiddlewareDispatcher; use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Adapter\SynchronousAdapter; use Yiisoft\Queue\Cli\LoopInterface; use Yiisoft\Queue\Cli\SimpleLoop; use Yiisoft\Queue\Middleware\CallableFactory; -use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\Consume\MiddlewareFactoryConsume; +use Yiisoft\Queue\Middleware\MiddlewareFactory; use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher; use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFactoryFailure; -use Yiisoft\Queue\Middleware\Push\MiddlewareFactoryPush; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareDispatcher; use Yiisoft\Queue\Queue; use Yiisoft\Queue\Worker\Worker; use Yiisoft\Queue\Worker\WorkerInterface; @@ -109,7 +107,7 @@ protected function createQueue(): Queue $this->getWorker(), $this->getLoop(), new NullLogger(), - $this->getPushMiddlewareDispatcher(), + $this->getMiddlewareDispatcher(), ); } @@ -134,7 +132,7 @@ protected function createWorker(): WorkerInterface new NullLogger(), new Injector($this->getContainer()), $this->getContainer(), - $this->getConsumeMiddlewareDispatcher(), + $this->getMiddlewareDispatcher(), $this->getFailureMiddlewareDispatcher(), ); } @@ -181,20 +179,10 @@ protected function needsRealAdapter(): bool return false; } - protected function getPushMiddlewareDispatcher(): PushMiddlewareDispatcher + protected function getMiddlewareDispatcher(): MiddlewareDispatcher { - return new PushMiddlewareDispatcher( - new MiddlewareFactoryPush( - $this->getContainer(), - new CallableFactory($this->getContainer()), - ), - ); - } - - protected function getConsumeMiddlewareDispatcher(): ConsumeMiddlewareDispatcher - { - return new ConsumeMiddlewareDispatcher( - new MiddlewareFactoryConsume( + return new MiddlewareDispatcher( + new MiddlewareFactory( $this->getContainer(), new CallableFactory($this->getContainer()), ), diff --git a/tests/Unit/Middleware/Consume/ConsumeRequestTest.php b/tests/Unit/Middleware/Consume/ConsumeRequestTest.php deleted file mode 100644 index 6493fccd..00000000 --- a/tests/Unit/Middleware/Consume/ConsumeRequestTest.php +++ /dev/null @@ -1,23 +0,0 @@ -createMock(QueueInterface::class); - $consumeRequest = new ConsumeRequest($message, $queue); - - $this->assertNotSame($consumeRequest, $consumeRequest->withMessage($message)); - $this->assertNotSame($consumeRequest, $consumeRequest->withQueue($queue)); - } -} diff --git a/tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php b/tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php deleted file mode 100644 index b706bbff..00000000 --- a/tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php +++ /dev/null @@ -1,64 +0,0 @@ - TestCallableMiddleware::class, 'index'], - '["class" => "Yiisoft\Queue\Tests\Unit\Middleware\Consume\Support\TestCallableMiddleware", "index"]', - ], - ]; - } - - /** - * @dataProvider dataBase - */ - public function testBase(mixed $definition, string $expected): void - { - $exception = new InvalidMiddlewareDefinitionException($definition); - self::assertStringEndsWith('. Got ' . $expected . '.', $exception->getMessage()); - } - - public function dataUnknownDefinition(): array - { - return [ - [42], - [[new stdClass()]], - ]; - } - - /** - * @dataProvider dataUnknownDefinition - */ - public function testUnknownDefinition(mixed $definition): void - { - $exception = new InvalidMiddlewareDefinitionException($definition); - self::assertSame( - 'Parameter should be either middleware class name or a callable.', - $exception->getMessage() - ); - } -} diff --git a/tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php b/tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php deleted file mode 100644 index 383db050..00000000 --- a/tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php +++ /dev/null @@ -1,185 +0,0 @@ -getConsumeRequest(); - $queue = $this->createMock(QueueInterface::class); - - $dispatcher = $this->createDispatcher()->withMiddlewares( - [ - static function (ConsumeRequest $request) use ($queue): ConsumeRequest { - return $request->withMessage(new Message('test', 'New closure test data'))->withQueue($queue); - }, - ] - ); - - $request = $dispatcher->dispatch($request, $this->getRequestHandler()); - $this->assertSame('New closure test data', $request->getMessage()->getData()); - } - - public function testArrayMiddlewareCallableDefinition(): void - { - $request = $this->getConsumeRequest(); - $container = $this->createContainer( - [ - TestCallableMiddleware::class => new TestCallableMiddleware(), - ] - ); - $dispatcher = $this->createDispatcher($container)->withMiddlewares([[TestCallableMiddleware::class, 'index']]); - $request = $dispatcher->dispatch($request, $this->getRequestHandler()); - $this->assertSame('New test data', $request->getMessage()->getData()); - } - - public function testFactoryArrayDefinition(): void - { - $request = $this->getConsumeRequest(); - $container = $this->createContainer(); - $definition = [ - 'class' => TestMiddleware::class, - '__construct()' => ['message' => 'New test data from the definition'], - ]; - $dispatcher = $this->createDispatcher($container)->withMiddlewares([$definition]); - $request = $dispatcher->dispatch($request, $this->getRequestHandler()); - $this->assertSame('New test data from the definition', $request->getMessage()->getData()); - } - - public function testMiddlewareFullStackCalled(): void - { - $request = $this->getConsumeRequest(); - - $middleware1 = static function (ConsumeRequest $request, MessageHandlerConsumeInterface $handler): ConsumeRequest { - $request = $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'new test data')); - - return $handler->handleConsume($request); - }; - $middleware2 = static function (ConsumeRequest $request, MessageHandlerConsumeInterface $handler): ConsumeRequest { - $request = $request->withMessage(new Message('new handler', $request->getMessage()->getData())); - - return $handler->handleConsume($request); - }; - - $dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); - - $request = $dispatcher->dispatch($request, $this->getRequestHandler()); - $this->assertSame('new test data', $request->getMessage()->getData()); - $this->assertSame('new handler', $request->getMessage()->getHandlerName()); - } - - public function testMiddlewareStackInterrupted(): void - { - $request = $this->getConsumeRequest(); - - $middleware1 = static function (ConsumeRequest $request, MessageHandlerConsumeInterface $handler): ConsumeRequest { - return $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'first')); - }; - $middleware2 = static function (ConsumeRequest $request, MessageHandlerConsumeInterface $handler): ConsumeRequest { - return $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'second')); - }; - - $dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); - - $request = $dispatcher->dispatch($request, $this->getRequestHandler()); - $this->assertSame('first', $request->getMessage()->getData()); - } - - public function dataHasMiddlewares(): array - { - return [ - [[], false], - [[[TestCallableMiddleware::class, 'index']], true], - ]; - } - - /** - * @dataProvider dataHasMiddlewares - */ - public function testHasMiddlewares(array $definitions, bool $expected): void - { - self::assertSame( - $expected, - $this->createDispatcher()->withMiddlewares($definitions)->hasMiddlewares() - ); - } - - public function testImmutability(): void - { - $dispatcher = $this->createDispatcher(); - self::assertNotSame($dispatcher, $dispatcher->withMiddlewares([])); - } - - public function testResetStackOnWithMiddlewares(): void - { - $request = $this->getConsumeRequest(); - $container = $this->createContainer( - [ - TestCallableMiddleware::class => new TestCallableMiddleware(), - TestMiddleware::class => new TestMiddleware(), - ] - ); - - $dispatcher = $this - ->createDispatcher($container) - ->withMiddlewares([[TestCallableMiddleware::class, 'index']]); - $dispatcher->dispatch($request, $this->getRequestHandler()); - - $dispatcher = $dispatcher->withMiddlewares([TestMiddleware::class]); - $request = $dispatcher->dispatch($request, $this->getRequestHandler()); - - self::assertSame('New middleware test data', $request->getMessage()->getData()); - } - - private function getRequestHandler(): MessageHandlerConsumeInterface - { - return new class () implements MessageHandlerConsumeInterface { - public function handleConsume(ConsumeRequest $request): ConsumeRequest - { - return $request; - } - }; - } - - private function createDispatcher( - ContainerInterface $container = null, - ): ConsumeMiddlewareDispatcher { - $container ??= $this->createContainer([AdapterInterface::class => new FakeAdapter()]); - $callableFactory = new CallableFactory($container); - - return new ConsumeMiddlewareDispatcher( - new MiddlewareFactoryConsume($container, $callableFactory), - ); - } - - private function createContainer(array $instances = []): ContainerInterface - { - return new SimpleContainer($instances); - } - - private function getConsumeRequest(): ConsumeRequest - { - return new ConsumeRequest( - new Message('handler', 'data'), - $this->createMock(QueueInterface::class) - ); - } -} diff --git a/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php b/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php deleted file mode 100644 index 5278acb3..00000000 --- a/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php +++ /dev/null @@ -1,200 +0,0 @@ -getContainer([TestMiddleware::class => new TestMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware(TestMiddleware::class); - self::assertInstanceOf(TestMiddleware::class, $middleware); - } - - public function testCreateFromAliasString(): void - { - $container = $this->getContainer(['test' => new TestMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware('test'); - self::assertInstanceOf(TestMiddleware::class, $middleware); - } - - public function testCreateFromArray(): void - { - $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware( - [TestCallableMiddleware::class, 'index'] - ); - self::assertSame( - 'New test data', - $middleware->processConsume( - $this->getConsumeRequest(), - $this->createMock(MessageHandlerConsumeInterface::class) - )->getMessage()->getData(), - ); - } - - public function testCreateFromClosureResponse(): void - { - $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware( - fn (): ConsumeRequest => new ConsumeRequest( - new Message('test', 'test data'), - $this->createMock(QueueInterface::class), - ) - ); - self::assertSame( - 'test data', - $middleware->processConsume( - $this->getConsumeRequest(), - $this->createMock(MessageHandlerConsumeInterface::class) - )->getMessage()->getData() - ); - } - - public function testCreateFromClosureMiddleware(): void - { - $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware( - static fn (): MiddlewareConsumeInterface => new TestMiddleware() - ); - self::assertSame( - 'New middleware test data', - $middleware->processConsume( - $this->getConsumeRequest(), - $this->createMock(MessageHandlerConsumeInterface::class) - )->getMessage()->getData() - ); - } - - public function testCreateWithUseParamsMiddleware(): void - { - $container = $this->getContainer([TestMiddleware::class => new TestMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware(TestMiddleware::class); - - self::assertSame( - 'New middleware test data', - $middleware->processConsume( - $this->getConsumeRequest(), - $this->getRequestHandler() - )->getMessage()->getData() - ); - } - - public function testCreateWithTestCallableMiddleware(): void - { - $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware( - [TestCallableMiddleware::class, 'index'] - ); - $request = $this->getConsumeRequest(); - - self::assertSame( - 'New test data', - $middleware->processConsume( - $request, - $this->getRequestHandler() - )->getMessage()->getData() - ); - } - - public function testInvalidMiddlewareWithWrongCallable(): void - { - $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware( - static fn () => 42 - ); - - $this->expectException(InvalidMiddlewareDefinitionException::class); - $middleware->processConsume( - $this->getConsumeRequest(), - $this->createMock(MessageHandlerConsumeInterface::class) - ); - } - - public function invalidMiddlewareDefinitionProvider(): array - { - return [ - 'wrong string' => ['test'], - 'wrong class' => [TestCallableMiddleware::class], - 'wrong array size' => [['test']], - 'array not a class' => [['class', 'test']], - 'wrong array type' => [['class' => TestCallableMiddleware::class, 'index']], - 'wrong array with int items' => [[7, 42]], - 'array with wrong method name' => [[TestCallableMiddleware::class, 'notExists']], - 'array wrong class' => [['class' => InvalidController::class]], - ]; - } - - /** - * @dataProvider invalidMiddlewareDefinitionProvider - */ - public function testInvalidMiddleware(mixed $definition): void - { - $this->expectException(InvalidMiddlewareDefinitionException::class); - $this->getMiddlewareFactory()->createConsumeMiddleware($definition); - } - - public function testInvalidMiddlewareWithWrongController(): void - { - $container = $this->getContainer([InvalidController::class => new InvalidController()]); - $middleware = $this->getMiddlewareFactory($container)->createConsumeMiddleware( - [InvalidController::class, 'index'] - ); - - $this->expectException(InvalidMiddlewareDefinitionException::class); - $middleware->processConsume( - $this->getConsumeRequest(), - $this->createMock(MessageHandlerConsumeInterface::class) - ); - } - - private function getMiddlewareFactory(ContainerInterface $container = null): MiddlewareFactoryConsumeInterface - { - $container ??= $this->getContainer([AdapterInterface::class => new FakeAdapter()]); - - return new MiddlewareFactoryConsume($container, new CallableFactory($container)); - } - - private function getContainer(array $instances = []): ContainerInterface - { - return new SimpleContainer($instances); - } - - private function getRequestHandler(): MessageHandlerConsumeInterface - { - return new class () implements MessageHandlerConsumeInterface { - public function handleConsume(ConsumeRequest $request): ConsumeRequest - { - return $request; - } - }; - } - - private function getConsumeRequest(): ConsumeRequest - { - return new ConsumeRequest( - new Message('handler', 'data'), - $this->createMock(QueueInterface::class) - ); - } -} diff --git a/tests/Unit/Middleware/Consume/Support/FailMiddleware.php b/tests/Unit/Middleware/Consume/Support/FailMiddleware.php deleted file mode 100644 index dd8ed5b7..00000000 --- a/tests/Unit/Middleware/Consume/Support/FailMiddleware.php +++ /dev/null @@ -1,18 +0,0 @@ -withMessage(new Message('test', 'New test data')); - } -} diff --git a/tests/Unit/Middleware/Consume/Support/TestMiddleware.php b/tests/Unit/Middleware/Consume/Support/TestMiddleware.php deleted file mode 100644 index 1e4508f0..00000000 --- a/tests/Unit/Middleware/Consume/Support/TestMiddleware.php +++ /dev/null @@ -1,22 +0,0 @@ -withMessage(new Message('test', $this->message)); - } -} diff --git a/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php b/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php index 7629cb8f..246f117d 100644 --- a/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php +++ b/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php @@ -6,11 +6,12 @@ use Exception; use InvalidArgumentException; +use Yiisoft\Queue\AMQP\Middleware\DelayMiddleware; use Yiisoft\Queue\Message\Message; +use Yiisoft\Queue\Middleware\DelayMiddlewareInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\Implementation\ExponentialDelayMiddleware; use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface; -use Yiisoft\Queue\Middleware\Push\Implementation\DelayMiddlewareInterface; use Yiisoft\Queue\QueueInterface; use Yiisoft\Queue\Tests\TestCase; diff --git a/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php b/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php index b0393412..ef812831 100644 --- a/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php +++ b/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php @@ -7,6 +7,7 @@ use Exception; use PHPUnit\Framework\Assert; use RuntimeException; +use Yiisoft\Queue\AMQP\Middleware\DelayMiddleware; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; @@ -14,7 +15,7 @@ use Yiisoft\Queue\Middleware\FailureHandling\Implementation\SendAgainMiddleware; use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface; use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFailureInterface; -use Yiisoft\Queue\Middleware\Push\Implementation\DelayMiddlewareInterface; +use Yiisoft\Queue\Middleware\DelayMiddlewareInterface; use Yiisoft\Queue\QueueInterface; use Yiisoft\Queue\Tests\TestCase; diff --git a/tests/Unit/Middleware/Push/InvalidMiddlewareDefinitionExceptionTest.php b/tests/Unit/Middleware/InvalidMiddlewareDefinitionExceptionTest.php similarity index 82% rename from tests/Unit/Middleware/Push/InvalidMiddlewareDefinitionExceptionTest.php rename to tests/Unit/Middleware/InvalidMiddlewareDefinitionExceptionTest.php index 00fc2100..b4d755bc 100644 --- a/tests/Unit/Middleware/Push/InvalidMiddlewareDefinitionExceptionTest.php +++ b/tests/Unit/Middleware/InvalidMiddlewareDefinitionExceptionTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Tests\Unit\Middleware\Push; +namespace Yiisoft\Queue\Tests\Unit\Middleware; use PHPUnit\Framework\TestCase; use stdClass; use Yiisoft\Queue\Middleware\InvalidMiddlewareDefinitionException; -use Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestCallableMiddleware; +use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware; final class InvalidMiddlewareDefinitionExceptionTest extends TestCase { @@ -20,15 +20,15 @@ public function dataBase(): array ], [ new TestCallableMiddleware(), - 'an instance of "Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestCallableMiddleware"', + 'an instance of "Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware"', ], [ [TestCallableMiddleware::class, 'notExistsAction'], - '["Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestCallableMiddleware", "notExistsAction"]', + '["Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware", "notExistsAction"]', ], [ ['class' => TestCallableMiddleware::class, 'index'], - '["class" => "Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestCallableMiddleware", "index"]', + '["class" => "Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware", "index"]', ], ]; } diff --git a/tests/Unit/Middleware/Push/MiddlewareDispatcherTest.php b/tests/Unit/Middleware/MiddlewareDispatcherTest.php similarity index 72% rename from tests/Unit/Middleware/Push/MiddlewareDispatcherTest.php rename to tests/Unit/Middleware/MiddlewareDispatcherTest.php index 5eb8dc27..0cbeb0b0 100644 --- a/tests/Unit/Middleware/Push/MiddlewareDispatcherTest.php +++ b/tests/Unit/Middleware/MiddlewareDispatcherTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Tests\Unit\Middleware\Push; +namespace Yiisoft\Queue\Tests\Unit\Middleware; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; @@ -10,23 +10,23 @@ use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Middleware\CallableFactory; -use Yiisoft\Queue\Middleware\Push\MessageHandlerPushInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewareFactoryPush; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\Push\PushRequest; +use Yiisoft\Queue\Middleware\MessageHandlerInterface; +use Yiisoft\Queue\Middleware\MiddlewareFactory; +use Yiisoft\Queue\Middleware\MiddlewareDispatcher; +use Yiisoft\Queue\Middleware\Request; use Yiisoft\Queue\Tests\App\FakeAdapter; -use Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestCallableMiddleware; -use Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestMiddleware; +use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware; +use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestMiddleware; final class MiddlewareDispatcherTest extends TestCase { public function testCallableMiddlewareCalled(): void { - $request = $this->getPushRequest(); + $request = $this->getRequest(); $dispatcher = $this->createDispatcher()->withMiddlewares( [ - static fn (PushRequest $request, AdapterInterface $adapter): PushRequest => $request + static fn (Request $request, AdapterInterface $adapter): Request => $request ->withMessage(new Message('test', 'New closure test data')) ->withAdapter($adapter->withChannel('closure-channel')), ] @@ -43,7 +43,7 @@ public function testCallableMiddlewareCalled(): void public function testArrayMiddlewareCallableDefinition(): void { - $request = $this->getPushRequest(); + $request = $this->getRequest(); $container = $this->createContainer( [ TestCallableMiddleware::class => new TestCallableMiddleware(), @@ -56,7 +56,7 @@ public function testArrayMiddlewareCallableDefinition(): void public function testFactoryArrayDefinition(): void { - $request = $this->getPushRequest(); + $request = $this->getRequest(); $container = $this->createContainer(); $definition = [ 'class' => TestMiddleware::class, @@ -69,14 +69,14 @@ public function testFactoryArrayDefinition(): void public function testMiddlewareFullStackCalled(): void { - $request = $this->getPushRequest(); + $request = $this->getRequest(); - $middleware1 = static function (PushRequest $request, MessageHandlerPushInterface $handler): PushRequest { + $middleware1 = static function (Request $request, MessageHandlerInterface $handler): Request { $request = $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'new test data')); - return $handler->handlePush($request); + return $handler->handle($request); }; - $middleware2 = static function (PushRequest $request, MessageHandlerPushInterface $handler): PushRequest { + $middleware2 = static function (Request $request, MessageHandlerInterface $handler): Request { /** * @noinspection NullPointerExceptionInspection * @@ -84,7 +84,7 @@ public function testMiddlewareFullStackCalled(): void */ $request = $request->withAdapter($request->getAdapter()->withChannel('new channel')); - return $handler->handlePush($request); + return $handler->handle($request); }; $dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); @@ -100,10 +100,10 @@ public function testMiddlewareFullStackCalled(): void public function testMiddlewareStackInterrupted(): void { - $request = $this->getPushRequest(); + $request = $this->getRequest(); - $middleware1 = static fn (PushRequest $request, MessageHandlerPushInterface $handler): PushRequest => $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'first')); - $middleware2 = static fn (PushRequest $request, MessageHandlerPushInterface $handler): PushRequest => $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'second')); + $middleware1 = static fn (Request $request, MessageHandlerInterface $handler): Request => $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'first')); + $middleware2 = static fn (Request $request, MessageHandlerInterface $handler): Request => $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'second')); $dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); @@ -138,7 +138,7 @@ public function testImmutability(): void public function testResetStackOnWithMiddlewares(): void { - $request = $this->getPushRequest(); + $request = $this->getRequest(); $container = $this->createContainer( [ TestCallableMiddleware::class => new TestCallableMiddleware(), @@ -157,10 +157,10 @@ public function testResetStackOnWithMiddlewares(): void self::assertSame('New middleware test data', $request->getMessage()->getData()); } - private function getRequestHandler(): MessageHandlerPushInterface + private function getRequestHandler(): MessageHandlerInterface { - return new class () implements MessageHandlerPushInterface { - public function handlePush(PushRequest $request): PushRequest + return new class () implements MessageHandlerInterface { + public function handle(Request $request): Request { return $request; } @@ -169,12 +169,12 @@ public function handlePush(PushRequest $request): PushRequest private function createDispatcher( ContainerInterface $container = null, - ): PushMiddlewareDispatcher { + ): MiddlewareDispatcher { $container ??= $this->createContainer([AdapterInterface::class => new FakeAdapter()]); $callableFactory = new CallableFactory($container); - return new PushMiddlewareDispatcher( - new MiddlewareFactoryPush($container, $callableFactory), + return new MiddlewareDispatcher( + new MiddlewareFactory($container, $callableFactory), ); } @@ -183,8 +183,8 @@ private function createContainer(array $instances = []): ContainerInterface return new SimpleContainer($instances); } - private function getPushRequest(): PushRequest + private function getRequest(): Request { - return new PushRequest(new Message('handler', 'data'), new FakeAdapter()); + return new Request(new Message('handler', 'data'), new FakeAdapter()); } } diff --git a/tests/Unit/Middleware/Push/MiddlewareFactoryTest.php b/tests/Unit/Middleware/MiddlewareFactoryTest.php similarity index 65% rename from tests/Unit/Middleware/Push/MiddlewareFactoryTest.php rename to tests/Unit/Middleware/MiddlewareFactoryTest.php index c5a3b673..13c962fa 100644 --- a/tests/Unit/Middleware/Push/MiddlewareFactoryTest.php +++ b/tests/Unit/Middleware/MiddlewareFactoryTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Tests\Unit\Middleware\Push; +namespace Yiisoft\Queue\Tests\Unit\Middleware; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; @@ -11,34 +11,34 @@ use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Middleware\CallableFactory; use Yiisoft\Queue\Middleware\InvalidMiddlewareDefinitionException; -use Yiisoft\Queue\Middleware\Push\MessageHandlerPushInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewareFactoryPush; -use Yiisoft\Queue\Middleware\Push\MiddlewareFactoryPushInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewarePushInterface; -use Yiisoft\Queue\Middleware\Push\PushRequest; +use Yiisoft\Queue\Middleware\MessageHandlerInterface; +use Yiisoft\Queue\Middleware\MiddlewareFactory; +use Yiisoft\Queue\Middleware\MiddlewareFactoryInterface; +use Yiisoft\Queue\Middleware\MiddlewareInterface; +use Yiisoft\Queue\Middleware\Request; use Yiisoft\Queue\Tests\App\FakeAdapter; -use Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\InvalidController; -use Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestCallableMiddleware; -use Yiisoft\Queue\Tests\Unit\Middleware\Push\Support\TestMiddleware; +use Yiisoft\Queue\Tests\Unit\Middleware\Support\InvalidController; +use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware; +use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestMiddleware; final class MiddlewareFactoryTest extends TestCase { public function testCreateFromString(): void { $container = $this->getContainer([TestMiddleware::class => new TestMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createPushMiddleware(TestMiddleware::class); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware(TestMiddleware::class); self::assertInstanceOf(TestMiddleware::class, $middleware); } public function testCreateCallableFromArray(): void { $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createPushMiddleware([TestCallableMiddleware::class, 'index']); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware([TestCallableMiddleware::class, 'index']); self::assertSame( 'New test data', - $middleware->processPush( - $this->getPushRequest(), - $this->createMock(MessageHandlerPushInterface::class) + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) )->getMessage()->getData(), ); } @@ -46,16 +46,16 @@ public function testCreateCallableFromArray(): void public function testCreateFromClosureResponse(): void { $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createPushMiddleware( - static function (): PushRequest { - return new PushRequest(new Message('test', 'test data'), new FakeAdapter()); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + static function (): Request { + return new Request(new Message('test', 'test data'), new FakeAdapter()); } ); self::assertSame( 'test data', - $middleware->processPush( - $this->getPushRequest(), - $this->createMock(MessageHandlerPushInterface::class) + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) )->getMessage()->getData() ); } @@ -63,16 +63,16 @@ static function (): PushRequest { public function testCreateFromClosureMiddleware(): void { $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createPushMiddleware( - static function (): MiddlewarePushInterface { + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + static function (): MiddlewareInterface { return new TestMiddleware(); } ); self::assertSame( 'New middleware test data', - $middleware->processPush( - $this->getPushRequest(), - $this->createMock(MessageHandlerPushInterface::class) + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) )->getMessage()->getData() ); } @@ -80,12 +80,12 @@ static function (): MiddlewarePushInterface { public function testCreateWithUseParamsMiddleware(): void { $container = $this->getContainer([TestMiddleware::class => new TestMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createPushMiddleware(TestMiddleware::class); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware(TestMiddleware::class); self::assertSame( 'New middleware test data', - $middleware->processPush( - $this->getPushRequest(), + $middleware->process( + $this->getRequest(), $this->getRequestHandler() )->getMessage()->getData() ); @@ -94,12 +94,12 @@ public function testCreateWithUseParamsMiddleware(): void public function testCreateWithTestCallableMiddleware(): void { $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); - $middleware = $this->getMiddlewareFactory($container)->createPushMiddleware([TestCallableMiddleware::class, 'index']); - $request = $this->getPushRequest(); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware([TestCallableMiddleware::class, 'index']); + $request = $this->getRequest(); self::assertSame( 'New test data', - $middleware->processPush( + $middleware->process( $request, $this->getRequestHandler() )->getMessage()->getData() @@ -126,28 +126,28 @@ public function invalidMiddlewareDefinitionProvider(): array public function testInvalidMiddleware(mixed $definition): void { $this->expectException(InvalidMiddlewareDefinitionException::class); - $this->getMiddlewareFactory()->createPushMiddleware($definition); + $this->getMiddlewareFactory()->createMiddleware($definition); } public function testInvalidMiddlewareWithWrongController(): void { $container = $this->getContainer([InvalidController::class => new InvalidController()]); - $middleware = $this->getMiddlewareFactory($container)->createPushMiddleware( + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( [InvalidController::class, 'index'] ); $this->expectException(InvalidMiddlewareDefinitionException::class); - $middleware->processPush( - $this->getPushRequest(), - $this->createMock(MessageHandlerPushInterface::class) + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) ); } - private function getMiddlewareFactory(ContainerInterface $container = null): MiddlewareFactoryPushInterface + private function getMiddlewareFactory(ContainerInterface $container = null): MiddlewareFactoryInterface { $container ??= $this->getContainer([AdapterInterface::class => new FakeAdapter()]); - return new MiddlewareFactoryPush($container, new CallableFactory($container)); + return new MiddlewareFactory($container, new CallableFactory($container)); } private function getContainer(array $instances = []): ContainerInterface @@ -155,18 +155,18 @@ private function getContainer(array $instances = []): ContainerInterface return new SimpleContainer($instances); } - private function getRequestHandler(): MessageHandlerPushInterface + private function getRequestHandler(): MessageHandlerInterface { - return new class () implements MessageHandlerPushInterface { - public function handlePush(PushRequest $request): PushRequest + return new class () implements MessageHandlerInterface { + public function handle(Request $request): Request { return $request; } }; } - private function getPushRequest(): PushRequest + private function getRequest(): Request { - return new PushRequest(new Message('handler', 'data'), new FakeAdapter()); + return new Request(new Message('handler', 'data'), new FakeAdapter()); } } diff --git a/tests/Unit/Middleware/Push/PushRequestTest.php b/tests/Unit/Middleware/Push/PushRequestTest.php deleted file mode 100644 index 2c1533e5..00000000 --- a/tests/Unit/Middleware/Push/PushRequestTest.php +++ /dev/null @@ -1,22 +0,0 @@ -assertNotSame($pushRequest, $pushRequest->withAdapter(new FakeAdapter())); - $this->assertNotSame($pushRequest, $pushRequest->withMessage($message)); - } -} diff --git a/tests/Unit/Middleware/Push/Support/TestMiddleware.php b/tests/Unit/Middleware/Push/Support/TestMiddleware.php deleted file mode 100644 index a15c24f0..00000000 --- a/tests/Unit/Middleware/Push/Support/TestMiddleware.php +++ /dev/null @@ -1,22 +0,0 @@ -withMessage(new Message('test', $this->message)); - } -} diff --git a/tests/Unit/Middleware/PushRequestTest.php b/tests/Unit/Middleware/PushRequestTest.php new file mode 100644 index 00000000..bdb64978 --- /dev/null +++ b/tests/Unit/Middleware/PushRequestTest.php @@ -0,0 +1,22 @@ +assertNotSame($Request, $Request->withAdapter(new FakeAdapter())); + $this->assertNotSame($Request, $Request->withMessage($message)); + } +} diff --git a/tests/Unit/Middleware/Push/Support/InvalidController.php b/tests/Unit/Middleware/Support/InvalidController.php similarity index 68% rename from tests/Unit/Middleware/Push/Support/InvalidController.php rename to tests/Unit/Middleware/Support/InvalidController.php index 95642cfb..14006ccf 100644 --- a/tests/Unit/Middleware/Push/Support/InvalidController.php +++ b/tests/Unit/Middleware/Support/InvalidController.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Tests\Unit\Middleware\Push\Support; +namespace Yiisoft\Queue\Tests\Unit\Middleware\Support; final class InvalidController { diff --git a/tests/Unit/Middleware/Push/Support/TestCallableMiddleware.php b/tests/Unit/Middleware/Support/TestCallableMiddleware.php similarity index 53% rename from tests/Unit/Middleware/Push/Support/TestCallableMiddleware.php rename to tests/Unit/Middleware/Support/TestCallableMiddleware.php index 035ed999..1c1eeffd 100644 --- a/tests/Unit/Middleware/Push/Support/TestCallableMiddleware.php +++ b/tests/Unit/Middleware/Support/TestCallableMiddleware.php @@ -2,14 +2,14 @@ declare(strict_types=1); -namespace Yiisoft\Queue\Tests\Unit\Middleware\Push\Support; +namespace Yiisoft\Queue\Tests\Unit\Middleware\Support; use Yiisoft\Queue\Message\Message; -use Yiisoft\Queue\Middleware\Push\PushRequest; +use Yiisoft\Queue\Middleware\Request; final class TestCallableMiddleware { - public function index(PushRequest $request): PushRequest + public function index(Request $request): Request { return $request->withMessage(new Message('test', 'New test data')); } diff --git a/tests/Unit/Middleware/Support/TestMiddleware.php b/tests/Unit/Middleware/Support/TestMiddleware.php new file mode 100644 index 00000000..1225678b --- /dev/null +++ b/tests/Unit/Middleware/Support/TestMiddleware.php @@ -0,0 +1,22 @@ +withMessage(new Message('test', $this->message)); + } +} diff --git a/tests/Unit/WorkerTest.php b/tests/Unit/WorkerTest.php index 4187358f..8d3022e3 100644 --- a/tests/Unit/WorkerTest.php +++ b/tests/Unit/WorkerTest.php @@ -7,13 +7,14 @@ use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Yiisoft\Injector\Injector; +use Yiisoft\Queue\Middleware\MiddlewareDispatcher; +use Yiisoft\Queue\Middleware\MiddlewareFactoryInterface; +use Yiisoft\Queue\Middleware\PushMiddlewareDispatcher; use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Test\Support\Log\SimpleLogger; use Yiisoft\Queue\Exception\JobFailureException; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\Consume\MiddlewareFactoryConsumeInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher; use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFactoryFailureInterface; use Yiisoft\Queue\QueueInterface; @@ -195,7 +196,7 @@ private function createWorkerByParams( $logger, new Injector($container), $container, - new ConsumeMiddlewareDispatcher($this->createMock(MiddlewareFactoryConsumeInterface::class)), + new MiddlewareDispatcher($this->createMock(MiddlewareFactoryInterface::class)), new FailureMiddlewareDispatcher($this->createMock(MiddlewareFactoryFailureInterface::class), []), ); } From 6f1ee246a3b687a581dd52568b66cc12c3c5bad2 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sun, 14 Jan 2024 10:36:32 +0000 Subject: [PATCH 2/7] Apply fixes from StyleCI --- src/Middleware/MiddlewareFactory.php | 3 --- tests/Integration/MessageConsumingTest.php | 2 -- tests/Integration/MiddlewareTest.php | 1 - .../Implementation/ExponentialDelayMiddlewareTest.php | 1 - .../FailureHandling/Implementation/SendAgainMiddlewareTest.php | 1 - tests/Unit/Middleware/PushRequestTest.php | 2 +- tests/Unit/WorkerTest.php | 1 - 7 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Middleware/MiddlewareFactory.php b/src/Middleware/MiddlewareFactory.php index e02d621b..06449391 100644 --- a/src/Middleware/MiddlewareFactory.php +++ b/src/Middleware/MiddlewareFactory.php @@ -10,9 +10,6 @@ use Yiisoft\Definitions\Exception\InvalidConfigException; use Yiisoft\Definitions\Helpers\DefinitionValidator; use Yiisoft\Injector\Injector; -use Yiisoft\Queue\Middleware\CallableFactory; -use Yiisoft\Queue\Middleware\InvalidCallableConfigurationException; -use Yiisoft\Queue\Middleware\InvalidMiddlewareDefinitionException; use function is_string; diff --git a/tests/Integration/MessageConsumingTest.php b/tests/Integration/MessageConsumingTest.php index 7c4eeeaa..70ef607a 100644 --- a/tests/Integration/MessageConsumingTest.php +++ b/tests/Integration/MessageConsumingTest.php @@ -9,8 +9,6 @@ use Yiisoft\Injector\Injector; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\Consume\MiddlewareFactoryConsumeInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher; use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFactoryFailureInterface; use Yiisoft\Queue\Middleware\MiddlewareDispatcher; diff --git a/tests/Integration/MiddlewareTest.php b/tests/Integration/MiddlewareTest.php index 2c5e7997..8aae0436 100644 --- a/tests/Integration/MiddlewareTest.php +++ b/tests/Integration/MiddlewareTest.php @@ -9,7 +9,6 @@ use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Yiisoft\Injector\Injector; -use Yiisoft\Queue\AMQP\Middleware\DelayMiddleware; use Yiisoft\Queue\Middleware\DelayMiddlewareInterface; use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Test\Support\Log\SimpleLogger; diff --git a/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php b/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php index 246f117d..47c8e18c 100644 --- a/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php +++ b/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php @@ -6,7 +6,6 @@ use Exception; use InvalidArgumentException; -use Yiisoft\Queue\AMQP\Middleware\DelayMiddleware; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Middleware\DelayMiddlewareInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; diff --git a/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php b/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php index ef812831..6a722a75 100644 --- a/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php +++ b/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php @@ -7,7 +7,6 @@ use Exception; use PHPUnit\Framework\Assert; use RuntimeException; -use Yiisoft\Queue\AMQP\Middleware\DelayMiddleware; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; diff --git a/tests/Unit/Middleware/PushRequestTest.php b/tests/Unit/Middleware/PushRequestTest.php index bdb64978..5bee6569 100644 --- a/tests/Unit/Middleware/PushRequestTest.php +++ b/tests/Unit/Middleware/PushRequestTest.php @@ -9,7 +9,7 @@ use Yiisoft\Queue\Tests\App\FakeAdapter; use Yiisoft\Queue\Tests\TestCase; -final class RequestTest extends TestCase +final class PushRequestTest extends TestCase { public function testImmutable(): void { diff --git a/tests/Unit/WorkerTest.php b/tests/Unit/WorkerTest.php index 8d3022e3..1c9f6252 100644 --- a/tests/Unit/WorkerTest.php +++ b/tests/Unit/WorkerTest.php @@ -9,7 +9,6 @@ use Yiisoft\Injector\Injector; use Yiisoft\Queue\Middleware\MiddlewareDispatcher; use Yiisoft\Queue\Middleware\MiddlewareFactoryInterface; -use Yiisoft\Queue\Middleware\PushMiddlewareDispatcher; use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Test\Support\Log\SimpleLogger; use Yiisoft\Queue\Exception\JobFailureException; From 548d3c877b7cb245abb499bed3d27de1752d4045 Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sun, 14 Jan 2024 17:45:00 +0700 Subject: [PATCH 3/7] Fix log message --- src/Queue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Queue.php b/src/Queue.php index e38dd250..4044949a 100644 --- a/src/Queue.php +++ b/src/Queue.php @@ -60,7 +60,7 @@ public function push( $messageId = $message->getMetadata()[IdEnvelope::MESSAGE_ID_KEY] ?? 'null'; $this->logger->info( - 'ed message with handler name "{handlerName}" to the queue. Assigned ID #{id}.', + 'Pushed message with handler name "{handlerName}" to the queue. Assigned ID #{id}.', ['handlerName' => $message->getHandlerName(), 'id' => $messageId] ); From 84db7a429f6c8ca93b9d746e5d77aadfbb457a0a Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sun, 14 Jan 2024 17:46:22 +0700 Subject: [PATCH 4/7] Implement method --- src/Debug/QueueDecorator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Debug/QueueDecorator.php b/src/Debug/QueueDecorator.php index 556357e4..94853a1d 100644 --- a/src/Debug/QueueDecorator.php +++ b/src/Debug/QueueDecorator.php @@ -64,6 +64,6 @@ public function withChannelName(string $channel): QueueInterface public function getAdapter(): ?AdapterInterface { - // TODO: Implement getAdapter() method. + return $this->queue->getAdapter(); } } From 83028217d84d6b808723896edfa5bb7cc0b9906d Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sun, 14 Jan 2024 18:05:30 +0700 Subject: [PATCH 5/7] Revert some consume middlewares --- src/Debug/QueueCollector.php | 4 +- src/Worker/Worker.php | 14 +- .../Integration/Support/ConsumeMiddleware.php | 27 +++ .../Middleware/Consume/ConsumeRequestTest.php | 24 ++ ...validMiddlewareDefinitionExceptionTest.php | 73 ++++++ .../Consume/MiddlewareDispatcherTest.php | 186 ++++++++++++++++ .../Consume/MiddlewareFactoryTest.php | 208 ++++++++++++++++++ 7 files changed, 522 insertions(+), 14 deletions(-) create mode 100644 tests/Integration/Support/ConsumeMiddleware.php create mode 100644 tests/Unit/Middleware/Consume/ConsumeRequestTest.php create mode 100644 tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php create mode 100644 tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php create mode 100644 tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php diff --git a/src/Debug/QueueCollector.php b/src/Debug/QueueCollector.php index 1a8c9d76..d0bc7171 100644 --- a/src/Debug/QueueCollector.php +++ b/src/Debug/QueueCollector.php @@ -4,11 +4,11 @@ namespace Yiisoft\Queue\Debug; +use Yiisoft\Queue\Middleware\MiddlewareInterface; use Yiisoft\Yii\Debug\Collector\CollectorTrait; use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface; use Yiisoft\Queue\Enum\JobStatus; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Push\MiddlewarePushInterface; use Yiisoft\Queue\QueueInterface; final class QueueCollector implements SummaryCollectorInterface @@ -53,7 +53,7 @@ public function collectStatus(string $id, JobStatus $status): void public function collectPush( string $channel, MessageInterface $message, - string|array|callable|MiddlewarePushInterface ...$middlewareDefinitions, + string|array|callable|MiddlewareInterface ...$middlewareDefinitions, ): void { if (!$this->isActive()) { return; diff --git a/src/Worker/Worker.php b/src/Worker/Worker.php index 46bf645d..13471fb7 100644 --- a/src/Worker/Worker.php +++ b/src/Worker/Worker.php @@ -57,12 +57,12 @@ public function process(MessageInterface $message, QueueInterface $queue): Messa $request = new Request($message, $queue->getAdapter()); $closure = fn (MessageInterface $message): mixed => $this->injector->invoke($handler, [$message]); try { - return $this->consumeMiddlewareDispatcher->dispatch($request, $this->createConsumeHandler($closure))->getMessage(); + return $this->consumeMiddlewareDispatcher->dispatch($request, new ConsumeFinalHandler($closure))->getMessage(); } catch (Throwable $exception) { $request = new FailureHandlingRequest($request->getMessage(), $exception, $queue); try { - $result = $this->failureMiddlewareDispatcher->dispatch($request, $this->createFailureHandler()); + $result = $this->failureMiddlewareDispatcher->dispatch($request, new FailureFinalHandler()); $this->logger->info($exception->getMessage()); return $result->getMessage(); @@ -140,14 +140,4 @@ private function prepare(callable|object|array|string|null $definition): callabl return $definition; } - - private function createConsumeHandler(Closure $handler): MessageHandlerInterface - { - return new ConsumeFinalHandler($handler); - } - - private function createFailureHandler(): MessageFailureHandlerInterface - { - return new FailureFinalHandler(); - } } diff --git a/tests/Integration/Support/ConsumeMiddleware.php b/tests/Integration/Support/ConsumeMiddleware.php new file mode 100644 index 00000000..347920f4 --- /dev/null +++ b/tests/Integration/Support/ConsumeMiddleware.php @@ -0,0 +1,27 @@ +getMessage(); + $stack = $message->getData(); + $stack[] = $this->stage; + $messageNew = new Message($message->getHandlerName(), $stack); + + return $handler->handle($request->withMessage($messageNew)); + } +} diff --git a/tests/Unit/Middleware/Consume/ConsumeRequestTest.php b/tests/Unit/Middleware/Consume/ConsumeRequestTest.php new file mode 100644 index 00000000..f2942570 --- /dev/null +++ b/tests/Unit/Middleware/Consume/ConsumeRequestTest.php @@ -0,0 +1,24 @@ +createMock(AdapterInterface::class); + $consumeRequest = new Request($message, $adapter); + + $this->assertNotSame($consumeRequest, $consumeRequest->withMessage($message)); + $this->assertNotSame($consumeRequest, $consumeRequest->withAdapter($adapter)); + } +} diff --git a/tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php b/tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php new file mode 100644 index 00000000..26efb343 --- /dev/null +++ b/tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php @@ -0,0 +1,73 @@ + TestCallableMiddleware::class, 'index'], + sprintf( + '["class" => "%s", "index"]', + TestCallableMiddleware::class, + ), + ], + ]; + } + + /** + * @dataProvider dataBase + */ + public function testBase(mixed $definition, string $expected): void + { + $exception = new InvalidMiddlewareDefinitionException($definition); + self::assertStringEndsWith('. Got ' . $expected . '.', $exception->getMessage()); + } + + public function dataUnknownDefinition(): array + { + return [ + [42], + [[new stdClass()]], + ]; + } + + /** + * @dataProvider dataUnknownDefinition + */ + public function testUnknownDefinition(mixed $definition): void + { + $exception = new InvalidMiddlewareDefinitionException($definition); + self::assertSame( + 'Parameter should be either middleware class name or a callable.', + $exception->getMessage() + ); + } +} diff --git a/tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php b/tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php new file mode 100644 index 00000000..5f016bc1 --- /dev/null +++ b/tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php @@ -0,0 +1,186 @@ +getRequest(); + $queue = $this->createMock(QueueInterface::class); + $adapter = $this->createMock(AdapterInterface::class); + + $dispatcher = $this->createDispatcher()->withMiddlewares( + [ + static function (Request $request) use ($adapter): Request { + return $request->withMessage(new Message('test', 'New closure test data'))->withAdapter($adapter); + }, + ] + ); + + $request = $dispatcher->dispatch($request, $this->getRequestHandler()); + $this->assertSame('New closure test data', $request->getMessage()->getData()); + } + + public function testArrayMiddlewareCallableDefinition(): void + { + $request = $this->getRequest(); + $container = $this->createContainer( + [ + TestCallableMiddleware::class => new TestCallableMiddleware(), + ] + ); + $dispatcher = $this->createDispatcher($container)->withMiddlewares([[TestCallableMiddleware::class, 'index']]); + $request = $dispatcher->dispatch($request, $this->getRequestHandler()); + $this->assertSame('New test data', $request->getMessage()->getData()); + } + + public function testFactoryArrayDefinition(): void + { + $request = $this->getRequest(); + $container = $this->createContainer(); + $definition = [ + 'class' => TestMiddleware::class, + '__construct()' => ['message' => 'New test data from the definition'], + ]; + $dispatcher = $this->createDispatcher($container)->withMiddlewares([$definition]); + $request = $dispatcher->dispatch($request, $this->getRequestHandler()); + $this->assertSame('New test data from the definition', $request->getMessage()->getData()); + } + + public function testMiddlewareFullStackCalled(): void + { + $request = $this->getRequest(); + + $middleware1 = static function (Request $request, MessageHandlerInterface $handler): Request { + $request = $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'new test data')); + + return $handler->handle($request); + }; + $middleware2 = static function (Request $request, MessageHandlerInterface $handler): Request { + $request = $request->withMessage(new Message('new handler', $request->getMessage()->getData())); + + return $handler->handle($request); + }; + + $dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); + + $request = $dispatcher->dispatch($request, $this->getRequestHandler()); + $this->assertSame('new test data', $request->getMessage()->getData()); + $this->assertSame('new handler', $request->getMessage()->getHandlerName()); + } + + public function testMiddlewareStackInterrupted(): void + { + $request = $this->getRequest(); + + $middleware1 = static function (Request $request, MessageHandlerInterface $handler): Request { + return $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'first')); + }; + $middleware2 = static function (Request $request, MessageHandlerInterface $handler): Request { + return $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'second')); + }; + + $dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); + + $request = $dispatcher->dispatch($request, $this->getRequestHandler()); + $this->assertSame('first', $request->getMessage()->getData()); + } + + public function dataHasMiddlewares(): array + { + return [ + [[], false], + [[[TestCallableMiddleware::class, 'index']], true], + ]; + } + + /** + * @dataProvider dataHasMiddlewares + */ + public function testHasMiddlewares(array $definitions, bool $expected): void + { + self::assertSame( + $expected, + $this->createDispatcher()->withMiddlewares($definitions)->hasMiddlewares() + ); + } + + public function testImmutability(): void + { + $dispatcher = $this->createDispatcher(); + self::assertNotSame($dispatcher, $dispatcher->withMiddlewares([])); + } + + public function testResetStackOnWithMiddlewares(): void + { + $request = $this->getRequest(); + $container = $this->createContainer( + [ + TestCallableMiddleware::class => new TestCallableMiddleware(), + TestMiddleware::class => new TestMiddleware(), + ] + ); + + $dispatcher = $this + ->createDispatcher($container) + ->withMiddlewares([[TestCallableMiddleware::class, 'index']]); + $dispatcher->dispatch($request, $this->getRequestHandler()); + + $dispatcher = $dispatcher->withMiddlewares([TestMiddleware::class]); + $request = $dispatcher->dispatch($request, $this->getRequestHandler()); + + self::assertSame('New middleware test data', $request->getMessage()->getData()); + } + + private function getRequestHandler(): MessageHandlerInterface + { + return new class () implements MessageHandlerInterface { + public function handle(Request $request): Request + { + return $request; + } + }; + } + + private function createDispatcher( + ContainerInterface $container = null, + ): MiddlewareDispatcher { + $container ??= $this->createContainer([AdapterInterface::class => new FakeAdapter()]); + $callableFactory = new CallableFactory($container); + + return new MiddlewareDispatcher( + new MiddlewareFactory($container, $callableFactory), + ); + } + + private function createContainer(array $instances = []): ContainerInterface + { + return new SimpleContainer($instances); + } + + private function getRequest(): Request + { + return new Request( + new Message('handler', 'data'), + $this->createMock(AdapterInterface::class) + ); + } +} diff --git a/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php b/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php new file mode 100644 index 00000000..cbdd763c --- /dev/null +++ b/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php @@ -0,0 +1,208 @@ +getContainer([ConsumeMiddleware::class => new ConsumeMiddleware('stage1')]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware(ConsumeMiddleware::class); + self::assertInstanceOf(ConsumeMiddleware::class, $middleware); + } + + public function testCreateFromAliasString(): void + { + $container = $this->getContainer(['test' => new ConsumeMiddleware('stage1')]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware('test'); + self::assertInstanceOf(ConsumeMiddleware::class, $middleware); + } + + public function testCreateFromArray(): void + { + $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + [TestCallableMiddleware::class, 'index'] + ); + self::assertSame( + 'New test data', + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) + )->getMessage()->getData(), + ); + } + + public function testCreateFromClosureResponse(): void + { + $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + fn (): Request => new Request( + new Message('test', 'test data'), + $this->createMock(AdapterInterface::class), + ) + ); + self::assertSame( + 'test data', + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) + )->getMessage()->getData() + ); + } + + public function testCreateFromClosureMiddleware(): void + { + $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + static fn (): MiddlewareInterface => new ConsumeMiddleware('stage1') + ); + + $handler = $this->createMock(MessageHandlerInterface::class); + $handler->expects($this->once())->method('handle')->willReturnCallback( + static fn (Request $request): Request => $request->withMessage( + new Message('test', 'New middleware test data') + ) + ); + + self::assertSame( + 'New middleware test data', + $middleware->process( + $this->getRequest(), + $handler + )->getMessage()->getData() + ); + } + + public function testCreateWithUseParamsMiddleware(): void + { + $container = $this->getContainer([ConsumeMiddleware::class => new ConsumeMiddleware('stage1')]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware(ConsumeMiddleware::class); + + self::assertSame( + ['data', 'stage1'], + $middleware->process( + $this->getRequest(), + $this->getRequestHandler() + )->getMessage()->getData() + ); + } + + public function testCreateWithTestCallableMiddleware(): void + { + $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + [TestCallableMiddleware::class, 'index'] + ); + $request = $this->getRequest(); + + self::assertSame( + 'New test data', + $middleware->process( + $request, + $this->getRequestHandler() + )->getMessage()->getData() + ); + } + + public function testInvalidMiddlewareWithWrongCallable(): void + { + $container = $this->getContainer([TestCallableMiddleware::class => new TestCallableMiddleware()]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + static fn () => 42 + ); + + $this->expectException(InvalidMiddlewareDefinitionException::class); + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) + ); + } + + public function invalidMiddlewareDefinitionProvider(): array + { + return [ + 'wrong string' => ['test'], + 'wrong class' => [TestCallableMiddleware::class], + 'wrong array size' => [['test']], + 'array not a class' => [['class', 'test']], + 'wrong array type' => [['class' => TestCallableMiddleware::class, 'index']], + 'wrong array with int items' => [[7, 42]], + 'array with wrong method name' => [[TestCallableMiddleware::class, 'notExists']], + 'array wrong class' => [['class' => InvalidController::class]], + ]; + } + + /** + * @dataProvider invalidMiddlewareDefinitionProvider + */ + public function testInvalidMiddleware(mixed $definition): void + { + $this->expectException(InvalidMiddlewareDefinitionException::class); + $this->getMiddlewareFactory()->createMiddleware($definition); + } + + public function testInvalidMiddlewareWithWrongController(): void + { + $container = $this->getContainer([InvalidController::class => new InvalidController()]); + $middleware = $this->getMiddlewareFactory($container)->createMiddleware( + [InvalidController::class, 'index'] + ); + + $this->expectException(InvalidMiddlewareDefinitionException::class); + $middleware->process( + $this->getRequest(), + $this->createMock(MessageHandlerInterface::class) + ); + } + + private function getMiddlewareFactory(ContainerInterface $container = null): MiddlewareFactoryInterface + { + $container ??= $this->getContainer([AdapterInterface::class => new FakeAdapter()]); + + return new MiddlewareFactory($container, new CallableFactory($container)); + } + + private function getContainer(array $instances = []): ContainerInterface + { + return new SimpleContainer($instances); + } + + private function getRequestHandler(): MessageHandlerInterface + { + return new class () implements MessageHandlerInterface { + public function handle(Request $request): Request + { + return $request; + } + }; + } + + private function getRequest(): Request + { + return new Request( + new Message('handler', ['data']), + $this->createMock(AdapterInterface::class) + ); + } +} From 7fe6ad738323593e133815c5967c109ae51ab765 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sun, 14 Jan 2024 11:05:43 +0000 Subject: [PATCH 6/7] Apply fixes from StyleCI --- src/Worker/Worker.php | 3 --- tests/Unit/Middleware/Consume/ConsumeRequestTest.php | 1 - tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php | 1 - 3 files changed, 5 deletions(-) diff --git a/src/Worker/Worker.php b/src/Worker/Worker.php index 13471fb7..16953be2 100644 --- a/src/Worker/Worker.php +++ b/src/Worker/Worker.php @@ -4,7 +4,6 @@ namespace Yiisoft\Queue\Worker; -use Closure; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; @@ -20,8 +19,6 @@ use Yiisoft\Queue\Middleware\FailureHandling\FailureFinalHandler; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\FailureMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface; -use Yiisoft\Queue\Middleware\MessageHandlerInterface; use Yiisoft\Queue\Middleware\MiddlewareDispatcher; use Yiisoft\Queue\Middleware\Request; use Yiisoft\Queue\QueueInterface; diff --git a/tests/Unit/Middleware/Consume/ConsumeRequestTest.php b/tests/Unit/Middleware/Consume/ConsumeRequestTest.php index f2942570..053e7668 100644 --- a/tests/Unit/Middleware/Consume/ConsumeRequestTest.php +++ b/tests/Unit/Middleware/Consume/ConsumeRequestTest.php @@ -7,7 +7,6 @@ use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Middleware\Request; -use Yiisoft\Queue\QueueInterface; use Yiisoft\Queue\Tests\TestCase; final class ConsumeRequestTest extends TestCase diff --git a/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php b/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php index cbdd763c..eaf3d4eb 100644 --- a/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php +++ b/tests/Unit/Middleware/Consume/MiddlewareFactoryTest.php @@ -18,7 +18,6 @@ use Yiisoft\Queue\Middleware\MiddlewareFactory; use Yiisoft\Queue\Middleware\MiddlewareFactoryInterface; use Yiisoft\Queue\Middleware\InvalidMiddlewareDefinitionException; -use Yiisoft\Queue\QueueInterface; use Yiisoft\Queue\Tests\App\FakeAdapter; use Yiisoft\Queue\Tests\Unit\Middleware\Support\InvalidController; From df89b8e3790e6bcb952dca8e5ba91023cc413352 Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sun, 14 Jan 2024 18:09:41 +0700 Subject: [PATCH 7/7] Fix psalm --- src/Middleware/FailureHandling/FailureFinalHandler.php | 3 ++- src/Middleware/FailureHandling/FailureHandlingRequest.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Middleware/FailureHandling/FailureFinalHandler.php b/src/Middleware/FailureHandling/FailureFinalHandler.php index f9668231..9d67728f 100644 --- a/src/Middleware/FailureHandling/FailureFinalHandler.php +++ b/src/Middleware/FailureHandling/FailureFinalHandler.php @@ -16,6 +16,7 @@ final class FailureFinalHandler implements MessageFailureHandlerInterface */ public function handleFailure(FailureHandlingRequest $request): FailureHandlingRequest { - throw $request->getException(); + // TODO: Add tests + throw $request->getException() ?? new \RuntimeException('Message processing failed.'); } } diff --git a/src/Middleware/FailureHandling/FailureHandlingRequest.php b/src/Middleware/FailureHandling/FailureHandlingRequest.php index 7d350684..922e9b83 100644 --- a/src/Middleware/FailureHandling/FailureHandlingRequest.php +++ b/src/Middleware/FailureHandling/FailureHandlingRequest.php @@ -22,7 +22,7 @@ public function getMessage(): MessageInterface return $this->message; } - public function getException(): Throwable + public function getException(): ?Throwable { return $this->exception; }