Skip to content

Enable to use aws es with iam auth #98

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .php_cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

$finder = Symfony\Component\Finder\Finder::create()
->notPath('bootstrap/cache')
->notPath('storage')
->notPath('vendor')
->in(__DIR__)
->name('*.php')
->ignoreDotFiles(true)
->ignoreVCS(true);

$fixers = [
'-psr0',
'-php_closing_tag',
'blankline_after_open_tag',
'concat_without_spaces',
'double_arrow_multiline_whitespaces',
'duplicate_semicolon',
'empty_return',
'extra_empty_lines',
'include',
'join_function',
'list_commas',
'multiline_array_trailing_comma',
'namespace_no_leading_whitespace',
'newline_after_open_tag',
'no_blank_lines_after_class_opening',
'no_empty_lines_after_phpdocs',
'object_operator',
'operators_spaces',
'phpdoc_indent',
'phpdoc_no_access',
'phpdoc_no_package',
'phpdoc_scalar',
'phpdoc_short_description',
'phpdoc_to_comment',
'phpdoc_trim',
'phpdoc_type_to_var',
'phpdoc_var_without_name',
'remove_leading_slash_use',
'remove_lines_between_uses',
'return',
'self_accessor',
'single_array_no_trailing_comma',
'single_blank_line_before_namespace',
'single_quote',
'spaces_before_semicolon',
'spaces_cast',
'standardize_not_equal',
'ternary_spaces',
'trim_array_spaces',
'unalign_equals',
'unary_operators_spaces',
'whitespacy_lines',
'multiline_spaces_before_semicolon',
'short_array_syntax',
'short_echo_tag',
];

return Symfony\CS\Config\Config::create()
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers($fixers)
->finder($finder)
->setUsingCache(true);

3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
"phpunit/phpunit": "~4.2|~5.0",
"mockery/mockery": "^0.9.4"
},
"suggest": {
"aws/aws-sdk-php": "^3.19"
},
"autoload": {
"psr-4": {
"Elasticquent\\": "src/"
Expand Down
111 changes: 111 additions & 0 deletions src/ElasticSearchClientFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

namespace Elasticquent;

final class ElasticSearchClientFactory
{
use ElasticquentConfigTrait;

/**
* @var array
*/
private $config;

/**
* ElasticSearchClientFactory constructor.
*/
public function __construct()
{
/* @var array $config */
$this->config = $this->getElasticConfig();
}

/**
* @return \Elasticsearch\Client
*/
public function getClient()
{
// elasticsearch v2.0 using builder
if (class_exists('\Elasticsearch\ClientBuilder')) {
// elasticsearch v2.0 using builder
$awsConfig = $this->getElasticConfig('aws');
if (!empty($awsConfig) && array_get($this->getElasticConfig('aws'), 'iam', false)) {
if ($handler = $this->getAwsESHandler()) {
array_set($this->config, 'handler', $handler);
}
}

return \Elasticsearch\ClientBuilder::fromConfig($this->config);
}

// elasticsearch v1
return new \Elasticsearch\Client($this->config);
}

/**
* @return bool|\Closure
*/
private function getAwsESHandler()
{
$classExistsChecks = [
'\Aws\Credentials\Credentials',
'\Aws\Signature\SignatureV4',
'\GuzzleHttp\Psr7\Request',
'\GuzzleHttp\Psr7\Uri',
'\GuzzleHttp\Ring\Future\CompletedFutureArray',
];

foreach ($classExistsChecks as $classExistsCheck) {
if (!class_exists($classExistsCheck)) {
return false;
}
}

$awsConfig = $this->getElasticConfig('aws');
if (empty($awsConfig)) {
return false;
}

$key = array_get($awsConfig, 'key');
$secret = array_get($awsConfig, 'secret');
$region = array_get($awsConfig, 'region', 'us-west-2');

$psr7Handler = \Aws\default_http_handler();
$signer = new \Aws\Signature\SignatureV4('es', $region);

$handler = function (array $request) use (
$psr7Handler,
$signer,
$key,
$secret
) {
// Amazon ES listens on standard ports (443 for HTTPS, 80 for HTTP).
$request['headers']['host'][0] = parse_url($request['headers']['host'][0], PHP_URL_HOST);

$credentials = new \Aws\Credentials\Credentials($key, $secret);

// Create a PSR-7 request from the array passed to the handler
$psr7Request = new \GuzzleHttp\Psr7\Request($request['http_method'],
(new \GuzzleHttp\Psr7\Uri($request['uri']))->withScheme($request['scheme'])->withHost($request['headers']['host'][0]),
$request['headers'], $request['body']);

// Sign the PSR-7 request with credentials from the environment
$signedRequest = $signer->signRequest($psr7Request, $credentials);

// Send the signed request to Amazon ES
/** @var \Psr\Http\Message\ResponseInterface $response */
$response = $psr7Handler($signedRequest)->wait();

// Convert the PSR-7 response to a RingPHP response
return new \GuzzleHttp\Ring\Future\CompletedFutureArray([
'status' => $response->getStatusCode(),
'headers' => $response->getHeaders(),
'body' => $response->getBody()->detach(),
'transfer_stats' => ['total_time' => 0],
'effective_url' => (string) $psr7Request->getUri(),
]);
};

return $handler;
}
}
13 changes: 3 additions & 10 deletions src/ElasticquentClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,14 @@ trait ElasticquentClientTrait
use ElasticquentConfigTrait;

/**
* Get ElasticSearch Client
* Get ElasticSearch Client.
*
* @return \Elasticsearch\Client
*/
public function getElasticSearchClient()
{
$config = $this->getElasticConfig();
$factory = new ElasticSearchClientFactory();

// elasticsearch v2.0 using builder
if (class_exists('\Elasticsearch\ClientBuilder')) {
return \Elasticsearch\ClientBuilder::fromConfig($config);
}

// elasticsearch v1
return new \Elasticsearch\Client($config);
return $factory->getClient();
}

}
8 changes: 4 additions & 4 deletions src/ElasticquentCollection.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php namespace Elasticquent;
<?php

namespace Elasticquent;

class ElasticquentCollection extends \Illuminate\Database\Eloquent\Collection
{

use ElasticquentCollectionTrait;

}
}
44 changes: 23 additions & 21 deletions src/ElasticquentCollectionTrait.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<?php namespace Elasticquent;
<?php

