From 20774772d2aafe59b7cc32865e84875f28d9b3b0 Mon Sep 17 00:00:00 2001 From: Pavel Batanov Date: Wed, 13 Apr 2016 13:26:53 +0300 Subject: [PATCH] Extract RPC commons (#13) --- composer.json | 1 + .../CacheableResponseCollection.php | 87 -------------- .../Api/Rpc/Decorators/CacheableRpcClient.php | 80 ------------- .../Rpc/Decorators/LazyResponseCollection.php | 74 ------------ .../Api/Rpc/Decorators/LazyRpcClient.php | 48 -------- .../Decorators/LoggableResponseCollection.php | 109 ------------------ .../Api/Rpc/Decorators/LoggableRpcClient.php | 54 --------- .../Rpc/Decorators/RequestKeyExtractor.php | 38 ------ .../Rpc/Exception/BadInvocationException.php | 13 --- .../Exception/RemoteCallFailedException.php | 13 --- .../Rpc/Exception/RpcExceptionInterface.php | 13 --- .../Api/Rpc/ResponseCollectionInterface.php | 21 ---- src/ScayTrase/Api/Rpc/RpcClientInterface.php | 21 ---- src/ScayTrase/Api/Rpc/RpcErrorInterface.php | 17 --- src/ScayTrase/Api/Rpc/RpcRequestInterface.php | 17 --- .../Api/Rpc/RpcResponseInterface.php | 20 ---- .../Api/Rpc/Tests/AbstractRpcTest.php | 73 ------------ src/ScayTrase/Api/Rpc/Tests/DecoratorTest.php | 96 --------------- .../Api/Rpc/Tests/LazyClientTest.php | 57 --------- 19 files changed, 1 insertion(+), 851 deletions(-) delete mode 100644 src/ScayTrase/Api/Rpc/Decorators/CacheableResponseCollection.php delete mode 100644 src/ScayTrase/Api/Rpc/Decorators/CacheableRpcClient.php delete mode 100644 src/ScayTrase/Api/Rpc/Decorators/LazyResponseCollection.php delete mode 100644 src/ScayTrase/Api/Rpc/Decorators/LazyRpcClient.php delete mode 100644 src/ScayTrase/Api/Rpc/Decorators/LoggableResponseCollection.php delete mode 100644 src/ScayTrase/Api/Rpc/Decorators/LoggableRpcClient.php delete mode 100644 src/ScayTrase/Api/Rpc/Decorators/RequestKeyExtractor.php delete mode 100644 src/ScayTrase/Api/Rpc/Exception/BadInvocationException.php delete mode 100644 src/ScayTrase/Api/Rpc/Exception/RemoteCallFailedException.php delete mode 100644 src/ScayTrase/Api/Rpc/Exception/RpcExceptionInterface.php delete mode 100644 src/ScayTrase/Api/Rpc/ResponseCollectionInterface.php delete mode 100644 src/ScayTrase/Api/Rpc/RpcClientInterface.php delete mode 100644 src/ScayTrase/Api/Rpc/RpcErrorInterface.php delete mode 100644 src/ScayTrase/Api/Rpc/RpcRequestInterface.php delete mode 100644 src/ScayTrase/Api/Rpc/RpcResponseInterface.php delete mode 100644 src/ScayTrase/Api/Rpc/Tests/AbstractRpcTest.php delete mode 100644 src/ScayTrase/Api/Rpc/Tests/DecoratorTest.php delete mode 100644 src/ScayTrase/Api/Rpc/Tests/LazyClientTest.php diff --git a/composer.json b/composer.json index 34ca4e7..5d61d69 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "minimum-stability": "stable", "require": { "php": "~5.5|~7.0", + "scaytrase/rpc-common": "~1.0", "psr/log": "~1.0", "guzzlehttp/guzzle": "~6.0", "paragonie/random_compat": "~1.1@stable" diff --git a/src/ScayTrase/Api/Rpc/Decorators/CacheableResponseCollection.php b/src/ScayTrase/Api/Rpc/Decorators/CacheableResponseCollection.php deleted file mode 100644 index 549d06f..0000000 --- a/src/ScayTrase/Api/Rpc/Decorators/CacheableResponseCollection.php +++ /dev/null @@ -1,87 +0,0 @@ -cache = $cache; - $this->extractor = $extractor; - $this->items = $items; - $this->proxiedCollection = $proxiedCollection; - $this->ttl = $ttl ?: null; - } - - - /** {@inheritdoc} */ - public function getResponse(RpcRequestInterface $request) - { - $key = $this->extractor->getKey($request); - - /** @var CacheItemInterface $item */ - $item = $this->items[$key]['item']; - - if ($item->isHit()) { - return $item->get(); - } - - $item->expiresAfter($this->ttl); - $item->set($this->proxiedCollection->getResponse($request)); - - $this->cache->save($item); - - return $item->get(); - } - - /** {@inheritdoc} */ - public function getIterator() - { - foreach ($this->items as $key => $data) { - /** @var CacheItemInterface $item */ - $item = $data['item']; - - if ($item->isHit()) { - yield $item->get(); - } - - yield $this->getResponse($data['request']); - } - } -} diff --git a/src/ScayTrase/Api/Rpc/Decorators/CacheableRpcClient.php b/src/ScayTrase/Api/Rpc/Decorators/CacheableRpcClient.php deleted file mode 100644 index 5614fe2..0000000 --- a/src/ScayTrase/Api/Rpc/Decorators/CacheableRpcClient.php +++ /dev/null @@ -1,80 +0,0 @@ -decoratedClient = $decoratedClient; - $this->cache = $cache; - $this->ttl = $ttl; - - $this->extractor = new RequestKeyExtractor((string)$keyPrefix); - } - - /** {@inheritdoc} */ - public function invoke($calls) - { - if (!is_array($calls)) { - $calls = [$calls]; - } - - $items = []; - $proxiedRequests = []; - foreach ($calls as $call) { - $key = $this->extractor->getKey($call); - $item = $this->cache->getItem($key); - $items[$key]['request'] = $call; - $items[$key]['item'] = $item; - if (!$item->isHit()) { - $proxiedRequests[] = $call; - } - } - - // Prevent batch calls when not necessary - if (count($proxiedRequests) === 1 && !is_array($calls)) { - $proxiedRequests = array_shift($proxiedRequests); - } - - return new CacheableResponseCollection( - $this->cache, - $this->extractor, - $items, - $this->decoratedClient->invoke($proxiedRequests), - $this->ttl - ); - } -} diff --git a/src/ScayTrase/Api/Rpc/Decorators/LazyResponseCollection.php b/src/ScayTrase/Api/Rpc/Decorators/LazyResponseCollection.php deleted file mode 100644 index a134434..0000000 --- a/src/ScayTrase/Api/Rpc/Decorators/LazyResponseCollection.php +++ /dev/null @@ -1,74 +0,0 @@ -client = $client; } - - - /** {@inheritdoc} */ - public function getResponse(RpcRequestInterface $request) - { - if (!$this->initialized) { - $this->init(); - } - - return $this->collection->getResponse($request); - } - - private function init() - { - $this->collection = $this->client->invoke($this->requests); - $this->requests = null; - $this->initialized = true; - } - - public function append(RpcRequestInterface $request) - { - if ($this->isFrozen()) { - throw new \LogicException('Cannot add request to frozen lazy collection'); - } - - $this->requests[] = $request; - } - - public function isFrozen() - { - return $this->initialized; - } - - /** {@inheritdoc} */ - public function getIterator() - { - if (!$this->initialized) { - $this->init(); - } - - return $this->collection; - } -} diff --git a/src/ScayTrase/Api/Rpc/Decorators/LazyRpcClient.php b/src/ScayTrase/Api/Rpc/Decorators/LazyRpcClient.php deleted file mode 100644 index 9a7c698..0000000 --- a/src/ScayTrase/Api/Rpc/Decorators/LazyRpcClient.php +++ /dev/null @@ -1,48 +0,0 @@ -decoratedClient = $decoratedClient; - $this->collection = new LazyResponseCollection($decoratedClient); - } - - public function invoke($calls) - { - // Reset collection if previous was already sent - if ($this->collection->isFrozen()) { - $this->collection = new LazyResponseCollection($this->decoratedClient); - } - - if (!is_array($calls)) { - $calls = [$calls]; - } - - foreach ($calls as $call) { - $this->collection->append($call); - } - - return $this->collection; - } -} diff --git a/src/ScayTrase/Api/Rpc/Decorators/LoggableResponseCollection.php b/src/ScayTrase/Api/Rpc/Decorators/LoggableResponseCollection.php deleted file mode 100644 index af3b43f..0000000 --- a/src/ScayTrase/Api/Rpc/Decorators/LoggableResponseCollection.php +++ /dev/null @@ -1,109 +0,0 @@ -decoratedCollection = $decoratedCollection; - $this->logger = $logger; - } - - /** {@inheritdoc} */ - public function getResponse(RpcRequestInterface $request) - { - $response = $this->decoratedCollection->getResponse($request); - $this->logResponseWithRequest($request, $response); - - return $response; - } - - /** {@inheritdoc} */ - public function getIterator() - { - foreach ($this->decoratedCollection as $response) { - $this->logResponse($response); - yield $response; - } - } - - /** - * @param RpcRequestInterface $request - * @param RpcResponseInterface $response - */ - private function logResponseWithRequest(RpcRequestInterface $request, RpcResponseInterface $response) - { - $hash = spl_object_hash($response); - if (in_array($hash, $this->loggedResponses, true)) { - return; - } - - if ($response->isSuccessful()) { - $this->logger->info( - sprintf('Method "%s" call was successful', $request->getMethod()), - ['request_hash' => spl_object_hash($request)] - ); - $this->logger->debug( - sprintf("Resposne:\n%s", json_encode($response->getBody(), JSON_PRETTY_PRINT)), - ['request_hash' => spl_object_hash($request)] - ); - } else { - $this->logger->info( - sprintf('Method "%s" call was failed', $request->getMethod()), - ['request_hash' => spl_object_hash($request)] - ); - $this->logger->error( - sprintf('ERROR %s: %s', $response->getError()->getCode(), $response->getError()->getMessage()), - ['request_hash' => spl_object_hash($request)] - ); - } - - $this->loggedResponses[] = $hash; - } - - private function logResponse(RpcResponseInterface $response) - { - $hash = spl_object_hash($response); - if (in_array($hash, $this->loggedResponses, true)) { - return; - } - - if ($response->isSuccessful()) { - $this->logger->info('Successful RPC call'); - $this->logger->debug( - sprintf("Resposne:\n%s", json_encode($response->getBody(), JSON_PRETTY_PRINT)) - ); - } else { - $this->logger->error( - sprintf('RPC Error %s: %s', $response->getError()->getCode(), $response->getError()->getMessage()) - ); - } - - $this->loggedResponses[] = $hash; - } -} diff --git a/src/ScayTrase/Api/Rpc/Decorators/LoggableRpcClient.php b/src/ScayTrase/Api/Rpc/Decorators/LoggableRpcClient.php deleted file mode 100644 index 3971b72..0000000 --- a/src/ScayTrase/Api/Rpc/Decorators/LoggableRpcClient.php +++ /dev/null @@ -1,54 +0,0 @@ -decoratedClient = $decoratedClient; - $this->logger = $logger; - - if (null === $this->logger) { - $this->logger = new NullLogger(); - } - } - - /** {@inheritdoc} */ - public function invoke($calls) - { - if (!is_array($calls)) { - $calls = [$calls]; - } - - foreach ($calls as $call) { - $this->logger->debug( - sprintf('%s Invoking RPC method "%s"', spl_object_hash($call), $call->getMethod()), - json_decode(json_encode($call->getParameters()), true) - ); - } - - return new LoggableResponseCollection($this->decoratedClient->invoke($calls), $this->logger); - } -} diff --git a/src/ScayTrase/Api/Rpc/Decorators/RequestKeyExtractor.php b/src/ScayTrase/Api/Rpc/Decorators/RequestKeyExtractor.php deleted file mode 100644 index c5d42dc..0000000 --- a/src/ScayTrase/Api/Rpc/Decorators/RequestKeyExtractor.php +++ /dev/null @@ -1,38 +0,0 @@ -keyPrefix = $keyPrefix; } - - - public function getKey(RpcRequestInterface $request) - { - $data = [ - 'method' => (string)$request->getMethod(), - 'params' => json_decode(json_encode($request->getParameters()), true), - ]; - - $stringData = json_encode($data); - - return $this->keyPrefix . sha1($stringData); - } -} diff --git a/src/ScayTrase/Api/Rpc/Exception/BadInvocationException.php b/src/ScayTrase/Api/Rpc/Exception/BadInvocationException.php deleted file mode 100644 index 1060bdd..0000000 --- a/src/ScayTrase/Api/Rpc/Exception/BadInvocationException.php +++ /dev/null @@ -1,13 +0,0 @@ -prophesize(RpcRequestInterface::class); - $request->getMethod()->willReturn($method); - $request->getParameters()->willReturn((object)$params); - - - return $request->reveal(); - } - - /** - * @param array $data - * - * @return RpcResponseInterface - */ - protected function getResponseMock(array $data = []) - { - $response = $this->prophesize(RpcResponseInterface::class); - $response->isSuccessful()->willReturn(true); - $response->getBody()->willReturn((object)$data); - - return $response->reveal(); - } - - /** - * @param RpcRequestInterface[] $requests - * @param RpcResponseInterface[] $responses - * - * @return \PHPUnit_Framework_MockObject_MockObject|RpcClientInterface - */ - protected function getClientMock(array $requests = [], array $responses = []) - { - self::assertEquals(count($requests), count($responses)); - - $client = $this->prophesize(RpcClientInterface::class); - $that = $this; - $client->invoke(Argument::type('array'))->will(function ($args) use ($that, $requests, $responses) { - $collection = $that->prophesize(ResponseCollectionInterface::class); - foreach ($requests as $key => $request) { - if (in_array($request, $args[0], true)) { - $collection->getResponse(Argument::exact($request))->willReturn($responses[$key]); - } - } - return $collection->reveal(); - }); - - return $client->reveal(); - } -} diff --git a/src/ScayTrase/Api/Rpc/Tests/DecoratorTest.php b/src/ScayTrase/Api/Rpc/Tests/DecoratorTest.php deleted file mode 100644 index 42cdb56..0000000 --- a/src/ScayTrase/Api/Rpc/Tests/DecoratorTest.php +++ /dev/null @@ -1,96 +0,0 @@ -expects(self::atLeastOnce())->method('log'); - - $rq1 = $this->getRequestMock('/test1', ['param1' => 'test']); - $rs1 = $this->getResponseMock(['param1' => 'test']); - /** @var RpcRequestInterface[] $requests */ - $requests = [$rq1]; - - $client = new LoggableRpcClient($this->getClientMock([$rq1], [$rs1]), $logger); - - self::assertEquals($rs1, $client->invoke($requests)->getResponse($rq1)); - } - - public function testCacheableClient() - { - if (!interface_exists(CacheItemPoolInterface::class)) { - self::markTestSkipped('install psr/cache in order to run these tests'); - } - - $rq1 = $this->getRequestMock('/test1', ['param1' => 'test']); - $rq2 = $this->getRequestMock('/test1', ['param1' => 'test']); - $rs1 = $this->getResponseMock(['payload' => bin2hex(random_bytes(20))]); - - $cache = $this->getCache(); - - $client = new CacheableRpcClient($this->getClientMock([$rq1], [$rs1]), $cache, 5); - $response = $client->invoke([$rq1])->getResponse($rq1); - self::assertEquals($rs1, $response); - - $client = new CacheableRpcClient($this->getClientMock(), $cache, 5); - $response = $client->invoke([$rq2])->getResponse($rq2); - self::assertEquals($rs1, $response); - } - - /** - * @return CacheItemPoolInterface - */ - private function getCache() - { - static $items = []; - $cache = $this->prophesize(CacheItemPoolInterface::class); - $that = $this; - $cache->getItem(Argument::type('string'))->will(function ($args) use (&$items, $that) { - $key = $args[0]; - if (!array_key_exists($key, $items)) { - $item = $that->prophesize(CacheItemInterface::class); - - $item->getKey()->willReturn($key); - $item->isHit()->willReturn(false); - $item->set(Argument::any())->will(function ($args) use ($item) { - $item->get()->willReturn($args[0]); - }); - $item->expiresAfter(Argument::type('int'))->willReturn($item); - $item->expiresAfter(Argument::exact(null))->willReturn($item); - $item->expiresAfter(Argument::type(\DateInterval::class))->willReturn($item); - $item->expiresAt(Argument::type(\DateTimeInterface::class))->willReturn($item); - $items[$key] = $item; - } - - return $items[$key]->reveal(); - }); - $cache->save(Argument::type(CacheItemInterface::class))->will(function ($args) use (&$items) { - $item = $args[0]; - $items[$item->getKey()]->isHit()->willReturn(true); - }); - - return $cache->reveal(); - } -} diff --git a/src/ScayTrase/Api/Rpc/Tests/LazyClientTest.php b/src/ScayTrase/Api/Rpc/Tests/LazyClientTest.php deleted file mode 100644 index b2e03a4..0000000 --- a/src/ScayTrase/Api/Rpc/Tests/LazyClientTest.php +++ /dev/null @@ -1,57 +0,0 @@ -getRequestMock('/test1', ['param1' => 'test']); - $rq2 = $this->getRequestMock('/test2', ['param2' => 'test']); - $rq3 = $this->getRequestMock('/test3', ['param3' => 'test']); - - $rs1 = $this->getResponseMock(['param1' => 'test']); - $rs2 = $this->getResponseMock(['param2' => 'test']); - $rs3 = $this->getResponseMock(['param3' => 'test']); - - /** @var RpcRequestInterface[] $requests */ - $requests = [$rq1, $rq2, $rq3]; - /** @var RpcResponseInterface[] $responses */ - $responses = [$rs1, $rs2, $rs3]; - - $client = $this->getClientMock($requests, $responses); - - - $lazyClient = new LazyRpcClient($client); - - $c1 = $lazyClient->invoke($rq1); - $c2 = $lazyClient->invoke($rq2); - $c3 = $lazyClient->invoke($rq3); - - self::assertEquals($c1, $c2); - self::assertEquals($c1, $c3); - - - foreach ($requests as $id => $request) { - - $response = $c1->getResponse($request); - - self::assertNotNull($response); - self::assertTrue($c1->isFrozen()); - self::assertEquals($response, $responses[$id]); - self::assertTrue($response->isSuccessful()); - self::assertInstanceOf(\stdClass::class, $response->getBody()); - self::assertEquals($request->getParameters(), $response->getBody()); - } - } -}