nsq-cluster 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f22947bac09ad1ac1a45fac63b669d0adf275421
4
- data.tar.gz: c54f9eac0639203bd805a7b2b3720270ca213fa8
3
+ metadata.gz: 033d98f5168d98c5ccbbcf74f07c39e664381211
4
+ data.tar.gz: 2bbce8696cb02e03e1957a50ceab19497f8d6a5c
5
5
  SHA512:
6
- metadata.gz: a2897e1ee5a2f1b25f8dc04f2e3b3653fe30baaa6f102409e8ca69abaebaf73cb63788fbfb29d11f9dd05030bf0382f9d30bc3d96a92a378bb4c33a2449c87e4
7
- data.tar.gz: a48a8ee1ecc632bfa5f00e860bb4b1046a13d7ecd1f3282bd53c1d1543967f7d9c2edd4de7d1caba0a7fcb5058eeb8543d2d1a05402aa72c6fc7fdf4fcfb192f
6
+ metadata.gz: 806ce00281ea63daec5f0cb793cd3db757cb1d7e4999c842417426de1c61b97174509eab98abf987fc51fa32ed6dd1fd55ba98ac040fb6196320b6dc7ddd0887
7
+ data.tar.gz: c7c335b5e6e6b984de79d7c758c45ada043f2e4fa63e5e5f44b4be716e700a3a194d549d441e576f7836858b5404c05f4e2663e7c9260a4776917b60a374c3f0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nsq-cluster (0.1.0)
4
+ nsq-cluster (0.1.1)
5
5
  nsq-cluster
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -15,3 +15,64 @@ cluster.nsqd.last.start
15
15
  # Tear down the whole cluster
16
16
  cluster.destroy
