Skip to content

Commit

Permalink
Fix for using cache pools with multiple areas (#2232)
Browse files Browse the repository at this point in the history
* enable configuring cache for each area

* add test

* lint

* remove deprecation test

* use global cache as fallback

* delete redundant code

* add more tests

* lint

* append area to cache item_id

* cache config test cases

* change $cacheItemId type to string only

* fix reference not passed

---------

Co-authored-by: Adrian Brajkovic <adrian.brajkovic@sofascore.com>
Co-authored-by: DjordyKoert <djordy.koert@yoursurprise.com>
  • Loading branch information
3 people committed Mar 6, 2024
1 parent f98641d commit 32537bb
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/ApiDocGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final class ApiDocGenerator
/** @var CacheItemPoolInterface|null */
private $cacheItemPool;

/** @var string|null */
/** @var string */
private $cacheItemId;

/** @var string[] */
Expand All @@ -65,7 +65,7 @@ public function __construct($describers, $modelDescribers, CacheItemPoolInterfac
$this->describers = $describers;
$this->modelDescribers = $modelDescribers;
$this->cacheItemPool = $cacheItemPool;
$this->cacheItemId = $cacheItemId;
$this->cacheItemId = $cacheItemId ?? 'openapi_doc';
$this->generator = $generator ?? new Generator($this->logger);
}

Expand All @@ -91,7 +91,7 @@ public function generate(): OpenApi
}

if ($this->cacheItemPool) {
$item = $this->cacheItemPool->getItem($this->cacheItemId ?? 'openapi_doc');
$item = $this->cacheItemPool->getItem($this->cacheItemId);
if ($item->isHit()) {
return $this->openApi = $item->get();
}
Expand Down
13 changes: 13 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public function getConfigTreeBuilder(): TreeBuilder
'documentation' => [],
'name_patterns' => [],
'disable_default_routes' => false,
'cache' => [],
],
]
)
Expand Down Expand Up @@ -122,6 +123,18 @@ public function getConfigTreeBuilder(): TreeBuilder
->example(['info' => ['title' => 'My App']])
->prototype('variable')->end()
->end()
->arrayNode('cache')
->children()
->scalarNode('pool')
->info('define cache pool to use')
->defaultNull()
->end()
->scalarNode('item_id')
->info('define cache item id')
->defaultNull()
->end()
->end()
->end()
->end()
->end()
->end()
Expand Down
11 changes: 7 additions & 4 deletions src/DependencyInjection/NelmioApiDocExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,13 @@ public function load(array $configs, ContainerBuilder $container): void
$container->register('nelmio_api_doc.open_api.generator', Generator::class)
->setPublic(false);

$cachePool = isset($config['cache']['pool']) ? new Reference($config['cache']['pool']) : null;
$cacheItemId = $config['cache']['item_id'] ?? null;
$cachePool = $config['cache']['pool'] ?? null;
$cacheItemId = $config['cache']['item_id'] ?? 'openapi_doc';

foreach ($config['areas'] as $area => $areaConfig) {
$areaCachePool = $areaConfig['cache']['pool'] ?? $cachePool;
$areaCacheItemId = $areaConfig['cache']['item_id'] ?? sprintf('%s.%s', $cacheItemId, $area);

$nameAliases = $this->findNameAliases($config['models']['names'], $area);
$container->register(sprintf('nelmio_api_doc.generator.%s', $area), ApiDocGenerator::class)
->setPublic(true)
Expand All @@ -99,8 +102,8 @@ public function load(array $configs, ContainerBuilder $container): void
->setArguments([
new TaggedIteratorArgument(sprintf('nelmio_api_doc.describer.%s', $area)),
new TaggedIteratorArgument('nelmio_api_doc.model_describer'),
$cachePool,
$cacheItemId,
null !== $areaCachePool ? new Reference($areaCachePool) : null,
$areaCacheItemId,
new Reference('nelmio_api_doc.open_api.generator'),
]);

Expand Down
146 changes: 127 additions & 19 deletions tests/DependencyInjection/NelmioApiDocExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Nelmio\ApiDocBundle\DependencyInjection\NelmioApiDocExtension;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class NelmioApiDocExtensionTest extends TestCase
{
Expand Down Expand Up @@ -151,41 +152,148 @@ public function testMergesRootKeysFromMultipleConfigurations()
], $container->getDefinition('nelmio_api_doc.describers.config')->getArgument(0));
}

