elasticsearch-api 7.3.0 → 7.5.0

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.
Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +16 -23
  3. data/elasticsearch-api.gemspec +1 -1
  4. data/lib/elasticsearch/api/actions/abort_benchmark.rb +1 -2
  5. data/lib/elasticsearch/api/actions/benchmark.rb +2 -3
  6. data/lib/elasticsearch/api/actions/bulk.rb +35 -68
  7. data/lib/elasticsearch/api/actions/cat/aliases.rb +30 -52
  8. data/lib/elasticsearch/api/actions/cat/allocation.rb +36 -50
  9. data/lib/elasticsearch/api/actions/cat/count.rb +25 -46
  10. data/lib/elasticsearch/api/actions/cat/fielddata.rb +31 -33
  11. data/lib/elasticsearch/api/actions/cat/health.rb +27 -37
  12. data/lib/elasticsearch/api/actions/cat/help.rb +14 -10
  13. data/lib/elasticsearch/api/actions/cat/indices.rb +45 -62
  14. data/lib/elasticsearch/api/actions/cat/master.rb +24 -34
  15. data/lib/elasticsearch/api/actions/cat/nodeattrs.rb +20 -16
  16. data/lib/elasticsearch/api/actions/cat/nodes.rb +34 -46
  17. data/lib/elasticsearch/api/actions/cat/params_registry.rb +0 -1
  18. data/lib/elasticsearch/api/actions/cat/pending_tasks.rb +29 -35
  19. data/lib/elasticsearch/api/actions/cat/plugins.rb +21 -18
  20. data/lib/elasticsearch/api/actions/cat/recovery.rb +40 -56
  21. data/lib/elasticsearch/api/actions/cat/repositories.rb +21 -24
  22. data/lib/elasticsearch/api/actions/cat/segments.rb +29 -22
  23. data/lib/elasticsearch/api/actions/cat/shards.rb +38 -59
  24. data/lib/elasticsearch/api/actions/cat/snapshots.rb +32 -27
  25. data/lib/elasticsearch/api/actions/cat/tasks.rb +25 -19
  26. data/lib/elasticsearch/api/actions/cat/templates.rb +26 -18
  27. data/lib/elasticsearch/api/actions/cat/thread_pool.rb +36 -46
  28. data/lib/elasticsearch/api/actions/clear_scroll.rb +21 -8
  29. data/lib/elasticsearch/api/actions/cluster/allocation_explain.rb +15 -13
  30. data/lib/elasticsearch/api/actions/cluster/get_settings.rb +18 -18
  31. data/lib/elasticsearch/api/actions/cluster/health.rb +42 -44
  32. data/lib/elasticsearch/api/actions/cluster/params_registry.rb +0 -1
  33. data/lib/elasticsearch/api/actions/cluster/pending_tasks.rb +15 -17
  34. data/lib/elasticsearch/api/actions/cluster/put_settings.rb +20 -17
  35. data/lib/elasticsearch/api/actions/cluster/remote_info.rb +8 -6
  36. data/lib/elasticsearch/api/actions/cluster/reroute.rb +25 -37
  37. data/lib/elasticsearch/api/actions/cluster/state.rb +37 -41
  38. data/lib/elasticsearch/api/actions/cluster/stats.rb +20 -12
  39. data/lib/elasticsearch/api/actions/count.rb +52 -39
  40. data/lib/elasticsearch/api/actions/create.rb +25 -26
  41. data/lib/elasticsearch/api/actions/delete.rb +43 -36
  42. data/lib/elasticsearch/api/actions/delete_by_query.rb +74 -62
  43. data/lib/elasticsearch/api/actions/delete_by_query_rethrottle.rb +39 -0
  44. data/lib/elasticsearch/api/actions/delete_by_rethrottle.rb +4 -3
  45. data/lib/elasticsearch/api/actions/delete_script.rb +19 -13
  46. data/lib/elasticsearch/api/actions/exists.rb +44 -34
  47. data/lib/elasticsearch/api/actions/exists_source.rb +43 -25
  48. data/lib/elasticsearch/api/actions/explain.rb +46 -51
  49. data/lib/elasticsearch/api/actions/field_caps.rb +27 -20
  50. data/lib/elasticsearch/api/actions/get.rb +42 -41
  51. data/lib/elasticsearch/api/actions/get_script.rb +19 -14
  52. data/lib/elasticsearch/api/actions/get_source.rb +38 -44
  53. data/lib/elasticsearch/api/actions/index.rb +60 -89
  54. data/lib/elasticsearch/api/actions/indices/analyze.rb +19 -48
  55. data/lib/elasticsearch/api/actions/indices/clear_cache.rb +29 -41
  56. data/lib/elasticsearch/api/actions/indices/clone.rb +50 -0
  57. data/lib/elasticsearch/api/actions/indices/close.rb +28 -32
  58. data/lib/elasticsearch/api/actions/indices/create.rb +22 -70
  59. data/lib/elasticsearch/api/actions/indices/delete.rb +23 -35
  60. data/lib/elasticsearch/api/actions/indices/delete_alias.rb +24 -20
  61. data/lib/elasticsearch/api/actions/indices/delete_template.rb +18 -20
  62. data/lib/elasticsearch/api/actions/indices/exists.rb +32 -34
  63. data/lib/elasticsearch/api/actions/indices/exists_alias.rb +33 -29
  64. data/lib/elasticsearch/api/actions/indices/exists_template.rb +21 -16
  65. data/lib/elasticsearch/api/actions/indices/exists_type.rb +29 -29
  66. data/lib/elasticsearch/api/actions/indices/flush.rb +28 -28
  67. data/lib/elasticsearch/api/actions/indices/flush_synced.rb +23 -12
  68. data/lib/elasticsearch/api/actions/indices/forcemerge.rb +26 -41
  69. data/lib/elasticsearch/api/actions/indices/freeze.rb +7 -8
  70. data/lib/elasticsearch/api/actions/indices/get.rb +25 -19
  71. data/lib/elasticsearch/api/actions/indices/get_alias.rb +31 -23
  72. data/lib/elasticsearch/api/actions/indices/get_field_mapping.rb +42 -38
  73. data/lib/elasticsearch/api/actions/indices/get_mapping.rb +39 -31
  74. data/lib/elasticsearch/api/actions/indices/get_settings.rb +34 -37
  75. data/lib/elasticsearch/api/actions/indices/get_template.rb +21 -23
  76. data/lib/elasticsearch/api/actions/indices/get_upgrade.rb +48 -0
  77. data/lib/elasticsearch/api/actions/indices/open.rb +24 -21
  78. data/lib/elasticsearch/api/actions/indices/params_registry.rb +0 -1
  79. data/lib/elasticsearch/api/actions/indices/put_alias.rb +25 -27
  80. data/lib/elasticsearch/api/actions/indices/put_mapping.rb +40 -39
  81. data/lib/elasticsearch/api/actions/indices/put_settings.rb +30 -37
  82. data/lib/elasticsearch/api/actions/indices/put_template.rb +23 -23
  83. data/lib/elasticsearch/api/actions/indices/recovery.rb +20 -23
  84. data/lib/elasticsearch/api/actions/indices/refresh.rb +22 -26
  85. data/lib/elasticsearch/api/actions/indices/rollover.rb +28 -19
  86. data/lib/elasticsearch/api/actions/indices/segments.rb +24 -17
  87. data/lib/elasticsearch/api/actions/indices/shard_stores.rb +27 -15
  88. data/lib/elasticsearch/api/actions/indices/shrink.rb +23 -17
  89. data/lib/elasticsearch/api/actions/indices/split.rb +23 -17
  90. data/lib/elasticsearch/api/actions/indices/stats.rb +53 -104
  91. data/lib/elasticsearch/api/actions/indices/unfreeze.rb +7 -7
  92. data/lib/elasticsearch/api/actions/indices/update_aliases.rb +15 -32
  93. data/lib/elasticsearch/api/actions/indices/upgrade.rb +26 -16
  94. data/lib/elasticsearch/api/actions/indices/validate_query.rb +46 -59
  95. data/lib/elasticsearch/api/actions/info.rb +9 -6
  96. data/lib/elasticsearch/api/actions/ingest/delete_pipeline.rb +18 -12
  97. data/lib/elasticsearch/api/actions/ingest/get_pipeline.rb +21 -11
  98. data/lib/elasticsearch/api/actions/ingest/params_registry.rb +0 -1
  99. data/lib/elasticsearch/api/actions/ingest/processor_grok.rb +12 -13
  100. data/lib/elasticsearch/api/actions/ingest/put_pipeline.rb +19 -14
  101. data/lib/elasticsearch/api/actions/ingest/simulate.rb +23 -13
  102. data/lib/elasticsearch/api/actions/mget.rb +37 -44
  103. data/lib/elasticsearch/api/actions/msearch.rb +54 -54
  104. data/lib/elasticsearch/api/actions/msearch_template.rb +46 -35
  105. data/lib/elasticsearch/api/actions/mtermvectors.rb +39 -35
  106. data/lib/elasticsearch/api/actions/nodes/hot_threads.rb +30 -25
  107. data/lib/elasticsearch/api/actions/nodes/info.rb +29 -63
  108. data/lib/elasticsearch/api/actions/nodes/params_registry.rb +0 -1
  109. data/lib/elasticsearch/api/actions/nodes/reload_secure_settings.rb +24 -22
  110. data/lib/elasticsearch/api/actions/nodes/shutdown.rb +4 -4
  111. data/lib/elasticsearch/api/actions/nodes/stats.rb +43 -36
  112. data/lib/elasticsearch/api/actions/nodes/usage.rb +31 -10
  113. data/lib/elasticsearch/api/actions/params_registry.rb +0 -1
  114. data/lib/elasticsearch/api/actions/ping.rb +12 -13
  115. data/lib/elasticsearch/api/actions/put_script.rb +26 -30
  116. data/lib/elasticsearch/api/actions/rank_eval.rb +24 -15
  117. data/lib/elasticsearch/api/actions/reindex.rb +25 -48
  118. data/lib/elasticsearch/api/actions/reindex_rethrottle.rb +18 -12
  119. data/lib/elasticsearch/api/actions/remote/info.rb +1 -2
  120. data/lib/elasticsearch/api/actions/render_search_template.rb +17 -15
  121. data/lib/elasticsearch/api/actions/scripts_painless_execute.rb +8 -6
  122. data/lib/elasticsearch/api/actions/scroll.rb +28 -51
  123. data/lib/elasticsearch/api/actions/search.rb +104 -165
  124. data/lib/elasticsearch/api/actions/search_shards.rb +31 -28
  125. data/lib/elasticsearch/api/actions/search_template.rb +48 -40
  126. data/lib/elasticsearch/api/actions/snapshot/cleanup_repository.rb +44 -0
  127. data/lib/elasticsearch/api/actions/snapshot/create.rb +22 -29
  128. data/lib/elasticsearch/api/actions/snapshot/create_repository.rb +19 -24
  129. data/lib/elasticsearch/api/actions/snapshot/delete.rb +20 -22
  130. data/lib/elasticsearch/api/actions/snapshot/delete_repository.rb +16 -18
  131. data/lib/elasticsearch/api/actions/snapshot/get.rb +22 -31
  132. data/lib/elasticsearch/api/actions/snapshot/get_repository.rb +21 -25
  133. data/lib/elasticsearch/api/actions/snapshot/params_registry.rb +0 -1
  134. data/lib/elasticsearch/api/actions/snapshot/restore.rb +21 -32
  135. data/lib/elasticsearch/api/actions/snapshot/status.rb +23 -24
  136. data/lib/elasticsearch/api/actions/snapshot/verify_repository.rb +18 -13
  137. data/lib/elasticsearch/api/actions/tasks/cancel.rb +19 -13
  138. data/lib/elasticsearch/api/actions/tasks/get.rb +16 -13
  139. data/lib/elasticsearch/api/actions/tasks/list.rb +20 -18
  140. data/lib/elasticsearch/api/actions/tasks/params_registry.rb +0 -1
  141. data/lib/elasticsearch/api/actions/termvectors.rb +52 -70
  142. data/lib/elasticsearch/api/actions/update.rb +53 -98
  143. data/lib/elasticsearch/api/actions/update_by_query.rb +77 -66
  144. data/lib/elasticsearch/api/actions/update_by_query_rethrottle.rb +17 -11
  145. data/lib/elasticsearch/api/version.rb +1 -1
  146. data/spec/elasticsearch/api/actions/cat/segments_spec.rb +9 -11
  147. data/spec/elasticsearch/api/actions/cluster/put_settings_spec.rb +1 -1
  148. data/spec/elasticsearch/api/actions/count_spec.rb +8 -8
  149. data/spec/elasticsearch/api/actions/delete_by_query_spec.rb +12 -7
  150. data/spec/elasticsearch/api/actions/delete_script_spec.rb +0 -14
  151. data/spec/elasticsearch/api/actions/exists_document_spec.rb +1 -1
  152. data/spec/elasticsearch/api/actions/get_document_source_spec.rb +1 -1
  153. data/spec/elasticsearch/api/actions/index_document_spec.rb +6 -15
  154. data/spec/elasticsearch/api/actions/indices/analyze_spec.rb +0 -4
  155. data/spec/elasticsearch/api/actions/indices/clear_cache_spec.rb +1 -5
  156. data/spec/elasticsearch/api/actions/indices/clone_spec.rb +109 -0
  157. data/spec/elasticsearch/api/actions/indices/delete_alias_spec.rb +2 -2
  158. data/spec/elasticsearch/api/actions/indices/get_spec.rb +0 -11
  159. data/spec/elasticsearch/api/actions/indices/put_alias_spec.rb +3 -3
  160. data/spec/elasticsearch/api/actions/indices/put_mapping_spec.rb +3 -3
  161. data/spec/elasticsearch/api/actions/indices/stats_spec.rb +0 -1
  162. data/spec/elasticsearch/api/actions/nodes/hot_threads_spec.rb +3 -3
  163. data/spec/elasticsearch/api/actions/put_script_spec.rb +20 -15
  164. data/spec/elasticsearch/api/actions/render_search_template_spec.rb +23 -7
  165. data/spec/elasticsearch/api/actions/scroll_spec.rb +37 -0
  166. data/spec/elasticsearch/api/actions/search_spec.rb +0 -15
  167. data/spec/elasticsearch/api/actions/tasks/list_spec.rb +0 -11
  168. data/spec/elasticsearch/api/actions/update_document_spec.rb +3 -7
  169. data/spec/elasticsearch/api/rest_api_yaml_spec.rb +1 -1
  170. data/spec/rest_yaml_tests_helper.rb +12 -0
  171. data/utils/Gemfile +1 -0
  172. data/utils/Thorfile +0 -1
  173. data/utils/thor/generate_source.rb +192 -85
  174. data/utils/thor/generator/endpoint_specifics.rb +157 -0
  175. data/utils/thor/generator/files_helper.rb +37 -0
  176. data/utils/thor/lister.rb +3 -4
  177. data/utils/thor/templates/_documentation_top.erb +27 -0
  178. data/utils/thor/templates/_method_setup.erb +35 -0
  179. data/utils/thor/templates/_params_registry.erb +12 -0
  180. data/utils/thor/templates/_perform_request.erb +37 -0
  181. data/utils/thor/templates/method.erb +59 -0
  182. data/utils/thor/templates/{ruby/test.erb → test.erb} +0 -0
  183. data/utils/thor/templates/{ruby/test_helper.rb → test_helper.rb} +0 -0
  184. metadata +31 -14
  185. data/spec/elasticsearch/api/actions/scoll_spec.rb +0 -21
  186. data/utils/thor/generate_api.rb +0 -193
  187. data/utils/thor/templates/ruby/method.erb +0 -62
