diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php index 42af35528..efd6eedaf 100644 --- a/Command/PopulateCommand.php +++ b/Command/PopulateCommand.php @@ -111,6 +111,8 @@ protected function execute(InputInterface $input, OutputInterface $output) throw new \InvalidArgumentException('Cannot specify type option without an index.'); } + $this->resetter->resetAllTemplates(); + if (null !== $index) { if (null !== $type) { $this->populateIndexType($output, $index, $type, $reset, $options); diff --git a/Command/ResetCommand.php b/Command/ResetCommand.php index 85c548378..c8caa1b82 100755 --- a/Command/ResetCommand.php +++ b/Command/ResetCommand.php @@ -62,6 +62,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (null !== $type) { $output->writeln(sprintf('Resetting %s/%s', $index, $type)); + $this->resetter->resetAllTemplates(); $this->resetter->resetIndexType($index, $type); } else { $indexes = null === $index @@ -69,6 +70,8 @@ protected function execute(InputInterface $input, OutputInterface $output) : array($index) ; + $this->resetter->resetAllTemplates(); + foreach ($indexes as $index) { $output->writeln(sprintf('Resetting %s', $index)); $this->resetter->resetIndex($index, false, $force); diff --git a/Configuration/ConfigManager.php b/Configuration/ConfigManager.php index 5e7a4fd96..d6af9023d 100644 --- a/Configuration/ConfigManager.php +++ b/Configuration/ConfigManager.php @@ -22,13 +22,22 @@ class ConfigManager implements ManagerInterface private $indexes = array(); /** - * @param Source\SourceInterface[] $sources + * @var IndexTemplateConfig[] */ - public function __construct(array $sources) + private $indexTemplates = array(); + + /** + * @param Source\SourceInterface[] $indexSources + * @param Source\SourceInterface[] $indexTemplateSources + */ + public function __construct(array $indexSources, array $indexTemplateSources) { - foreach ($sources as $source) { + foreach ($indexSources as $source) { $this->indexes = array_merge($source->getConfiguration(), $this->indexes); } + foreach ($indexTemplateSources as $source) { + $this->indexTemplates = array_merge($source->getConfiguration(), $this->indexTemplates); + } } /** @@ -68,6 +77,25 @@ public function getTypeConfiguration($indexName, $typeName) return $type; } + /** + * @param string $indexTemplateName + * + * @return IndexTemplateConfig + */ + public function getIndexTemplateConfiguration($indexTemplateName) + { + if (!$this->hasIndexTemplateConfiguration($indexTemplateName)) { + throw new \InvalidArgumentException(sprintf('Index template with name "%s" is not configured.', $indexTemplateName)); + } + + return $this->indexTemplates[$indexTemplateName]; + } + + public function getIndexTemplatesNames() + { + return array_keys($this->indexTemplates); + } + /** * @param string $indexName * @@ -77,4 +105,9 @@ public function hasIndexConfiguration($indexName) { return isset($this->indexes[$indexName]); } + + public function hasIndexTemplateConfiguration($indexTemplateName) + { + return isset($this->indexTemplates[$indexTemplateName]); + } } diff --git a/Configuration/IndexConfig.php b/Configuration/IndexConfig.php index 749b10d76..c92915a45 100644 --- a/Configuration/IndexConfig.php +++ b/Configuration/IndexConfig.php @@ -11,37 +11,8 @@ namespace FOS\ElasticaBundle\Configuration; -class IndexConfig +class IndexConfig extends IndexConfigAbstract { - /** - * The name of the index for ElasticSearch. - * - * @var string - */ - private $elasticSearchName; - - /** - * The internal name of the index. May not be the same as the name used in ElasticSearch, - * especially if aliases are enabled. - * - * @var string - */ - private $name; - - /** - * An array of settings sent to ElasticSearch when creating the index. - * - * @var array - */ - private $settings; - - /** - * All types that belong to this index. - * - * @var TypeConfig[] - */ - private $types; - /** * Indicates if the index should use an alias, allowing an index repopulation to occur * without overwriting the current index. @@ -66,54 +37,6 @@ public function __construct($name, array $types, array $config) $this->useAlias = isset($config['useAlias']) ? $config['useAlias'] : false; } - /** - * @return string - */ - public function getElasticSearchName() - { - return $this->elasticSearchName; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return array - */ - public function getSettings() - { - return $this->settings; - } - - /** - * @param string $typeName - * - * @return TypeConfig - * - * @throws \InvalidArgumentException - */ - public function getType($typeName) - { - if (!array_key_exists($typeName, $this->types)) { - throw new \InvalidArgumentException(sprintf('Type "%s" does not exist on index "%s"', $typeName, $this->name)); - } - - return $this->types[$typeName]; - } - - /** - * @return \FOS\ElasticaBundle\Configuration\TypeConfig[] - */ - public function getTypes() - { - return $this->types; - } - /** * @return boolean */ diff --git a/Configuration/IndexConfigAbstract.php b/Configuration/IndexConfigAbstract.php new file mode 100644 index 000000000..d9398d6cb --- /dev/null +++ b/Configuration/IndexConfigAbstract.php @@ -0,0 +1,96 @@ + + */ +class IndexConfigAbstract +{ + /** + * The name of the index for ElasticSearch. + * + * @var string + */ + protected $elasticSearchName; + + /** + * The internal name of the index. May not be the same as the name used in ElasticSearch, + * especially if aliases are enabled. + * + * @var string + */ + protected $name; + + /** + * An array of settings sent to ElasticSearch when creating the index. + * + * @var array + */ + protected $settings; + + /** + * All types that belong to this index. + * + * @var TypeConfig[] + */ + protected $types; + + /** + * @return string + */ + public function getElasticSearchName() + { + return $this->elasticSearchName; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return array + */ + public function getSettings() + { + return $this->settings; + } + + /** + * @param string $typeName + * + * @return TypeConfig + * + * @throws \InvalidArgumentException + */ + public function getType($typeName) + { + if (!array_key_exists($typeName, $this->types)) { + throw new \InvalidArgumentException(sprintf('Type "%s" does not exist on index "%s"', $typeName, $this->name)); + } + + return $this->types[$typeName]; + } + + /** + * @return \FOS\ElasticaBundle\Configuration\TypeConfig[] + */ + public function getTypes() + { + return $this->types; + } +} \ No newline at end of file diff --git a/Configuration/IndexTemplateConfig.php b/Configuration/IndexTemplateConfig.php new file mode 100644 index 000000000..b476b5430 --- /dev/null +++ b/Configuration/IndexTemplateConfig.php @@ -0,0 +1,47 @@ + + */ +class IndexTemplateConfig extends IndexConfigAbstract +{ + /** + * Index name pattern + * + * @var string + */ + private $template; + + /** + * Constructor expects an array as generated by the Container Configuration builder. + * + * @param string $name + * @param TypeConfig[] $types + * @param array $config + */ + public function __construct($name, array $types, array $config) + { + $this->elasticSearchName = isset($config['elasticSearchName']) ? $config['elasticSearchName'] : $name; + $this->name = $name; + $this->settings = isset($config['settings']) ? $config['settings'] : array(); + if (!isset($config['template'])) { + throw new \InvalidArgumentException('Index template value must be set'); + } + $this->template = $config['template']; + $this->types = $types; + } + + /** + * Gets index name pattern + * + * @return string + */ + public function getTemplate() + { + return $this->template; + } +} diff --git a/Configuration/Source/TemplateContainerSource.php b/Configuration/Source/TemplateContainerSource.php new file mode 100644 index 000000000..b679813c6 --- /dev/null +++ b/Configuration/Source/TemplateContainerSource.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Configuration\Source; + +use FOS\ElasticaBundle\Configuration\IndexTemplateConfig; +use FOS\ElasticaBundle\Configuration\TypeConfig; + +/** + * Returns index and type configuration from the container. + */ +class TemplateContainerSource implements SourceInterface +{ + /** + * The internal container representation of information. + * + * @var array + */ + private $configArray; + + public function __construct(array $configArray) + { + $this->configArray = $configArray; + } + + /** + * Should return all configuration available from the data source. + * + * @return IndexTemplateConfig[] + */ + public function getConfiguration() + { + $indexes = array(); + foreach ($this->configArray as $config) { + $types = $this->getTypes($config); + $index = new IndexTemplateConfig($config['name'], $types, array( + 'elasticSearchName' => $config['elasticsearch_name'], + 'settings' => $config['settings'], + 'template' => $config['template'], + )); + + $indexes[$config['name']] = $index; + } + + return $indexes; + } + + /** + * Builds TypeConfig objects for each type. + * + * @param array $config + * + * @return array + */ + protected function getTypes($config) + { + $types = array(); + + if (isset($config['types'])) { + foreach ($config['types'] as $typeConfig) { + $types[$typeConfig['name']] = new TypeConfig( + $typeConfig['name'], + $typeConfig['mapping'], + $typeConfig['config'] + ); + } + } + + return $types; + } +} diff --git a/DependencyInjection/Compiler/ConfigSourcePass.php b/DependencyInjection/Compiler/ConfigSourcePass.php index 92a248902..699f0bb3a 100644 --- a/DependencyInjection/Compiler/ConfigSourcePass.php +++ b/DependencyInjection/Compiler/ConfigSourcePass.php @@ -17,6 +17,8 @@ class ConfigSourcePass implements CompilerPassInterface { + const SOURCE_TYPE_INDEX_TEMPLATE = 'index_template'; + /** * {@inheritDoc} */ @@ -26,11 +28,18 @@ public function process(ContainerBuilder $container) return; } - $sources = array(); + $indexSources = array(); + $indexTemplateSources = array(); foreach (array_keys($container->findTaggedServiceIds('fos_elastica.config_source')) as $id) { - $sources[] = new Reference($id); + $tag = $container->findDefinition($id)->getTag('fos_elastica.config_source'); + if (isset($tag[0]['source']) && $tag[0]['source'] === self::SOURCE_TYPE_INDEX_TEMPLATE) { + $indexTemplateSources[] = new Reference($id); + } else { + $indexSources[] = new Reference($id); + } } - $container->getDefinition('fos_elastica.config_manager')->replaceArgument(0, $sources); + $container->getDefinition('fos_elastica.config_manager')->replaceArgument(0, $indexSources); + $container->getDefinition('fos_elastica.config_manager')->replaceArgument(1, $indexTemplateSources); } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 474fa3114..6fb3f2bef 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -39,6 +39,7 @@ public function getConfigTreeBuilder() $this->addClientsSection($rootNode); $this->addIndexesSection($rootNode); + $this->addIndexTemplatesSection($rootNode); $rootNode ->children() @@ -611,4 +612,34 @@ protected function getSerializerNode() return $node; } + + /** + * Adds the configuration for the "index_templates" key. + * + * @param ArrayNodeDefinition $rootNode + * + * @return void + */ + private function addIndexTemplatesSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->fixXmlConfig('index_template') + ->children() + ->arrayNode('index_templates') + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ->scalarNode('template_name') + ->info('Defaults to the name of the index template, but can be modified if the index name is different in ElasticSearch') + ->end() + ->scalarNode('template')->isRequired()->end() + ->scalarNode('client')->end() + ->variableNode('settings')->defaultValue(array())->end() + ->end() + ->append($this->getTypesNode()) + ->end() + ->end() + ->end() + ; + } } diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php index 2c0d4fe8c..ea7b4c6ed 100644 --- a/DependencyInjection/FOSElasticaExtension.php +++ b/DependencyInjection/FOSElasticaExtension.php @@ -26,6 +26,13 @@ class FOSElasticaExtension extends Extension */ private $indexConfigs = array(); + /** + * An array of index templates as configured by the extension. + * + * @var array + */ + private $indexTemplateConfigs = array(); + /** * If we've encountered a type mapped to a specific persistence driver, it will be loaded * here. @@ -72,7 +79,10 @@ public function load(array $configs, ContainerBuilder $container) $this->loadIndexes($config['indexes'], $container); $container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index'])); + $this->loadIndexTemplates($config['index_templates'], $container); + $container->getDefinition('fos_elastica.config_source.container')->replaceArgument(0, $this->indexConfigs); + $container->getDefinition('fos_elastica.config_source.template_container')->replaceArgument(0, $this->indexTemplateConfigs); $this->loadIndexManager($container); @@ -189,6 +199,50 @@ private function loadIndexes(array $indexes, ContainerBuilder $container) $indexable->replaceArgument(0, $indexableCallbacks); } + + /** + * Loads the configured indexes. + * + * @param array $indexTemplates An array of indexes configurations + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @throws \InvalidArgumentException + * + * @return array + */ + private function loadIndexTemplates(array $indexTemplates, ContainerBuilder $container) + { + $indexableCallbacks = array(); + foreach ($indexTemplates as $name => $indexTemplate) { + $indexId = sprintf('fos_elastica.index_template.%s', $name); + $indexTemplateName = isset($indexTemplate['template_name']) ? $indexTemplate['template_name'] : $name; + + $indexDef = new DefinitionDecorator('fos_elastica.index_template_prototype'); + $indexDef->replaceArgument(0, $indexTemplateName); + $indexDef->addTag('fos_elastica.index_template', array( + 'name' => $name, + )); + + if (isset($indexTemplate['client'])) { + $client = $this->getClient($indexTemplate['client']); + $indexDef->setFactoryService($client); + } + + $container->setDefinition($indexId, $indexDef); + $reference = new Reference($indexId); + + $this->indexTemplateConfigs[$name] = array( + 'elasticsearch_name' => $indexTemplateName, + 'reference' => $reference, + 'name' => $name, + 'settings' => $indexTemplate['settings'], + 'template' => $indexTemplate['template'], + ); + + $this->loadTypes((array) $indexTemplate['types'], $container, $this->indexTemplateConfigs[$name], $indexableCallbacks); + } + } + /** * Loads the configured index finders. * @@ -223,7 +277,7 @@ private function loadIndexFinder(ContainerBuilder $container, $name, Reference $ * @param array $indexConfig * @param array $indexableCallbacks */ - private function loadTypes(array $types, ContainerBuilder $container, array $indexConfig, array &$indexableCallbacks) + private function loadTypes(array $types, ContainerBuilder $container, array &$indexConfig, array &$indexableCallbacks) { foreach ($types as $name => $type) { $indexName = $indexConfig['name']; @@ -280,7 +334,7 @@ private function loadTypes(array $types, ContainerBuilder $container, array $ind null; } - $this->indexConfigs[$indexName]['types'][$name] = $typeConfig; + $indexConfig['types'][$name] = $typeConfig; if (isset($type['persistence'])) { $this->loadTypePersistenceIntegration($type['persistence'], $container, new Reference($typeId), $indexName, $name); @@ -634,8 +688,13 @@ private function loadIndexManager(ContainerBuilder $container) return $index['reference']; }, $this->indexConfigs); + $indexTemplateRefs = array_map(function ($index) { + return $index['reference']; + }, $this->indexTemplateConfigs); + $managerDef = $container->getDefinition('fos_elastica.index_manager'); $managerDef->replaceArgument(0, $indexRefs); + $managerDef->replaceArgument(2, $indexTemplateRefs); } /** diff --git a/Elastica/Client.php b/Elastica/Client.php index f881d4659..31b397bb1 100644 --- a/Elastica/Client.php +++ b/Elastica/Client.php @@ -3,6 +3,7 @@ namespace FOS\ElasticaBundle\Elastica; use Elastica\Client as BaseClient; +use Elastica\IndexTemplate; use Elastica\Request; use FOS\ElasticaBundle\Logger\ElasticaLogger; use Symfony\Component\Stopwatch\Stopwatch; @@ -22,6 +23,13 @@ class Client extends BaseClient */ private $indexCache = array(); + /** + * Stores created index template to avoid recreation. + * + * @var array + */ + private $indexTemplateCache = array(); + /** * Symfony's debugging Stopwatch. * @@ -74,6 +82,15 @@ public function getIndex($name) return $this->indexCache[$name] = new Index($this, $name); } + public function getIndexTemplate($name) + { + if (isset($this->indexTemplateCache[$name])) { + return $this->indexTemplateCache[$name]; + } + + return $this->indexTemplateCache[$name] = new IndexTemplate($this, $name); + } + /** * Sets a stopwatch instance for debugging purposes. * diff --git a/Index/IndexManager.php b/Index/IndexManager.php index 98ce870d8..523321c4e 100644 --- a/Index/IndexManager.php +++ b/Index/IndexManager.php @@ -2,6 +2,7 @@ namespace FOS\ElasticaBundle\Index; +use Elastica\IndexTemplate; use FOS\ElasticaBundle\Elastica\Index; class IndexManager @@ -16,14 +17,21 @@ class IndexManager */ private $indexes; + /** + * @var IndexTemplate[] + */ + private $indexTemplates; + /** * @param array $indexes * @param Index $defaultIndex + * @param array $templates */ - public function __construct(array $indexes, Index $defaultIndex) + public function __construct(array $indexes, Index $defaultIndex, array $templates = array()) { $this->defaultIndex = $defaultIndex; $this->indexes = $indexes; + $this->indexTemplates = $templates; } /** @@ -58,6 +66,24 @@ public function getIndex($name = null) return $this->indexes[$name]; } + /** + * Gets an index template by its name. + * + * @param string $name Index template to return + * + * @return IndexTemplate + * + * @throws \InvalidArgumentException if no index template exists for the given name + */ + public function getIndexTemplate($name = null) + { + if (!isset($this->indexTemplates[$name])) { + throw new \InvalidArgumentException(sprintf('The index template "%s" does not exist', $name)); + } + + return $this->indexTemplates[$name]; + } + /** * Gets the default index. * diff --git a/Index/MappingBuilder.php b/Index/MappingBuilder.php index af9e43b35..92caf0505 100644 --- a/Index/MappingBuilder.php +++ b/Index/MappingBuilder.php @@ -11,7 +11,8 @@ namespace FOS\ElasticaBundle\Index; -use FOS\ElasticaBundle\Configuration\IndexConfig; +use FOS\ElasticaBundle\Configuration\IndexConfigAbstract; +use FOS\ElasticaBundle\Configuration\IndexTemplateConfig; use FOS\ElasticaBundle\Configuration\TypeConfig; class MappingBuilder @@ -26,11 +27,11 @@ class MappingBuilder /** * Builds mappings for an entire index. * - * @param IndexConfig $indexConfig + * @param IndexConfigAbstract $indexConfig * * @return array */ - public function buildIndexMapping(IndexConfig $indexConfig) + public function buildIndexMapping(IndexConfigAbstract $indexConfig) { $typeMappings = array(); foreach ($indexConfig->getTypes() as $typeConfig) { @@ -51,6 +52,20 @@ public function buildIndexMapping(IndexConfig $indexConfig) return $mapping; } + /** + * Builds mappings for an entire index template. + * + * @param IndexTemplateConfig $indexTemplateConfig + * + * @return array + */ + public function buildIndexTemplateMapping(IndexTemplateConfig $indexTemplateConfig) + { + $mapping = $this->buildIndexMapping($indexTemplateConfig); + $mapping['template'] = $indexTemplateConfig->getTemplate(); + return $mapping; + } + /** * Builds mappings for a single type. * diff --git a/Index/Resetter.php b/Index/Resetter.php index 4d7e807a2..3e3eb51ba 100644 --- a/Index/Resetter.php +++ b/Index/Resetter.php @@ -151,6 +151,22 @@ public function resetIndexType($indexName, $typeName) $this->dispatcher->dispatch(TypeResetEvent::POST_TYPE_RESET, $event); } + public function resetAllTemplates() + { + foreach ($this->configManager->getIndexTemplatesNames() as $name) { + $this->resetTemplate($name); + } + } + + public function resetTemplate($indexTemplateName) + { + $indexConfig = $this->configManager->getIndexTemplateConfiguration($indexTemplateName); + $indexTemplate = $this->indexManager->getIndexTemplate($indexTemplateName); + + $mapping = $this->mappingBuilder->buildIndexTemplateMapping($indexConfig); + $indexTemplate->create($mapping); + } + /** * A command run when a population has finished. * diff --git a/Resources/config/config.xml b/Resources/config/config.xml index 324d6e626..3dc0b5c1e 100644 --- a/Resources/config/config.xml +++ b/Resources/config/config.xml @@ -26,6 +26,7 @@ + diff --git a/Resources/config/index.xml b/Resources/config/index.xml index c3c98cc22..63068131c 100644 --- a/Resources/config/index.xml +++ b/Resources/config/index.xml @@ -8,6 +8,7 @@ FOS\ElasticaBundle\Index\AliasProcessor FOS\ElasticaBundle\Finder\TransformedFinder FOS\ElasticaBundle\Elastica\Index + Elastica\IndexTemplate FOS\ElasticaBundle\Provider\Indexable FOS\ElasticaBundle\Index\IndexManager FOS\ElasticaBundle\Index\Resetter @@ -27,6 +28,11 @@ + + + + + @@ -34,6 +40,7 @@ + diff --git a/Resources/config/source.xml b/Resources/config/source.xml index c0f085cc3..ed327a5e8 100644 --- a/Resources/config/source.xml +++ b/Resources/config/source.xml @@ -7,7 +7,12 @@ - + + + + + + diff --git a/Tests/Command/ResetCommandTest.php b/Tests/Command/ResetCommandTest.php index d63b380f3..ebb3d4462 100644 --- a/Tests/Command/ResetCommandTest.php +++ b/Tests/Command/ResetCommandTest.php @@ -3,14 +3,27 @@ namespace FOS\ElasticaBundle\Tests\Command; use FOS\ElasticaBundle\Command\ResetCommand; +use FOS\ElasticaBundle\Index\IndexManager; +use FOS\ElasticaBundle\Index\Resetter; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\DependencyInjection\Container; class ResetCommandTest extends \PHPUnit_Framework_TestCase { + /** + * @var \PHPUnit_Framework_MockObject_MockObject|ResetCommand + */ private $command; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|Resetter + */ private $resetter; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|IndexManager + */ private $indexManager; public function setup() @@ -19,7 +32,7 @@ public function setup() $this->resetter = $this->getMockBuilder('\FOS\ElasticaBundle\Resetter') ->disableOriginalConstructor() - ->setMethods(array('resetIndex', 'resetIndexType')) + ->setMethods(array('resetIndex', 'resetIndexType', 'resetAllTemplates')) ->getMock(); $container->set('fos_elastica.resetter', $this->resetter); @@ -42,10 +55,13 @@ public function testResetAllIndexes() ->will($this->returnValue(array('index1' => true, 'index2' => true))); $this->resetter->expects($this->at(0)) + ->method('resetAllTemplates'); + + $this->resetter->expects($this->at(1)) ->method('resetIndex') ->with($this->equalTo('index1')); - $this->resetter->expects($this->at(1)) + $this->resetter->expects($this->at(2)) ->method('resetIndex') ->with($this->equalTo('index2')); @@ -61,6 +77,9 @@ public function testResetIndex() ->method('getAllIndexes'); $this->resetter->expects($this->at(0)) + ->method('resetAllTemplates'); + + $this->resetter->expects($this->at(1)) ->method('resetIndex') ->with($this->equalTo('index1')); @@ -79,6 +98,9 @@ public function testResetIndexType() ->method('resetIndex'); $this->resetter->expects($this->at(0)) + ->method('resetAllTemplates'); + + $this->resetter->expects($this->at(1)) ->method('resetIndexType') ->with($this->equalTo('index1'), $this->equalTo('type1')); diff --git a/Tests/Configuration/ConfigManagerTest.php b/Tests/Configuration/ConfigManagerTest.php new file mode 100644 index 000000000..d343ef8b3 --- /dev/null +++ b/Tests/Configuration/ConfigManagerTest.php @@ -0,0 +1,38 @@ + 'index_template_elastic_name1', + 'settings' => array(1), + 'template' => 't*', + ); + $indexTemplate = new IndexTemplateConfig($name, array(), $config); + $this->assertEquals($name, $indexTemplate->getName()); + $this->assertEquals( + $config, + array( + 'elasticSearchName' => $indexTemplate->getElasticSearchName(), + 'settings' => $indexTemplate->getSettings(), + 'template' => $indexTemplate->getTemplate(), + ) + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testIncorrectInstantiate() + { + $name = 'index_template1'; + new IndexTemplateConfig($name, array(), array()); + } + +} diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index 2fb6cdf73..554027e0c 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -34,6 +34,7 @@ public function testUnconfiguredConfiguration() $this->assertSame(array( 'clients' => array(), 'indexes' => array(), + 'index_templates' => array(), 'default_manager' => 'orm', ), $configuration); } @@ -266,6 +267,56 @@ public function testNestedProperties() )); } + public function testIndexTemplates() + { + $this->getConfigs(array( + 'clients' => array( + 'default' => array('url' => 'http://localhost:9200'), + ), + 'index_templates' => array( + 'test' => array( + 'template' => 't*', + 'settings' => array( + 'number_of_shards' => 1 + ), + 'types' => array( + 'user' => array( + 'properties' => array( + 'field1' => array(), + ), + 'persistence' => array(), + ), + 'user_profile' => array( + '_parent' => array( + 'type' => 'user', + 'property' => 'owner', + ), + 'properties' => array( + 'field1' => array(), + 'field2' => array( + 'type' => 'nested', + 'properties' => array( + 'nested_field1' => array( + 'type' => 'integer', + ), + 'nested_field2' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'type' => 'integer', + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + )); + } + public function testCompressionConfig() { $configuration = $this->getConfigs(array( diff --git a/Tests/Index/ResetterTest.php b/Tests/Index/ResetterTest.php index abff0935f..581834c5d 100644 --- a/Tests/Index/ResetterTest.php +++ b/Tests/Index/ResetterTest.php @@ -2,18 +2,20 @@ namespace FOS\ElasticaBundle\Tests\Index; -use Elastica\Exception\ResponseException; -use Elastica\Request; -use Elastica\Response; use Elastica\Type; -use Elastica\Type\Mapping; +use FOS\ElasticaBundle\Configuration\ConfigManager; use FOS\ElasticaBundle\Configuration\IndexConfig; +use FOS\ElasticaBundle\Configuration\IndexTemplateConfig; use FOS\ElasticaBundle\Configuration\TypeConfig; use FOS\ElasticaBundle\Elastica\Index; +use Elastica\IndexTemplate; use FOS\ElasticaBundle\Event\IndexResetEvent; use FOS\ElasticaBundle\Event\TypeResetEvent; use FOS\ElasticaBundle\Index\AliasProcessor; +use FOS\ElasticaBundle\Index\IndexManager; +use FOS\ElasticaBundle\Index\MappingBuilder; use FOS\ElasticaBundle\Index\Resetter; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; class ResetterTest extends \PHPUnit_Framework_TestCase { @@ -22,11 +24,34 @@ class ResetterTest extends \PHPUnit_Framework_TestCase */ private $resetter; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|AliasProcessor + */ private $aliasProcessor; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|ConfigManager + */ private $configManager; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|EventDispatcherInterface + */ private $dispatcher; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Elastica\Client + */ private $elasticaClient; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|IndexManager + */ private $indexManager; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|MappingBuilder + */ private $mappingBuilder; public function testResetAllIndexes() @@ -54,6 +79,29 @@ public function testResetAllIndexes() $this->resetter->resetAllIndexes(); } + public function testResetAllIndexTemplates() + { + $indexTemplate = 'index_template1'; + + $config = array( + 'template' => 't*' + ); + $indexTemplateConfig = new IndexTemplateConfig($indexTemplate, array(), $config); + $this->mockIndexTemplate($indexTemplate, $indexTemplateConfig); + + $this->configManager->expects($this->once()) + ->method('getIndexTemplatesNames') + ->will($this->returnValue(array($indexTemplate))); + + $this->elasticaClient->expects($this->exactly(1)) + ->method('request') + ->withConsecutive( + array('/_template/index_template1', 'PUT', array(), array()) + ); + + $this->resetter->resetAllTemplates(); + } + public function testResetIndex() { $indexConfig = new IndexConfig('index1', array(), array()); @@ -254,6 +302,25 @@ private function mockIndex($indexName, IndexConfig $config, $mapping = array()) return $index; } + private function mockIndexTemplate($indexTemplateName, IndexTemplateConfig $config, $mapping = array()) + { + $this->configManager->expects($this->atLeast(1)) + ->method('getIndexTemplateConfiguration') + ->with($indexTemplateName) + ->will($this->returnValue($config)); + $index = new IndexTemplate($this->elasticaClient, $indexTemplateName); + $this->indexManager->expects($this->any()) + ->method('getIndexTemplate') + ->with($indexTemplateName) + ->willReturn($index); + $this->mappingBuilder->expects($this->any()) + ->method('buildIndexTemplateMapping') + ->with($config) + ->willReturn($mapping); + + return $index; + } + private function mockType($typeName, $indexName, TypeConfig $typeConfig, IndexConfig $indexConfig, $mapping = array()) { $this->configManager->expects($this->atLeast(1))