public function testApiDocGeneratorWithCachePool()
/**
* @dataProvider provideCacheConfig
*/
public function testApiDocGeneratorWithCachePool(array $config, array $expectedValues)
{
$container = new ContainerBuilder();
$container->setParameter('kernel.bundles', []);

$extension = new NelmioApiDocExtension();
$extension->load([
[
'documentation' => [
'info' => [
'title' => 'API documentation',
'description' => 'This is the api documentation, use it wisely',
],
],
$extension->load([$config], $container);

$reference = $container->getDefinition('nelmio_api_doc.generator.default')->getArgument(2);
if (null === $expectedValues['defaultCachePool']) {
$this->assertNull($reference);
} else {
$this->assertInstanceOf(Reference::class, $reference);
$this->assertSame($expectedValues['defaultCachePool'], (string) $reference);
}

$reference = $container->getDefinition('nelmio_api_doc.generator.area1')->getArgument(2);
if (null === $expectedValues['area1CachePool']) {
$this->assertNull($reference);
} else {
$this->assertInstanceOf(Reference::class, $reference);
$this->assertSame($expectedValues['area1CachePool'], (string) $reference);
}

$cacheItemId = $container->getDefinition('nelmio_api_doc.generator.default')->getArgument(3);
$this->assertSame($expectedValues['defaultCacheItemId'], $cacheItemId);

$cacheItemId = $container->getDefinition('nelmio_api_doc.generator.area1')->getArgument(3);
$this->assertSame($expectedValues['area1CacheItemId'], $cacheItemId);
}

public static function provideCacheConfig(): iterable
{
yield 'default cache.item_id & area appending' => [
'config' => [
'cache' => [
'pool' => 'test.cache',
'item_id' => 'nelmio.docs',
],
'areas' => [
'default' => [],
'area1' => [],
],
],
], $container);
'expectedValues' => [
'defaultCachePool' => 'test.cache',
'defaultCacheItemId' => 'openapi_doc.default',
'area1CachePool' => 'test.cache',
'area1CacheItemId' => 'openapi_doc.area1',
],
];

$reference = $container->getDefinition('nelmio_api_doc.generator.default')->getArgument(2);
$this->assertSame('test.cache', (string) $reference);
yield 'configuring cache.item_id & area appending' => [
'config' => [
'cache' => [
'pool' => 'test.cache',
'item_id' => 'test.docs',
],
'areas' => [
'default' => [],
'area1' => [],
],
],
'expectedValues' => [
'defaultCachePool' => 'test.cache',
'defaultCacheItemId' => 'test.docs.default',
'area1CachePool' => 'test.cache',
'area1CacheItemId' => 'test.docs.area1',
],
];

$reference = $container->getDefinition('nelmio_api_doc.generator.area1')->getArgument(2);
$this->assertSame('test.cache', (string) $reference);
yield 'overwriting item_id for an area' => [
'config' => [
'cache' => [
'pool' => 'test.cache',
'item_id' => 'nelmio.docs',
],
'areas' => [
'default' => [
'cache' => [
'pool' => 'test.cache.default',
'item_id' => 'nelmio.docs.default',
],
],
'area1' => [],
],
],
'expectedValues' => [
'defaultCachePool' => 'test.cache.default',
'defaultCacheItemId' => 'nelmio.docs.default',
'area1CachePool' => 'test.cache',
'area1CacheItemId' => 'nelmio.docs.area1',
],
];

$cacheItemId = $container->getDefinition('nelmio_api_doc.generator.default')->getArgument(3);
$this->assertSame('nelmio.docs', $cacheItemId);
yield 'setting cache for a single area' => [
'config' => [
'areas' => [
'default' => [
],
'area1' => [
'cache' => [
'pool' => 'app.cache',
'item_id' => 'docs',
],
],
],
],
'expectedValues' => [
'defaultCachePool' => null,
'defaultCacheItemId' => 'openapi_doc.default',
'area1CachePool' => 'app.cache',
'area1CacheItemId' => 'docs',
],
];

$cacheItemId = $container->getDefinition('nelmio_api_doc.generator.area1')->getArgument(3);
$this->assertSame('nelmio.docs', $cacheItemId);
yield 'setting a global cache pool & shared item_id' => [
'config' => [
'cache' => [
'pool' => 'app.cache',
],
'areas' => [
'default' => [
'cache' => [
'item_id' => 'docs',
],
],
'area1' => [
'cache' => [
'item_id' => 'docs',
],
],
],
],
'expectedValues' => [
'defaultCachePool' => 'app.cache',
'defaultCacheItemId' => 'docs',
'area1CachePool' => 'app.cache',
'area1CacheItemId' => 'docs',
],
];
}
}

0 comments on commit 32537bb

Please sign in to comment.