Refactor search engine provider

This commit is contained in:
Mathieu Darse
2014-09-10 16:45:22 +02:00
parent f8f40d8081
commit de8e9e3bfc
7 changed files with 51 additions and 118 deletions

View File

@@ -42,6 +42,7 @@ use Alchemy\Phrasea\Command\Task\TaskRun;
use Alchemy\Phrasea\Command\Task\TaskStart;
use Alchemy\Phrasea\Command\Task\TaskStop;
use Alchemy\Phrasea\Command\Task\TaskState;
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
require_once __DIR__ . '/../lib/autoload.php';
@@ -119,7 +120,7 @@ $cli->command(new XSendFileConfigurationDumper());
$cli->command(new XSendFileMappingGenerator());
$cli->command(new CrossDomainGenerator());
if ($cli['phraseanet.SE']->getName() === 'ElasticSearch') {
if ($cli['search_engine.type'] === SearchEngineInterface::TYPE_ELASTICSEARCH) {
$cli->command(new IndexCreateCommand());
$cli->command(new IndexDropCommand());
$cli->command(new IndexPopulateCommand());

View File

@@ -27,7 +27,7 @@ main:
type: ArrayCache
options: []
search-engine:
type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine
type: phrasea
options: []
task-manager:
status: started

View File

@@ -14,7 +14,10 @@ namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\SearchEngine\SearchEngineLogger;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticSearchEngine;
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer;
use Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine;
use Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngineSubscriber;
use Elasticsearch\Client;
use Silex\Application;
use Silex\ServiceProviderInterface;
@@ -23,28 +26,38 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['phraseanet.SE'] = $app->share(function ($app) {
$engineOptions = $app['conf']->get(['main', 'search-engine', 'options']);
$app['phraseanet.SE'] = function ($app) {
return $app['search_engine'];
};
return $app['phraseanet.SE.engine-class']::create($app, $engineOptions);
$app['search_engine'] = $app->share(function ($app) {
$type = $app['search_engine.type'];
switch ($type) {
case SearchEngineInterface::TYPE_ELASTICSEARCH:
return new ElasticSearchEngine(
$app,
$app['elasticsearch.client'],
$app['serializer.es-record'],
$app['elasticsearch.options']['index']
);
case SearchEngineInterface::TYPE_PHRASEA:
return new PhraseaEngine($app);
default:
throw new InvalidArgumentException(sprintf('Invalid search engine type "%s".', $type));
}
});
$app['search_engine.type'] = function ($app) {
return $app['conf']->get(['main', 'search-engine', 'type']);
};
$app['phraseanet.SE.logger'] = $app->share(function (Application $app) {
return new SearchEngineLogger($app);
});
$app['phraseanet.SE.engine-class'] = $app->share(function ($app) {
$engineClass = $app['conf']->get(['main', 'search-engine', 'type']);
if (!class_exists($engineClass) || $engineClass instanceof SearchEngineInterface) {
throw new InvalidArgumentException(sprintf('%s is not valid SearchEngineInterface', $engineClass));
}
return $engineClass;
});
// Only used for Phrasea search engine
$app['phraseanet.SE.subscriber'] = $app->share(function ($app) {
return $app['phraseanet.SE.engine-class']::createSubscriber($app);
return new PhraseaEngineSubscriber($app);
});
$app['elasticsearch.indexer'] = $app->share(function ($app) {
@@ -56,6 +69,15 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
);
});
$app['elasticsearch.client'] = $app->share(function($app) {
$options = $app['elasticsearch.options'];
$host = sprintf('%s:%s', $options['host'], $options['port']);
// TODO (mdarse) Add logging support
return new Client(array('hosts' => array($host)));
});
$app['elasticsearch.options'] = $app->share(function($app) {
$options = $app['conf']->get(['main', 'search-engine', 'options']);
$defaults = [
@@ -72,14 +94,16 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
public function boot(Application $app)
{
if ($app['phraseanet.configuration']->isSetup()) {
$app['dispatcher'] = $app->share(
$app->extend('dispatcher', function ($dispatcher, Application $app) {
$dispatcher->addSubscriber($app['phraseanet.SE.subscriber']);
if (!$app['phraseanet.configuration']->isSetup()) {
return;
}
return $dispatcher;
})
);
if ($app['search_engine.type'] === SearchEngineInterface::TYPE_PHRASEA) {
$app['dispatcher'] = $app->share($app->extend('dispatcher', function ($dispatcher, Application $app) {
$dispatcher->addSubscriber($app['phraseanet.SE.subscriber']);
return $dispatcher;
}));
}
}
}

View File

@@ -335,44 +335,6 @@ class ElasticSearchEngine implements SearchEngineInterface
{
}
/**
* {@inheritdoc}
*/
public static function createSubscriber(Application $app)
{
return new ElasticSearchEngineSubscriber();
}
/**
* {@inheritdoc}
*
* @todo Allow multiple hosts!
* @return \Alchemy\Phrasea\SearchEngine\Elastic\ElasticSearchEngine
*/
public static function create(Application $app, array $options = [])
{
$options = array_replace([
'host' => '127.0.0.1',
'port' => '9200',
'index' => 'phraseanet',
], $options);
$clientParams = ['hosts' => [sprintf('%s:%s', $options['host'], $options['port'])]];
// Create file logger for debug
if ($app['debug']) {
$logger = new $app['monolog.logger.class']('search logger');
$logger->pushHandler(new RotatingFileHandler($app['log.path'].DIRECTORY_SEPARATOR.'elasticsearch.log', 2), Logger::INFO);
$clientParams['logObject'] = $logger;
$clientParams['logging'] = true;
}
$client = new Client($clientParams);
return new static($app, $client, $app['serializer.es-record'], $options['index']);
}
private function createQueryParams($query, SearchEngineOptions $options, \record_adapter $record = null)
{
$params = [

View File

@@ -1,22 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\SearchEngine\Elastic;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ElasticSearchEngineSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [];
}
}

View File

@@ -503,26 +503,6 @@ class PhraseaEngine implements SearchEngineInterface
return $html ;
}
/**
* {@inheritdoc}
*
* @return PhraseaEngineSubscriber
*/
public static function createSubscriber(Application $app)
{
return new PhraseaEngineSubscriber($app);
}
/**
* {@inheritdoc}
*
* @return PhraseaEngine
*/
public static function create(Application $app, array $options = [])
{
return new static($app);
}
/**
* Executes the Phrasea query
*

View File

@@ -19,6 +19,9 @@ use Alchemy\Phrasea\Model\Entities\FeedEntry;
interface SearchEngineInterface
{
const TYPE_ELASTICSEARCH = 'elasticsearch';
const TYPE_PHRASEA = 'phrasea';
const GEM_TYPE_RECORD = 'record';
const GEM_TYPE_STORY = 'story';
const GEM_TYPE_ENTRY = 'entry';
@@ -205,19 +208,4 @@ interface SearchEngineInterface
* @return SearchEngineInterface
*/
public function clearCache();
/**
* Returns a subscriber
*
* @return EventSubscriberInterface
*/
public static function createSubscriber(Application $app);
/**
* Creates the adapter.
*
* @param Application $app
* @param array $options
*/
public static function create(Application $app, array $options = []);
}