namespace Elasticquent;

/**
* Elasticquent Collection Trait
* Elasticquent Collection Trait.
*
* Elasticsearch functions that you
* can run on collections of documents.
Expand All @@ -11,7 +13,7 @@ trait ElasticquentCollectionTrait
use ElasticquentClientTrait;

/**
* Add To Index
* Add To Index.
*
* Add all documents in this collection to to the Elasticsearch document index.
*
Expand All @@ -20,19 +22,19 @@ trait ElasticquentCollectionTrait
public function addToIndex()
{
if ($this->isEmpty()) {
return null;
return;
}

$params = array();
$params = [];

foreach ($this->all() as $item) {
$params['body'][] = array(
'index' => array(
'_id' => $item->getKey(),
'_type' => $item->getTypeName(),
$params['body'][] = [
'index' => [
'_id' => $item->getKey(),
'_type' => $item->getTypeName(),
'_index' => $item->getIndexName(),
),
);
],
];

$params['body'][] = $item->getIndexDocumentData();
}
Expand All @@ -41,31 +43,31 @@ public function addToIndex()
}

/**
* Delete From Index
* Delete From Index.
*
* @return array
*/
public function deleteFromIndex()
{
$all = $this->all();

$params = array();
$params = [];

foreach ($all as $item) {
$params['body'][] = array(
'delete' => array(
'_id' => $item->getKey(),
'_type' => $item->getTypeName(),
$params['body'][] = [
'delete' => [
'_id' => $item->getKey(),
'_type' => $item->getTypeName(),
'_index' => $item->getIndexName(),
),
);
],
];
}

return $this->getElasticSearchClient()->bulk($params);
}

/**
* Reindex
* Reindex.
*
* Delete the items and then re-index them.
*
Expand All @@ -74,7 +76,7 @@ public function deleteFromIndex()
public function reindex()
{
$this->deleteFromIndex();

return $this->addToIndex();
}

}
19 changes: 10 additions & 9 deletions src/ElasticquentConfigTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
trait ElasticquentConfigTrait
{
/**
* Get Index Name
* Get Index Name.
*
* @return string
*/
Expand All @@ -24,15 +24,16 @@ public function getIndexName()
}

/**
* Get the Elasticquent config
* Get the Elasticquent config.
*
* @param string $key the configuration key
* @param string $key the configuration key
* @param string $prefix filename of configuration file
*
* @return array configuration
*/
public function getElasticConfig($key = 'config', $prefix = 'elasticquent')
{
$key = $prefix . ($key ? '.' : '') . $key;
$key = $prefix.($key ? '.' : '').$key;

if (function_exists('config')) {
// Get config helper for Laravel 5.1+
Expand All @@ -49,7 +50,7 @@ public function getElasticConfig($key = 'config', $prefix = 'elasticquent')
}

/**
* Inject given config file into an instance of Laravel's config
* Inject given config file into an instance of Laravel's config.
*
* @throws \Exception when the configuration file is not found
* @return \Illuminate\Config\Repository configuration repository
Expand All @@ -62,17 +63,17 @@ protected function getConfigHelper()
throw new \Exception('Config file not found.');
}

return new \Illuminate\Config\Repository(array('elasticquent' => require($config_file)));
return new \Illuminate\Config\Repository(['elasticquent' => require($config_file)]);
}

/**
* Get the config path and file name to use when Laravel framework isn't present
* e.g. using Eloquent stand-alone or running unit tests
* e.g. using Eloquent stand-alone or running unit tests.
*
* @return string config file path
* @return string config file path
*/
protected function getConfigFile()
{
return __DIR__ . '/config/elasticquent.php';
return __DIR__.'/config/elasticquent.php';
}
}
Loading