diff --git a/composer.json b/composer.json index 93584fc..ea25485 100644 --- a/composer.json +++ b/composer.json @@ -5,12 +5,12 @@ "type": "library", "require": { "elasticsearch/elasticsearch": "^2.3", - "zendframework/zend-servicemanager": "^2.7", + "zendframework/zend-servicemanager": "^3.1.1", "zendframework/zend-modulemanager": "^2.7" }, "require-dev": { - "phpunit/phpunit": "^4.0", - "zendframework/zend-stdlib": "^2.7", + "phpunit/phpunit": "^4.8 || ^5.0", + "zendframework/zend-stdlib": "^3.0.1", "satooshi/php-coveralls": "~1.0" }, "license": "Apache-2.0", diff --git a/src/Service/AbstractFactory.php b/src/Service/AbstractFactory.php index d24cedc..ad26e68 100644 --- a/src/Service/AbstractFactory.php +++ b/src/Service/AbstractFactory.php @@ -3,10 +3,11 @@ namespace ElasticsearchModule\Service; use ArrayObject; -use Zend\Stdlib\ArrayObject as ZendArrayObject; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\Factory\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; +use Zend\Stdlib\ArrayObject as ZendArrayObject; /** * @author Pedro Alves @@ -33,10 +34,10 @@ public function __construct($name) abstract public function getServiceType(); /** - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container * @param array|ArrayObject|ZendArrayObject $config */ - abstract protected function create(ServiceLocatorInterface $serviceLocator, $config); + abstract protected function create(ContainerInterface $container, $config); /** * @param ServiceLocatorInterface $serviceLocator @@ -45,25 +46,35 @@ abstract protected function create(ServiceLocatorInterface $serviceLocator, $con */ public function createService(ServiceLocatorInterface $serviceLocator) { - $config = $serviceLocator->get('Config'); + return $this($serviceLocator, sprintf('elasticsearch.%s.%s', $this->getServiceType(), $this->name)); + } + + /** + * @param ContainerInterface $container + * @return mixed + * @throws ServiceNotCreatedException + */ + public function __invoke(ContainerInterface $container, $requestedName, array $options = null) + { + $config = $container->get('Config'); $serviceType = $this->getServiceType(); if (!isset($config['elasticsearch'][$serviceType][$this->name])) { - throw new ServiceNotCreatedException("elasticserach.$serviceType.{$this->name} could not be found"); + throw new ServiceNotCreatedException("$requestedName could not be found"); } - return $this->create($serviceLocator, $config['elasticsearch'][$serviceType][$this->name]); + return $this->create($container, $config['elasticsearch'][$serviceType][$this->name]); } /** - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container * @param string $serviceOrClass * @return mixed */ - protected function getServiceOrClassObject(ServiceLocatorInterface $serviceLocator, $serviceOrClass) + protected function getServiceOrClassObject(ContainerInterface $container, $serviceOrClass) { - if ($serviceLocator->has($serviceOrClass)) { - return $serviceLocator->get($serviceOrClass); + if ($container->has($serviceOrClass)) { + return $container->get($serviceOrClass); } else if (class_exists($serviceOrClass)) { return new $serviceOrClass(); } diff --git a/src/Service/AbstractLogFactory.php b/src/Service/AbstractLogFactory.php index 9dc94f9..7583dea 100644 --- a/src/Service/AbstractLogFactory.php +++ b/src/Service/AbstractLogFactory.php @@ -2,9 +2,9 @@ namespace ElasticsearchModule\Service; +use Interop\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\ServiceLocatorInterface; /** * @author Pedro Alves @@ -15,10 +15,10 @@ abstract class AbstractLogFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { $logName = $config[$this->getKey()]; - return $this->getLoggerOrThrowException($serviceLocator, $logName); + return $this->getLoggerOrThrowException($container, $logName); } /** @@ -30,14 +30,14 @@ public function getServiceType() } /** - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container * @param string $logName * @return LoggerInterface * @throws ServiceNotCreatedException */ - private function getLoggerOrThrowException(ServiceLocatorInterface $serviceLocator, $logName) + private function getLoggerOrThrowException(ContainerInterface $container, $logName) { - $logger = $this->getServiceOrClassObject($serviceLocator, $logName); + $logger = $this->getServiceOrClassObject($container, $logName); if (!$logger instanceof LoggerInterface) { throw new ServiceNotCreatedException("There is no '$logName' log"); diff --git a/src/Service/ClientFactory.php b/src/Service/ClientFactory.php index 703e99f..9b7d291 100644 --- a/src/Service/ClientFactory.php +++ b/src/Service/ClientFactory.php @@ -4,8 +4,8 @@ use Elasticsearch\Client; use Elasticsearch\Transport; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\ServiceLocatorInterface; /** * @author Pedro Alves @@ -17,14 +17,18 @@ class ClientFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { - $transport = $serviceLocator->get($config['transport']); + $transport = $container->get($config['transport']); if (!$transport instanceof Transport) { throw $this->getException('transport', Transport::class, ServiceNotCreatedException::class, $transport); } - $endpoint = $serviceLocator->get($config['endpoint']); + $endpoint = $container->get($config['endpoint']); + + if (!is_callable($endpoint)) { + throw $this->getException('endpoint', 'callable', ServiceNotCreatedException::class, $endpoint); + } return new Client($transport, $endpoint); } diff --git a/src/Service/ConnectionFactory.php b/src/Service/ConnectionFactory.php index 5d9435a..e64253c 100644 --- a/src/Service/ConnectionFactory.php +++ b/src/Service/ConnectionFactory.php @@ -4,8 +4,8 @@ use ArrayObject; use Elasticsearch\Connections\ConnectionFactoryInterface; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\ServiceLocatorInterface; use Zend\Stdlib\ArrayObject as ZendArrayObject; /** @@ -17,12 +17,12 @@ class ConnectionFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { $factoryName = $config['factory']; - $handler = $serviceLocator->get($config['handler']); - $loggers = $serviceLocator->get($config['loggers']); - $serializer = $this->getServiceOrClassObject($serviceLocator, $config['serializer']); + $handler = $container->get($config['handler']); + $loggers = $container->get($config['loggers']); + $serializer = $this->getServiceOrClassObject($container, $config['serializer']); $params = $this->getConnectionParametersFromConfiguration($config); $connectionFactory = new $factoryName($handler, $params, $serializer, $loggers['logger'], $loggers['tracer']); diff --git a/src/Service/ConnectionPoolFactory.php b/src/Service/ConnectionPoolFactory.php index 7e34bf2..bb3b4bc 100644 --- a/src/Service/ConnectionPoolFactory.php +++ b/src/Service/ConnectionPoolFactory.php @@ -6,9 +6,9 @@ use Elasticsearch\ConnectionPool\AbstractConnectionPool; use Elasticsearch\Connections\ConnectionFactoryInterface; use Elasticsearch\Connections\ConnectionInterface; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\InvalidArgumentException; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\ServiceLocatorInterface; use Zend\Stdlib\ArrayObject as ZendArrayObject; /** @@ -21,7 +21,7 @@ class ConnectionPoolFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { $className = $config['class']; @@ -32,8 +32,8 @@ protected function create(ServiceLocatorInterface $serviceLocator, $config) AbstractConnectionPool::class )); } - $selector = $this->getServiceOrClassObject($serviceLocator, $config['selector']); - $connectionFactory = $this->getServiceOrClassObject($serviceLocator, $config['connection_factory']); + $selector = $this->getServiceOrClassObject($container, $config['selector']); + $connectionFactory = $this->getServiceOrClassObject($container, $config['connection_factory']); if (!$connectionFactory instanceof ConnectionFactoryInterface) { throw $this->getException( diff --git a/src/Service/EndpointFactory.php b/src/Service/EndpointFactory.php index 09e7aba..14dbfb2 100644 --- a/src/Service/EndpointFactory.php +++ b/src/Service/EndpointFactory.php @@ -4,8 +4,8 @@ use Elasticsearch\Serializers\SerializerInterface; use ElasticsearchModule\Container\EndpointsInterface; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\ServiceLocatorInterface; /** * @author Pedro Alves @@ -17,9 +17,9 @@ class EndpointFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { - $serializer = $this->getServiceOrClassObject($serviceLocator, $config['serializer']); + $serializer = $this->getServiceOrClassObject($container, $config['serializer']); if (!$serializer instanceof SerializerInterface) { throw $this->getException( @@ -29,20 +29,20 @@ protected function create(ServiceLocatorInterface $serviceLocator, $config) $serializer ); } - $transport = $serviceLocator->get($config['transport']); - $container = $config['container']; - $container = new $container($transport, $serializer); + $transport = $container->get($config['transport']); + $endpointContainer = $config['container']; + $endpointContainer = new $endpointContainer($transport, $serializer); - if (!$container instanceof EndpointsInterface) { + if (!$endpointContainer instanceof EndpointsInterface) { throw $this->getException( 'container', EndpointsInterface::class, ServiceNotCreatedException::class, - $container + $endpointContainer ); } - return $container; + return $endpointContainer; } /** diff --git a/src/Service/HandlerFactory.php b/src/Service/HandlerFactory.php index 91fc3e4..a29f465 100644 --- a/src/Service/HandlerFactory.php +++ b/src/Service/HandlerFactory.php @@ -4,7 +4,8 @@ use ArrayObject; use Elasticsearch\ClientBuilder; -use Zend\ServiceManager\ServiceLocatorInterface; +use Interop\Container\ContainerInterface; +use Psr\Container\ContainerInterface as ContainerInterface2; use Zend\Stdlib\ArrayObject as ZendArrayObject; /** @@ -16,11 +17,11 @@ class HandlerFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { return ClientBuilder::defaultHandler( - $this->getHandlerParams($serviceLocator, $config, 'multi_handler', 'handle_factory'), - $this->getHandlerParams($serviceLocator, $config, 'single_handler', 'factory') + $this->getHandlerParams($container, $config, 'multi_handler', 'handle_factory'), + $this->getHandlerParams($container, $config, 'single_handler', 'factory') ); } @@ -33,33 +34,35 @@ public function getServiceType() } /** - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface2 $container * @param array|ArrayObject|ZendArrayObject $handlerConfig * @param string $paramKey * @param string $factoryKey * @return array */ - private function getHandlerParams(ServiceLocatorInterface $serviceLocator, $handlerConfig, $paramKey, $factoryKey) + private function getHandlerParams(ContainerInterface $container, $handlerConfig, $paramKey, $factoryKey) { if (!isset($handlerConfig['params'][$paramKey])) { return []; } return $this->createFactoryInConfig( - $serviceLocator, + $container, $handlerConfig['params'][$paramKey], $factoryKey ); } /** + * @param ContainerInterface $container + * @param array $handlerParams * @param string $factoryKey * @return array */ - private function createFactoryInConfig(ServiceLocatorInterface $serviceLocator, $handlerParams, $factoryKey) + private function createFactoryInConfig(ContainerInterface $container, $handlerParams, $factoryKey) { if ($this->hasHandlerFactoryOption($handlerParams, $factoryKey)) { $serviceOrClass = $handlerParams[$factoryKey]; - $handlerParams[$factoryKey] = $this->getServiceOrClassObject($serviceLocator, $serviceOrClass); + $handlerParams[$factoryKey] = $this->getServiceOrClassObject($container, $serviceOrClass); if (!is_callable($handlerParams[$factoryKey])) { unset($handlerParams[$factoryKey]); diff --git a/src/Service/InvalidTypeExceptionTrait.php b/src/Service/InvalidTypeExceptionTrait.php index 2b8cd05..a6545cb 100644 --- a/src/Service/InvalidTypeExceptionTrait.php +++ b/src/Service/InvalidTypeExceptionTrait.php @@ -11,17 +11,19 @@ trait InvalidTypeExceptionTrait { /** * @param string $name - * @param string $className + * @param string $classNameOrType * @param string $exceptionClass * @param mixed $var * @return Exception */ - private function getException($name, $className, $exceptionClass, $var) + private function getException($name, $classNameOrType, $exceptionClass, $var) { + $message = (class_exists($classNameOrType) || interface_exists($classNameOrType)) ? + "instance of %s" : "%s"; return new $exceptionClass(sprintf( - "The %s must be instance of %s, %s given", + "The %s must be $message, %s given", $name, - $className, + $classNameOrType, is_object($var) ? get_class($var) : gettype($var) )); } diff --git a/src/Service/LoggersFactory.php b/src/Service/LoggersFactory.php index e25f35e..6949f3d 100644 --- a/src/Service/LoggersFactory.php +++ b/src/Service/LoggersFactory.php @@ -3,7 +3,7 @@ namespace ElasticsearchModule\Service; use ArrayObject; -use Zend\ServiceManager\ServiceLocatorInterface; +use Interop\Container\ContainerInterface; /** * @author Pedro Alves @@ -14,7 +14,7 @@ class LoggersFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { $factories = $config['factories']; $loggers = []; @@ -22,7 +22,7 @@ protected function create(ServiceLocatorInterface $serviceLocator, $config) foreach ($factories as $name => $factory) { if (in_array(AbstractFactory::class, class_parents($factory))) { $factory = new $factory($this->getName()); - $loggers[$name] = $factory->create($serviceLocator, $config); + $loggers[$name] = $factory->create($container, $config); } } return new ArrayObject($loggers); diff --git a/src/Service/TransportFactory.php b/src/Service/TransportFactory.php index 30cce72..cbae015 100644 --- a/src/Service/TransportFactory.php +++ b/src/Service/TransportFactory.php @@ -4,8 +4,8 @@ use Elasticsearch\ConnectionPool\AbstractConnectionPool; use Elasticsearch\Transport; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\ServiceLocatorInterface; /** * @author Pedro Alves @@ -17,11 +17,11 @@ class TransportFactory extends AbstractFactory /** * {@inheritDoc} */ - protected function create(ServiceLocatorInterface $serviceLocator, $config) + protected function create(ContainerInterface $container, $config) { $retries = isset($config['retries']) ? $config['retries'] : 2; $sniffOnStart = isset($config['sniff_on_start']) ? $config['sniff_on_start'] : false; - $connectionPool = $serviceLocator->get($config['connection_pool']); + $connectionPool = $container->get($config['connection_pool']); if (!$connectionPool instanceof AbstractConnectionPool) { throw $this->getException( @@ -31,7 +31,7 @@ protected function create(ServiceLocatorInterface $serviceLocator, $config) $connectionPool ); } - $loggers = $serviceLocator->get($config['loggers']); + $loggers = $container->get($config['loggers']); return new Transport($retries, $sniffOnStart, $connectionPool, $loggers['logger']); } diff --git a/src/ServiceFactory/AbstractElasticsearchServiceFactory.php b/src/ServiceFactory/AbstractElasticsearchServiceFactory.php index 5a45a14..5f072e4 100644 --- a/src/ServiceFactory/AbstractElasticsearchServiceFactory.php +++ b/src/ServiceFactory/AbstractElasticsearchServiceFactory.php @@ -2,8 +2,9 @@ namespace ElasticsearchModule\ServiceFactory; -use Zend\ServiceManager\AbstractFactoryInterface; -use Zend\ServiceManager\FactoryInterface; +use Interop\Container\ContainerInterface; +use Zend\ServiceManager\Factory\AbstractFactoryInterface; +use Zend\ServiceManager\Factory\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; /** @@ -11,30 +12,30 @@ */ class AbstractElasticsearchServiceFactory implements AbstractFactoryInterface { - + /** * {@inheritDoc} */ - public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { - return $this->getFactory($serviceLocator, $requestedName) !== null; + $factory = $this->getFactory($container, $requestedName); + return $factory($container, $requestedName); } /** * {@inheritDoc} */ - public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + public function canCreate(ContainerInterface $container, $requestedName) { - $factory = $this->getFactory($serviceLocator, $requestedName); - return $factory->createService($serviceLocator); + return $this->getFactory($container, $requestedName) !== null; } /** - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container * @param string $requestedName * @return FactoryInterface */ - private function getFactory(ServiceLocatorInterface $serviceLocator, $requestedName) + private function getFactory(ContainerInterface $container, $requestedName) { $pattern = "/^elasticsearch\.(?P[a-z0-9_-]+)\.(?P[a-z0-9_-]+)$/"; $matches = []; @@ -44,7 +45,7 @@ private function getFactory(ServiceLocatorInterface $serviceLocator, $requestedN } $serviceType = $matches['serviceType']; $serviceName = $matches['serviceName']; - $config = $serviceLocator->get('Config'); + $config = $container->get('Config'); $elasticsearchModuleConfig = $config['elasticsearch']; if (!isset($elasticsearchModuleConfig[$serviceType]) || diff --git a/tests/Service/AbstractLogFactoryTest.php b/tests/Service/AbstractLogFactoryTest.php index 45f40f8..0055dfb 100644 --- a/tests/Service/AbstractLogFactoryTest.php +++ b/tests/Service/AbstractLogFactoryTest.php @@ -38,7 +38,7 @@ public function testCreateLoggerFromServiceLocator() /** * @expectedException \Zend\ServiceManager\Exception\ServiceNotCreatedException - * @expectedExceptionMessage elasticserach.loggers.exception could not be found + * @expectedExceptionMessage elasticsearch.loggers.exception could not be found */ public function testThrowsExceptionWhenNotFindTheLogConfig() { diff --git a/tests/Service/ClientFactoryTest.php b/tests/Service/ClientFactoryTest.php index 4ecbec9..dac65ef 100644 --- a/tests/Service/ClientFactoryTest.php +++ b/tests/Service/ClientFactoryTest.php @@ -41,4 +41,22 @@ public function testThrowExceptionWhenTransportVariableIsNotAnInstanceOfElastics $factory->createService($clientContainer); } + + /** + * @expectedException \Zend\ServiceManager\Exception\ServiceNotCreatedException + */ + public function testThrowExceptionWhenEndpointVariableIsNotACallable() + { + $config = $this->getConfig(); + $transportContainer = $this->getContainerWithTransportDependencies($config); + $clientContainer = $this->createServiceLocatorMock(['get']); + $this->mockMappedReturn($clientContainer, 'get', [ + 'Config' => $config, + 'elasticsearch.transport.default' => $this->getTransport($transportContainer, 'default'), + 'elasticsearch.endpoint.default' => new stdClass(), + ]); + $factory = new ClientFactory('default'); + + $factory->createService($clientContainer); + } } diff --git a/tests/Service/HandlerFactoryTest.php b/tests/Service/HandlerFactoryTest.php index ecb2ac2..30d3b00 100644 --- a/tests/Service/HandlerFactoryTest.php +++ b/tests/Service/HandlerFactoryTest.php @@ -24,7 +24,7 @@ public function testCreateHandlerFromConfiguration() /** * @expectedException \Zend\ServiceManager\Exception\ServiceNotCreatedException - * @expectedExceptionMessage elasticserach.handler.not-found could not be found + * @expectedExceptionMessage elasticsearch.handler.not-found could not be found */ public function testThrowsExceptionWhenHandlerConfigurationNotExist() { diff --git a/tests/ServiceFactory/AbstractElasticsearchServiceFactoryTest.php b/tests/ServiceFactory/AbstractElasticsearchServiceFactoryTest.php index 724f40b..e1886e9 100644 --- a/tests/ServiceFactory/AbstractElasticsearchServiceFactoryTest.php +++ b/tests/ServiceFactory/AbstractElasticsearchServiceFactoryTest.php @@ -8,7 +8,6 @@ use Elasticsearch\Connections\ConnectionFactoryInterface; use Elasticsearch\Transport; use ElasticsearchModuleTest\Service\AbstractTest; -use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceManager; /** @@ -25,7 +24,7 @@ protected function setUp() { parent::setUp(); $config = $this->getConfig(); - $this->serviceManager = new ServiceManager(new Config($config['service_manager'])); + $this->serviceManager = new ServiceManager($config['service_manager']); $this->serviceManager->setService('Config', $config); }