iron_mq 5.0.1 → 6.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,7 +20,7 @@ Gem::Specification.new do |gem|
20
20
  gem.add_runtime_dependency "iron_core", ">= 0.5.1"
21
21
 
22
22
  gem.add_development_dependency "test-unit"
23
- gem.add_development_dependency "minitest"
23
+ gem.add_development_dependency "minitest", ">= 5.0"
24
24
  gem.add_development_dependency "rake"
25
25
  gem.add_development_dependency "beanstalk-client"
26
26
  gem.add_development_dependency "uber_config"
@@ -29,5 +29,6 @@ Gem::Specification.new do |gem|
29
29
  gem.add_development_dependency "quicky"
30
30
  gem.add_development_dependency "iron_worker_ng"
31
31
  gem.add_development_dependency "go"
32
+ gem.add_development_dependency "parallel"
32
33
  end
33
34
 
@@ -11,40 +11,47 @@ module IronMQ
11
11
 
12
12
  def initialize(options={})
13
13
  default_options = {
14
- :scheme => 'https',
15
- :host => IronMQ::Client::AWS_US_EAST_HOST,
16
- :port => 443,
17
- :api_version => 1,
18
- :user_agent => 'iron_mq_ruby-' + IronMQ::VERSION + ' (iron_core_ruby-' + IronCore.version + ')'
14
+ scheme: 'https',
15
+ host: IronMQ::Client::AWS_US_EAST_HOST,
16
+ port: 443,
17
+ api_version: 3,
18
+ user_agent: 'iron_mq_ruby-' + IronMQ::VERSION +
19
+ ' (iron_core_ruby-' + IronCore.version + ')'
19
20
  }
20
21
 
21
- super('iron', 'mq', options, default_options, [:project_id, :token, :api_version])
22
+ super('iron', 'mq', options, default_options,
23
+ [:project_id, :token, :api_version])
22
24
 
23
- IronCore::Logger.error 'IronMQ', "Token is not set", IronCore::Error if @token.nil?
25
+ if @keystone.nil?
26
+ if @token.nil?
27
+ IronCore::Logger.error 'IronMQ', 'Token is not set', IronCore::Error
28
+ end
24
29
 
25
- check_id(@project_id, 'project_id')
30
+ check_id(@project_id, 'project_id')
31
+ end
26
32
 
27
33
  @logger = Logger.new(STDOUT)
28
34
  @logger.level = Logger::INFO
29
35
  end
30
36
 
31
37
  def headers
32
- super.merge({'Authorization' => "OAuth #{@token}"})
38
+ super.merge({'Authorization' => "OAuth #{@token_provider.nil? ? @token : @token_provider.token}"})
33
39
  end
34
40
 
35
41
  def base_url
36
- @base_url = "#{super}#{@api_version}/projects/#{@project_id}/queues"
42
+ @base_url ||= "#{super}#{@api_version}/projects/#{@project_id}/queues"
37
43
  end
38
44
 
39
45
  def queues_list(options = {})
40
46
  is_raw = [options.delete(:raw),
41
47
  options.delete('raw')].compact.first
42
48
  response = parse_response(get('', options)) # GET base_url
49
+ # p response
43
50
  # returns list of evaluated queues
44
51
  if is_raw
45
52
  response.map{ |q_info| ResponseBase.new(q_info) }
46
53
  else
47
- response.map{ |q_info| Queue.new(self, q_info["name"]) }
54
+ response['queues'].map { |q_info| Queue.new(self, q_info['name']) }
48
55
  end
49
56
  end
50
57
 
@@ -58,11 +65,11 @@ module IronMQ
58
65
  alias_method :queue, :queues_get
59
66
 
60
67
  # Backward compatibility for
61
- # client.queues.get(:name => "my_queue")
62
- # client.queues.get("name" => "my_queue")
68
+ # client.queues.get(name: 'my_queue')
69
+ # client.queues.get('name' => 'my_queue')
63
70
  def get(*args)
64
71
  if args.size == 1 && args[0].is_a?(Hash)
65
- queue_name = (args[0][:name] || args[0]["name"]).to_s
72
+ queue_name = (args[0][:name] || args[0]['name']).to_s
66
73
  queue_name.empty? ? super : queues_get(queue_name)
67
74
  else
68
75
  super
@@ -76,6 +83,23 @@ module IronMQ
76
83
  def queues
77
84
  self
78
85
  end
