Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
1c08c06d
Commit
1c08c06d
authored
Nov 25, 2013
by
Carsten Brandt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented connection based on CUrl
far better than depending on fat guzzle
parent
a2aa4ff8
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
168 additions
and
81 deletions
+168
-81
.travis.yml
.travis.yml
+0
-1
Connection.php
extensions/elasticsearch/Connection.php
+116
-11
Exception.php
extensions/elasticsearch/Exception.php
+44
-0
GuzzleConnection.php
extensions/elasticsearch/GuzzleConnection.php
+0
-63
Query.php
extensions/elasticsearch/Query.php
+1
-1
composer.json
extensions/elasticsearch/composer.json
+2
-1
ElasticSearchConnectionTest.php
.../extensions/elasticsearch/ElasticSearchConnectionTest.php
+1
-2
ElasticSearchTestCase.php
...s/unit/extensions/elasticsearch/ElasticSearchTestCase.php
+1
-2
QueryTest.php
tests/unit/extensions/elasticsearch/QueryTest.php
+3
-0
No files found.
.travis.yml
View file @
1c08c06d
...
...
@@ -12,7 +12,6 @@ services:
before_script
:
-
composer self-update && composer --version
-
composer require satooshi/php-coveralls 0.6.* --dev --prefer-dist
-
composer require guzzle/http v3.7.3 --dev --prefer-dist
-
mysql -e 'CREATE DATABASE yiitest;';
-
psql -U postgres -c 'CREATE DATABASE yiitest;';
-
echo 'elasticsearch version ' && curl http://localhost:9200/
...
...
extensions/elasticsearch/Connection.php
View file @
1c08c06d
...
...
@@ -9,8 +9,8 @@ namespace yii\elasticsearch;
use
Yii
;
use
yii\base\Component
;
use
yii\base\Exception
;
use
yii\base\InvalidConfigException
;
use
yii\helpers\Json
;
/**
* elasticsearch Connection is used to connect to an elasticsearch cluster version 0.20 or higher
...
...
@@ -18,7 +18,7 @@ use yii\base\InvalidConfigException;
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
abstract
class
Connection
extends
Component
class
Connection
extends
Component
{
/**
* @event Event an event that is triggered after a DB connection is established
...
...
@@ -44,6 +44,19 @@ abstract class Connection extends Component
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/_configuration.html#_example_configuring_http_basic_auth
public
$auth
=
[];
/**
* @var float timeout to use for connecting to an elasticsearch node.
* This value will be used to configure the curl `CURLOPT_CONNECTTIMEOUT` option.
* If not set, no explicit timeout will be set for curl.
*/
public
$connectionTimeout
=
null
;
/**
* @var float timeout to use when reading the response from an elasticsearch node.
* This value will be used to configure the curl `CURLOPT_TIMEOUT` option.
* If not set, no explicit timeout will be set for curl.
*/
public
$dataTimeout
=
null
;
public
function
init
()
{
...
...
@@ -92,7 +105,7 @@ abstract class Connection extends Component
if
(
strncmp
(
$host
,
'inet[/'
,
6
)
==
0
)
{
$host
=
substr
(
$host
,
6
,
-
1
);
}
$response
=
$this
->
httpRequest
(
'
get
'
,
'http://'
.
$host
.
'/_cluster/nodes'
);
$response
=
$this
->
httpRequest
(
'
GET
'
,
'http://'
.
$host
.
'/_cluster/nodes'
);
$this
->
nodes
=
$response
[
'nodes'
];
if
(
empty
(
$this
->
nodes
))
{
throw
new
Exception
(
'cluster autodetection did not find any active node.'
);
...
...
@@ -161,34 +174,34 @@ abstract class Connection extends Component
return
new
QueryBuilder
(
$this
);
}
public
function
get
(
$url
,
$options
=
[],
$body
=
null
,
$validCodes
=
[]
)
public
function
get
(
$url
,
$options
=
[],
$body
=
null
)
{
$this
->
open
();
return
$this
->
httpRequest
(
'
get
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
return
$this
->
httpRequest
(
'
GET
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
}
public
function
head
(
$url
,
$options
=
[],
$body
=
null
)
{
$this
->
open
();
return
$this
->
httpRequest
(
'
head
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
return
$this
->
httpRequest
(
'
HEAD
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
}
public
function
post
(
$url
,
$options
=
[],
$body
=
null
)
{
$this
->
open
();
return
$this
->
httpRequest
(
'
post
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
return
$this
->
httpRequest
(
'
POST
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
}
public
function
put
(
$url
,
$options
=
[],
$body
=
null
)
{
$this
->
open
();
return
$this
->
httpRequest
(
'
put
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
return
$this
->
httpRequest
(
'
PUT
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
}
public
function
delete
(
$url
,
$options
=
[],
$body
=
null
)
{
$this
->
open
();
return
$this
->
httpRequest
(
'
delete
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
return
$this
->
httpRequest
(
'
DELETE
'
,
$this
->
createUrl
(
$url
,
$options
),
$body
);
}
private
function
createUrl
(
$path
,
$options
=
[])
...
...
@@ -201,10 +214,102 @@ abstract class Connection extends Component
$url
.=
'?'
.
http_build_query
(
$options
);
}
return
$url
;
$host
=
$this
->
nodes
[
$this
->
activeNode
][
'http_address'
];
if
(
strncmp
(
$host
,
'inet[/'
,
6
)
==
0
)
{
$host
=
substr
(
$host
,
6
,
-
1
);
}
return
'http://'
.
$host
.
'/'
.
$url
;
}
protected
function
httpRequest
(
$method
,
$url
,
$requestBody
=
null
)
{
$method
=
strtoupper
(
$method
);
// response body and headers
$headers
=
[];
$body
=
''
;
protected
abstract
function
httpRequest
(
$type
,
$url
,
$body
=
null
);
$options
=
[
CURLOPT_USERAGENT
=>
'Yii2 Framework '
.
__CLASS__
,
CURLOPT_RETURNTRANSFER
=>
false
,
CURLOPT_HEADER
=>
false
,
// http://www.php.net/manual/en/function.curl-setopt.php#82418
CURLOPT_HTTPHEADER
=>
[
'Expect:'
],
CURLOPT_WRITEFUNCTION
=>
function
(
$curl
,
$data
)
use
(
&
$body
)
{
$body
.=
$data
;
return
mb_strlen
(
$data
,
'8bit'
);
},
CURLOPT_HEADERFUNCTION
=>
function
(
$curl
,
$data
)
use
(
&
$headers
)
{
foreach
(
explode
(
"
\r\n
"
,
$data
)
as
$row
)
{
if
((
$pos
=
strpos
(
$row
,
':'
))
!==
false
)
{
$headers
[
strtolower
(
substr
(
$row
,
0
,
$pos
))]
=
trim
(
substr
(
$row
,
$pos
+
1
));
}
}
return
mb_strlen
(
$data
,
'8bit'
);
},
CURLOPT_CUSTOMREQUEST
=>
$method
,
];
if
(
$this
->
connectionTimeout
!==
null
)
{
$options
[
CURLOPT_CONNECTTIMEOUT
]
=
$this
->
connectionTimeout
;
}
if
(
$this
->
dataTimeout
!==
null
)
{
$options
[
CURLOPT_TIMEOUT
]
=
$this
->
dataTimeout
;
}
if
(
$requestBody
!==
null
)
{
$options
[
CURLOPT_POSTFIELDS
]
=
$requestBody
;
}
if
(
$method
==
'HEAD'
)
{
$options
[
CURLOPT_NOBODY
]
=
true
;
unset
(
$options
[
CURLOPT_WRITEFUNCTION
]);
}
$curl
=
curl_init
(
$url
);
curl_setopt_array
(
$curl
,
$options
);
curl_exec
(
$curl
);
$responseCode
=
curl_getinfo
(
$curl
,
CURLINFO_HTTP_CODE
);
curl_close
(
$curl
);
if
(
$responseCode
>=
200
&&
$responseCode
<
300
)
{
if
(
$method
==
'HEAD'
)
{
return
true
;
}
else
{
if
(
isset
(
$headers
[
'content-length'
])
&&
(
$len
=
mb_strlen
(
$body
,
'8bit'
))
<
$headers
[
'content-length'
])
{
throw
new
Exception
(
"Incomplete data received from elasticsearch:
$len
<
{
$headers
[
'content-length'
]
}
"
,
[
'requestMethod'
=>
$method
,
'requestUrl'
=>
$url
,
'requestBody'
=>
$requestBody
,
'responseCode'
=>
$responseCode
,
'responseHeaders'
=>
$headers
,
'responseBody'
=>
$body
,
]);
}
if
(
isset
(
$headers
[
'content-type'
])
&&
!
strncmp
(
$headers
[
'content-type'
],
'application/json'
,
16
))
{
return
Json
::
decode
(
$body
);
}
throw
new
Exception
(
'Unsupported data received from elasticsearch: '
.
$headers
[
'content-type'
],
[
'requestMethod'
=>
$method
,
'requestUrl'
=>
$url
,
'requestBody'
=>
$requestBody
,
'responseCode'
=>
$responseCode
,
'responseHeaders'
=>
$headers
,
'responseBody'
=>
$body
,
]);
}
}
elseif
(
$responseCode
==
404
)
{
return
false
;
}
else
{
throw
new
Exception
(
"Elasticsearch request failed with code
$responseCode
."
,
[
'requestMethod'
=>
$method
,
'requestUrl'
=>
$url
,
'requestBody'
=>
$requestBody
,
'responseCode'
=>
$responseCode
,
'responseHeaders'
=>
$headers
,
'responseBody'
=>
$body
,
]);
}
}
public
function
getNodeInfo
()
{
...
...
extensions/elasticsearch/Exception.php
0 → 100644
View file @
1c08c06d
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\elasticsearch
;
/**
* Exception represents an exception that is caused by elasticsearch-related operations.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class
Exception
extends
\yii\db\Exception
{
/**
* @var array additional information about the http request that caused the error.
*/
public
$errorInfo
=
[];
/**
* Constructor.
* @param string $message error message
* @param array $errorInfo error info
* @param integer $code error code
* @param \Exception $previous The previous exception used for the exception chaining.
*/
public
function
__construct
(
$message
,
$errorInfo
=
[],
$code
=
0
,
\Exception
$previous
=
null
)
{
$this
->
errorInfo
=
$errorInfo
;
parent
::
__construct
(
$message
,
$code
,
$previous
);
}
/**
* @return string the user-friendly name of this exception
*/
public
function
getName
()
{
return
\Yii
::
t
(
'yii'
,
'Elasticsearch Database Exception'
);
}
}
\ No newline at end of file
extensions/elasticsearch/GuzzleConnection.php
deleted
100644 → 0
View file @
a2aa4ff8
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\elasticsearch
;
use
Guzzle\Http\Exception\ClientErrorResponseException
;
use
yii\base\Exception
;
use
yii\helpers\Json
;
/**
* Class GuzzleConnection
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class
GuzzleConnection
extends
Connection
{
/**
* @var \Guzzle\Http\Client
*/
private
$_http
;
protected
function
httpRequest
(
$type
,
$url
,
$body
=
null
)
{
if
(
$this
->
_http
===
null
)
{
$this
->
_http
=
new
\Guzzle\Http\Client
(
'http://localhost:9200/'
);
// TODO use active node
//$guzzle->setDefaultOption()
}
$requestOptions
=
[];
if
(
$type
==
'head'
)
{
$requestOptions
[
'exceptions'
]
=
false
;
}
if
(
$type
==
'get'
&&
$body
!==
null
)
{
$type
=
'post'
;
}
try
{
$response
=
$this
->
_http
->
createRequest
(
strtoupper
(
$type
)
,
$url
,
null
,
$body
,
$requestOptions
)
->
send
();
}
catch
(
ClientErrorResponseException
$e
)
{
if
(
$e
->
getResponse
()
->
getStatusCode
()
==
404
)
{
return
false
;
}
throw
new
Exception
(
"elasticsearch error:
\n\n
"
.
$body
.
"
\n\n
"
.
$e
->
getMessage
()
.
print_r
(
Json
::
decode
(
$e
->
getResponse
()
->
getBody
(
true
)),
true
),
0
,
$e
);
}
if
(
$type
==
'head'
)
{
return
$response
->
getStatusCode
()
==
200
;
}
return
Json
::
decode
(
$response
->
getBody
(
true
));
}
}
\ No newline at end of file
extensions/elasticsearch/Query.php
View file @
1c08c06d
...
...
@@ -483,7 +483,7 @@ class Query extends Component implements QueryInterface
*/
public
function
fields
(
$fields
)
{
if
(
is_array
(
$fields
))
{
if
(
is_array
(
$fields
)
||
$fields
===
null
)
{
$this
->
fields
=
$fields
;
}
else
{
$this
->
fields
=
func_get_args
();
...
...
extensions/elasticsearch/composer.json
View file @
1c08c06d
...
...
@@ -18,7 +18,8 @@
}
],
"require"
:
{
"yiisoft/yii2"
:
"*"
"yiisoft/yii2"
:
"*"
,
"ext-curl"
:
"*"
},
"autoload"
:
{
"psr-0"
:
{
"yii
\\
elasticsearch
\\
"
:
""
}
...
...
tests/unit/extensions/elasticsearch/ElasticSearchConnectionTest.php
View file @
1c08c06d
...
...
@@ -3,7 +3,6 @@
namespace
yiiunit\extensions\elasticsearch
;
use
yii\elasticsearch\Connection
;
use
yii\elasticsearch\GuzzleConnection
;
/**
* @group elasticsearch
...
...
@@ -12,7 +11,7 @@ class ElasticSearchConnectionTest extends ElasticSearchTestCase
{
public
function
testOpen
()
{
$connection
=
new
Guzzle
Connection
();
$connection
=
new
Connection
();
$connection
->
autodetectCluster
;
$connection
->
nodes
=
[
[
'http_address'
=>
'inet[/127.0.0.1:9200]'
],
...
...
tests/unit/extensions/elasticsearch/ElasticSearchTestCase.php
View file @
1c08c06d
...
...
@@ -4,7 +4,6 @@ namespace yiiunit\extensions\elasticsearch;
use
Yii
;
use
yii\elasticsearch\Connection
;
use
yii\elasticsearch\GuzzleConnection
;
use
yiiunit\TestCase
;
Yii
::
setAlias
(
'@yii/elasticsearch'
,
__DIR__
.
'/../../../../extensions/elasticsearch'
);
...
...
@@ -43,7 +42,7 @@ class ElasticSearchTestCase extends TestCase
{
$databases
=
$this
->
getParam
(
'databases'
);
$params
=
isset
(
$databases
[
'elasticsearch'
])
?
$databases
[
'elasticsearch'
]
:
array
();
$db
=
new
Guzzle
Connection
();
$db
=
new
Connection
();
if
(
$reset
)
{
$db
->
open
();
}
...
...
tests/unit/extensions/elasticsearch/QueryTest.php
View file @
1c08c06d
...
...
@@ -33,6 +33,9 @@ class QueryTest extends ElasticSearchTestCase
$query
->
fields
([
'name'
,
'status'
]);
$this
->
assertEquals
([
'name'
,
'status'
],
$query
->
fields
);
$query
->
fields
(
'name'
,
'status'
);
$this
->
assertEquals
([
'name'
,
'status'
],
$query
->
fields
);
$result
=
$query
->
one
(
$this
->
getConnection
());
$this
->
assertEquals
(
2
,
count
(
$result
[
'_source'
]));
$this
->
assertArrayHasKey
(
'status'
,
$result
[
'_source'
]);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment