iij-dag-client 1.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.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +13 -0
  4. data/LICENSE.txt +174 -0
  5. data/Rakefile +43 -0
  6. data/config/settings.yml +11 -0
  7. data/iij-dag-client.gemspec +31 -0
  8. data/lib/dag.rb +33 -0
  9. data/lib/dag/client.rb +36 -0
  10. data/lib/dag/client/api.rb +295 -0
  11. data/lib/dag/client/api/cluster.rb +111 -0
  12. data/lib/dag/client/api/database.rb +58 -0
  13. data/lib/dag/client/api/job.rb +116 -0
  14. data/lib/dag/client/api/list_params.rb +36 -0
  15. data/lib/dag/client/api/rest_parameter.rb +149 -0
  16. data/lib/dag/client/api/storage.rb +354 -0
  17. data/lib/dag/client/api/storage_result.rb +52 -0
  18. data/lib/dag/client/api/table.rb +131 -0
  19. data/lib/dag/client/cluster.rb +26 -0
  20. data/lib/dag/client/cluster_validation.rb +59 -0
  21. data/lib/dag/client/database.rb +79 -0
  22. data/lib/dag/client/exception.rb +43 -0
  23. data/lib/dag/client/job.rb +56 -0
  24. data/lib/dag/client/job_validation.rb +22 -0
  25. data/lib/dag/client/model.rb +9 -0
  26. data/lib/dag/client/model/bucket.rb +20 -0
  27. data/lib/dag/client/model/bucket_collection.rb +34 -0
  28. data/lib/dag/client/model/cluster.rb +100 -0
  29. data/lib/dag/client/model/cluster_collection.rb +76 -0
  30. data/lib/dag/client/model/database.rb +34 -0
  31. data/lib/dag/client/model/database_collection.rb +51 -0
  32. data/lib/dag/client/model/job.rb +125 -0
  33. data/lib/dag/client/model/job_collection.rb +114 -0
  34. data/lib/dag/client/model/object.rb +56 -0
  35. data/lib/dag/client/model/object_collection.rb +64 -0
  36. data/lib/dag/client/model/table.rb +55 -0
  37. data/lib/dag/client/model/table_collection.rb +60 -0
  38. data/lib/dag/client/storage.rb +41 -0
  39. data/lib/dag/client/table.rb +16 -0
  40. data/lib/dag/client/version.rb +5 -0
  41. data/lib/dag/settings.rb +9 -0
  42. metadata +210 -0