86
+
87
+ def create_queue(queue_name, options)
88
+ response = self.put("/#{CGI::escape(queue_name).gsub('+', '%20')}",
89
+ {queue: options})
90
+ queue_hash = JSON.parse(response.body.to_s)
91
+
92
+ ResponseBase.new(queue_hash['queue'])
93
+ end
94
+
95
+ def update_queue(queue_name, options)
96
+ response = self.patch("/#{CGI::escape(queue_name).gsub('+', '%20')}",
97
+ {queue: options})
98
+ queue_hash = JSON.parse(response.body.to_s)
99
+
100
+ ResponseBase.new(queue_hash['queue'])
101
+ end
102
+
79
103
  end
80
104
 
81
105
  end
@@ -30,17 +30,25 @@ module IronMQ
30
30
  @raw['reserved_count']
31
31
  end
32
32
 
33
+ def reservation_id
34
+ @raw['reservation_id']
35
+ end
36
+
37
+ def push_statuses
38
+ @raw['push_statuses']
39
+ end
40
+
33
41
  def touch
34
- call_api_and_parse_response(:post, "/touch")
42
+ call_api_and_parse_response(:post, '/touch')
35
43
  end
36
44
 
37
45
  def release(options = {})
38
- call_api_and_parse_response(:post, "/release", options)
46
+ call_api_and_parse_response(:post, '/release', options)
39
47
  end
40
48
 
41
49
  # `options` was kept for backward compatibility
42
50
  def subscribers(options = {})
43
- response = call_api_and_parse_response(:get, "/subscribers", {}, false)
51
+ response = call_api_and_parse_response(:get, '/subscribers', {}, false)
44
52
 
45
53
  response['subscribers'].map { |s| Subscriber.new(s, self, options) }
46
54
  end
@@ -49,16 +57,22 @@ module IronMQ
49
57
  call_api_and_parse_response(:delete)
50
58
  rescue Rest::HttpError => ex
51
59
  #if ex.code == 404
52
- # Rest.logger.info("Delete got 404, safe to ignore.")
60
+ # Rest.logger.info('Delete got 404, safe to ignore.')
53
61
  # # return ResponseBase as normal
54
- # ResponseBase.new({"msg" => "Deleted"}, 404)
62
+ # ResponseBase.new({'msg' => 'Deleted'}, 404)
55
63
  #else
56
- raise ex
64
+ raise ex
57
65
  #end
58
66
  end
59
67
 
60
- def call_api_and_parse_response(meth, ext_path = "", options = {}, instantiate = true)
61
- @queue.call_api_and_parse_response(meth, "#{path(ext_path)}", options, instantiate)
68
+ def call_api_and_parse_response(meth, ext_path = '',
69
+ options = {}, instantiate = true)
70
+ if self.reservation_id && !self.reservation_id.empty?
71
+ options[:reservation_id] = self.reservation_id
72
+ end
73
+ @queue.call_api_and_parse_response(meth,
74
+ "#{path(ext_path)}",
75
+ options, instantiate)
62
76
  end
63
77
 
64
78
  private
@@ -18,49 +18,46 @@ module IronMQ
18
18
  def load
19
19
  reload if @raw.nil?
20
20
 
21
- @raw
21
+ @raw['queue']
22
22
  end
23
23
 
24
24
  def reload
25
- @raw = call_api_and_parse_response(:get, "", {}, false, true)
25
+ @raw = call_api_and_parse_response(:get, '', {}, false, true)
26
26
  self
27
27
  end
28
28
 
29
29
  def id
30
- load
31
- @raw['id']
30
+ load['id']
32
31
  end
33
32
 
34
33
  def size
35
- load
36
- @raw['size'].to_i
34
+ load['size'].to_i
37
35
  end
38
36
 
39
37
  def total_messages
40
- load
41
- @raw['total_messages'].to_i
38
+ load['total_messages'].to_i
42
39
  end
43
40
 
44
- def push_type
45
- load
46
- @raw['push_type']
41
+ def type
42
+ load['type']
47
43
  end
48
44
 
49
45
  def push_queue?
50
- # FIXME: `push_type` parameter in not guaranted it's push queue.
51
- # When the parameter absent it is not guaranted that queue is not push queue.
52
- ptype = push_type
53
- not (ptype.nil? || ptype.empty?)
46
+ ['multicast', 'unicast'].include?(type)
54
47
  end
55
48
 
56
- def update(options)
57
- call_api_and_parse_response(:post, "", options)
49
+ def push_info
50
+ load['push']
51
+ end
52
+
53
+ def update(options={})
54
+ call_api_and_parse_response(:put, '', {queue: options})
58
55
  end
59
56
 
60
57
  alias_method :update_queue, :update
61
58
 
62
59
  def clear
63
- call_api_and_parse_response(:post, "/clear", {}, false, true)
60
+ call_api_and_parse_response(:delete, '/messages', {}, false, true)
64
61
  end
