nsq-cluster 0.1.0 → 0.1.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.
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