From 5b927db796dcd8375c90bbfff7417dd1572b9687 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Thu, 2 Nov 2017 13:33:44 +0100 Subject: [PATCH 1/2] EZP-28176: Fixed so that it possible to define new purge_type in other bundles --- .../DependencyInjection/EzPublishCoreExtension.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php index 853bd588c1f..ecd202c7b34 100644 --- a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php +++ b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php @@ -363,6 +363,7 @@ private function handleCache(array $config, ContainerBuilder $container, FileLoa { $loader->load('cache.yml'); + $purgeService = null; if (isset($config['http_cache']['purge_type'])) { switch ($config['http_cache']['purge_type']) { case 'local': @@ -371,15 +372,12 @@ private function handleCache(array $config, ContainerBuilder $container, FileLoa case 'http': $purgeService = 'ezpublish.http_cache.purge_client.fos'; break; - default: - if (!$container->has($config['http_cache']['purge_type'])) { - throw new \InvalidArgumentException("Invalid ezpublish.http_cache.purge_type. Can be 'single', 'multiple' or a valid service identifier implementing PurgeClientInterface."); - } - - $purgeService = $config['http_cache']['purge_type']; } - $container->setAlias('ezpublish.http_cache.purge_client', $purgeService); + $container->setParameter('ezpublish.http_cache.purge_type', $config['http_cache']['purge_type']); + if ($purgeService !== null) { + $container->setAlias('ezpublish.http_cache.purge_client', $purgeService); + } } } From 5b45826043a3c8bef1362afeede2038eb3237260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20R?= Date: Wed, 15 Nov 2017 18:02:23 +0100 Subject: [PATCH 2/2] EZP-28176: Move purge type logic to compiler pass and addapt tests --- .../Compiler/HttpCachePass.php | 35 ++++++++++++++++ .../DependencyInjection/Configuration.php | 16 +++++--- .../EzPublishCoreExtension.php | 12 ------ .../Compiler/HttpCachePassTest.php | 41 ++++++++++++++++++- .../EzPublishCoreExtensionTest.php | 31 +++++--------- 5 files changed, 96 insertions(+), 39 deletions(-) diff --git a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/HttpCachePass.php b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/HttpCachePass.php index 4e851345b7d..da089183b71 100644 --- a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/HttpCachePass.php +++ b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/HttpCachePass.php @@ -8,6 +8,7 @@ */ namespace eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler; +use eZ\Publish\Core\MVC\Symfony\Cache\PurgeClientInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use InvalidArgumentException; @@ -21,6 +22,12 @@ class HttpCachePass implements CompilerPassInterface { public function process(ContainerBuilder $container) + { + $this->processCacheManager($container); + $this->processPurgeClient($container); + } + + private function processCacheManager(ContainerBuilder $container) { if (!$container->hasDefinition('ezpublish.http_cache.cache_manager')) { return; @@ -45,4 +52,32 @@ public function process(ContainerBuilder $container) $cacheManagerDef = $container->findDefinition('ezpublish.http_cache.cache_manager'); $cacheManagerDef->replaceArgument(0, new Reference('fos_http_cache.proxy_client.varnish')); } + + private function processPurgeClient(ContainerBuilder $container) + { + // Check that alias exists (if not it has been removed by another bundle) + if (!$container->has('ezpublish.http_cache.purge_client')) { + return; + } + + $purgeType = $container->getParameter('ezpublish.http_cache.purge_type'); + switch ($purgeType) { + case 'local': + $purgeService = 'ezpublish.http_cache.purge_client.local'; + break; + case 'http': + $purgeService = 'ezpublish.http_cache.purge_client.fos'; + break; + default: + if (!$container->has($purgeType)) { + throw new InvalidArgumentException("Invalid ezpublish.http_cache.purge_type. Can be 'local', 'http' or a valid service identifier implementing PurgeClientInterface."); + } elseif (!$container->get($purgeType) instanceof PurgeClientInterface) { + throw new InvalidArgumentException('Invalid ezpublish.http_cache.purge_type, it needs to implement PurgeClientInterface.'); + } + + $purgeService = $purgeType; + } + + $container->setAlias('ezpublish.http_cache.purge_client', $purgeService); + } } diff --git a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration.php b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration.php index 4a6a9bc3780..58e2a568f2c 100644 --- a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration.php +++ b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration.php @@ -327,14 +327,20 @@ private function addHttpCacheSection(ArrayNodeDefinition $rootNode) Http cache purge type. Cache purge for content/locations is triggered when needed (e.g. on publish) and will result in one or several Http PURGE requests. -Can be "local" or "http" or a valid service ID: +Can be "local", "http" or a valid symfony service id: - If "local" is used, an Http PURGE request will be emulated when needed (e.g. when using Symfony internal reverse proxy). -- If "http" is used, only one Http BAN request will be sent, with X-Location-Id header containing locationIds to ban. - X-Location-Id consists in a Regexp containing locationIds to ban. - Examples: +- If "http" is used, a full HTTP PURGE/BAN is done to a real reverse proxy (Varnish, ..) depending on your config +- If custom symfony service id is used, then check documentation on that service for how it behaves and how you need to configure your system for it. + +If ezplatform-http-cache package is enabled (default as of 1.12 and up), then go to documentation on this package for further +info on how it supports multiple response tagging, purges and allow plugins for custom purge types. + +If that is not enabled, then the (deprecated as of 1.8) default BAN based system will be used instead. +Where ressponses can be tagged by a single X-Location-Id header, and for purges a single Http BAN request will be sent, +where X-Location-Id header consists of a Regexp containing locationIds to ban. + BAN Examples: - (123|456|789) => Purge locations #123, #456, #789. - .* => Purge all locations. -- If a serviceId is provided, it must be defined in the ServiceContainer and must implement eZ\Publish\Core\MVC\Symfony\Cache\PurgeClientInterface. EOT; $rootNode diff --git a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php index ecd202c7b34..7c383516c57 100644 --- a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php +++ b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php @@ -365,19 +365,7 @@ private function handleCache(array $config, ContainerBuilder $container, FileLoa $purgeService = null; if (isset($config['http_cache']['purge_type'])) { - switch ($config['http_cache']['purge_type']) { - case 'local': - $purgeService = 'ezpublish.http_cache.purge_client.local'; - break; - case 'http': - $purgeService = 'ezpublish.http_cache.purge_client.fos'; - break; - } - $container->setParameter('ezpublish.http_cache.purge_type', $config['http_cache']['purge_type']); - if ($purgeService !== null) { - $container->setAlias('ezpublish.http_cache.purge_client', $purgeService); - } } } diff --git a/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/HttpCachePassTest.php b/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/HttpCachePassTest.php index ec3c44e302f..2bf47ec7d53 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/HttpCachePassTest.php +++ b/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/HttpCachePassTest.php @@ -30,7 +30,7 @@ public function testProcessVarnishProxyNotRegistered() $this->compile(); } - public function testProcess() + public function testProcessCacheManager() { $this->setDefinition('ezpublish.http_cache.cache_manager', new Definition('foo', array(true))); $varnishProxyClient = new Definition(); @@ -49,4 +49,43 @@ public function testProcess() new Reference('fos_http_cache.proxy_client.varnish') ); } + + public function processPurgeClientProvider() + { + return [ + ['local', 'ezpublish.http_cache.purge_client.local'], + ['http', 'ezpublish.http_cache.purge_client.fos'], + ]; + } + + /** + * @dataProvider processPurgeClientProvider + * + * @param string $paramValue + * @param string $expectedServiceAlias + * @param \Symfony\Component\DependencyInjection\Definition|null $customService + */ + public function testProcessPurgeClient($paramValue, $expectedServiceId, Definition $customService = null) + { + $this->setDefinition('ezpublish.http_cache.purge_client', new Definition()); + $this->setParameter('ezpublish.http_cache.purge_type', $paramValue); + if ($customService) { + $this->setDefinition($paramValue, $customService); + } + + $this->compile(); + + $this->assertContainerBuilderHasAlias('ezpublish.http_cache.purge_client', $expectedServiceId); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testProcessPurgeClientOnInvalidService() + { + $this->setDefinition('ezpublish.http_cache.purge_client', new Definition()); + $this->setParameter('ezpublish.http_cache.purge_type', 'foo'); + + $this->compile(); + } } diff --git a/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/EzPublishCoreExtensionTest.php b/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/EzPublishCoreExtensionTest.php index 94627f18a51..c243df0e3f9 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/EzPublishCoreExtensionTest.php +++ b/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/EzPublishCoreExtensionTest.php @@ -231,59 +231,46 @@ public function testRoutingConfiguration() * @dataProvider cacheConfigurationProvider * * @param array $customCacheConfig - * @param string $expectedPurgeService - * @param int $expectedTimeout + * @param string $expectedPurgeType */ - public function testCacheConfiguration(array $customCacheConfig, $expectedPurgeService) + public function testCacheConfiguration(array $customCacheConfig, $expectedPurgeType) { $this->load($customCacheConfig); - $this->assertContainerBuilderHasAlias('ezpublish.http_cache.purge_client', $expectedPurgeService); + $this->assertContainerBuilderHasParameter('ezpublish.http_cache.purge_type', $expectedPurgeType); } public function cacheConfigurationProvider() { return array( - array(array(), 'ezpublish.http_cache.purge_client.local', 1), + array(array(), 'local'), array( array( 'http_cache' => array('purge_type' => 'local'), ), - 'ezpublish.http_cache.purge_client.local', + 'local', ), array( array( 'http_cache' => array('purge_type' => 'multiple_http'), ), - 'ezpublish.http_cache.purge_client.fos', + 'http', ), array( array( 'http_cache' => array('purge_type' => 'single_http'), ), - 'ezpublish.http_cache.purge_client.fos', + 'http', ), array( array( 'http_cache' => array('purge_type' => 'http'), ), - 'ezpublish.http_cache.purge_client.fos', + 'http', ), ); } - /** - * @expectedException \InvalidArgumentException - */ - public function testCacheConfigurationWrongPurgeType() - { - $this->load( - array( - 'http_cache' => array('purge_type' => 'foobar', 'timeout' => 12), - ) - ); - } - public function testCacheConfigurationCustomPurgeService() { $serviceId = 'foobar'; @@ -293,6 +280,8 @@ public function testCacheConfigurationCustomPurgeService() 'http_cache' => array('purge_type' => 'foobar', 'timeout' => 12), ) ); + + $this->assertContainerBuilderHasParameter('ezpublish.http_cache.purge_type', 'foobar'); } public function testLocaleConfiguration()