17
17
  ```
18
+
19
+ Available methods that map to [`nsqd`'s](http://nsq.io/components/nsqd.html) HTTP endpoints.
20
+
21
+ ```ruby
22
+ # nsqd
23
+ nsqd = cluster.nsqd.first
24
+
25
+ # Publish a message to a topic
26
+ nsqd.pub('stats', 'a message')
27
+
28
+ # Publish multiple messages to a topic
29
+ nsqd.mpub('stats', 'a message', 'a second message', 'last message')
30
+
31
+ # Create a topic
32
+ nsqd.create(topic: 'stats')
33
+
34
+ # Create a channel for a known topic
35
+ nsqd.create(topic: 'stats', channel: 'default')
36
+
37
+ # Follow the same argument pattern for #delete, #empty, #pause, and #unpause
38
+
39
+ # Get stats in JSON format
40
+ nsqd.stats
41
+
42
+ # Ping nsqd
43
+ nsqd.ping
44
+
45
+ # Get general information
46
+ nsqd.info
47
+ ```
48
+
49
+ Available methods that map to [`nsqlookupd`'s](http://nsq.io/components/nsqlookupd.html) HTTP endpoints.
50
+
51
+ ```ruby
52
+ #nsqlookupd
53
+ nsqlookupd = cluster.nsqlookupd.first
54
+
55
+ # Look up list of producers by topic
56
+ nsqlookupd.lookup('stats')
57
+
58
+ # Get a list of known topics
59
+ nsqlookupd.topics
60
+
61
+ # Get a list of known channels for a topic
62
+ nsqlookupd.channels('stats')
63
+
64
+ # Get a list of known nodes
65
+ nsqlookupd.nodes
66
+
67
+ # Delete a topic
68
+ nsqlookupd.delete(topic: 'stats')
69
+
70
+ # Delete a channel for a known topic
71
+ nsqlookupd.delete(topic: 'stats', channel: 'default')
72
+
73
+ # Ping nsqlookupd
74
+ nsqlookupd.ping
75
+
76
+ # Get general info
77
+ nsqlookupd.info
78
+ ```
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
data/bin/nsq-cluster CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ $:.unshift File.join(File.dirname(__FILE__), "../lib")
4
+
3
5
  require 'nsq-cluster'
4
6
  require 'optparse'
5
7
 
@@ -0,0 +1,32 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module HTTPWrapper
5
+
6
+
7
+ def post(path, params = {}, body = nil)
8
+ uri = uri("#{path}?#{URI.encode_www_form(params)}")
9
+ request = Net::HTTP::Post.new(uri)
10
+ request.body = body
11
+
12
+ Net::HTTP.start(uri.hostname, uri.port) do |http|
13
+ http.request(request)
14
+ end
15
+ end
16
+
17
+
18
+ def get(path, params = {})
19
+ uri = uri(path)
20
+ uri.query = URI.encode_www_form(params)
21
+ Net::HTTP.get_response(uri)
22
+ end
23
+
24
+
25
+ private
26
+
27
+
28
+ def uri(path)
29
+ URI("http://#{@host}:#{@http_port}/#{path}")
30
+ end
31
+
32
+ end
@@ -1,7 +1,9 @@
1
1
  require_relative 'process_wrapper'
2
+ require_relative 'http_wrapper'
2
3
  require 'fileutils'
3
4
 
4
5
  class Nsqd < ProcessWrapper
6
+ include HTTPWrapper
5
7
 
6
8
 
7
9
  attr_reader :host, :tcp_port, :http_port
@@ -60,8 +62,69 @@ class Nsqd < ProcessWrapper
60
62
  end
61
63
 
62
64
 
65
+ # publish a single message to a topic
66
+ def pub(topic, message)
67
+ post 'pub', { topic: topic }, message
68
+ end
69
+
70
+
71
+ # publish multiple messages to a topic
72
+ def mpub(topic, *messages)
73
+ post 'mpub', { topic: topic }, messages.join("\n")
74
+ end
75
+
76
+
77
+ # create a topic or a channel in an existing topic
78
+ def create(params = {})
79
+ nsqd_post 'create', topic: params[:topic], channel: params[:channel]
80
+ end
81
+
82
+
83
+ # delete a topic or a channel in an existing topic
84
+ def delete(params = {})
85
+ nsqd_post 'delete', topic: params[:topic], channel: params[:channel]
86
+ end
87
+
88
+
89
+ # empty a topic or a channel in an existing topic
90
+ def empty(params = {})
91
+ nsqd_post 'empty', topic: params[:topic], channel: params[:channel]
92
+ end
93
+
94
+
95
+ # pause a topic or a channel in a topic
96
+ def pause(params = {})
97
+ nsqd_post 'pause', topic: params[:topic], channel: params[:channel]
98
+ end
99
+
100
+
101
+ # unpause a topic or a channel in a topic
102
+ def unpause(params = {})
103
+ nsqd_post 'unpause', topic: params[:topic], channel: params[:channel]
104
+ end
105
+
106
+
107
+ # return stats in json format
108
+ def stats
109
+ get 'stats', format: 'json'
110
+ end
111
+
112
+
113
+ # monitoring endpoint
114
+ def ping
115
+ get 'ping'
116
+ end
117
+
118
+
119
+ # returns version number
120
+ def info
121
+ get 'info'
122
+ end
123
+
124
+
63
125
  private
64
126
 
127
+
65
128
  def create_data_directory
66
129
  Dir.mkdir(data_path)
67
130
  end
@@ -71,4 +134,15 @@ class Nsqd < ProcessWrapper
71
134
  FileUtils.rm_rf(data_path) if Dir.exist?(data_path)
72
135
  end
73
136
 
137
+
138
+ def nsqd_post(action, params)
139
+ if params[:topic] && params[:channel]
140
+ post "#{action}_channel", topic: params[:topic], channel: params[:channel]
141
+ elsif params[:topic]
142
+ post "#{action}_topic", topic: params[:topic]
143
+ else
144
+ raise 'you must specify a topic or topic and channel'
145
+ end
146
+ end
147
+
74
148
  end
@@ -1,6 +1,8 @@
1
1
  require_relative 'process_wrapper'
2
+ require_relative 'http_wrapper'
2
3
 
3
4
  class Nsqlookupd < ProcessWrapper
5
+ include HTTPWrapper
4
6
 
5
7
  attr_reader :host, :tcp_port, :http_port
6
8
 
@@ -25,4 +27,60 @@ class Nsqlookupd < ProcessWrapper
25
27
  ]
26
28
  end
27
29
 
30
+
31
+ # return a list of producers for a topic
32
+ def lookup(topic)
33
+ get 'lookup', topic: topic
34
+ end
35
+
36
+
37
+ # return a list of all known topics
38
+ def topics
39
+ get 'topics'
40
+ end
41
+
42
+
43
+ # return a list of all known channels for a topic
44
+ def channels(topic)
45
+ get 'channels', topic: topic
46
+ end
47
+
48
+
49
+ # return a list of all known nsqd
50
+ def nodes
51
+ get 'nodes'
52
+ end
53
+
54
+
55
+ # delete a topic or a channel in an existing topic
56
+ def delete(params = {})
57
+ nsqlookupd_post 'delete', topic: params[:topic], channel: params[:channel]
58
+ end
59
+
60
+
61
+ # monitoring endpoint
62
+ def ping
63
+ get 'ping'
64
+ end
65
+
66
+
67
+ # returns version number
68
+ def info
69
+ get 'info'
70
+ end
71
+
72
+
73
+ private
74
+
75
+
76
+ def nsqlookupd_post(action, params)
77
+ if params[:topic] && params[:channel]
78
+ post "#{action}_channel", topic: params[:topic], channel: params[:channel]
79
+ elsif params[:topic]
80
+ post "#{action}_topic", topic: params[:topic]
81
+ else
82
+ raise 'you must specify a topic or topic and channel'
83
+ end
84
+ end
85
+
28
86
  end
data/nsq-cluster.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: nsq-cluster 0.1.0 ruby lib
5
+ # stub: nsq-cluster 0.1.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "nsq-cluster"
9
- s.version = "0.1.0"
9
+ s.version = "0.1.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Brendan Schwartz"]
14
- s.date = "2014-04-14"
14
+ s.date = "2014-06-26"
15
15
  s.description = "Setup nsqd, nsqlookupd, and nsqadmin in a jiffy. Great for testing!"
16
16
  s.email = "brendan@wistia.com"
17
17
  s.executables = ["nsq-cluster"]
@@ -31,13 +31,16 @@ Gem::Specification.new do |s|
31
31
  "VERSION",
32
32
  "bin/nsq-cluster",
33
33
  "lib/nsq-cluster.rb",
34
+ "lib/nsq-cluster/http_wrapper.rb",
34
35
  "lib/nsq-cluster/nsqadmin.rb",
35
36
  "lib/nsq-cluster/nsqd.rb",
36
37
  "lib/nsq-cluster/nsqlookupd.rb",
37
38
  "lib/nsq-cluster/process_wrapper.rb",
38
39
  "nsq-cluster.gemspec",
39
40
  "test/helper.rb",
40
- "test/nsq_cluster_spec.rb"
41
+ "test/nsq_cluster_spec.rb",
42
+ "test/nsqd_spec.rb",
43
+ "test/nsqlookupd_spec.rb"
41
44
  ]
42
45
  s.homepage = "http://github.com/wistia/nsq-cluster"
43
46
  s.licenses = ["MIT"]
data/test/helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'json'
1
2
  require 'simplecov'
2
3
  require 'minitest/autorun'
3
4
  require 'minitest/pride'
data/test/nsqd_spec.rb ADDED
@@ -0,0 +1,159 @@
1
+ require 'helper'
2
+
3
+ describe Nsqd do
4
+
5
+ before do
6
+ @cluster = NsqCluster.new(nsqd_count: 1, nsqlookupd_count: 1)
7
+ @nsqd = @cluster.nsqd.first
8
+ sleep 0.1
9
+ end
10
+
11
+ after do
12
+ @cluster.destroy
13
+ end
14
+
15
+ describe 'api endpoints' do
16
+ describe '#ping' do
17
+ it 'should return status 200' do
18
+ @nsqd.ping.code.must_equal '200'
19
+ end
20
+ end
21
+
22
+ describe '#info' do
23
+ it 'should return status 200' do
24
+ @nsqd.info.code.must_equal '200'
25
+ end
26
+ end
27
+
28
+ describe '#stats' do
29
+ it 'should return status 200' do
30
+ @nsqd.stats.code.must_equal '200'
31
+ end
32
+
33
+ it 'should return JSON' do
34
+ JSON.parse(@nsqd.stats.body).must_be_kind_of Hash
35
+ end
36
+ end
37
+
38
+ describe '#pub' do
39
+ it 'should return status 200' do
40
+ resp = @nsqd.pub('test', 'a message')
41
+ resp.code.must_equal '200'
42
+ end
43
+ end
44
+
45
+ describe '#mpub' do
46
+ it 'should return status 200' do
47
+ resp = @nsqd.mpub('test', 'a message', 'another message', 'last message')
48
+ resp.code.must_equal '200'
49
+ end
50
+
51
+ it 'should create multiple messages' do
52
+ resp = @nsqd.mpub('test', 'a message', 'another message', 'last message')
53
+
54
+ topic = JSON.parse(@nsqd.stats.body)['data']['topics'].select do |t|
55
+ t['topic_name'] == 'test'
56
+ end.first
57
+
58
+ topic['message_count'].must_equal 3
59
+ end
60
+ end
61
+
62
+ describe '#create' do
63
+ it 'should return status 200' do
64
+ resp1 = @nsqd.create(topic: 'test')
65
+ resp2 = @nsqd.create(topic: 'test', channel: 'default')
66
+ resp1.code.must_equal '200'
67
+ resp2.code.must_equal '200'
68
+ end
69
+
70
+ it 'should raise error if topic is not specified' do
71
+ proc { @nsqd.create(channel: 'default') }.must_raise RuntimeError
72
+ end
73
+ end
74
+
75
+ describe '#delete' do
76
+ before do
77
+ @nsqd.create(topic: 'test')
78
+ end
79
+
80
+ context 'an existing channel' do
81
+ it 'should return status 200' do
82
+ @nsqd.create(topic: 'test', channel: 'default')
83
+ resp = @nsqd.delete(topic: 'test', channel: 'default')
84
+ resp.code.must_equal '200'
85
+ end
86
+ end
87
+
88
+ context 'a non-existant channel' do
89
+ it 'should return status 500' do
90
+ resp = @nsqd.delete(topic: 'test', channel: 'default')
91
+ resp.code.must_equal '500'
92
+ end
93
+ end
94
+ end
95
+
96
+ describe '#pause' do
97
+ before do
98
+ @nsqd.create(topic: 'test')
99
+ end
100
+
101
+ context 'an existing channel' do
102
+ it 'should return status 200' do
103
+ @nsqd.create(topic: 'test', channel: 'default')
104
+ resp = @nsqd.pause(topic: 'test', channel: 'default')
105
+ resp.code.must_equal '200'
106
+ end
107
+ end
108
+
109
+ context 'a non-existant channel' do
110
+ it 'should return status 500' do
111
+ resp = @nsqd.pause(topic: 'test', channel: 'default')
112
+ resp.code.must_equal '500'
113
+ end
114
+ end
115
+ end
116
+
117
+ describe '#unpause' do
118
+ before do
119
+ @nsqd.create(topic: 'test')
120
+ end
121
+
122
+ context 'an existing channel' do
123
+ it 'should return status 200' do
124
+ @nsqd.create(topic: 'test', channel: 'default')
125
+ resp = @nsqd.unpause(topic: 'test', channel: 'default')
126
+ resp.code.must_equal '200'
127
+ end
128
+ end
129
+
130
+ context 'a non-existant channel' do
131
+ it 'should return status 500' do
132
+ resp = @nsqd.unpause(topic: 'test', channel: 'default')
133
+ resp.code.must_equal '500'
134
+ end
135
+ end
136
+ end
137
+
138
+ describe '#empty' do
139
+ before do
140
+ @nsqd.create(topic: 'test')
141
+ end
142
+
143
+ context 'an existing channel' do
144
+ it 'should return status 200' do
145
+ @nsqd.create(topic: 'test', channel: 'default')
146
+ resp = @nsqd.empty(topic: 'test', channel: 'default')
147
+ resp.code.must_equal '200'
148
+ end
149
+ end
150
+
151
+ context 'a non-existant channel' do
152
+ it 'should return status 500' do
153
+ resp = @nsqd.empty(topic: 'test', channel: 'default')
154
+ resp.code.must_equal '500'
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+
3
+ describe Nsqlookupd do
4
+
5
+ before do
6
+ @cluster = NsqCluster.new(nsqd_count: 1, nsqlookupd_count: 1)
7
+ @nsqd = @cluster.nsqd.first
8
+ @nsqlookupd = @cluster.nsqlookupd.first
9
+ sleep 0.1
10
+ end
11
+
12
+ after do
13
+ @cluster.destroy
14
+ end
15
+
16
+ describe 'api endpoints' do
17
+ describe '#ping' do
18
+ it 'should return status 200' do
19
+ @nsqlookupd.ping.code.must_equal '200'
20
+ end
21
+ end
22
+
23
+ describe '#info' do
24
+ it 'should return status 200' do
25
+ @nsqlookupd.info.code.must_equal '200'
26
+ end
27
+ end
28
+
29
+ describe '#nodes' do
30
+ it 'should return status 200' do
31
+ @nsqlookupd.nodes.code.must_equal '200'
32
+ end
33
+ end
34
+
35
+ describe '#topic' do
36
+ it 'should return status 200' do
37
+ @nsqlookupd.topics.code.must_equal '200'
38
+ end
39
+ end
40
+
41
+ describe '#channels' do
42
+ it 'should return status 200' do
43
+ @nsqlookupd.channels('default').code.must_equal '200'
44
+ end
45
+ end
46
+
47
+ describe '#lookup' do
48
+ context 'an existing topic' do
49
+ before do
50
+ @nsqd.create(topic: 'test')
51
+ end
52
+
53
+ it 'should return status 200' do
54
+ @nsqlookupd.lookup('test').code.must_equal '200'
55
+ end
56
+ end
57
+
58
+ context 'a non-existant topic' do
59
+ it 'should return status 500' do
60
+ @nsqlookupd.lookup('wtf').code.must_equal '500'
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nsq-cluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brendan Schwartz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-14 00:00:00.000000000 Z
11
+ date: 2014-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nsq-cluster
@@ -114,6 +114,7 @@ files:
114
114
  - VERSION
115
115
  - bin/nsq-cluster
116
116
  - lib/nsq-cluster.rb
117
+ - lib/nsq-cluster/http_wrapper.rb
117
118
  - lib/nsq-cluster/nsqadmin.rb
118
119
  - lib/nsq-cluster/nsqd.rb
119
120
  - lib/nsq-cluster/nsqlookupd.rb
@@ -121,6 +122,8 @@ files:
121
122
  - nsq-cluster.gemspec
122
123
  - test/helper.rb
123
124
  - test/nsq_cluster_spec.rb
125
+ - test/nsqd_spec.rb
126
+ - test/nsqlookupd_spec.rb
124
127
  homepage: http://github.com/wistia/nsq-cluster
125
128
  licenses:
126
129
  - MIT