aliyun-mqs 0.0.3

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: abd6a6844d4985d359ec5a61d4623b989523ca02
4
+ data.tar.gz: 0d659d51d20a37c68faa71aa32e1e32f87590e52
5
+ SHA512:
6
+ metadata.gz: 8f973502a48e1a9937dff5abd27e99b917d2e04eb14a5ffe729b7f5eed90841af9a84f6a8153559a8f8babb5c6c01c90f159808f8f5e04751e2cb787e42d00cd
7
+ data.tar.gz: ed4cdf563e6e182b52c63bf13cf42551df76d90d9771e2576a5b9b84e67866773e892a3da5a66fb2708c8bf2845dc3e55543e0d3e02d4b4c643728f0fe7c2972
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mqs.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 MgaMPKAy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # aliyun-mqs
2
+
3
+ Talk to the mighty Aliyun MQS with charming ruby.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'aliyun-mqs'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install aliyun-mqs
20
+
21
+ ## Usage
22
+
23
+ ### Require
24
+
25
+ ```ruby
26
+ require 'aliyun/mqs'
27
+ ```
28
+
29
+ ###
30
+
31
+ ### Configure
32
+
33
+ ```ruby
34
+ Aliyun::Mqs.configure do |config|
35
+ config.access_key_id = '0123456789ABCDEF'
36
+ config.access_key_secret = '*********************'
37
+ config.access_region = 'cn-hangzhou'
38
+ config.access_owner_id = 'cirno'
39
+ end
40
+ ```
41
+
42
+ ### Response
43
+
44
+ Most API returns a `Response` object, which contains status and all leaf element in the XML response.
45
+ Eg: Every leaf element of
46
+
47
+ ```xml
48
+ <?xml version="1.0"?>
49
+ <Message xmlns="http://mqs.aliyuncs.com/doc/v1">
50
+ <MessageBodyMD5>654E27D8879283831B664BD8B7F0AD4</MessageBodyMD5>
51
+ <MessageId>6003A74BEB1D5460-1-147DF4497D4-200000024</MessageId>
52
+ </Message>
53
+ ```
54
+ can be accessed as:
55
+
56
+ ```ruby
57
+ Aliyun::Response::message_body_md5
58
+ Aliyun::Response::message_id
59
+ ```
60
+
61
+ To determine wheater a request call is succeed, use `Response::success?`. `Response` is an imutable object, all instance method with side-effects will return a new instance of `Response`. So, instead of
62
+
63
+ ```ruby
64
+ message = queue.receive # message is an Response
65
+ message.visibility = 1.minute
66
+ message.visibility = 8.minute # wrong, reuse receipt handle
67
+ ```
68
+
69
+ you shoud pass the return value (agian, an `Response`) around:
70
+
71
+ ```ruby
72
+ resp = queue.receive
73
+ resp = resp.visibility = 1.minute
74
+ resp = resp.visibility = 8.minute
75
+ ```
76
+
77
+ ### Get an existing queue
78
+
79
+ ```ruby
80
+ queue = Aliyun::Mqs.get 'queue-name'
81
+ queue = Aliyun::Mqs.get 'queue-name', :access_owner_id: 'your_id'
82
+ ```
83
+
84
+ ### Delete a queue
85
+
86
+ ```ruby
87
+ queue.destroy
88
+ ```
89
+
90
+ ### Send messages
91
+
92
+ ```ruby
93
+ resp = queue.send "Hello, World!"
94
+ resp = queue.send "Hello, Cirno!", delay_seconds: 9, priority: 9
95
+ ```
96
+
97
+ ### Recveive messages
98
+
99
+ ```ruby
100
+ message = queue.receive
101
+ message = queue.receive waitseconds: 10, peekonly: true
102
+ message = queue.peek
103
+ ```
104
+
105
+ ### Delete messages
106
+
107
+ ```ruby
108
+ message.delete
109
+ queue.delete message
110
+ queue.delete "#{you_message_recipet_handlerer}"
111
+ ```
112
+
113
+ ### Change message visibility (not implemented yet)
114
+
115
+ ```ruby
116
+ resp = message.visibility = Time.now + 1.hour
117
+ resp = message.visibility = Time.now.to_f * 1000 + 10
118
+ resp = message.visibility += 1.hour
119
+ ```
120
+
121
+ ## Contributing
122
+
123
+ 1. Fork it ( https://github.com/mgampkay/aliyun-mqs/fork )
124
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
125
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
126
+ 4. Push to the branch (`git push origin my-new-feature`)
127
+ 5. Create a new Pull Request
128
+
129
+ ## References
130
+
131
+ + xiaohuilam's [aliyun-mqs-php-library](https://github.com/xiaohuilam/aliyun-mqs-php-library)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aliyun/mqs/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'aliyun-mqs'
8
+ spec.version = Aliyun::Mqs::VERSION
9
+ spec.authors = ["mgampkay"]
10
+ spec.email = ["mgampkay@gmail.com"]
11
+ spec.summary = 'Ruby SDK for Aliyun MQS (non-official)'
12
+ spec.description = 'Non-official SDK for Aliyun MQS'
13
+ spec.homepage = 'https://github.com/mgampkay/aliyun-mqs'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'nokogiri', '>= 1.6'
22
+ spec.add_dependency 'activesupport', '>= 4.1'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.7"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
data/lib/aliyun/mqs.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'aliyun/mqs/version'
2
+ require 'aliyun/mqs/queue'
3
+ require 'aliyun/mqs/response'
4
+ require 'aliyun/mqs/configuration'
5
+ require 'aliyun/mqs/http'
6
+
7
+ module Aliyun
8
+ module Mqs
9
+
10
+ class << self
11
+ attr_writer :configuration
12
+ end
13
+
14
+ def self.configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ def self.configure
19
+ yield(configuration)
20
+ end
21
+
22
+ def self.get(name, access_owner_id: nil)
23
+ Aliyun::Mqs::Queue.new(name, access_owner_id: access_owner_id)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,8 @@
1
+ module Aliyun
2
+ module Mqs
3
+ class Configuration
4
+ attr_accessor :access_key_id, :access_key_secret, :access_region
5
+ attr_accessor :access_owner_id
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,58 @@
1
+ require 'base64'
2
+ require 'date'
3
+ require 'digest'
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module Aliyun
8
+ module Mqs
9
+ module Http
10
+ Version = '2014-07-08'
11
+ ContentType = 'text/xml;utf-8'
12
+
13
+ def send_request(verb, request_uri, body = '')
14
+ uri = URI.parse(request_uri)
15
+ content_md5 = Base64::encode64(Digest::MD5.hexdigest body).chop
16
+ gmt_date = DateTime.now.httpdate
17
+ mqs_headers = {'x-mqs-version' => Version}
18
+ headers = {'Host' => uri.host,
19
+ 'Date' => gmt_date,
20
+ 'Content-Type' => ContentType,
21
+ 'Content-MD5' => content_md5
22
+ }
23
+ headers.merge! mqs_headers
24
+ resource = uri.path + (uri.query != nil ? '?' + uri.query : '')
25
+ headers['Authorization'] = sign_header(verb, content_md5, gmt_date, mqs_headers, resource)
26
+
27
+ http = Net::HTTP.new(uri.host, uri.port)
28
+
29
+ case verb.downcase
30
+ when 'get'
31
+ request = Net::HTTP::Get.new(uri.request_uri)
32
+ when 'post'
33
+ request = Net::HTTP::Post.new(uri.request_uri)
34
+ request.body = body
35
+ when 'delete'
36
+ request = Net::HTTP::Delete.new(uri.request_uri)
37
+ when 'put'
38
+ request = Net::HTTP::Put.new(uri.request_uri)
39
+ request.body = body
40
+ end
41
+ request.initialize_http_header(headers)
42
+ response = http.request(request)
43
+ Response.new(self, response)
44
+ end
45
+
46
+ def sign_header(verb, content_md5, gmt_date, mqs_headers = {}, resources = '/')
47
+ header = ''
48
+ mqs_headers.sort.each do |k,v|
49
+ header << k.downcase + ':'+ v + "\n"
50
+ end
51
+ sign = sprintf "%s\n%s\n%s\n%s\n%s%s", verb, content_md5, ContentType, gmt_date, header, resources
52
+ sign = Base64::encode64(Digest::HMAC.digest(sign, Mqs.configuration.access_key_secret, Digest::SHA1)).chop
53
+ "MQS #{Mqs.configuration.access_key_id}:#{sign}"
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,78 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'builder'
3
+ require 'aliyun/mqs/http'
4
+
5
+ module Aliyun
6
+ module Mqs
7
+
8
+ class Queue
9
+ include Mqs::Http
10
+
11
+ def initialize(name, access_owner_id: nil)
12
+ @access_key_id = Mqs.configuration.access_key_id
13
+ @access_key_secret = Mqs.configuration.access_key_secret
14
+ @access_region = Mqs.configuration.access_region
15
+ @access_owner_id = access_owner_id || Mqs.configuration.access_owner_id
16
+ @access_queue = name
17
+ @access_host = "#{@access_owner_id}.mqs-#{@access_region}.aliyuncs.com"
18
+ throw '参数不能为nil' if instance_variables.any? {|x| x == nil}
19
+ end
20
+
21
+
22
+ def destroy
23
+ verb = 'DELETE'
24
+ request_resource = "/#{@access_queue}"
25
+ request_uri = "http://#{@access_host}#{request_resource}"
26
+ send_request(verb, request_uri)
27
+ end
28
+
29
+ def send(message_body, delay_seconds: 0, priority: 8)
30
+ verb = 'POST'
31
+ content_body = to_xml(message_body, delay_seconds, priority)
32
+ request_resource = "/#{@access_queue}/messages"
33
+ request_uri = "http://#{@access_host}#{request_resource}"
34
+ send_request(verb, request_uri, content_body)
35
+ end
36
+
37
+ def receive(waitseconds: nil, peekonly: false)
38
+ verb = 'GET'
39
+ query_params = {}
40
+ query_params[:waitseconds] = waitseconds if waitseconds
41
+ query_params[:peekonly] = true if peekonly # Aliyun doesn't accept uncessary query params
42
+ request_resource = "/#{@access_queue}/messages" + (query_params.length > 0 ? '?' + query_params.to_param : '')
43
+ request_uri = "http://#{@access_host}#{request_resource}"
44
+ send_request(verb, request_uri)
45
+ end
46
+
47
+ def delete message
48
+ verb = 'DELETE'
49
+ if String === message
50
+ receipt_handle = message
51
+ elsif Response === message
52
+ receipt_handle = message.receipt_handle
53
+ end
54
+ request_resource = "/#{@access_queue}/messages?" + {ReceiptHandle: receipt_handle}.to_param
55
+ request_uri = "http://#{@access_host}#{request_resource}"
56
+ send_request(verb, request_uri)
57
+ end
58
+
59
+ def peek(waitseconcds: nil)
60
+ receive(waitseconds: waitseconcds, peekonly: true)
61
+ end
62
+
63
+ private
64
+
65
+ def to_xml(message_body, delay_seconds, priority)
66
+ xml = Builder::XmlMarkup.new( :indent => 2 )
67
+ xml.instruct! :xml, :encoding => 'UTF-8'
68
+ xml.Message(:xmlns => 'http://mqs.aliyuncs.com/doc/v1/') do |m|
69
+ m.MessageBody message_body
70
+ m.DelaySeconds delay_seconds
71
+ m.Priority priority
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,46 @@
1
+ require 'nokogiri'
2
+ require 'active_support/core_ext/string/inflections'
3
+
4
+ module Aliyun
5
+ module Mqs
6
+
7
+ class Response
8
+
9
+ def initialize(queue, response)
10
+ @queue = queue
11
+ @success = (response.code =~ /^20./) == 0
12
+ if response.body
13
+ begin
14
+ xml_to_attribute(response.body)
15
+ end
16
+ end
17
+ end
18
+
19
+ def success?
20
+ @success
21
+ end
22
+
23
+ def delete
24
+ @queue.delete self
25
+ end
26
+
27
+ private
28
+
29
+ def xml_to_attribute(xml)
30
+ Nokogiri::XML(xml).root.children.each do |child|
31
+ if child.element?
32
+ name = child.name.underscore
33
+ value = child.content.to_s
34
+ value = Time.at(value.to_f / 1000) if name.end_with?('_time')
35
+ define_singleton_method name do
36
+ instance_variable_get ('@' + name)
37
+ end
38
+ self.instance_variable_set('@' + name, value)
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ module Aliyun
2
+ module Mqs
3
+ VERSION = "0.0.3"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aliyun-mqs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - mgampkay
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Non-official SDK for Aliyun MQS
70
+ email:
71
+ - mgampkay@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - aliyun-mqs.gemspec
82
+ - lib/aliyun/mqs.rb
83
+ - lib/aliyun/mqs/configuration.rb
84
+ - lib/aliyun/mqs/http.rb
85
+ - lib/aliyun/mqs/queue.rb
86
+ - lib/aliyun/mqs/response.rb
87
+ - lib/aliyun/mqs/version.rb
88
+ homepage: https://github.com/mgampkay/aliyun-mqs
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.2.2
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Ruby SDK for Aliyun MQS (non-official)
112
+ test_files: []