65
62
 
66
63
  alias_method :clear_queue, :clear
@@ -72,27 +69,40 @@ module IronMQ
72
69
  return r
73
70
  rescue Rest::HttpError => ex
74
71
  #if ex.code == 404
75
- # Rest.logger.info("Delete got 404, safe to ignore.")
72
+ # Rest.logger.info('Delete got 404, safe to ignore.')
76
73
  # # return ResponseBase as normal
77
- # ResponseBase.new({"msg" => "Deleted"}, 404)
74
+ # ResponseBase.new({'msg' => 'Deleted'}, 404)
78
75
  #else
79
76
  raise ex
80
77
  #end
81
78
  end
82
79
 
83
80
  # Backward compatibility
84
- def delete(message_id, options = {})
81
+ def delete(message_id, reservation_id = nil)
85
82
  # API does not accept any options
86
- Message.new(self, {"id" => message_id}).delete
83
+ options = {}
84
+ options['id'] = message_id
85
+ unless reservation_id.nil?
86
+ options['reservation_id'] = reservation_id
87
+ end
88
+ Message.new(self, options).delete
87
89
  end
88
90
 
89
91
  # Accepts an array of message ids
90
92
  def delete_messages(ids)
91
- call_api_and_parse_response(:delete, "/messages", :ids => ids)
93
+ call_api_and_parse_response(:delete, '/messages', ids: ids)
94
+ end
95
+
96
+ def delete_reserved_messages(messages)
97
+ ids = messages.map do |message|
98
+ {id: message.id, reservation_id: message.reservation_id}
99
+ end
100
+
101
+ call_api_and_parse_response(:delete, '/messages', ids: ids)
92
102
  end
93
103
 
94
104
  def add_subscribers(subscribers)
95
- call_api_and_parse_response(:post, "/subscribers", :subscribers => subscribers)
105
+ call_api_and_parse_response(:post, '/subscribers',{subscribers: subscribers})
96
106
  end
97
107
 
98
108
  # `options` for backward compatibility
@@ -102,10 +112,12 @@ module IronMQ
102
112
 
103
113
  def remove_subscribers(subscribers)
104
114
  call_api_and_parse_response(:delete,
105
- "/subscribers",
115
+ '/subscribers',
106
116
  {
107
- :subscribers => subscribers,
108
- :headers => {"Content-Type" => @client.content_type}
117
+ subscribers: subscribers,
118
+ headers: {
119
+ 'Content-Type' => @client.content_type
120
+ }
109
121
  })
110
122
  end
111
123
 
@@ -113,31 +125,53 @@ module IronMQ
113
125
  remove_subscribers([subscriber])
114
126
  end
115
127
 
128
+ def replace_subscribers(subscribers)
129
+ call_api_and_parse_response(:put,
130
+ '/subscribers',
131
+ {
132
+ subscribers: subscribers,
133
+ headers: {
134
+ 'Content-Type' => @client.content_type
135
+ }
136
+ })
137
+ end
138
+
139
+ def replace_subscriber(subscriber)
140
+ replace_subscribers([subscriber])
141
+ end
142
+
116
143
  # `options` was kept for backward compatibility
117
144
  def subscribers(options = {})
118
145
  load
119
- if @raw['subscribers']
120
- return @raw['subscribers'].map { |s| Subscriber.new(s, self, options) }
121
- end
122
- []
123
- end
146
+ return [] if info['push'].nil? || info['push']['subscribers'].nil?
124
147
 
125
- def add_alert(alert)
126
- add_alerts([alert])
148
+ info['push']['subscribers'].map { |s| Subscriber.new(s, self, options) }
127
149
  end
128
150
 
129
151
  def add_alerts(alerts)
130
- call_api_and_parse_response(:post, '/alerts', :alerts => alerts)
152
+ call_api_and_parse_response(:patch, '', queue: {alerts: alerts})
153
+ end
154
+
155
+ def add_alert(alert)
156
+ add_alerts([alert])
131
157
  end
132
158
 
133
159
  def remove_alerts(alerts)
134
- call_api_and_parse_response(:delete, '/alerts', :alerts => alerts)
160
+ call_api_and_parse_response(:delete, '/alerts', alerts: alerts)
135
161
  end
136
162
 
137
163
  def remove_alert(alert)
138
164
  remove_alerts([alert])
139
165
  end
140
166
 
167
+ def replace_alerts(alerts)
168
+ call_api_and_parse_response(:put, '/alerts', alerts: alerts)
169
+ end
170
+
171
+ def clear_alerts
172
+ replace_alerts([])
173
+ end
174
+
141
175
  def alerts
142
176
  load
143
177
  return nil unless @raw['alerts']
