elastic_search_thrift 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG +3 -0
- data/Gemfile +6 -0
- data/LICENSE +20 -0
- data/README.markdown +39 -0
- data/Rakefile +16 -0
- data/config/elasticsearch.thrift +82 -0
- data/elastic_search_thrift.gemspec +21 -0
- data/lib/elastic_search_thrift.rb +23 -0
- data/lib/elastic_search_thrift/client.rb +86 -0
- data/lib/elastic_search_thrift/elasticsearch_constants.rb +11 -0
- data/lib/elastic_search_thrift/elasticsearch_types.rb +123 -0
- data/lib/elastic_search_thrift/mini_thrift.rb +40 -0
- data/lib/elastic_search_thrift/rest.rb +81 -0
- data/lib/elastic_search_thrift/thrift_extensions.rb +9 -0
- data/lib/elastic_search_thrift/tire_client.rb +69 -0
- data/lib/elastic_search_thrift/version.rb +11 -0
- data/test/config.yml +4 -0
- data/test/elastic_search_thrift/test_client.rb +36 -0
- data/test/elastic_search_thrift/test_tire_client.rb +56 -0
- data/test/test_helper.rb +31 -0
- metadata +125 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) George Ogata
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
## Elastic Search Thrift
|
2
|
+
|
3
|
+
Ruby ElasticSearch client that uses the thrift transport.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
gem install elastic_search_thrift
|
8
|
+
|
9
|
+
You will of course also need the
|
10
|
+
[thrift transport plugin for ElasticSearch][plugin].
|
11
|
+
|
12
|
+
[plugin]: https://github.com/elasticsearch/elasticsearch-transport-thrift
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
require 'elasticsearch_thrift'
|
17
|
+
|
18
|
+
# This is the default configuration.
|
19
|
+
ElasticSearchThrift.configure(host: '127.0.0.1', port: 9500)
|
20
|
+
|
21
|
+
ElasticSearchThrift.client.open do |client|
|
22
|
+
client.get('/')
|
23
|
+
end
|
24
|
+
|
25
|
+
## Tire Integration
|
26
|
+
|
27
|
+
ElasticSearchThrift.configure_tire
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
|
31
|
+
* [Bug reports](https://github.com/howaboutwe/elastic_search_thrift/issues)
|
32
|
+
* [Source](https://github.com/howaboutwe/elastic_search_thrift)
|
33
|
+
* Patches: Fork on Github, send pull request.
|
34
|
+
* Include tests where practical.
|
35
|
+
* Leave the version alone, or bump it in a separate commit.
|
36
|
+
|
37
|
+
## Copyright
|
38
|
+
|
39
|
+
Copyright (c) George Ogata. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'ritual'
|
2
|
+
|
3
|
+
task :configure do
|
4
|
+
FileUtils.mkdir_p 'config'
|
5
|
+
system "curl https://raw.github.com/elasticsearch/elasticsearch-transport-thrift/master/elasticsearch.thrift > config/elasticsearch.thrift"
|
6
|
+
system "sed -i '' -e 's|namespace rb ElasticSearch.Thrift|namespace rb ElasticSearchThrift|' config/elasticsearch.thrift"
|
7
|
+
end
|
8
|
+
|
9
|
+
task :thrift do
|
10
|
+
system "thrift --gen rb -out lib/elastic_search_thrift config/elasticsearch.thrift"
|
11
|
+
|
12
|
+
Dir['lib/elastic_search_thrift/{elasticsearch_constants,elasticsearch_types,rest}.rb'].each do |path|
|
13
|
+
system "sed -i '' -e \"s|require 'thrift'|require 'elastic_search_thrift/mini_thrift'|\" #{path}"
|
14
|
+
system "sed -i '' -e \"s|require 'elasticsearch_types'|require 'elastic_search_thrift/elasticsearch_types'|\" #{path}"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
namespace java org.elasticsearch.thrift
|
2
|
+
namespace csharp ElasticSearch.Thrift
|
3
|
+
namespace cpp elasticsearch.thrift
|
4
|
+
namespace rb ElasticSearchThrift
|
5
|
+
namespace py elasticsearch
|
6
|
+
namespace perl Elasticsearch
|
7
|
+
namespace php Elasticsearch
|
8
|
+
|
9
|
+
enum Method {
|
10
|
+
GET = 0,
|
11
|
+
PUT = 1,
|
12
|
+
POST = 2,
|
13
|
+
DELETE = 3,
|
14
|
+
HEAD = 4,
|
15
|
+
OPTIONS = 5
|
16
|
+
}
|
17
|
+
|
18
|
+
struct RestRequest {
|
19
|
+
1: required Method method,
|
20
|
+
2: required string uri
|
21
|
+
3: optional map<string, string> parameters
|
22
|
+
4: optional map<string, string> headers
|
23
|
+
5: optional binary body
|
24
|
+
}
|
25
|
+
|
26
|
+
enum Status {
|
27
|
+
CONT = 100,
|
28
|
+
SWITCHING_PROTOCOLS = 101,
|
29
|
+
OK = 200,
|
30
|
+
CREATED = 201,
|
31
|
+
ACCEPTED = 202,
|
32
|
+
NON_AUTHORITATIVE_INFORMATION = 203,
|
33
|
+
NO_CONTENT = 204,
|
34
|
+
RESET_CONTENT = 205,
|
35
|
+
PARTIAL_CONTENT = 206,
|
36
|
+
MULTI_STATUS = 207,
|
37
|
+
MULTIPLE_CHOICES = 300,
|
38
|
+
MOVED_PERMANENTLY = 301,
|
39
|
+
FOUND = 302,
|
40
|
+
SEE_OTHER = 303,
|
41
|
+
NOT_MODIFIED = 304,
|
42
|
+
USE_PROXY = 305,
|
43
|
+
TEMPORARY_REDIRECT = 307,
|
44
|
+
BAD_REQUEST = 400,
|
45
|
+
UNAUTHORIZED = 401,
|
46
|
+
PAYMENT_REQUIRED = 402,
|
47
|
+
FORBIDDEN = 403,
|
48
|
+
NOT_FOUND = 404,
|
49
|
+
METHOD_NOT_ALLOWED = 405,
|
50
|
+
NOT_ACCEPTABLE = 406,
|
51
|
+
PROXY_AUTHENTICATION = 407,
|
52
|
+
REQUEST_TIMEOUT = 408,
|
53
|
+
CONFLICT = 409,
|
54
|
+
GONE = 410,
|
55
|
+
LENGTH_REQUIRED = 411,
|
56
|
+
PRECONDITION_FAILED = 412,
|
57
|
+
REQUEST_ENTITY_TOO_LARGE = 413,
|
58
|
+
REQUEST_URI_TOO_LONG = 414,
|
59
|
+
UNSUPPORTED_MEDIA_TYPE = 415,
|
60
|
+
REQUESTED_RANGE_NOT_SATISFIED = 416,
|
61
|
+
EXPECTATION_FAILED = 417,
|
62
|
+
UNPROCESSABLE_ENTITY = 422,
|
63
|
+
LOCKED = 423,
|
64
|
+
FAILED_DEPENDENCY = 424,
|
65
|
+
INTERNAL_SERVER_ERROR = 500,
|
66
|
+
NOT_IMPLEMENTED = 501,
|
67
|
+
BAD_GATEWAY = 502,
|
68
|
+
SERVICE_UNAVAILABLE = 503,
|
69
|
+
GATEWAY_TIMEOUT = 504,
|
70
|
+
INSUFFICIENT_STORAGE = 506
|
71
|
+
}
|
72
|
+
|
73
|
+
struct RestResponse {
|
74
|
+
1: required Status status,
|
75
|
+
2: optional map<string, string> headers,
|
76
|
+
3: optional binary body
|
77
|
+
}
|
78
|
+
|
79
|
+
service Rest {
|
80
|
+
RestResponse execute(1:required RestRequest request)
|
81
|
+
}
|
82
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.unshift File.expand_path('lib', File.dirname(__FILE__))
|
3
|
+
require 'elastic_search_thrift/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'elastic_search_thrift'
|
7
|
+
gem.version = ElasticSearchThrift::VERSION
|
8
|
+
gem.authors = ['George Ogata']
|
9
|
+
gem.email = ['george.ogata@gmail.com']
|
10
|
+
gem.description = "Thrift client for ElasticSearch"
|
11
|
+
gem.summary = "Thrift client for ElasticSearch"
|
12
|
+
gem.homepage = 'https://github.com/howaboutwe/elastic_search_thrift'
|
13
|
+
|
14
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
gem.files = `git ls-files`.split("\n")
|
16
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
|
18
|
+
gem.add_dependency 'thrift', '~> 0.9.1'
|
19
|
+
gem.add_dependency 'json', '>= 1.6.0', '< 1.9.0'
|
20
|
+
gem.add_development_dependency 'bundler'
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ElasticSearchThrift
|
2
|
+
autoload :Client, 'elastic_search_thrift/client'
|
3
|
+
autoload :TireClient, 'elastic_search_thrift/tire_client'
|
4
|
+
autoload :VERSION, 'elastic_search_thrift/version'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :configuration
|
8
|
+
|
9
|
+
def configure(attributes)
|
10
|
+
self.configuration = attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
def client
|
14
|
+
@client ||= Client.new(configuration)
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure_tire
|
18
|
+
TireClient.install
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
configure host: '127.0.0.1', port: 9500
|
23
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require 'elastic_search_thrift/mini_thrift'
|
4
|
+
require 'elastic_search_thrift/elasticsearch_constants'
|
5
|
+
require 'elastic_search_thrift/elasticsearch_types'
|
6
|
+
require 'elastic_search_thrift/rest'
|
7
|
+
require 'elastic_search_thrift/thrift_extensions'
|
8
|
+
|
9
|
+
module ElasticSearchThrift
|
10
|
+
class Client
|
11
|
+
def initialize(options = {})
|
12
|
+
host = options[:host] || options['host'] || '127.0.0.1'
|
13
|
+
port = options[:port] || options['port'] || 9500
|
14
|
+
@socket = Thrift::Socket.new(host, port)
|
15
|
+
@transport = Thrift::BufferedTransport.new(socket)
|
16
|
+
@protocol = Thrift::BinaryProtocol.new(transport)
|
17
|
+
@client = ElasticSearchThrift::Rest::Client.new(protocol)
|
18
|
+
|
19
|
+
# Create finalizer proc in separate scope so it doesn't prevent GC.
|
20
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer_for(self))
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.finalizer_for(instance)
|
24
|
+
-> { instance.close }
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :socket, :transport, :protocol, :client
|
28
|
+
|
29
|
+
def get(path, parameters = {}, body = {})
|
30
|
+
request(ElasticSearchThrift::Method::GET, path, parameters, body)
|
31
|
+
end
|
32
|
+
|
33
|
+
def put(path, parameters = {}, body = {})
|
34
|
+
request(ElasticSearchThrift::Method::PUT, path, parameters, body)
|
35
|
+
end
|
36
|
+
|
37
|
+
def post(path, parameters = {}, body = {})
|
38
|
+
request(ElasticSearchThrift::Method::POST, path, parameters, body)
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(path, parameters = {}, body = {})
|
42
|
+
request(ElasticSearchThrift::Method::DELETE, path, parameters, body)
|
43
|
+
end
|
44
|
+
|
45
|
+
def request(method, uri, parameters = {}, body = {})
|
46
|
+
request = RestRequest.new
|
47
|
+
request.method = method
|
48
|
+
request.uri = uri
|
49
|
+
request.parameters = normalize_hash(parameters)
|
50
|
+
request.headers = {}
|
51
|
+
request.body = body.to_json
|
52
|
+
@client.execute(request)
|
53
|
+
end
|
54
|
+
|
55
|
+
def open
|
56
|
+
@transport.open unless open?
|
57
|
+
if block_given?
|
58
|
+
begin
|
59
|
+
yield self
|
60
|
+
ensure
|
61
|
+
close
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def open?
|
67
|
+
@transport.open?
|
68
|
+
end
|
69
|
+
|
70
|
+
def close
|
71
|
+
@transport.close if open?
|
72
|
+
end
|
73
|
+
|
74
|
+
def normalize_hash(hash)
|
75
|
+
return hash if hash.empty?
|
76
|
+
|
77
|
+
result = {}
|
78
|
+
hash.each do |key, value|
|
79
|
+
result[key.to_s] = value.to_s
|
80
|
+
end
|
81
|
+
result
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
Response = Struct.new(:status, :headers, :body)
|
86
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift Compiler (0.9.0)
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'elastic_search_thrift/mini_thrift'
|
8
|
+
require 'elastic_search_thrift/elasticsearch_types'
|
9
|
+
|
10
|
+
module ElasticSearchThrift
|
11
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift Compiler (0.9.0)
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'elastic_search_thrift/mini_thrift'
|
8
|
+
|
9
|
+
module ElasticSearchThrift
|
10
|
+
module Method
|
11
|
+
GET = 0
|
12
|
+
PUT = 1
|
13
|
+
POST = 2
|
14
|
+
DELETE = 3
|
15
|
+
HEAD = 4
|
16
|
+
OPTIONS = 5
|
17
|
+
VALUE_MAP = {0 => "GET", 1 => "PUT", 2 => "POST", 3 => "DELETE", 4 => "HEAD", 5 => "OPTIONS"}
|
18
|
+
VALID_VALUES = Set.new([GET, PUT, POST, DELETE, HEAD, OPTIONS]).freeze
|
19
|
+
end
|
20
|
+
|
21
|
+
module Status
|
22
|
+
CONT = 100
|
23
|
+
SWITCHING_PROTOCOLS = 101
|
24
|
+
OK = 200
|
25
|
+
CREATED = 201
|
26
|
+
ACCEPTED = 202
|
27
|
+
NON_AUTHORITATIVE_INFORMATION = 203
|
28
|
+
NO_CONTENT = 204
|
29
|
+
RESET_CONTENT = 205
|
30
|
+
PARTIAL_CONTENT = 206
|
31
|
+
MULTI_STATUS = 207
|
32
|
+
MULTIPLE_CHOICES = 300
|
33
|
+
MOVED_PERMANENTLY = 301
|
34
|
+
FOUND = 302
|
35
|
+
SEE_OTHER = 303
|
36
|
+
NOT_MODIFIED = 304
|
37
|
+
USE_PROXY = 305
|
38
|
+
TEMPORARY_REDIRECT = 307
|
39
|
+
BAD_REQUEST = 400
|
40
|
+
UNAUTHORIZED = 401
|
41
|
+
PAYMENT_REQUIRED = 402
|
42
|
+
FORBIDDEN = 403
|
43
|
+
NOT_FOUND = 404
|
44
|
+
METHOD_NOT_ALLOWED = 405
|
45
|
+
NOT_ACCEPTABLE = 406
|
46
|
+
PROXY_AUTHENTICATION = 407
|
47
|
+
REQUEST_TIMEOUT = 408
|
48
|
+
CONFLICT = 409
|
49
|
+
GONE = 410
|
50
|
+
LENGTH_REQUIRED = 411
|
51
|
+
PRECONDITION_FAILED = 412
|
52
|
+
REQUEST_ENTITY_TOO_LARGE = 413
|
53
|
+
REQUEST_URI_TOO_LONG = 414
|
54
|
+
UNSUPPORTED_MEDIA_TYPE = 415
|
55
|
+
REQUESTED_RANGE_NOT_SATISFIED = 416
|
56
|
+
EXPECTATION_FAILED = 417
|
57
|
+
UNPROCESSABLE_ENTITY = 422
|
58
|
+
LOCKED = 423
|
59
|
+
FAILED_DEPENDENCY = 424
|
60
|
+
INTERNAL_SERVER_ERROR = 500
|
61
|
+
NOT_IMPLEMENTED = 501
|
62
|
+
BAD_GATEWAY = 502
|
63
|
+
SERVICE_UNAVAILABLE = 503
|
64
|
+
GATEWAY_TIMEOUT = 504
|
65
|
+
INSUFFICIENT_STORAGE = 506
|
66
|
+
VALUE_MAP = {100 => "CONT", 101 => "SWITCHING_PROTOCOLS", 200 => "OK", 201 => "CREATED", 202 => "ACCEPTED", 203 => "NON_AUTHORITATIVE_INFORMATION", 204 => "NO_CONTENT", 205 => "RESET_CONTENT", 206 => "PARTIAL_CONTENT", 207 => "MULTI_STATUS", 300 => "MULTIPLE_CHOICES", 301 => "MOVED_PERMANENTLY", 302 => "FOUND", 303 => "SEE_OTHER", 304 => "NOT_MODIFIED", 305 => "USE_PROXY", 307 => "TEMPORARY_REDIRECT", 400 => "BAD_REQUEST", 401 => "UNAUTHORIZED", 402 => "PAYMENT_REQUIRED", 403 => "FORBIDDEN", 404 => "NOT_FOUND", 405 => "METHOD_NOT_ALLOWED", 406 => "NOT_ACCEPTABLE", 407 => "PROXY_AUTHENTICATION", 408 => "REQUEST_TIMEOUT", 409 => "CONFLICT", 410 => "GONE", 411 => "LENGTH_REQUIRED", 412 => "PRECONDITION_FAILED", 413 => "REQUEST_ENTITY_TOO_LARGE", 414 => "REQUEST_URI_TOO_LONG", 415 => "UNSUPPORTED_MEDIA_TYPE", 416 => "REQUESTED_RANGE_NOT_SATISFIED", 417 => "EXPECTATION_FAILED", 422 => "UNPROCESSABLE_ENTITY", 423 => "LOCKED", 424 => "FAILED_DEPENDENCY", 500 => "INTERNAL_SERVER_ERROR", 501 => "NOT_IMPLEMENTED", 502 => "BAD_GATEWAY", 503 => "SERVICE_UNAVAILABLE", 504 => "GATEWAY_TIMEOUT", 506 => "INSUFFICIENT_STORAGE"}
|
67
|
+
VALID_VALUES = Set.new([CONT, SWITCHING_PROTOCOLS, OK, CREATED, ACCEPTED, NON_AUTHORITATIVE_INFORMATION, NO_CONTENT, RESET_CONTENT, PARTIAL_CONTENT, MULTI_STATUS, MULTIPLE_CHOICES, MOVED_PERMANENTLY, FOUND, SEE_OTHER, NOT_MODIFIED, USE_PROXY, TEMPORARY_REDIRECT, BAD_REQUEST, UNAUTHORIZED, PAYMENT_REQUIRED, FORBIDDEN, NOT_FOUND, METHOD_NOT_ALLOWED, NOT_ACCEPTABLE, PROXY_AUTHENTICATION, REQUEST_TIMEOUT, CONFLICT, GONE, LENGTH_REQUIRED, PRECONDITION_FAILED, REQUEST_ENTITY_TOO_LARGE, REQUEST_URI_TOO_LONG, UNSUPPORTED_MEDIA_TYPE, REQUESTED_RANGE_NOT_SATISFIED, EXPECTATION_FAILED, UNPROCESSABLE_ENTITY, LOCKED, FAILED_DEPENDENCY, INTERNAL_SERVER_ERROR, NOT_IMPLEMENTED, BAD_GATEWAY, SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, INSUFFICIENT_STORAGE]).freeze
|
68
|
+
end
|
69
|
+
|
70
|
+
class RestRequest
|
71
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
72
|
+
METHOD = 1
|
73
|
+
URI = 2
|
74
|
+
PARAMETERS = 3
|
75
|
+
HEADERS = 4
|
76
|
+
BODY = 5
|
77
|
+
|
78
|
+
FIELDS = {
|
79
|
+
METHOD => {:type => ::Thrift::Types::I32, :name => 'method', :enum_class => ::ElasticSearchThrift::Method},
|
80
|
+
URI => {:type => ::Thrift::Types::STRING, :name => 'uri'},
|
81
|
+
PARAMETERS => {:type => ::Thrift::Types::MAP, :name => 'parameters', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}, :optional => true},
|
82
|
+
HEADERS => {:type => ::Thrift::Types::MAP, :name => 'headers', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}, :optional => true},
|
83
|
+
BODY => {:type => ::Thrift::Types::STRING, :name => 'body', :binary => true, :optional => true}
|
84
|
+
}
|
85
|
+
|
86
|
+
def struct_fields; FIELDS; end
|
87
|
+
|
88
|
+
def validate
|
89
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field method is unset!') unless @method
|
90
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field uri is unset!') unless @uri
|
91
|
+
unless @method.nil? || ::ElasticSearchThrift::Method::VALID_VALUES.include?(@method)
|
92
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field method!')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
::Thrift::Struct.generate_accessors self
|
97
|
+
end
|
98
|
+
|
99
|
+
class RestResponse
|
100
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
101
|
+
STATUS = 1
|
102
|
+
HEADERS = 2
|
103
|
+
BODY = 3
|
104
|
+
|
105
|
+
FIELDS = {
|
106
|
+
STATUS => {:type => ::Thrift::Types::I32, :name => 'status', :enum_class => ::ElasticSearchThrift::Status},
|
107
|
+
HEADERS => {:type => ::Thrift::Types::MAP, :name => 'headers', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}, :optional => true},
|
108
|
+
BODY => {:type => ::Thrift::Types::STRING, :name => 'body', :binary => true, :optional => true}
|
109
|
+
}
|
110
|
+
|
111
|
+
def struct_fields; FIELDS; end
|
112
|
+
|
113
|
+
def validate
|
114
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field status is unset!') unless @status
|
115
|
+
unless @status.nil? || ::ElasticSearchThrift::Status::VALID_VALUES.include?(@status)
|
116
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field status!')
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
::Thrift::Struct.generate_accessors self
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Require just the parts of the thrift library that we need.
|
2
|
+
#
|
3
|
+
# The thrift.rb in the thrift gem loads all sorts of stuff we don't use, and
|
4
|
+
# depends on thin. This is brittle, but seems the lesser evil.
|
5
|
+
|
6
|
+
require 'thrift/bytes'
|
7
|
+
require 'thrift/core_ext'
|
8
|
+
require 'thrift/exceptions'
|
9
|
+
require 'thrift/types'
|
10
|
+
require 'thrift/processor'
|
11
|
+
require 'thrift/client'
|
12
|
+
require 'thrift/struct'
|
13
|
+
require 'thrift/union'
|
14
|
+
require 'thrift/struct_union'
|
15
|
+
|
16
|
+
# serializer
|
17
|
+
require 'thrift/serializer/serializer'
|
18
|
+
require 'thrift/serializer/deserializer'
|
19
|
+
|
20
|
+
# protocol
|
21
|
+
require 'thrift/protocol/base_protocol'
|
22
|
+
require 'thrift/protocol/binary_protocol'
|
23
|
+
require 'thrift/protocol/binary_protocol_accelerated'
|
24
|
+
require 'thrift/protocol/compact_protocol'
|
25
|
+
require 'thrift/protocol/json_protocol'
|
26
|
+
|
27
|
+
# transport
|
28
|
+
require 'thrift/transport/base_transport'
|
29
|
+
require 'thrift/transport/base_server_transport'
|
30
|
+
require 'thrift/transport/socket'
|
31
|
+
require 'thrift/transport/server_socket'
|
32
|
+
require 'thrift/transport/unix_socket'
|
33
|
+
require 'thrift/transport/unix_server_socket'
|
34
|
+
require 'thrift/transport/buffered_transport'
|
35
|
+
require 'thrift/transport/framed_transport'
|
36
|
+
require 'thrift/transport/http_client_transport'
|
37
|
+
require 'thrift/transport/io_stream_transport'
|
38
|
+
require 'thrift/transport/memory_buffer_transport'
|
39
|
+
|
40
|
+
require 'thrift/thrift_native'
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift Compiler (0.9.0)
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'elastic_search_thrift/mini_thrift'
|
8
|
+
require 'elastic_search_thrift/elasticsearch_types'
|
9
|
+
|
10
|
+
module ElasticSearchThrift
|
11
|
+
module Rest
|
12
|
+
class Client
|
13
|
+
include ::Thrift::Client
|
14
|
+
|
15
|
+
def execute(request)
|
16
|
+
send_execute(request)
|
17
|
+
return recv_execute()
|
18
|
+
end
|
19
|
+
|
20
|
+
def send_execute(request)
|
21
|
+
send_message('execute', Execute_args, :request => request)
|
22
|
+
end
|
23
|
+
|
24
|
+
def recv_execute()
|
25
|
+
result = receive_message(Execute_result)
|
26
|
+
return result.success unless result.success.nil?
|
27
|
+
raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'execute failed: unknown result')
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
class Processor
|
33
|
+
include ::Thrift::Processor
|
34
|
+
|
35
|
+
def process_execute(seqid, iprot, oprot)
|
36
|
+
args = read_args(iprot, Execute_args)
|
37
|
+
result = Execute_result.new()
|
38
|
+
result.success = @handler.execute(args.request)
|
39
|
+
write_result(result, oprot, 'execute', seqid)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
# HELPER FUNCTIONS AND STRUCTURES
|
45
|
+
|
46
|
+
class Execute_args
|
47
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
48
|
+
REQUEST = 1
|
49
|
+
|
50
|
+
FIELDS = {
|
51
|
+
REQUEST => {:type => ::Thrift::Types::STRUCT, :name => 'request', :class => ::ElasticSearchThrift::RestRequest}
|
52
|
+
}
|
53
|
+
|
54
|
+
def struct_fields; FIELDS; end
|
55
|
+
|
56
|
+
def validate
|
57
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field request is unset!') unless @request
|
58
|
+
end
|
59
|
+
|
60
|
+
::Thrift::Struct.generate_accessors self
|
61
|
+
end
|
62
|
+
|
63
|
+
class Execute_result
|
64
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
65
|
+
SUCCESS = 0
|
66
|
+
|
67
|
+
FIELDS = {
|
68
|
+
SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::ElasticSearchThrift::RestResponse}
|
69
|
+
}
|
70
|
+
|
71
|
+
def struct_fields; FIELDS; end
|
72
|
+
|
73
|
+
def validate
|
74
|
+
end
|
75
|
+
|
76
|
+
::Thrift::Struct.generate_accessors self
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'tire'
|
2
|
+
require 'cgi'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module ElasticSearchThrift
|
6
|
+
class TireClient
|
7
|
+
def self.install
|
8
|
+
Tire::Configuration.client(new)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@client = ElasticSearchThrift.client
|
13
|
+
@client.open
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :client
|
17
|
+
|
18
|
+
def get(url, data = {})
|
19
|
+
execute :get, url, data
|
20
|
+
end
|
21
|
+
|
22
|
+
def post(url, data)
|
23
|
+
execute :post, url, data
|
24
|
+
end
|
25
|
+
|
26
|
+
def put(url, data)
|
27
|
+
execute :put, url, data
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete(url)
|
31
|
+
execute :delete, url, nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def head(url)
|
35
|
+
execute :head, url, nil
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def execute(method, url, data)
|
41
|
+
path, params = parse_url(url)
|
42
|
+
path.chomp!('/')
|
43
|
+
response = client.send(method, path, params, normalize_data(data))
|
44
|
+
Tire::HTTP::Response.new(response.body, response.status, response.headers)
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_url(url)
|
48
|
+
uri = URI.parse(url)
|
49
|
+
|
50
|
+
params = {}
|
51
|
+
if uri.query
|
52
|
+
uri.query.split('&').each do |pair|
|
53
|
+
key, value = pair.split('=', 2)
|
54
|
+
params[CGI.unescape(key)] = CGI.unescape(value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
[uri.path, params]
|
59
|
+
end
|
60
|
+
|
61
|
+
def normalize_data(data)
|
62
|
+
if data.is_a?(String)
|
63
|
+
data =~ /\S/ ? JSON.parse(data) : {}
|
64
|
+
else
|
65
|
+
data || {}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/test/config.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe ElasticSearchThrift::Client do
|
4
|
+
let(:client) { make_client }
|
5
|
+
|
6
|
+
it "executes requests and returns the response" do
|
7
|
+
with_thrift_client do |client|
|
8
|
+
response = client.request(ElasticSearchThrift::Method::GET, '/', {})
|
9
|
+
response.status.must_equal 200
|
10
|
+
response.headers.must_be_nil
|
11
|
+
response.data['version'].wont_be_nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "performs GET, POST, PUT, and DELETE requests properly" do
|
16
|
+
with_http_client do |http|
|
17
|
+
with_thrift_client do |thrift|
|
18
|
+
thrift.put("/#{INDEX}")
|
19
|
+
|
20
|
+
status = JSON.parse(http.get("/#{INDEX}/_status").body)
|
21
|
+
status['indices'].keys.must_include INDEX
|
22
|
+
|
23
|
+
thrift.post("/#{INDEX}/thing", {'refresh' => 'true'}, {name: 'a'})
|
24
|
+
|
25
|
+
response = thrift.get("/#{INDEX}/thing/_search")
|
26
|
+
response.data['hits']['total'].must_equal 1
|
27
|
+
|
28
|
+
id = response.data['hits']['hits'][0]['_id']
|
29
|
+
thrift.delete("/#{INDEX}/thing/#{id}", {'refresh' => 'true'})
|
30
|
+
|
31
|
+
response = thrift.get("/#{INDEX}/thing/_search")
|
32
|
+
response.data['hits']['total'].must_equal 0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
ElasticSearchThrift::TireClient.install
|
4
|
+
|
5
|
+
describe ElasticSearchThrift::TireClient do
|
6
|
+
let(:client) { ElasticSearchThrift::TireClient.new }
|
7
|
+
|
8
|
+
def parse(json)
|
9
|
+
JSON.parse(json)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "executes requests and returns the response" do
|
13
|
+
response = client.get('/', {})
|
14
|
+
parse(response.body)['status'].must_equal 200
|
15
|
+
parse(response.body)['version'].wont_be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "performs GET, POST, PUT, and DELETE requests properly" do
|
19
|
+
base_url = "http://#{CONFIG['host']}:#{CONFIG['port']}"
|
20
|
+
with_http_client do |http|
|
21
|
+
client.put("#{base_url}/#{INDEX}", {})
|
22
|
+
status = JSON.parse(http.get("/#{INDEX}/_status").body)
|
23
|
+
status['indices'].keys.must_include INDEX
|
24
|
+
|
25
|
+
client.post("#{base_url}/#{INDEX}/thing?refresh=true", {name: 'a'})
|
26
|
+
response = client.get("#{base_url}/#{INDEX}/thing/_search")
|
27
|
+
parse(response.body)['hits']['total'].must_equal 1
|
28
|
+
|
29
|
+
id = parse(response.body)['hits']['hits'][0]['_id']
|
30
|
+
client.delete("#{base_url}/#{INDEX}/thing/#{id}?refresh=true")
|
31
|
+
response = client.get("#{base_url}/#{INDEX}/thing/_search")
|
32
|
+
parse(response.body)['hits']['total'].must_equal 0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "integrates correctly into the Tire DSL" do
|
37
|
+
with_http_client do |http|
|
38
|
+
index = Tire::Index.new(INDEX)
|
39
|
+
index.create.success?.must_equal true
|
40
|
+
status = JSON.parse(http.get("/#{INDEX}/_status").body)
|
41
|
+
status['indices'].keys.must_include INDEX
|
42
|
+
|
43
|
+
index.store(_type: 'thing', name: 'a')
|
44
|
+
index.refresh
|
45
|
+
response = client.get("/#{INDEX}/thing/_search")
|
46
|
+
parse(response.body)['hits']['total'].must_equal 1
|
47
|
+
|
48
|
+
id = parse(response.body)['hits']['hits'][0]['_id']
|
49
|
+
index.remove(_type: 'thing', id: id)
|
50
|
+
index.refresh
|
51
|
+
|
52
|
+
response = client.get("/#{INDEX}/thing/_search")
|
53
|
+
parse(response.body)['hits']['total'].must_equal 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
ROOT = File.expand_path('..', File.dirname(__FILE__))
|
2
|
+
$:.unshift "#{ROOT}/lib"
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'yaml'
|
6
|
+
require 'net/http'
|
7
|
+
require 'elastic_search_thrift'
|
8
|
+
|
9
|
+
require RUBY_VERSION < '2' ? 'debugger' : 'byebug'
|
10
|
+
|
11
|
+
CONFIG = YAML.load_file("#{ROOT}/test/config.yml")
|
12
|
+
INDEX = CONFIG.delete('index') || 'elastic_search_thrift'
|
13
|
+
ElasticSearchThrift.configure(CONFIG)
|
14
|
+
|
15
|
+
MiniTest::Spec.class_eval do
|
16
|
+
def with_thrift_client(&block)
|
17
|
+
client = ElasticSearchThrift::Client.new(host: CONFIG['host'], port: CONFIG['thrift_port'])
|
18
|
+
client.open(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_http_client
|
22
|
+
http = Net::HTTP.new(CONFIG['host'], CONFIG['http_port'])
|
23
|
+
http.start do
|
24
|
+
begin
|
25
|
+
yield http
|
26
|
+
ensure
|
27
|
+
http.delete("/#{INDEX}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: elastic_search_thrift
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- George Ogata
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thrift
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.6.0
|
38
|
+
- - <
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.9.0
|
41
|
+
type: :runtime
|
42
|
+
prerelease: false
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.6.0
|
49
|
+
- - <
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 1.9.0
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: bundler
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
type: :development
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
description: Thrift client for ElasticSearch
|
69
|
+
email:
|
70
|
+
- george.ogata@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- .gitignore
|
76
|
+
- CHANGELOG
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE
|
79
|
+
- README.markdown
|
80
|
+
- Rakefile
|
81
|
+
- config/elasticsearch.thrift
|
82
|
+
- elastic_search_thrift.gemspec
|
83
|
+
- lib/elastic_search_thrift.rb
|
84
|
+
- lib/elastic_search_thrift/client.rb
|
85
|
+
- lib/elastic_search_thrift/elasticsearch_constants.rb
|
86
|
+
- lib/elastic_search_thrift/elasticsearch_types.rb
|
87
|
+
- lib/elastic_search_thrift/mini_thrift.rb
|
88
|
+
- lib/elastic_search_thrift/rest.rb
|
89
|
+
- lib/elastic_search_thrift/thrift_extensions.rb
|
90
|
+
- lib/elastic_search_thrift/tire_client.rb
|
91
|
+
- lib/elastic_search_thrift/version.rb
|
92
|
+
- test/config.yml
|
93
|
+
- test/elastic_search_thrift/test_client.rb
|
94
|
+
- test/elastic_search_thrift/test_tire_client.rb
|
95
|
+
- test/test_helper.rb
|
96
|
+
homepage: https://github.com/howaboutwe/elastic_search_thrift
|
97
|
+
licenses: []
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.8.25
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: Thrift client for ElasticSearch
|
120
|
+
test_files:
|
121
|
+
- test/config.yml
|
122
|
+
- test/elastic_search_thrift/test_client.rb
|
123
|
+
- test/elastic_search_thrift/test_tire_client.rb
|
124
|
+
- test/test_helper.rb
|
125
|
+
has_rdoc:
|