@@ -53,16 +53,12 @@ describe 'client#update' do
53
53
  'foo/bar/1/_update'
54
54
  end
55
55
 
56
- let(:params) do
57
- { version: 100 }
58
- end
59
-
60
56
  let(:body) do
61
57
  {}
62
58
  end
63
59
 
64
60
  it 'performs the request' do
65
- expect(client_double.update(index: 'foo', type: 'bar', id: '1', version: 100, body: {}))
61
+ expect(client_double.update(index: 'foo', type: 'bar', id: '1', body: {}))
66
62
  end
67
63
  end
68
64
 
@@ -98,14 +94,14 @@ describe 'client#update' do
98
94
 
99
95
  it 'raises it to the user' do
100
96
  expect {
101
- client.update(index: 'foo', type: 'bar', id: 'XXX')
97
+ client.update(index: 'foo', type: 'bar', id: 'XXX', body: {})
102
98
  }.to raise_exception(NotFound)
103
99
  end
104
100
 
105
101
  context 'when the :ignore parameter is specified' do
106
102
 
107
103
  it 'does not raise the error to the user' do
108
- expect(client.update(index: 'foo', type: 'bar', id: 'XXX', ignore: 404)).to eq(false)
104
+ expect(client.update(index: 'foo', type: 'bar', id: 'XXX', body: {}, ignore: 404)).to eq(false)
109
105
  end