@@ -159,44 +193,42 @@ module IronMQ
159
193
  # For now user must pass objects like `[{:body => msg1}, {:body => msg2}]`
160
194
  payload.map { |msg| msg.merge(options) }
161
195
  else
162
- [options.merge(:body => payload)]
196
+ [options.merge(body: payload)]
163
197
  end
164
198
 
165
199
  # Do not instantiate response
166
- res = call_api_and_parse_response(:post, "/messages", {:messages => msgs}, false)
200
+ res = call_api_and_parse_response(:post, '/messages',
201
+ {messages: msgs}, false)
167
202
 
168
203
  if instantiate
169
204
  n = batch ? 2 : 1
170
- msg_ids = res["ids"].map { |id| {"id" => id} }
205
+ msg_ids = res['ids'].map { |id| {'id' => id} }
171
206
 
172
- process_messages(msg_ids, {:n => n})
207
+ process_messages(msg_ids, {n: n})
173
208
  else
174
209
  if batch
175
210
  # FIXME: Return Array of ResponseBase instead, it seems more clear than raw response
176
211
  #
177
- # res["ids"].map { |id| ResponseBase.new({"id" => id, "msg" => res["msg"]}) }
212
+ # res['ids'].map { |id| ResponseBase.new({'id' => id, 'msg' => res['msg']}) }
178
213
  #
179
214
  ResponseBase.new(res) # Backward capable
180
215
  else
181
- ResponseBase.new({"id" => res["ids"][0], "msg" => res["msg"]})
216
+ ResponseBase.new({'id' => res['ids'][0], 'msg' => res['msg']})
182
217
  end
183
218
  end
184
219
  end
185
220
 
186
221
  alias_method :post, :post_messages
187
222
 
188
- def get_messages(options = {})
189
- if options.is_a?(String)
190
- # assume it's an id
191
- return Message.new(self, {"id" => options})
192
- end
193
-
194
- resp = call_api_and_parse_response(:get, "/messages", options, false)
195
-
196
- process_messages(resp["messages"], options)
223
+ def reserve_messages(options = {})
224
+ resp = call_api_and_parse_response(:post, '/reservations', options, false)
225
+ process_messages(resp['messages'], options)
197
226
  end
198
227
 
199
- alias_method :get, :get_messages
228
+ # backwards compatibility
229
+ alias_method :get, :reserve_messages
230
+ alias_method :get_messages, :reserve_messages
231
+ alias_method :reserve, :reserve_messages
200
232
 
201
233
  # Backward compatibility
202
234
  def messages
@@ -205,13 +237,13 @@ module IronMQ
205
237
 
206
238
  def get_message(id)
207
239
  resp = call_api_and_parse_response(:get, "/messages/#{id}", {}, false)
208
- Message.new(self, resp)
240
+ Message.new(self, resp['message'])
209
241
  end
210
242
 
211
243
  def peek_messages(options = {})
212
- resp = call_api_and_parse_response(:get, "/messages/peek", options)
244
+ resp = call_api_and_parse_response(:get, '/messages', options)
213
245
 
214
- process_messages(resp["messages"], options)
246
+ process_messages(resp['messages'], options)
215
247
  end
216
248
 
217
249
  alias_method :peek, :peek_messages
@@ -233,17 +265,24 @@ module IronMQ
233
265
 
234
266
  alias_method :poll, :poll_messages
235
267
 
236
- def call_api_and_parse_response(meth, ext_path = "", options = {}, instantiate = true, ignore404 = false)
237
- r = nil
238
- response = if meth.to_s == "delete"
239
- headers = options.delete(:headers) || options.delete("headers") || {}
240
-
241
- @client.parse_response(@client.send(meth, "#{path(ext_path)}", options, headers))
242
- else
243
- @client.parse_response(@client.send(meth, "#{path(ext_path)}", options))
244
- end
245
- r = instantiate ? ResponseBase.new(response) : response
246
- r
268
+ def call_api_and_parse_response(meth, ext_path = '', options = {},
269
+ instantiate = true, ignore404 = false)
270
+ response =
271
+ if meth.to_s == 'delete'
272
+ headers = options.delete(:headers) ||
273
+ options.delete('headers') ||
274
+ Hash.new
275
+ headers['Content-Type'] = 'application/json'
276
+ @client.parse_response(@client.send(meth,
277
+ "#{path(ext_path)}",
278
+ options, headers))
279
+ else
280
+ @client.parse_response(@client.send(meth,
281
+ "#{path(ext_path)}",
282
+ options))
283
+ end
284
+
285
+ instantiate ? ResponseBase.new(response) : response
247
286
  end
248
287
 
249
288
  private