Skip to content

Commit

Permalink
Merge f0ce67f into 2e9cfbb
Browse files Browse the repository at this point in the history
  • Loading branch information
RikudouSage committed Oct 5, 2021
2 parents 2e9cfbb + f0ce67f commit dd2a46d
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 115 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

Don't use Symfony? Use the [standalone library](https://github.com/RikudouSage/DynamoDbCachePsr6).

> Since version 2 this library uses the lightweight [async-aws/dynamo-db](https://github.com/async-aws/dynamo-db)
> instead of the full AWS SDK.
## Installation

`composer require rikudou/psr6-dynamo-db-bundle`
Expand All @@ -28,7 +31,6 @@ implementation with the adapter from this bundle (default: **false**)
- `client_config` - If no `client_service` is configured, it will be created from the values of this config. It contains
two subkeys:
- `region` - the AWS region (default: **us-east-1**)
- `version` - the service version (default: **latest**)
- no other options are available, if you need to configure more, please create and assign custom `client_service`
- `encoder` - contains the settings for encoders:
- `service` - the service which will be used as the encoder
Expand Down Expand Up @@ -65,8 +67,6 @@ rikudou_dynamo_db_cache:
# The AWS region
region: us-east-1

# The service version
version: latest
encoder:

# The service to be used as the encoder/decoder
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
"license": "MIT",
"require": {
"symfony/framework-bundle": "^5.0",
"rikudou/psr6-dynamo-db": "^1.4",
"rikudou/psr6-dynamo-db": "^2.0",
"php": "^7.2 | ^8.0",
"symfony/cache": "^5.0"
"symfony/cache": "^5.0",
"ext-json": "*"
},
"autoload": {
"psr-4": {
Expand Down
10 changes: 5 additions & 5 deletions src/Cache/DynamoDbCacheAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Rikudou\DynamoDbCache\DynamoCacheItem;
use Rikudou\DynamoDbCache\DynamoDbCache;
use Rikudou\DynamoDbCache\Exception\InvalidArgumentException;
use Rikudou\DynamoDbCacheBundle\Converter\CacheItemConverter;
use Rikudou\DynamoDbCacheBundle\Converter\SymfonyCacheItemConverter;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Contracts\Cache\CacheInterface;
Expand All @@ -22,15 +22,15 @@ final class DynamoDbCacheAdapter implements AdapterInterface, CacheInterface
private $cache;

/**
* @var CacheItemConverter
* @var SymfonyCacheItemConverter
*/
private $converter;

/**
* @param DynamoDbCache $cache
* @param CacheItemConverter $converter
* @param DynamoDbCache $cache
* @param SymfonyCacheItemConverter $converter
*/
public function __construct(DynamoDbCache $cache, CacheItemConverter $converter)
public function __construct(DynamoDbCache $cache, SymfonyCacheItemConverter $converter)
{
$this->cache = $cache;
$this->converter = $converter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Rikudou\DynamoDbCache\Encoder\CacheItemEncoderInterface;
use Symfony\Component\Cache\CacheItem;

final class CacheItemConverter implements CacheItemConverterInterface
final class SymfonyCacheItemConverter implements CacheItemConverterInterface
{
/**
* @var ClockInterface
Expand Down
6 changes: 1 addition & 5 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/
final class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('rikudou_dynamo_db_cache');

Expand Down Expand Up @@ -38,10 +38,6 @@ public function getConfigTreeBuilder()
->info('The AWS region')
->defaultValue('us-east-1')
->end()
->scalarNode('version')
->info('The service version')
->defaultValue('latest')
->end()
->end()
->end()
->arrayNode('encoder')
Expand Down
3 changes: 1 addition & 2 deletions src/DependencyInjection/RikudouDynamoDbCacheExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rikudou\DynamoDbCacheBundle\DependencyInjection;

use Aws\DynamoDb\DynamoDbClient;
use AsyncAws\DynamoDb\DynamoDbClient;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
Expand Down Expand Up @@ -48,7 +48,6 @@ private function createDynamoClient(ContainerBuilder $container, array $configs)
$service = new Definition(DynamoDbClient::class);
$service->addArgument([
'region' => $configs['client_config']['region'],
'version' => $configs['client_config']['version'],
]);
$client = 'rikudou.dynamo_cache.internal.dynamo_client';
$container->setDefinition($client, $service);
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ services:
- '@rikudou.dynamo_cache.converter.cache_item'

rikudou.dynamo_cache.converter.cache_item:
class: Rikudou\DynamoDbCacheBundle\Converter\CacheItemConverter
class: Rikudou\DynamoDbCacheBundle\Converter\SymfonyCacheItemConverter
arguments:
- '@rikudou.clock.default'
- '@rikudou.dynamo_cache.encoder.default'
Expand Down
177 changes: 92 additions & 85 deletions tests/AbstractDynamoDbTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@

namespace Rikudou\Tests\DynamoDbCacheBundle;

use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Exception\DynamoDbException;
use Aws\Result;
use AsyncAws\Core\Response;
use AsyncAws\DynamoDb\DynamoDbClient;
use AsyncAws\DynamoDb\Result\BatchGetItemOutput;
use AsyncAws\DynamoDb\Result\BatchWriteItemOutput;
use AsyncAws\DynamoDb\Result\DeleteItemOutput;
use AsyncAws\DynamoDb\Result\GetItemOutput;
use AsyncAws\DynamoDb\Result\PutItemOutput;
use AsyncAws\DynamoDb\ValueObject\AttributeValue;
use Psr\Log\NullLogger;
use ReflectionObject;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;

abstract class AbstractDynamoDbTest extends AbstractCacheItemTest
{
Expand Down Expand Up @@ -80,8 +88,10 @@ public function __construct(
$this->parent = $parent;
}

public function getItem(array $args = [], bool $raw = false)
public function getItem($input): GetItemOutput
{
assert(is_array($input));

$reflection = new ReflectionObject($this->parent);
$pool = $reflection->getProperty('itemPoolSaved');
$pool->setAccessible(true);
Expand All @@ -92,34 +102,35 @@ public function getItem(array $args = [], bool $raw = false)
array_column(array_column($savePool, $this->idField), 'S')
);

$id = $args['Key'][$this->idField]['S'];
$id = $input['Key'][$this->idField]['S'];
if (!in_array($id, $availableIds, true)) {
throw $this->getException();
$data = [[]];
} else {
$data = array_filter(array_merge($this->pool, $savePool), function ($item) use ($id) {
return $item[$this->idField]['S'] === $id;
});
}

$data = array_filter(array_merge($this->pool, $savePool), function ($item) use ($id) {
return $item[$this->idField]['S'] === $id;
});

if ($raw) {
return reset($data);
foreach ($data as $key => $value) {
$data[$key] = new MockResponse(json_encode(['Item' => $value]));
}

return new Result([
'Item' => reset($data),
]);
$client = new MockHttpClient(reset($data));
return new GetItemOutput(
new Response(
$client->request('GET', 'https://example.com'),
$client,
new NullLogger()
)
);
}

public function batchGetItem(array $args = [])
public function batchGetItem($input): BatchGetItemOutput
{
$table = array_key_first($args['RequestItems']);
$keys = array_column(
array_column(
$args['RequestItems'][$table]['Keys'],
$this->idField
),
'S'
);
$table = array_key_first($input['RequestItems']);
$keys = array_map(function (array $data) {
return $data[$this->idField]->getS();
}, $input['RequestItems'][$table]->getKeys());

$result = [
'Responses' => [
Expand All @@ -128,29 +139,35 @@ public function batchGetItem(array $args = [])
];
$i = 0;
foreach ($keys as $key) {
try {
$data = $this->getItem([
'Key' => [
$this->idField => [
'S' => $key,
],
$data = $this->getItem([
'Key' => [
$this->idField => [
'S' => $key,
],
], true);
$result['Responses'][$table][] = $data;
} catch (DynamoDbException $e) {
if ($i % 2 === 0) {
$result['UnprocessedKeys'][$table][]['Keys'][]['S'] = $key;
}
],
])->getItem();
if (!count($data)) {
continue;
}
$result['Responses'][$table][] = array_map(function (AttributeValue $value) {
return $value->getS() ? ['S' => $value->getS()] : ['N' => $value->getN()];
}, $data);
++$i;
}

return new Result($result);
$client = new MockHttpClient(new MockResponse(json_encode($result)));
return new BatchGetItemOutput(
new Response(
$client->request('GET', 'https://example.com'),
$client,
new NullLogger()
)
);
}

public function deleteItem(array $args = [])
public function deleteItem($input): DeleteItemOutput
{
$key = $args['Key'][$this->idField]['S'];
$key = $input['Key'][$this->idField]['S'];
$this->getItem([
'Key' => [
$this->idField => [
Expand All @@ -172,16 +189,25 @@ public function deleteItem(array $args = [])
}

$pool->setValue($this->parent, $currentPool);

$client = new MockHttpClient(new MockResponse('{}'));
return new DeleteItemOutput(
new Response(
$client->request('GET', 'https://example.com'),
$client,
new NullLogger()
)
);
}

public function batchWriteItem(array $args = [])
public function batchWriteItem($input): BatchWriteItemOutput
{
$table = array_key_first($args['RequestItems']);
$table = array_key_first($input['RequestItems']);
$keys = array_column(
array_column(
array_column(
array_column(
$args['RequestItems'][$table],
$input['RequestItems'][$table],
'DeleteRequest'
),
'Key'
Expand All @@ -190,65 +216,46 @@ public function batchWriteItem(array $args = [])
),
'S'
);
$count = count($keys);
$unprocessed = 0;

foreach ($keys as $key) {
try {
$this->deleteItem([
'Key' => [
$this->idField => [
'S' => $key,
],
$this->deleteItem([
'Key' => [
$this->idField => [
'S' => $key,
],
]);
} catch (DynamoDbException $e) {
++$unprocessed;
}
],
]);
}

if ($unprocessed === $count) {
throw $this->getException('ProvisionedThroughputExceededException');
}
$client = new MockHttpClient(new MockResponse('{}'));
return new BatchWriteItemOutput(
new Response(
$client->request('GET', 'https://example.com'),
$client,
new NullLogger()
)
);
}

public function putItem(array $args = [])
public function putItem($input): PutItemOutput
{
if ($this->awsErrorCode !== 'ResourceNotFoundException') {
throw $this->getException();
}
$reflection = new ReflectionObject($this->parent);
$pool = $reflection->getProperty('itemPoolSaved');
$pool->setAccessible(true);

$currentPool = $pool->getValue($this->parent);
$currentPool[] = $args['Item'];
$currentPool[] = $input['Item'];

$pool->setValue($this->parent, $currentPool);
}

private function getException(string $errorCode = null): DynamoDbException
{
if ($errorCode === null) {
$errorCode = $this->awsErrorCode;
}

return new class($errorCode) extends DynamoDbException {
/**
* @var string
*/
private $awsErrorCode;

public function __construct(string $errorCode)
{
$this->awsErrorCode = $errorCode;
}

public function getAwsErrorCode()
{
return $this->awsErrorCode;
}
};
$client = new MockHttpClient(new MockResponse('{}'));
return new PutItemOutput(
new Response(
$client->request('GET', 'https://example.com'),
$client,
new NullLogger()
)
);
}
};
}
Expand Down
Loading

0 comments on commit dd2a46d

Please sign in to comment.