Commit 637fa264 authored by Cecilia Vela Gurovic's avatar Cecilia Vela Gurovic Committed by Gerrit Code Review

Merge "Bug 1811146: Upgrading elasticsearch-php to 6.1.0"

parents 4c9e818a e7bbd171
......@@ -2,13 +2,14 @@ Elasticsearch in Mahara
=======================
Website: https://github.com/elastic/elasticsearch-php
Version: 5.0.0
Version: 6.1.0
This version requires at least PHP version 5.6.6 to function.
This version requires at least PHP version 7.0.0 to function.
In addition, it requires the native JSON extension to be version 1.3.7 or higher.
This library is used to interact with the Elasticsearch server.
Changes:
* Removed the phpunit tests .xml files, the */tests/ and */docs/ and */Test/ dirs
* Removed the phpunit tests .xml files, the */tests/ and */docs/ and */travis/ dirs
* Removed the .github/ dir and .git* files
# 5.0
# 6.0
## Breaking changes
- [Search Templates]: PutTemplate endpoint has been removed (see [Elasticsearch Breaking Changes](https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_60_scripting_changes.html#_stored_search_template_apis_removed)),
use PutScript instead.
- Indices/Analyze Endpoint: `filters` and `char_filters` URI parameters have renamed to `filter` and `char_filter` respectively
- SearchExists endpoint has been removed ([use `size=0` and `terminate_after=1` instead](https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_50_search_changes.html#_search_exists_api_removed))
- Warmers have been removed because they are [no longer useful](https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_50_index_apis.html#_warmers)
- Indices/Optimize Endpoint has been removed ([use `_forcemerge` instead](https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_50_rest_api_changes.html#_literal__optimize_literal_endpoint_removed))
- MoreLikeThis (MLT) endpoint has been removed
- DeleteByQuery endpoint has been removed.
- Tasks/List and Tasks/Get are now separate endpoints (see: [[e0cc5f9]](http://github.com/elasticsearch/elasticsearch-php/commit/752d5a2))
- Client requires PHP 5.6.6 or higher
## Deprecations
- Percolator endpoints are deprecated and will be removed in Elasticsearch 6.0
## Internal BWC Breaks
- Namespace injection has changed slightly. If you use custom namespaces, you'll need to update your code (see: Add better ability to inject namespaces [[b1a27b7]](http://github.com/elasticsearch/elasticsearch-php/commit/b1a27b7))
- Endpoints no longer use the Transport directly. If you use custom endpoints, you'll need to do some minor
refactoring (see: Refactor to remove Transport dependence in endpoints [[ecd454c]](http://github.com/elasticsearch/elasticsearch-php/commit/ecd454c))
- To facilitate testing and other features, the `ConnectionInterface` has expanded to obtain some more methods ([[getPath()]](http://github.com/elasticsearch/elasticsearch-php/commit/8bcf1a8), [[getUserPass()]](http://github.com/elasticsearch/elasticsearch-php/commit/586fbdb), [[getHost()]](http://github.com/elasticsearch/elasticsearch-php/commit/445fdea))
- [#674](https://github.com/elastic/elasticsearch-php/pull/674) `ClientBuilder::defaultLogger()` method was removed. It is recommended to [create the logger object manually](https://github.com/elastic/elasticsearch-php/blob/master/docs/configuration.asciidoc#enabling-the-logger).
elasticsearch-php
=================
[![Build Status](https://img.shields.io/travis/elastic/elasticsearch-php.svg?style=flat-square)](https://travis-ci.org/elastic/elasticsearch-php)
[![Build Status](https://travis-ci.org/elastic/elasticsearch-php.svg?branch=master)](https://travis-ci.org/elastic/elasticsearch-php) [![Latest Stable Version](https://poser.pugx.org/elasticsearch/elasticsearch/v/stable)](https://packagist.org/packages/elasticsearch/elasticsearch) [![Total Downloads](https://poser.pugx.org/elasticsearch/elasticsearch/downloads)](https://packagist.org/packages/elasticsearch/elasticsearch)
Official low-level client for Elasticsearch. Its goal is to provide common ground for all Elasticsearch-related code in PHP; because of this it tries to be opinion-free and very extendable.
To maintain consistency across all the low-level clients (Ruby, Python, etc), clients accept simple associative arrays as parameters. All parameters, from the URI to the document body, are defined in the associative array.
To maintain consistency across all the low-level clients (Ruby, Python, etc.), clients accept simple associative arrays as parameters. All parameters, from the URI to the document body, are defined in the associative array.
Features
......@@ -18,22 +18,28 @@ Features
- Load balancing (with pluggable selection strategy) across all available nodes. Defaults to round-robin
- Pluggable connection pools to offer different connection strategies
- Generalized, pluggable architecture - most components can be replaced with your own custom class if specialized behavior is required
- Option to use asyncronous future, which enables parallel execution of curl requests to multiple nodes
- Option to use asynchronous future, which enables parallel execution of curl requests to multiple nodes
**Note:** If you want to use X-Pack API, you need to install an optional extension [elasticsearch/xpack](https://github.com/elastic/elasticsearch-x-pack-php).
Version Matrix
--------------
| Elasticsearch Version | Elasticsearch-PHP Branch |
| --------------------- | ------------------------ |
| >= 5.0 | 5.0 |
| >= 6.0 | 6.0 |
| >= 5.0, < 6.0 | 5.0 |
| >= 2.0, < 5.0 | 1.0 or 2.0 |
| >= 1.0, < 2.0 | 1.0 or 2.0 |
| <= 0.90.x | 0.4 |
- If you are using Elasticsearch 5.0+ , use Elasticsearch-PHP 5.0 branch.
- If you are using Elasticsearch 6.0+ , use Elasticsearch-PHP 6.0 branch.
- If you are using Elasticsearch 5.x , use Elasticsearch-PHP 5.0 branch.
- If you are using Elasticsearch 1.x or 2.x, prefer using the Elasticsearch-PHP 2.0 branch. The 1.0 branch is compatible however.
- If you are using a version older than 1.0, you must install the `0.4` Elasticsearch-PHP branch. Since ES 0.90.x and below is now EOL, the corresponding `0.4` branch will not receive any more development or bugfixes. Please upgrade.
- You should never use Elasticsearch-PHP Master branch, as it tracks Elasticearch master and may contain incomplete features or breaks in backwards compat. Only use ES-PHP master if you are developing against ES master for some reason.
- You should never use Elasticsearch-PHP Master branch, as it tracks Elasticsearch master and may contain incomplete features or breaks in backwards compatibility. Only use ES-PHP master if you are developing against ES master for some reason.
Documentation
--------------
......@@ -43,12 +49,12 @@ Installation via Composer
-------------------------
The recommended method to install _Elasticsearch-PHP_ is through [Composer](http://getcomposer.org).
1. Add ``elasticsearch/elasticsearch`` as a dependency in your project's ``composer.json`` file (change version to suit your version of Elasticsearch):
1. Add `elasticsearch/elasticsearch` as a dependency in your project's `composer.json` file (change version to suit your version of Elasticsearch):
```json
{
"require": {
"elasticsearch/elasticsearch": "~5.0"
"elasticsearch/elasticsearch": "~6.0"
}
}
```
......@@ -62,12 +68,12 @@ The recommended method to install _Elasticsearch-PHP_ is through [Composer](http
3. Install your dependencies:
```bash
php composer.phar install --no-dev
php composer.phar install
```
4. Require Composer's autoloader
Composer also prepares an autoload file that's capable of autoloading all of the classes in any of the libraries that it downloads. To use it, just add the following line to your code's bootstrap process:
Composer also prepares an autoload file that's capable of autoloading all the classes in any of the libraries that it downloads. To use it, just add the following line to your code's bootstrap process:
```php
<?php
......@@ -80,18 +86,17 @@ The recommended method to install _Elasticsearch-PHP_ is through [Composer](http
```
You can find out more on how to install Composer, configure autoloading, and other best-practices for defining dependencies at [getcomposer.org](http://getcomposer.org).
You'll notice that the installation command specified `--no-dev`. This prevents Composer from installing the various testing and development dependencies. For average users, there is no need to install the test suite (which also includes the complete source code of Elasticsearch). If you wish to contribute to development, just omit the `--no-dev` flag to be able to run tests.
PHP Version Requirement
----
Version 5.0 of this library requires at least PHP version 5.6.6 to function. In addition, it requires the native JSON
Version 6.0 of this library requires at least PHP version 7.0.0 to function. In addition, it requires the native JSON
extension to be version 1.3.7 or higher.
| PHP Version | Elasticsearch-PHP Branch |
| Elasticsearch-PHP Branch | PHP Version |
| ----------- | ------------------------ |
| >= 5.6.6 | 5.0 |
| >= 5.4.0 | 2.0 |
| >= 5.3.9 | 0.4, 1.0 |
| 6.0 | >= 7.0.0 |
| 5.0 | >= 5.6.6 |
| 2.0 | >= 5.4.0 |
| 0.4, 1.0 | >= 5.3.9 |
Quickstart
......@@ -148,7 +153,7 @@ $response = $client->get($params);
print_r($response);
```
The response contains some metadata (index, type, etc) as well as a `_source` field...this is the original document
The response contains some metadata (index, type, etc.) as well as a `_source` field...this is the original document
that you sent to Elasticsearch.
```php
......@@ -201,7 +206,7 @@ $response = $client->search($params);
print_r($response);
```
The response is a little different from the previous responses. We see some metadata (`took`, `timed_out`, etc) and
The response is a little different from the previous responses. We see some metadata (`took`, `timed_out`, etc.) and
an array named `hits`. This represents your search results. Inside of `hits` is another array named `hits`, which contains
individual search results:
......@@ -319,14 +324,34 @@ Array
)
```
Unit Testing using Mock a Elastic Client
========================================
```php
use GuzzleHttp\Ring\Client\MockHandler;
use Elasticsearch\ClientBuilder;
// The connection class requires 'body' to be a file stream handle
// Depending on what kind of request you do, you may need to set more values here
$handler = new MockHandler([
'status' => 200,
'transfer_stats' => [
'total_time' => 100
],
'body' => fopen('somefile.json')
]);
$builder = ClientBuilder::create();
$builder->setHosts(['somehost']);
$builder->setHandler($handler);
$client = $builder->build();
// Do a request and you'll get back the 'body' response above
```
Wrap up
=======
That was just a crash-course overview of the client and it's syntax. If you are familiar with elasticsearch, you'll notice that the methods are named just like REST endpoints.
That was just a crash-course overview of the client and its syntax. If you are familiar with Elasticsearch, you'll notice that the methods are named just like REST endpoints.
You'll also notice that the client is configured in a manner that facilitates easy discovery via the IDE. All core actions are available under the `$client` object (indexing, searching, getting, etc). Index and cluster management are located under the `$client->indices()` and `$client->cluster()` objects, respectively.
You'll also notice that the client is configured in a manner that facilitates easy discovery via the IDE. All core actions are available under the `$client` object (indexing, searching, getting, etc.). Index and cluster management are located under the `$client->indices()` and `$client->cluster()` objects, respectively.
Check out the rest of the [Documentation](http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/index.html) to see how the entire client works.
......
......@@ -10,18 +10,20 @@
}
],
"require": {
"php": "^5.6|^7.0",
"psr/log": "~1.0",
"guzzlehttp/ringphp" : "~1.0"
"php": "^7.0",
"ext-json": ">=1.3.7",
"guzzlehttp/ringphp": "~1.0",
"psr/log": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.7|^5.4",
"cpliakas/git-wrapper": "~1.0",
"doctrine/inflector": "^1.1",
"mockery/mockery": "0.9.4",
"symfony/yaml": "^2.8",
"phpstan/phpstan-shim": "0.9.1",
"phpunit/phpunit": "6.3.0",
"squizlabs/php_codesniffer": "3.0.2",
"symfony/finder": "^2.8",
"cpliakas/git-wrapper": "~1.0",
"sami/sami": "~3.2",
"doctrine/inflector": "^1.1"
"symfony/yaml": "^2.8"
},
"suggest": {
"ext-curl": "*",
......@@ -36,5 +38,18 @@
"psr-4": {
"Elasticsearch\\Tests\\": "tests/Elasticsearch/Tests/"
}
},
"config": {
"sort-packages": true
},
"scripts": {
"phpcs": [
"phpcs --standard=ruleset.xml --extensions=php --encoding=utf-8 --tab-width=4 -sp src",
"phpcs --standard=ruleset.xml --extensions=php --encoding=utf-8 --tab-width=4 -sp tests"
],
"phpstan": [
"@php vendor/phpstan/phpstan-shim/phpstan.phar analyse -c phpstan-src.neon src --level 2 --no-progress",
"@php vendor/phpstan/phpstan-shim/phpstan.phar analyse -c phpstan-tests.neon tests --level 7 --no-progress"
]
}
}
<?php
declare(strict_types = 1);
namespace Elasticsearch;
use Elasticsearch\Common\Exceptions\InvalidArgumentException;
......@@ -37,7 +39,7 @@ class ClientBuilder
/** @var Transport */
private $transport;
/** @var callback */
/** @var callable */
private $endpoint;
/** @var NamespaceBuilderInterface[] */
......@@ -89,9 +91,6 @@ class ClientBuilder
/** @var null|bool|string */
private $sslVerification = null;
/** @var bool */
private $allowBadJSON = false;
/**
* @return ClientBuilder
*/
......@@ -102,7 +101,7 @@ class ClientBuilder
/**
* Can supply first parm to Client::__construct() when invoking manually or with dependency injection
* @return this->ransport
* @return Transport
*
*/
public function getTransport()
......@@ -112,7 +111,7 @@ class ClientBuilder
/**
* Can supply second parm to Client::__construct() when invoking manually or with dependency injection
* @return this->endpoint
* @return callable
*
*/
public function getEndpoint()
......@@ -122,7 +121,7 @@ class ClientBuilder
/**
* Can supply third parm to Client::__construct() when invoking manually or with dependency injection
* @return this->registeredNamespacesBuilders
* @return NamespaceBuilderInterface[]
*
*/
public function getRegisteredNamespacesBuilders()
......@@ -165,8 +164,8 @@ class ClientBuilder
}
/**
* @param array $singleParams
* @param array $multiParams
* @param array $singleParams
* @throws \RuntimeException
* @return callable
*/
......@@ -215,19 +214,6 @@ class ClientBuilder
}
}
/**
* @param $path string
* @return \Monolog\Logger\Logger
*/
public static function defaultLogger($path, $level = Logger::WARNING)
{
$log = new Logger('log');
$handler = new StreamHandler($path, $level);
$log->pushHandler($handler);
return $log;
}
/**
* @param \Elasticsearch\Connections\ConnectionFactoryInterface $connectionFactory
* @return $this
......@@ -309,6 +295,10 @@ class ClientBuilder
*/
public function setLogger($logger)
{
if (!$logger instanceof LoggerInterface) {
throw new InvalidArgumentException('$logger must implement \Psr\Log\LoggerInterface!');
}
$this->logger = $logger;
return $this;
......@@ -320,6 +310,10 @@ class ClientBuilder
*/
public function setTracer($tracer)
{
if (!$tracer instanceof LoggerInterface) {
throw new InvalidArgumentException('$tracer must implement \Psr\Log\LoggerInterface!');
}
$this->tracer = $tracer;
return $this;
......@@ -394,7 +388,7 @@ class ClientBuilder
}
/**
* @param $cert
* @param string $cert The name of a file containing a PEM formatted certificate.
* @param null|string $password
* @return $this
*/
......@@ -406,7 +400,7 @@ class ClientBuilder
}
/**
* @param $key
* @param string $key The name of a file containing a private SSL key.
* @param null|string $password
* @return $this
*/
......@@ -428,24 +422,11 @@ class ClientBuilder
return $this;
}
public function allowBadJSONSerialization()
{
$this->allowBadJSON = true;
return $this;
}
/**
* @return Client
*/
public function build()
{
if(!defined('JSON_PRESERVE_ZERO_FRACTION') && $this->allowBadJSON === false) {
throw new RuntimeException("Your version of PHP / json-ext does not support the constant 'JSON_PRESERVE_ZERO_FRACTION',".
" which is important for proper type mapping in Elasticsearch. Please upgrade your PHP or json-ext.\n".
"If you are unable to upgrade, and are willing to accept the consequences, you may use the allowBadJSONSerialization()".
" method on the ClientBuilder to bypass this limitation.");
}
$this->buildLoggers();
if (is_null($this->handler)) {
......@@ -489,16 +470,16 @@ class ClientBuilder
$this->connectionParams = [];
}
// Make sure we are setting Content-type and Accept (unless the user has explicitly
// Make sure we are setting Content-Type and Accept (unless the user has explicitly
// overridden it
if (isset($this->connectionParams['client']['headers']) === false) {
$this->connectionParams['client']['headers'] = [
'Content-type' => ['application/json'],
'Content-Type' => ['application/json'],
'Accept' => ['application/json']
];
} else {
if (isset($this->connectionParams['client']['headers']['Content-type']) === false) {
$this->connectionParams['client']['headers']['Content-type'] = ['application/json'];
if (isset($this->connectionParams['client']['headers']['Content-Type']) === false) {
$this->connectionParams['client']['headers']['Content-Type'] = ['application/json'];
}
if (isset($this->connectionParams['client']['headers']['Accept']) === false) {
$this->connectionParams['client']['headers']['Accept'] = ['application/json'];
......@@ -525,7 +506,7 @@ class ClientBuilder
$this->endpoint = function ($class) use ($serializer) {
$fullPath = '\\Elasticsearch\\Endpoints\\' . $class;
if ($class === 'Bulk' || $class === 'Msearch' || $class === 'MPercolate') {
if ($class === 'Bulk' || $class === 'Msearch' || $class === 'MsearchTemplate' || $class === 'MPercolate') {
return new $fullPath($serializer);
} else {
return new $fullPath();
......@@ -535,7 +516,7 @@ class ClientBuilder
$registeredNamespaces = [];
foreach ($this->registeredNamespacesBuilders as $builder) {
/** @var $builder NamespaceBuilderInterface */
/** @var NamespaceBuilderInterface $builder */
$registeredNamespaces[$builder->getName()] = $builder->getObject($this->transport, $this->serializer);
}
......@@ -573,13 +554,15 @@ class ClientBuilder
$connections,
$this->selector,
$this->connectionFactory,
$this->connectionPoolArgs);
$this->connectionPoolArgs
);
} elseif (is_null($this->connectionPool)) {
$this->connectionPool = new StaticNoPingConnectionPool(
$connections,
$this->selector,
$this->connectionFactory,
$this->connectionPoolArgs);
$this->connectionPoolArgs
);
}
if (is_null($this->retries)) {
......@@ -628,7 +611,7 @@ class ClientBuilder
if (is_string($host)) {
$host = $this->prependMissingScheme($host);
$host = $this->extractURIParts($host);
} else if (is_array($host)) {
} elseif (is_array($host)) {
$host = $this->normalizeExtendedHost($host);
} else {
$this->logger->error("Could not parse host: ".print_r($host, true));
......@@ -641,10 +624,11 @@ class ClientBuilder
}
/**
* @param $host
* @param array $host
* @return array
*/
private function normalizeExtendedHost($host) {
private function normalizeExtendedHost(array $host)
{
if (isset($host['host']) === false) {
$this->logger->error("Required 'host' was not defined in extended format: ".print_r($host, true));
throw new RuntimeException("Required 'host' was not defined in extended format: ".print_r($host, true));
......@@ -687,7 +671,7 @@ class ClientBuilder
*/
private function prependMissingScheme($host)
{
if (!filter_var($host, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)) {
if (!filter_var($host, FILTER_VALIDATE_URL)) {
$host = 'http://' . $host;
}
......
<?php
declare(strict_types = 1);
namespace Elasticsearch\Common;
use Psr\Log\AbstractLogger;
......