110
106
  end
111
107
  end
@@ -18,7 +18,7 @@ describe 'Rest API YAML tests' do
18
18
  context "#{test.description}" do
19
19
 
20
20
  if test.skip_test?(ADMIN_CLIENT)
21
- skip 'Test contains feature(s) not yet support or version is not satisfied'
21
+ skip 'Test contains feature(s) not yet supported or version is not satisfied'
22
22
 
23
23
  else
24
24
 
@@ -72,6 +72,18 @@ skipped_tests << { file: 'delete/70_mix_typeless_typeful.yml',
72
72
  skipped_tests << { file: 'cat.templates/10_basic.yml',
73
73
  description: '*' }
74
74
 
75
+ # node_selector is not supported yet
76
+ skipped_tests << { file: 'cat.aliases/10_basic.yml',
77
+ description: '*' }
78
+
79
+ # Responses are there but not equal (eg.: yellow status)
80
+ skipped_tests << { file: 'cluster.health/10_basic.yml',
81
+ description: 'cluster health with closed index (pre 7.2.0)' }
82
+
83
+ # Regular expression not catching exact match:
84
+ skipped_tests << { file: 'cat.indices/10_basic.yml',
85
+ description: 'Test cat indices output for closed index (pre 7.2.0)' }
86
+
75
87
  SKIPPED_TESTS = skipped_tests
76
88
 
77
89
  # The directory of rest api YAML files.
data/utils/Gemfile CHANGED
@@ -11,3 +11,4 @@ gem 'multi_json'
11
11
  gem 'thor'
12
12
  gem 'json'
13
13
  gem 'pry'
14
+ gem 'rubocop'
data/utils/Thorfile CHANGED
@@ -2,6 +2,5 @@
2
2
  # Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3
3
  # See the LICENSE file in the project root for more information
4
4
 
5
- require File.expand_path('./thor/generate_api')
6
5
  require File.expand_path('./thor/generate_source')
7
6
  require File.expand_path('./thor/lister')
@@ -5,138 +5,245 @@
5
5
  # encoding: UTF-8
6
6
 
7
7
  require 'thor'
8
-
9
8
  require 'pathname'
10
9
  require 'active_support/core_ext/hash/deep_merge'
11
10
  require 'active_support/inflector'
12
11
  require 'multi_json'
13
12
  require 'coderay'
14
13
  require 'pry'
14
+ require_relative 'generator/files_helper'
15
+ require_relative 'generator/endpoint_specifics'
15
16
 
16
17
  module Elasticsearch
17
-
18
18
  module API
19
-
20
19
  # A command line application based on [Thor](https://github.com/wycats/thor),
21
20
  # which will read the JSON API spec file(s), and generate
22
21
  # the Ruby source code (one file per API endpoint) with correct
23
22
  # module namespace, method names, and RDoc documentation,
24
23
  # as well as test files for each endpoint.
25
24
  #
26
- # Currently it only generates Ruby source, but can easily be
27
- # extended and adapted to generate source code for other
28
- # programming languages.
25
+ # Specific exceptions and code snippets that need to be included are written
26
+ # in EndpointSpecifics (generator/endpoint_specifics) and the module is included
27
+ # here.
29
28
  #
30
29
  class SourceGenerator < Thor
31
30
  namespace 'api:code'
32
-
33
31
  include Thor::Actions
32
+ include EndpointSpecifics
34
33
 
35
- __root = Pathname( File.expand_path('../../..', __FILE__) )
36
-
37
- desc "generate", "Generate source code and tests from the REST API JSON specification"
38
- method_option :language, default: 'ruby', desc: 'Programming language'
39
- method_option :force, type: :boolean, default: false, desc: 'Overwrite the output'
40
- method_option :verbose, type: :boolean, default: false, desc: 'Output more information'
41
- method_option :input, default: File.expand_path('../../../../tmp/elasticsearch/rest-api-spec/api/**/*.json', __FILE__), desc: 'Path to directory with JSON API specs'
42
- method_option :output, default: File.expand_path('../../../tmp/out', __FILE__), desc: 'Path to output directory'
43
-
44
- def generate(*files)
45
- self.class.source_root File.expand_path('../', __FILE__)
46
-
47
- @input = Pathname(options[:input])
48
- @output = Pathname(options[:output])
34
+ __root = Pathname(File.expand_path('../../..', __FILE__))
49
35
 
50
- # -- Test helper
51
- copy_file "templates/ruby/test_helper.rb", @output.join('test').join('test_helper.rb') if options[:language] == 'ruby'
36
+ desc 'generate', 'Generate source code and tests from the REST API JSON specification'
37
+ method_option :verbose, type: :boolean, default: false, desc: 'Output more information'
38
+ method_option :tests, type: :boolean, default: false, desc: 'Generate test files'
39
+ method_option :xpack, type: :boolean, default: false, desc: 'Generate X-Pack'
52
40
 
53
- files = Dir.entries(@input.to_s).reject { |f| f.start_with?('.') || f.start_with?('_') }
41
+ def generate
42
+ self.class.source_root File.expand_path(__dir__)
43
+ @xpack = options[:xpack]
54
44
 
55
- files.each do |filepath|
56
- file = @input.join(filepath)
45
+ @input = FilesHelper.input_dir(@xpack)
46
+ @output = FilesHelper.output_dir(@xpack)
57
47
 
58
- @path = Pathname(file)
59
- @json = MultiJson.load( File.read(@path) )
60
- @spec = @json.values.first
48
+ FilesHelper.files(@xpack).each do |filepath|
49
+ @path = Pathname(@input.join(filepath))
50
+ @json = MultiJson.load(File.read(@path))
51
+ @spec = @json.values.first
61
52
  say_status 'json', @path, :yellow
62
53
 
63
54
  @spec['url'] ||= {}
64
- @spec['url']['parts'] ||= []
65
- @spec['url']['params'] ||= {}
66
55
 
67
- # say_status 'JSON', @spec.inspect, options[:verbose]
68
-
69
- @full_namespace = @json.keys.first.split('.')
70
- @namespace_depth = @full_namespace.size > 0 ? @full_namespace.size-1 : 0
56
+ @endpoint_name = @json.keys.first
57
+ @full_namespace = __full_namespace
58
+ @namespace_depth = @full_namespace.size > 0 ? @full_namespace.size - 1 : 0
71
59
  @module_namespace = @full_namespace[0, @namespace_depth]
72
60
  @method_name = @full_namespace.last
73
- @http_method = "Elasticsearch::API::HTTP_#{@spec['methods'].first}"
74
- @http_path = unless @spec['url']['parts'].empty?
75
- @spec['url']['path']
76
- .split('/')
77
- .compact
78
- .reject { |p| p =~ /^\s*$/ }
79
- .map { |p| p =~ /\{/ ? "\#\{arguments[:#{p.tr('{}', '')}]\}" : p }
80
- .join('/')
81
- .gsub(/^\//, '')
82
- else
83
- @spec['url']['path'].gsub(/^\//, '')
84
- end
85
-
86
- # -- Ruby files
87
-
88
- @path_to_file = @output.join('api').join( @module_namespace.join('/') ).join("#{@method_name}.rb")
89
-
90
- empty_directory @output.join('api').join( @module_namespace.join('/') )
91
-
92
- template "templates/#{options[:language]}/method.erb", @path_to_file
93
-
94
- if options[:verbose]
95
- colorized_output = CodeRay.scan_file(@path_to_file, :ruby).terminal
96
- lines = colorized_output.split("\n")
97
- say_status options[:language].downcase,
98
- lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n"),
99
- :yellow
100
- end
61
+ @parts = __endpoint_parts
62
+ @params = @spec['params'] || {}
63
+ @specific_params = specific_params(@module_namespace.first) # See EndpointSpecifics
64
+ @http_method = __http_method
65
+ @paths = @spec['url']['paths'].map { |b| b['path'] }
66
+ # Using Ruby's safe operator on array:
67
+ @deprecation_note = @spec['url']['paths'].last&.[]('deprecated')
68
+ @http_path = __http_path
69
+ @required_parts = __required_parts
101
70
 
102
- # --- Test files
71
+ @module_namespace.shift if @module_namespace.first == 'xpack'
72
+ @path_to_file = @output.join(@module_namespace.join('/')).join("#{@method_name}.rb")
73
+ dir = @output.join(@module_namespace.join('/'))
74
+ empty_directory(dir, verbose: false)
103
75
 
104
- @test_directory = @output.join('test/api').join( @module_namespace.join('/') )
105
- @test_file = @test_directory.join("#{@method_name}_test.rb")
76
+ # Write the file with the ERB template:
77
+ template('templates/method.erb', @path_to_file, force: true)
106
78
 
107
- empty_directory @test_directory
108
- template "templates/#{options[:language]}/test.erb", @test_file
79
+ print_source_code(@path_to_file) if options[:verbose]
109
80
 
110
- if options[:verbose]
111
- colorized_output = colorized_output = CodeRay.scan_file(@test_file, :ruby).terminal
112
- lines = colorized_output.split("\n")
113
- say_status options[:language].downcase,
114
- lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n"),
115
- :yellow
116
- say '▬'*terminal_width
117
- end
81
+ generate_tests if options[:tests]
82
+
83
+ puts
118
84
  end
119
85
 
120
- # -- Tree output
86
+ run_rubocop
121
87
 
122
- if options[:verbose] && `which tree > /dev/null 2>&1; echo $?`.to_i < 1
123
- lines = `tree #{@output}`.split("\n")
124
- say_status 'tree',
125
- lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n")
126
- end
88
+ # -- Tree output
89
+ print_tree if options[:verbose]
127
90
  end
128
91
 
129
92
  private
130
93
 
94
+ def __full_namespace
95
+ names = @endpoint_name.split('.')
96
+ if @xpack
97
+ names = (names.first == 'xpack' ? names : ['xpack', names].flatten)
98
+ # Return an array with 'ml' renamed to 'machine_learning' and 'ilm' to
99
+ # 'index_lifecycle_management'
100
+ names.map do |name|
101
+ name
102
+ .gsub(/^ml$/, 'machine_learning')
103
+ .gsub(/^ilm$/, 'index_lifecycle_management')
104
+ end
105
+ else
106
+ names
107
+ end
108
+ end
109
+
131
110
  # Create the hierarchy of directories based on API namespaces
132
111
  #
133
112
  def __create_directories(key, value)
134
- unless value['documentation']
135
- empty_directory @output.join(key)
136
- create_directory_hierarchy *value.to_a.first
113
+ return if value['documentation']
114
+
115
+ empty_directory @output.join(key)
116
+ create_directory_hierarchy * value.to_a.first
117
+ end
118
+
119
+ # Extract parts from each path
120
+ #
121
+ def __endpoint_parts
122
+ parts = @spec['url']['paths'].select do |a|
123
+ a.keys.include?('parts')
124
+ end.map do |path|
125
+ path&.[]('parts')
126
+ end
127
+ (parts.inject(&:merge) || [])
128
+ end
129
+
130
+ def __http_method
131
+ case @endpoint_name
132
+ when 'index'
133
+ '_id ? Elasticsearch::API::HTTP_PUT : Elasticsearch::API::HTTP_POST'
134
+ when 'count'
135
+ <<~SRC
136
+ if arguments[:body]
137
+ Elasticsearch::API::HTTP_POST
138
+ else
139
+ Elasticsearch::API::HTTP_GET
140
+ end
141
+ SRC
142
+ else
143
+ "Elasticsearch::API::HTTP_#{@spec['url']['paths'].map { |a| a['methods'] }.flatten.first}"
144
+ end
145
+ end
146
+
147
+ def __http_path
148
+ return "\"#{__parse_path(@paths.first)}\"" if @paths.size == 1
149
+ return termvectors_path if @method_name == 'termvectors'
150
+
151
+ result = ''
152
+ anchor_string = ''
153
+ @paths.sort { |a, b| b.length <=> a.length }.each_with_index do |path, i|
154
+ var_string = __extract_path_variables(path).map { |var| "_#{var}" }.join(' && ')
155
+ next if anchor_string == var_string
156
+
157
+ anchor_string = var_string
158
+ result += if i.zero?
159
+ "if #{var_string}\n"
160
+ elsif (i == @paths.size - 1) || var_string.empty?
161
+ "else\n"
162
+ else
163
+ "elsif #{var_string}\n"
164
+ end
165
+ result += "\"#{__parse_path(path)}\"\n"
137
166
  end
167
+ result += 'end'
168
+ result
169
+ end
170
+
171
+ def __parse_path(path)
172
+ path.gsub(/^\//, '')
173
+ .gsub(/\/$/, '')
174
+ .gsub('{', "\#{#{__utils}.__listify(_")
175
+ .gsub('}', ')}')
176
+ end
177
+
178
+ def __path_variables
179
+ @paths.map do |path|
180
+ __extract_path_variables(path)
181
+ end
182
+ end
183
+
184
+ # extract values that are in the {var} format:
185
+ def __extract_path_variables(path)
186
+ path.scan(/{(\w+)}/).flatten
187
+ end
188
+
189
+ # Find parts that are definitely required and should raise an error if
190
+ # they're not present
191
+ #
192
+ def __required_parts
193
+ required = []
194
+ return required if @endpoint_name == 'tasks.get'
195
+
196
+ required << 'body' if (@spec['body'] && @spec['body']['required'])
197
+ # Get required variables from paths:
198
+ req_variables = __path_variables.inject(:&) # find intersection
199
+ required << req_variables unless req_variables.empty?
200
+ required.flatten
138
201
  end
139
202
 
203
+ def docs_helper(name, info)
204
+ info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings'
205
+ tipo = info['type'] ? info['type'].capitalize : 'String'
206
+ description = info['description'] ? info['description'].strip : '[TODO]'
207
+ options = info['options'] ? "\n # (options: #{info['options'].join(', '.strip)})\n" : ''
208
+ required = info['required'] ? ' (*Required*)' : ''
209
+ deprecated = info['deprecated'] ? ' *Deprecated*' : ''
210
+ "# @option arguments [#{tipo}] :#{name} #{description} #{required} #{deprecated} #{options}\n"
211
+ end
212
+
213
+ def generate_tests
214
+ copy_file 'templates/test_helper.rb', @output.join('test').join('test_helper.rb')
215
+
216
+ @test_directory = @output.join('test/api').join(@module_namespace.join('/'))
217
+ @test_file = @test_directory.join("#{@method_name}_test.rb")
218
+
219
+ empty_directory @test_directory
220
+ template 'templates/test.erb', @test_file
221
+
222
+ print_source_code(@test_file) if options[:verbose]
223
+ end
224
+
225
+ def print_source_code(path_to_file)
226
+ colorized_output = CodeRay.scan_file(path_to_file, :ruby).terminal
227
+ lines = colorized_output.split("\n")
228
+ formatted = lines.first + "\n" + lines[1, lines.size].map { |l| ' ' * 14 + l }.join("\n")
229
+
230
+ say_status('ruby', formatted, :yellow)
231
+ end
232
+
233
+ def print_tree
234
+ return unless `which tree > /dev/null 2>&1; echo $?`.to_i < 1
235
+
236
+ lines = `tree #{@output}`.split("\n")
237
+ say_status('tree', lines.first + "\n" + lines[1, lines.size].map { |l| ' ' * 14 + l }.join("\n"))
238
+ end
239
+
240
+ def __utils
241
+ @xpack ? 'Elasticsearch::API::Utils' : 'Utils'
242
+ end
243
+
244
+ def run_rubocop
245
+ system("rubocop --format autogenconf -x #{FilesHelper::output_dir(@xpack)}")
246
+ end
140
247
  end
141
248
  end
142
249
  end
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to Elasticsearch B.V under one or more agreements.
4
+ # Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
5
+ # See the LICENSE file in the project root for more information
6
+
7
+ module Elasticsearch
8
+ module API
9
+ # Handles specific exceptional parameters and code snippets that need to be
10
+ # included in the generated code. This module is included in SourceGenerator
11
+ # so its methods can be used from the ERB template (method.erb). This will
12
+ # potentially be refactored into different templates.
13
+ module EndpointSpecifics
14
+ # Endpoints that need Utils.__rescue_from_not_found
15
+ IGNORE_404 = %w[
16
+ exists
17
+ indices.exists
18
+ indices.exists_alias
19
+ indices.exists_template
20
+ indices.exists_type
21
+ ].freeze
22
+
23
+ # Endpoints that need Utils.__rescue_from_not_found if the ignore
24
+ # parameter is included
25
+ COMPLEX_IGNORE_404 = %w[
26
+ delete
27
+ get
28
+ indices.flush_synced
29
+ indices.delete_template
30
+ indices.delete
31
+ security.get_role
32
+ security.get_user
33
+ snapshot.status
34
+ snapshot.get
35
+ snapshot.get_repository
36
+ snapshot.delete_repository
37
+ snapshot.delete
38
+ update
39
+ watcher.delete_watch
40
+ ].freeze
41
+
42
+ # Endpoints that need params[:h] listified
43
+ H_PARAMS = %w[aliases allocation count health indices nodes pending_tasks
44
+ recovery shards thread_pool].freeze
45
+
46
+ # Function that adds the listified h param code
47
+ def specific_params(namespace)
48
+ params = []
49
+ if H_PARAMS.include?(@method_name) && namespace == 'cat'
50
+ if @method_name == 'nodes'
51
+ params << 'params[:h] = Utils.__listify(params[:h], escape: false) if params[:h]'
52
+ else
53
+ params << 'params[:h] = Utils.__listify(params[:h]) if params[:h]'
54
+ end
55
+ end
56
+ params
57
+ end
58
+
59
+ def needs_ignore_404?(endpoint)
60
+ IGNORE_404.include? endpoint
61
+ end
62
+
63
+ def needs_complex_ignore_404?(endpoint)
64
+ COMPLEX_IGNORE_404.include? endpoint
65
+ end
66
+
67
+ def termvectors_path
68
+ <<~SRC
69
+ if _index && _type && _id
70
+ "\#{Utils.__listify(_index)}/\#{Utils.__listify(_type)}/\#{Utils.__listify(_id)}/\#{endpoint}"
71
+ elsif _index && _type
72
+ "\#{Utils.__listify(_index)}/\#{Utils.__listify(_type)}/\#{endpoint}"
73
+ elsif _index && _id
74
+ "\#{Utils.__listify(_index)}/\#{endpoint}/\#{Utils.__listify(_id)}"
75
+ else
76
+ "\#{Utils.__listify(_index)}/\#{endpoint}"
77
+ end
78
+ SRC
79
+ end
80
+
81
+ def ping_perform_request
82
+ <<~SRC
83
+ begin
84
+ perform_request(method, path, params, body).status == 200 ? true : false
85
+ rescue Exception => e
86
+ if e.class.to_s =~ /NotFound|ConnectionFailed/ || e.message =~ /Not\s*Found|404|ConnectionFailed/i
87
+ false
88
+ else
89
+ raise e
90
+ end
91
+ end
92
+ SRC
93
+ end
94
+
95
+ def indices_stats_params_registry
96
+ <<~SRC
97
+ ParamsRegistry.register(:stats_params, [
98
+ #{@spec['params'].keys.map { |k| ":#{k}" }.join(",\n")}
99
+ ].freeze)
100
+
101
+ ParamsRegistry.register(:stats_parts, [
102
+ #{@parts['metric']['options'].push('metric').map { |k| ":#{k}" }.join(",\n")}
103
+ ].freeze)
104
+ SRC
105
+ end
106
+
107
+ def msearch_body_helper
108
+ <<~SRC
109
+ case
110
+ when body.is_a?(Array) && body.any? { |d| d.has_key? :search }
111
+ payload = body.
112
+ inject([]) do |sum, item|
113
+ meta = item
114
+ data = meta.delete(:search)
115
+
116
+ sum << meta
117
+ sum << data
118
+ sum
119
+ end.
120
+ map { |item| Elasticsearch::API.serializer.dump(item) }
121
+ payload << "" unless payload.empty?
122
+ payload = payload.join("\n")
123
+ when body.is_a?(Array)
124
+ payload = body.map { |d| d.is_a?(String) ? d : Elasticsearch::API.serializer.dump(d) }
125
+ payload << "" unless payload.empty?
126
+ payload = payload.join("\n")
127
+ else
128
+ payload = body
129
+ end
130
+ SRC
131
+ end
132
+
133
+ def msearch_template_body_helper
134
+ <<~SRC
135
+ case
136
+ when body.is_a?(Array)
137
+ payload = body.map { |d| d.is_a?(String) ? d : Elasticsearch::API.serializer.dump(d) }
138
+ payload << "" unless payload.empty?
139
+ payload = payload.join("\n")
140
+ else
141
+ payload = body
142
+ end
143
+ SRC
144
+ end
145
+
146
+ def bulk_body_helper
147
+ <<~SRC
148
+ if body.is_a? Array
149
+ payload = Utils.__bulkify(body)
150
+ else
151
+ payload = body
152
+ end
153
+ SRC
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,37 @@
1
+ require 'pathname'
2
+
3
+ module Elasticsearch
4
+ module API
5
+ module FilesHelper
6
+ OSS_SRC_PATH = '../../../../../tmp/elasticsearch/rest-api-spec/src/main/resources/rest-api-spec/api/'.freeze
7
+ OSS_OUTPUT_DIR = '../../elasticsearch-api/lib/elasticsearch/api/actions'.freeze
8
+
9
+ XPACK_SRC_PATH = '../../../../../tmp/elasticsearch/x-pack/plugin/src/test/resources/rest-api-spec/api'.freeze
10
+ XPACK_OUTPUT_DIR = '../../elasticsearch-xpack/lib/elasticsearch/xpack/api/actions'.freeze
11
+
12
+ # Path to directory with JSON API specs
13
+ def self.input_dir(xpack = false)
14
+ input_dir = if xpack
15
+ File.expand_path(XPACK_SRC_PATH, __FILE__)
16
+ else
17
+ File.expand_path(OSS_SRC_PATH, __FILE__)
18
+ end
19
+ Pathname(input_dir)
20
+ end
21
+
22
+ # Path to directory to copy generated files
23
+ def self.output_dir(xpack = false)
24
+ xpack ? Pathname(XPACK_OUTPUT_DIR) : Pathname(OSS_OUTPUT_DIR)
25
+ end
26
+
27
+ # Only get JSON files and remove hidden files
28
+ def self.files(xpack = false)
29
+ Dir.entries(input_dir(xpack).to_s).reject do |f|
30
+ f.start_with?('.') ||
31
+ f.start_with?('_') ||
32
+ File.extname(f) != '.json'
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
data/utils/thor/lister.rb CHANGED
@@ -9,16 +9,16 @@ require 'thor'
9
9
  require 'pathname'
10
10
 
11
11
  module Elasticsearch
12
-
13
12
  module API
14
-
15
13
  class Lister < Thor
16
14
  namespace 'api'
17
15
 
16
+ DEFAULT_PATH = '../../tmp/elasticsearch/rest-api-spec/src/main/resources/rest-api-spec/api/'.freeze
17
+
18
18
  desc "list <PATH DIRECTORY WITH JSON SPEC FILES>", "List all the REST API endpoints from the JSON specification"
19
19
  method_option :verbose, type: :boolean, default: false, desc: 'Output more information'
20
20
  method_option :format, default: 'text', desc: 'Output format (text, json)'
21
- def list(directory)
21
+ def list(directory = DEFAULT_PATH)
22
22
  input = Pathname(directory).join('*.json')
23
23
  apis = Dir[input.to_s].map do |f|
24
24
  File.basename(f, '.json')
@@ -40,6 +40,5 @@ module Elasticsearch
40
40
  end
41
41
  end
42
42
  end
43
-
44
43
  end
45
44
  end
@@ -0,0 +1,27 @@
1
+ <%- if @spec['documentation']['description'] -%>
2
+ <%= ' '*(@namespace_depth+3) %># <%= @spec['documentation']['description'].gsub("\n", "\n#{' '*(@namespace_depth+3)}# ") -%>
3
+ <%- else %>
4
+ <%= ' '*(@namespace_depth+3) %># TODO: Description
5
+ <%- end %>
6
+ <%= ' '*(@namespace_depth+3) %>#
7
+ <%- unless @parts.nil? || @parts.empty? %><%# URL parts -%>
8
+ <%- @parts.each do |name, info| -%>
9
+ <%= docs_helper(name, info) -%>
10
+ <%- end -%>
11
+ <%- end -%><%# Body -%>
12
+ <%# URL parameters -%>
13
+ <%- @params.each do |name, info| -%>
14
+ <%= docs_helper(name, info) -%>
15
+ <%- end %>
16
+ <%= ' '*(@namespace_depth+3) + '# @option arguments [Hash] :body ' + (@spec['body']['description'] ? @spec['body']['description'].strip : 'TODO: Description') + (@spec['body']['required'] ? ' (*Required*)' : '') + "\n" if @spec['body'] -%>
17
+ <% if @deprecation_note -%>
18
+ #
19
+ # *Deprecation notice*:
20
+ # <%= @deprecation_note['description'] %>
21
+ # Deprecated since version <%= @deprecation_note['version'] %>
22
+ #
23
+ <% end -%>
24
+ <%= ' '*(@namespace_depth+3) -%>#
25
+ <%# Documentation link -%>
26
+ <%= ' '*(@namespace_depth+3) %># @see <%= @spec['documentation']['url'] ? @spec['documentation']['url'].gsub!(/\/(current|master)\//, '/7.5/') : "[TODO]" %>
27
+ <%= ' '*(@namespace_depth+3) %>#