@@ -0,0 +1,111 @@
1
+ module Dag
2
+ class Client::API
3
+ module Cluster
4
+ include Dag::Client::API::ListParams
5
+ include Dag::Client::ClusterValidation
6
+
7
+ def cluster_info_list(options = {})
8
+ resource = '/v1/'
9
+ query_params = list_params(options)
10
+ status = options[:status]
11
+ if status
12
+ statuses = status.split(',')
13
+ if statuses.any? { |s| !valid_cluster_info_list_status?(s) }
14
+ raise Dag::Client::ParameterInvalid.new("status is invalid: #{status}")
15
+ end
16
+ query_params = query_params.merge('status' => status)
17
+ end
18
+
19
+ type = options[:type]
20
+ if type
21
+ query_params = query_params.merge('type' => type)
22
+ end
23
+
24
+ cluster_name = options[:cluster_name]
25
+ if cluster_name
26
+ query_params = query_params.merge('clusterName' => cluster_name)
27
+ end
28
+
29
+ order = options[:order]
30
+ if order
31
+ unless ['asc', 'desc'].include?(order)
32
+ raise Dag::Client::ParameterInvalid.new("order is invalid: #{order}")
33
+ end
34
+ query_params = query_params.merge('order' => order)
35
+ end
36
+
37
+ execute(RestParameter.new(:get, resource, cano_resource: 'clusterManagement', query_params: query_params ))
38
+ end
39
+
40
+ def cluster_info(cluster_name)
41
+ resource = "/v1/#{cluster_name}"
42
+ execute(RestParameter.new(:get, resource, cano_resource: 'clusterManagement'))
43
+ end
44
+
45
+ def cluster_restart(cluster_name, params = {})
46
+ resource = "/v1/#{cluster_name}"
47
+ parameters = {}
48
+ force = params[:force]
49
+ unless force.nil?
50
+ unless [TrueClass, FalseClass].any? { |c| force.kind_of?(c) }
51
+ raise Dag::Client::ParameterInvalid.new("force is invalid: #{force}")
52
+ end
53
+ parameters.merge!('force' => force)
54
+ end
55
+
56
+ type = params[:type]
57
+ if type.present?
58
+ parameters.merge!('type' => type)
59
+ end
60
+
61
+ debug = params[:debug]
62
+ unless debug.nil?
63
+ unless [TrueClass, FalseClass].any? { |c| debug.kind_of?(c) }
64
+ raise Dag::Client::ParameterInvalid.new("debug is invalid: #{debug}")
65
+ end
66
+
67
+ parameters.merge!('debug' => debug)
68
+ end
69
+
70
+ execute(RestParameter.new(:put, resource,
71
+ cano_resource: 'clusterManagement',
72
+ content_type: 'application/json',
73
+ parameters: parameters,
74
+ blank_body: true
75
+ ))
76
+ end
77
+
78
+ def statistics(cluster_name, options = {})
79
+ resource = "/v1/#{cluster_name}/statistics"
80
+ execute(RestParameter.new(:get, resource, cano_resource: 'clusterManagement'))
81
+ end
82
+
83
+ def cluster_export_log(cluster_name, params = {})
84
+ parameters = {}
85
+
86
+ output_log_path = params[:output_log_path]
87
+ raise Dag::Client::ParameterInvalid.new('output_log_path is blank') if output_log_path.blank?
88
+
89
+ unless output_log_path.start_with?('dag://')
90
+ raise Dag::Client::ParameterInvalid.new("output_log_path should start with 'dag://'")
91
+ end
92
+ unless output_log_path.end_with?('/')
93
+ raise Dag::Client::ParameterInvalid.new("output_log_path should end with '/'")
94
+ end
95
+
96
+ parameters = parameters.merge('outputLogPath' => output_log_path)
97
+
98
+ compress = params[:compress]
99
+ unless compress.nil?
100
+ unless [TrueClass, FalseClass].any? { |c| compress.kind_of?(c) }
101
+ raise Dag::Client::ParameterInvalid.new("compress is invalid: #{compress}")
102
+ end
103
+
104
+ parameters = parameters.merge(compress: params[:compress])
105
+ end
106
+ resource = "/v1/#{cluster_name}/log"
107
+ execute(RestParameter.new(:put, resource, cano_resource: 'clusterManagement', content_type: 'application/json', parameters: parameters))
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,58 @@
1
+ module Dag
2
+ class Client::API
3
+ module Database
4
+ include Dag::Client::API::ListParams
5
+
6
+ def database_list(cluster_name, options = {})
7
+ resource = "/v1/#{cluster_name}"
8
+ execute(RestParameter.new(:get, resource, cano_resource: 'database', query_params: list_params(options)))
9
+ end
10
+
11
+ def create_database(cluster_name, db_name)
12
+ raise Dag::Client::ParameterInvalid.new('cluster_name is blank') if cluster_name.blank?
13
+ raise Dag::Client::ParameterInvalid.new('db_name is blank') if db_name.blank?
14
+
15
+ if db_name.length < 3
16
+ raise Dag::Client::ParameterInvalid.new("db name is too short")
17
+ end
18
+
19
+ if db_name.length > 63
20
+ raise Dag::Client::ParameterInvalid.new("db name is too long")
21
+ end
22
+
23
+ if db_name !~ /\A[a-z0-9]+\Z/
24
+ raise Dag::Client::ParameterInvalid.new("db name is invalid")
25
+ end
26
+
27
+ if hive_reserved_word?(db_name)
28
+ raise Dag::Client::ParameterInvalid.new("db name is reserved by hive")
29
+ end
30
+
31
+ execute(RestParameter.new(:put, "/v1/#{cluster_name}/#{db_name}", content_type: 'application/json', cano_resource: "database"))
32
+ end
33
+
34
+ def delete_database(cluster_name, db_name)
35
+ execute(RestParameter.new(:delete, "/v1/#{cluster_name}/#{db_name}", content_type: 'application/json', cano_resource: "database"))
36
+ end
37
+
38
+ private
39
+
40
+ def hive_reserved_word?(word)
41
+ %w(
42
+ true false all and or not like asc desc order by group where
43
+ from as select distinct insert overwrite outer join left right
44
+ full on partition partitions table tables tblproperties show msck
45
+ directory local locks transform using cluster distribute sort union load
46
+ data inpath is null create external alter describe drop reanme to
47
+ comment boolean tinyint smallint int bigint float double date
48
+ datetime timestamp string binary array map reduce partitioned
49
+ clustered sorted into buckets row format delimited fields terminated
50
+ collection items keys lines stored sequencefile textfile inputformat
51
+ outputformat location tablesample bucket out of cast add replace
52
+ columns rlike regexp temporary function explain extended serde with
53
+ serdeproperties limit set tblproperties
54
+ ).include?(word)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,116 @@
1
+ module Dag
2
+ class Client::API
3
+ module Job
4
+ include Dag::Client::API::ListParams
5
+
6
+ def query_info_list(options = {})
7
+ resource = "/v1/"
8
+ query_params = list_params(options)
9
+
10
+ status = options[:status]
11
+ if status
12
+ statuses = status.split(',')
13
+ if statuses.any? { |s| !['running', 'finished', 'canceled', 'error'].include?(s) }
14
+ raise Dag::Client::ParameterInvalid.new("status is invalid: #{status}")
15
+ end
16
+ query_params = query_params.merge('status' => status)
17
+ end
18
+
19
+ type = options[:type]
20
+ if type
21
+ unless ['select', 'split'].include?(type.to_s)
22
+ raise Dag::Client::ParameterInvalid.new("type is invalid: #{type}")
23
+ end
24
+ query_params = query_params.merge('type' => type)
25
+ end
26
+
27
+ cluster_name = options[:cluster_name]
28
+ if cluster_name
29
+ query_params = query_params.merge('clusterName' => cluster_name)
30
+ end
31
+
32
+ label_prefix = options[:label_prefix]
33
+ if label_prefix
34
+ query_params = query_params.merge('labelPrefix' => label_prefix)
35
+ end
36
+
37
+ cluster_rebooted = options[:cluster_rebooted]
38
+ unless cluster_rebooted.nil?
39
+ unless [TrueClass, FalseClass].any? { |c| cluster_rebooted.kind_of?(c) }
40
+ raise Dag::Client::ParameterInvalid.new("cluster_rebooted is invalid: #{cluster_rebooted}")
41
+ end
42
+ query_params = query_params.merge('clusterRebooted' => cluster_rebooted)
43
+ end
44
+
45
+ order = options[:order]
46
+ if order
47
+ unless ['asc', 'desc'].include?(order)
48
+ raise Dag::Client::ParameterInvalid.new("order is invalid: #{order}")
49
+ end
50
+ query_params = query_params.merge('order' => order)
51
+ end
52
+
53
+ execute(RestParameter.new(:get, resource, cano_resource: 'query', query_params: query_params))
54
+ end
55
+
56
+ def query_info(job_id)
57
+ resource = "/v1/#{job_id}"
58
+ execute(RestParameter.new(:get, resource, cano_resource: 'query'))
59
+ end
60
+
61
+ def query_log(job_id)
62
+ resource = "/v1/#{job_id}/log"
63
+ log_info = execute(RestParameter.new(:get, resource, cano_resource: 'query'))
64
+
65
+ if log_info.present?
66
+ io = StringIO.new('', 'r+')
67
+ log_info['log'].each_line do |line|
68
+ io.puts line unless line.include?('CLIService')
69
+ end
70
+ return { "log" => io.string }
71
+ end
72
+
73
+ log_info
74
+ end
75
+
76
+ def query_cancel(job_id)
77
+ resource = "/v1/#{job_id}"
78
+ execute(RestParameter.new(:delete, resource, cano_resource: 'query', content_type: 'application/json'))
79
+ end
80
+
81
+ def query(query: '', output_format: 'csv', output_resource_path: '', cluster_name: '', label: '')
82
+ raise Dag::Client::ParameterInvalid.new('query is blank') if query.blank?
83
+
84
+ raise Dag::Client::ParameterInvalid.new('query should start with SELECT') if query !~ /\ASELECT/i
85
+ raise Dag::Client::ParameterInvalid.new('query should not include OVERWRITE') if query =~ /OVERWRITE/i
86
+
87
+ if output_format && !['csv', 'tsv'].include?(output_format)
88
+ raise Dag::Client::ParameterInvalid.new('ouput_format should be csv or tsv')
89
+ end
90
+
91
+ raise Dag::Client::ParameterInvalid.new('output_resource_path is blank') if output_resource_path.blank?
92
+
93
+ unless output_resource_path.start_with?('dag://')
94
+ raise Dag::Client::ParameterInvalid.new("output_resource_path should start with 'dag://'")
95
+ end
96
+ unless output_resource_path.end_with?('/')
97
+ raise Dag::Client::ParameterInvalid.new("output_resource_path should end with '/'")
98
+ end
99
+
100
+ raise Dag::Client::ParameterInvalid.new('cluster_name is blank') if cluster_name.blank?
101
+
102
+
103
+ parameters = {
104
+ 'outputFormat' => output_format || 'csv',
105
+ 'outputResourcePath' => output_resource_path,
106
+ 'query' => query,
107
+ 'clusterName' => cluster_name,
108
+ 'label' => label,
109
+ }
110
+
111
+ resource = "/v1/"
112
+ execute(RestParameter.new(:post, resource, cano_resource: 'select', content_type: 'application/json', parameters: parameters))
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,36 @@
1
+ module Dag
2
+ class Client::API
3
+ module ListParams
4
+ def list_params(options)
5
+ params = {}
6
+
7
+ max = options[:max]
8
+
9
+ if max.present?
10
+ unless max.kind_of?(Integer)
11
+ raise Dag::Client::ParameterInvalid.new("max should be integer")
12
+ end
13
+
14
+ if max < 1
15
+ raise Dag::Client::ParameterInvalid.new("max should be greater than 0:#{max}")
16
+ end
17
+
18
+ if max > 100
19
+ raise Dag::Client::ParameterInvalid.new("max should be less than 100 or equal to 100:#{max}")
20
+ end
21
+
22
+ params.merge!('max' => max)
23
+ end
24
+
25
+ marker = options[:marker]
26
+
27
+
28
+ if marker.present?
29
+ params.merge!('marker' => marker)
30
+ end
31
+
32
+ params
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,149 @@
1
+ module Dag
2
+ class Client::API
3
+ class RestParameter
4
+
5
+ def initialize(method, resource, cano_resource: nil, query_params: {},
6
+ parameters: {}, bucket: '', content_type: nil, import: false,
7
+ raw_data: false, blank_body: false, headers: {}, multipart: false)
8
+
9
+ @method = method
10
+ @resource = resource
11
+ @cano_resource = cano_resource
12
+ @query_params = query_params
13
+ @parameters = parameters
14
+ @bucket = bucket
15
+ @content_type = content_type
16
+ @import = import
17
+ @raw_data = raw_data
18
+ @blank_body = blank_body
19
+ @headers = headers
20
+ @multipart = multipart
21
+ end
22
+
23
+ attr_reader :method
24
+ attr_reader :resource
25
+ attr_reader :cano_resource
26
+ attr_reader :query_params
27
+ attr_reader :parameters
28
+ attr_reader :bucket
29
+ attr_reader :content_type
30
+ attr_reader :headers
31
+
32
+ def url(uri, force_path_style = false)
33
+ url = uri.host
34
+ url += ":#{uri.port}" unless uri.port == 80 || uri.port == 443
35
+
36
+ if @bucket.present?
37
+ if force_path_style
38
+ url += '/' unless url.end_with? "/"
39
+ url += @bucket
40
+ else
41
+ url = [@bucket, url].join('.')
42
+ url += '/' unless url.end_with? "/"
43
+ end
44
+ end
45
+
46
+ if @bucket.blank? || @resource != '/'
47
+ url = File.join(url, @resource)
48
+ end
49
+
50
+ url += '/' if url.split('/').last == @bucket
51
+ url += '?' if @cano_resource.present? || @query_params.present?
52
+ url += @cano_resource if @cano_resource
53
+ url += '&' if @cano_resource.present? && @query_params.present?
54
+ url += "#{@query_params.to_param}" if @query_params.present?
55
+
56
+ uri.scheme + '://' + url
57
+ end
58
+
59
+ def http_verb
60
+ @method.to_s.upcase
61
+ end
62
+
63
+ def signature_content_type
64
+ result = ""
65
+ if @content_type.present?
66
+ result << @content_type
67
+ end
68
+
69
+ result << "\n"
70
+
71
+ result
72
+ end
73
+
74
+ def authentication(apikey, secret, force_path_style)
75
+
76
+ "IIJGIO" + " " + apikey + ":" + signature(secret, force_path_style)
77
+ end
78
+
79
+ def signature(secret, force_path_style = false)
80
+ http_verb = "#{self.http_verb}\n"
81
+ content_md5 = "\n"
82
+ content_type = signature_content_type
83
+ date = "#{calc_date}\n"
84
+
85
+ canonicalized_iijgio_headers = ""
86
+
87
+ string_to_sign = http_verb + content_md5 + content_type + date +
88
+ canonicalized_iijgio_headers + canonicalized_resource(force_path_style)
89
+
90
+ digest = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), secret, string_to_sign)
91
+ Base64.encode64(digest).strip
92
+ end
93
+
94
+ def canonicalized_resource(force_path_style = false)
95
+ result = ''
96
+
97
+ if @bucket.present?
98
+ result = '/'
99
+ result += "#{@bucket}/"
100
+ end
101
+
102
+ if @bucket.blank? || @resource != '/'
103
+ result = File.join(result, @resource)
104
+ end
105
+
106
+ result += '?' if @cano_resource.present?
107
+ result += @cano_resource if @cano_resource
108
+
109
+ result
110
+ end
111
+
112
+ def calc_date
113
+ return @date if @date
114
+ @date = Time.now.httpdate
115
+
116
+ @date
117
+ end
118
+
119
+ def import?
120
+ @import
121
+ end
122
+
123
+ def multipart?
124
+ @multipart
125
+ end
126
+
127
+ def raw_data?
128
+ @raw_data
129
+ end
130
+
131
+ def blank_body?
132
+ @blank_body
133
+ end
134
+
135
+ def to_s
136
+ [
137
+ "method:#{@method}",
138
+ "resource: #{@resource}",
139
+ "cano_resource: #{@cano_resource}",
140
+ "query_params: #{@query_params}",
141
+ "bucket: #{@bucket}",
142
+ "parameters: #{@parameters}",
143
+ "headers: #{@headers}"
144
+ ].join(", ")
145
+ end
146
+
147
+ end
148
+ end
149
+ end