elastic_search_thrift 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ == 0.0.1 2013-12-11
2
+
3
+ * Hi.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+ gemspec
3
+
4
+ gem "byebug", platform: :ruby_20
5
+ gem 'debugger', '~> 1.6.0', platform: :ruby_19
6
+ gem 'ritual', '~> 0.4.0'
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,9 @@
1
+ module ElasticSearchThrift
2
+ module ResponseMixin
3
+ def data
4
+ @data ||= JSON.parse(body)
5
+ end
6
+ end
7
+
8
+ RestResponse.send :include, ResponseMixin
9
+ 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
@@ -0,0 +1,11 @@
1
+ module ElasticSearchThrift
2
+ VERSION = [0, 0, 1]
3
+
4
+ class << VERSION
5
+ include Comparable
6
+
7
+ def to_s
8
+ join('.')
9
+ end
10
+ end
11
+ end
data/test/config.yml ADDED
@@ -0,0 +1,4 @@
1
+ host: 127.0.0.1
2
+ thrift_port: 9500
3
+ http_port: 9200
4
+ index: elastic_search_thrift
@@ -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
@@ -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: