efigence-influxdb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rubocop.yml +41 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +362 -0
  8. data/Rakefile +22 -0
  9. data/efigence-influxdb.gemspec +28 -0
  10. data/lib/influxdb.rb +21 -0
  11. data/lib/influxdb/client.rb +77 -0
  12. data/lib/influxdb/client/http.rb +98 -0
  13. data/lib/influxdb/config.rb +60 -0
  14. data/lib/influxdb/errors.rb +40 -0
  15. data/lib/influxdb/logging.rb +22 -0
  16. data/lib/influxdb/max_queue.rb +18 -0
  17. data/lib/influxdb/point_value.rb +31 -0
  18. data/lib/influxdb/query/cluster.rb +17 -0
  19. data/lib/influxdb/query/continuous_query.rb +36 -0
  20. data/lib/influxdb/query/core.rb +109 -0
  21. data/lib/influxdb/query/database.rb +21 -0
  22. data/lib/influxdb/query/series.rb +13 -0
  23. data/lib/influxdb/query/shard.rb +14 -0
  24. data/lib/influxdb/query/shard_space.rb +60 -0
  25. data/lib/influxdb/query/user.rb +38 -0
  26. data/lib/influxdb/version.rb +3 -0
  27. data/lib/influxdb/writer/async.rb +115 -0
  28. data/lib/influxdb/writer/udp.rb +21 -0
  29. data/spec/influxdb/cases/async_client_spec.rb +33 -0
  30. data/spec/influxdb/cases/query_cluster_spec.rb +65 -0
  31. data/spec/influxdb/cases/query_database_spec.rb +58 -0
  32. data/spec/influxdb/cases/query_series_spec.rb +50 -0
  33. data/spec/influxdb/cases/query_shard_spec.rb +43 -0
  34. data/spec/influxdb/cases/query_user_spec.rb +127 -0
  35. data/spec/influxdb/cases/querying_spec.rb +159 -0
  36. data/spec/influxdb/cases/retry_requests_spec.rb +97 -0
  37. data/spec/influxdb/cases/udp_client_spec.rb +21 -0
  38. data/spec/influxdb/cases/write_points_spec.rb +141 -0
  39. data/spec/influxdb/client_spec.rb +58 -0
  40. data/spec/influxdb/config_spec.rb +118 -0
  41. data/spec/influxdb/logging_spec.rb +48 -0
  42. data/spec/influxdb/max_queue_spec.rb +29 -0
  43. data/spec/influxdb/point_value_spec.rb +66 -0
  44. data/spec/influxdb/worker_spec.rb +23 -0
  45. data/spec/spec_helper.rb +8 -0
  46. metadata +192 -0
@@ -0,0 +1,65 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ describe "#create_cluster_admin" do
21
+ let(:user) { 'adminadmin' }
22
+ let(:pass) { 'passpass' }
23
+ let(:query) { "CREATE USER #{user} WITH PASSWORD '#{pass}' WITH ALL PRIVILEGES" }
24
+
25
+ before do
26
+ stub_request(:get, "http://influxdb.test:9999/query").with(
27
+ query: {u: "username", p: "password", q: query}
28
+ )
29
+ end
30
+
31
+ it "should GET to create a new cluster admin" do
32
+ expect(subject.create_cluster_admin(user, pass)).to be_a(Net::HTTPOK)
33
+ end
34
+ end
35
+
36
+ describe "#list_cluster_admins" do
37
+ let(:response) { {"results"=>[{"series"=>[{"columns"=>["user", "admin"], "values"=>[["dbadmin", true], ["foobar", false]]}]}]} }
38
+ let(:expected_result) { [{"username"=>"dbadmin"}] }
39
+
40
+ before do
41
+ stub_request(:get, "http://influxdb.test:9999/query").with(
42
+ query: {u: "username", p: "password", q: "SHOW USERS"}
43
+ ).to_return(:body => JSON.generate(response, :status => 200))
44
+ end
45
+
46
+ it "should GET a list of cluster admins" do
47
+ expect(subject.list_cluster_admins).to eq(expected_result)
48
+ end
49
+ end
50
+
51
+ describe "#revoke_cluster_admin_privileges" do
52
+ let(:user) { 'useruser' }
53
+ let(:query) { "REVOKE ALL PRIVILEGES FROM #{user}" }
54
+
55
+ before do
56
+ stub_request(:get, "http://influxdb.test:9999/query").with(
57
+ query: {u: "username", p: "password", q: query}
58
+ )
59
+ end
60
+
61
+ it "should GET to revoke cluster admin privileges from a user" do
62
+ expect(subject.revoke_cluster_admin_privileges(user)).to be_a(Net::HTTPOK)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ describe "#create_database" do
21
+ before do
22
+ stub_request(:get, "http://influxdb.test:9999/query").with(
23
+ query: {u: "username", p: "password", q: "CREATE DATABASE foo"}
24
+ )
25
+ end
26
+
27
+ it "should GET to create a new database" do
28
+ expect(subject.create_database("foo")).to be_a(Net::HTTPOK)
29
+ end
30
+ end
31
+
32
+ describe "#delete_database" do
33
+ before do
34
+ stub_request(:get, "http://influxdb.test:9999/query").with(
35
+ query: {u: "username", p: "password", q: "DROP DATABASE foo"}
36
+ )
37
+ end
38
+
39
+ it "should GET to remove a database" do
40
+ expect(subject.delete_database("foo")).to be_a(Net::HTTPOK)
41
+ end
42
+ end
43
+
44
+ describe "#list_databases" do
45
+ let(:response) { {"results"=>[{"series"=>[{"name"=>"databases", "columns"=>["name"], "values"=>[["foobar"]]}]}]} }
46
+ let(:expected_result) { [{"name"=>"foobar"}] }
47
+
48
+ before do
49
+ stub_request(:get, "http://influxdb.test:9999/query").with(
50
+ query: {u: "username", p: "password", q: "SHOW DATABASES"}
51
+ ).to_return(:body => JSON.generate(response), :status => 200)
52
+ end
53
+
54
+ it "should GET a list of databases" do
55
+ expect(subject.list_databases).to eq(expected_result)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ ### TODO ###
21
+
22
+ # describe "DELETE #delete_series" do
23
+ # it "removes a series" do
24
+ # stub_request(:delete, "http://influxdb.test:9999/db/database/series/foo").with(
25
+ # query: { u: "username", p: "password" }
26
+ # )
27
+
28
+ # expect(subject.delete_series("foo")).to be_a(Net::HTTPOK)
29
+ # end
30
+ # end
31
+
32
+ # describe "GET #list_series" do
33
+ # it "returns a list of all series names" do
34
+ # data = [
35
+ # { "name" => "list_series_result",
36
+ # "columns" => %w(time name),
37
+ # "points" => [[0, 'a'], [0, 'b']]
38
+ # }
39
+ # ]
40
+
41
+ # stub_request(:get, "http://influxdb.test:9999/db/database/series").with(
42
+ # query: { u: "username", p: "password", q: "list series", time_precision: "s" }
43
+ # ).to_return(
44
+ # body: JSON.generate(data)
45
+ # )
46
+
47
+ # expect(subject.list_series).to eq %w(a b)
48
+ # end
49
+ # end
50
+ end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ ### TODO ###
21
+
22
+ # describe "GET #list_shards" do
23
+ # it "returns a list of shards" do
24
+ # shard_list = { "longTerm" => [], "shortTerm" => [] }
25
+ # stub_request(:get, "http://influxdb.test:9999/cluster/shards").with(
26
+ # query: { u: "username", p: "password" }
27
+ # ).to_return(body: JSON.generate(shard_list, status: 200))
28
+
29
+ # expect(subject.list_shards).to eq shard_list
30
+ # end
31
+ # end
32
+
33
+ # describe "DELETE #delete_shard" do
34
+ # it "removes shard by id" do
35
+ # shard_id = 1
36
+ # stub_request(:delete, "http://influxdb.test:9999/cluster/shards/#{shard_id}").with(
37
+ # query: { u: "username", p: "password" }
38
+ # )
39
+
40
+ # expect(subject.delete_shard(shard_id, [1, 2])).to be_a(Net::HTTPOK)
41
+ # end
42
+ # end
43
+ end
@@ -0,0 +1,127 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ describe "#update user password" do
21
+ let(:user) { 'useruser' }
22
+ let(:pass) { 'passpass' }
23
+ let(:query) { "SET PASSWORD FOR #{user} = '#{pass}'" }
24
+
25
+ before do
26
+ stub_request(:get, "http://influxdb.test:9999/query").with(
27
+ query: {u: "username", p: "password", q: query}
28
+ )
29
+ end
30
+
31
+ it "should GET to update user password" do
32
+ expect(subject.update_user_password(user, pass)).to be_a(Net::HTTPOK)
33
+ end
34
+ end
35
+
36
+ describe "#grant_user_privileges" do
37
+ let(:user) { 'useruser' }
38
+ let(:perm) { :write }
39
+ let(:db) { 'foo' }
40
+ let(:query) { "GRANT #{perm.to_s.upcase} ON #{db} TO #{user}" }
41
+
42
+ before do
43
+ stub_request(:get, "http://influxdb.test:9999/query").with(
44
+ query: {u: "username", p: "password", q: query}
45
+ )
46
+ end
47
+
48
+ it "should GET to grant privileges for a user on a database" do
49
+ expect(subject.grant_user_privileges(user, db, perm)).to be_a(Net::HTTPOK)
50
+ end
51
+ end
52
+
53
+ describe "#revoke_user_privileges" do
54
+ let(:user) { 'useruser' }
55
+ let(:perm) { :write }
56
+ let(:db) { 'foo' }
57
+ let(:query) { "REVOKE #{perm.to_s.upcase} ON #{db} FROM #{user}" }
58
+
59
+ before do
60
+ stub_request(:get, "http://influxdb.test:9999/query").with(
61
+ query: {u: "username", p: "password", q: query}
62
+ )
63
+ end
64
+
65
+ it "should GET to revoke privileges from a user on a database" do
66
+ expect(subject.revoke_user_privileges(user, db, perm)).to be_a(Net::HTTPOK)
67
+ end
68
+ end
69
+
70
+ describe "#create_database_user" do
71
+ let(:user) { 'useruser' }
72
+ let(:pass) { 'passpass' }
73
+ let(:db) { 'foo' }
74
+ let(:query) { "CREATE user #{user} WITH PASSWORD '#{pass}'; GRANT ALL ON #{db} TO #{user}" }
75
+
76
+ before do
77
+ stub_request(:get, "http://influxdb.test:9999/query").with(
78
+ query: {u: "username", p: "password", q: query}
79
+ )
80
+ end
81
+
82
+ context "without specifying permissions" do
83
+ it "should GET to create a new database user with all permissions" do
84
+ expect(subject.create_database_user(db, user, pass)).to be_a(Net::HTTPOK)
85
+ end
86
+ end
87
+
88
+ context "with passing permission as argument" do
89
+ let(:permission) { :read }
90
+ let(:query) { "CREATE user #{user} WITH PASSWORD '#{pass}'; GRANT #{permission.to_s.upcase} ON #{db} TO #{user}" }
91
+
92
+ it "should GET to create a new database user with permission set" do
93
+ expect(subject.create_database_user(db, user, pass, permissions: permission)).to be_a(Net::HTTPOK)
94
+ end
95
+ end
96
+ end
97
+
98
+ describe "#delete_user" do
99
+ let(:user) { 'useruser' }
100
+ let(:query) { "DROP USER #{user}" }
101
+
102
+ before do
103
+ stub_request(:get, "http://influxdb.test:9999/query").with(
104
+ query: {u: "username", p: "password", q: query}
105
+ )
106
+ end
107
+
108
+ it "should GET to delete a user" do
109
+ expect(subject.delete_user(user)).to be_a(Net::HTTPOK)
110
+ end
111
+ end
112
+
113
+ describe "#list_users" do
114
+ let(:response) { {"results"=>[{"series"=>[{"columns"=>["user", "admin"], "values"=>[["dbadmin", true], ["foobar", false]]}]}]} }
115
+ let(:expected_result) { [{"username"=>"dbadmin", "admin"=>true}, {"username"=>"foobar", "admin"=>false}] }
116
+
117
+ before do
118
+ stub_request(:get, "http://influxdb.test:9999/query").with(
119
+ query: {u: "username", p: "password", q: "SHOW USERS"}
120
+ ).to_return(:body => JSON.generate(response, :status => 200))
121
+ end
122
+
123
+ it "should GET a list of database users" do
124
+ expect(subject.list_users).to eq(expected_result)
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,159 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+ let(:database) { subject.config.database }
20
+
21
+ describe "#query" do
22
+
23
+ context "with single series with multiple points" do
24
+ let(:response) do
25
+ {"results"=>[{"series"=>[{"name"=>"cpu", "tags"=>{"region"=>"us"},
26
+ "columns"=>["time", "temp", "value"],
27
+ "values"=>[["2015-07-07T14:58:37Z", 92, 0.3445], ["2015-07-07T14:59:09Z", 68, 0.8787]]}]}]}
28
+ end
29
+ let(:expected_result) do
30
+ [{"name"=>"cpu", "tags"=>{"region"=>"us"},
31
+ "values"=>[{"time"=>"2015-07-07T14:58:37Z", "temp"=>92, "value"=>0.3445},
32
+ {"time"=>"2015-07-07T14:59:09Z", "temp"=>68, "value"=>0.8787}]}]
33
+ end
34
+ let(:query) { 'SELECT * FROM cpu' }
35
+
36
+ before do
37
+ stub_request(:get, "http://influxdb.test:9999/query").with(
38
+ :query => {:q => query, :u => "username", :p => "password", :precision => 's', :db => database},
39
+ ).to_return(:body => JSON.generate(response))
40
+ end
41
+
42
+ it "should return array with single hash containing multiple values" do
43
+ expect(subject.query(query)).to eq(expected_result)
44
+ end
45
+ end
46
+
47
+ context "with series with different tags" do
48
+ let(:response) do
49
+ {"results"=>
50
+ [{"series"=>
51
+ [{"name"=>"cpu", "tags"=>{"region"=>"pl"}, "columns"=>["time", "temp", "value"], "values"=>[["2015-07-07T15:13:04Z", 34, 0.343443]]},
52
+ {"name"=>"cpu", "tags"=>{"region"=>"us"}, "columns"=>["time", "temp", "value"], "values"=>[["2015-07-07T14:58:37Z", 92, 0.3445], ["2015-07-07T14:59:09Z", 68, 0.8787]]}]}]}
53
+ end
54
+ let(:expected_result) do
55
+ [{"name"=>"cpu", "tags"=>{"region"=>"pl"},
56
+ "values"=>[{"time"=>"2015-07-07T15:13:04Z", "temp"=>34, "value"=>0.343443}]},
57
+ {"name"=>"cpu", "tags"=>{"region"=>"us"},
58
+ "values"=>[{"time"=>"2015-07-07T14:58:37Z", "temp"=>92, "value"=>0.3445},
59
+ {"time"=>"2015-07-07T14:59:09Z", "temp"=>68, "value"=>0.8787}]}]
60
+ end
61
+ let(:query) { 'SELECT * FROM cpu' }
62
+
63
+ before do
64
+ stub_request(:get, "http://influxdb.test:9999/query").with(
65
+ :query => {:q => query, :u => "username", :p => "password", :precision => 's', :db => database},
66
+ ).to_return(:body => JSON.generate(response))
67
+ end
68
+
69
+ it "should return array with 2 elements grouped by tags" do
70
+ expect(subject.query(query)).to eq(expected_result)
71
+ end
72
+ end
73
+
74
+ context "with multiple series with different tags" do
75
+ let(:response) do
76
+ {"results"=>
77
+ [{"series"=>
78
+ [{"name"=>"access_times.service_1", "tags"=>{"code"=>"200", "result"=>"failure", "status"=>"OK"}, "columns"=>["time", "value"], "values"=>[["2015-07-08T07:15:22Z", 327]]},
79
+ {"name"=>"access_times.service_1", "tags"=>{"code"=>"500", "result"=>"failure", "status"=>"Internal Server Error"}, "columns"=>["time", "value"], "values"=>[["2015-07-08T06:15:22Z", 873]]},
80
+ {"name"=>"access_times.service_2", "tags"=>{"code"=>"200", "result"=>"failure", "status"=>"OK"}, "columns"=>["time", "value"], "values"=>[["2015-07-08T07:15:22Z", 943]]},
81
+ {"name"=>"access_times.service_2", "tags"=>{"code"=>"500", "result"=>"failure", "status"=>"Internal Server Error"}, "columns"=>["time", "value"], "values"=>[["2015-07-08T06:15:22Z", 606]]}]}]}
82
+ end
83
+ let(:expected_result) do
84
+ [{"name"=>"access_times.service_1", "tags"=>{"code"=>"200", "result"=>"failure", "status"=>"OK"}, "values"=>[{"time"=>"2015-07-08T07:15:22Z", "value"=>327}]},
85
+ {"name"=>"access_times.service_1", "tags"=>{"code"=>"500", "result"=>"failure", "status"=>"Internal Server Error"}, "values"=>[{"time"=>"2015-07-08T06:15:22Z", "value"=>873}]},
86
+ {"name"=>"access_times.service_2", "tags"=>{"code"=>"200", "result"=>"failure", "status"=>"OK"}, "values"=>[{"time"=>"2015-07-08T07:15:22Z", "value"=>943}]},
87
+ {"name"=>"access_times.service_2", "tags"=>{"code"=>"500", "result"=>"failure", "status"=>"Internal Server Error"}, "values"=>[{"time"=>"2015-07-08T06:15:22Z", "value"=>606}]}]
88
+ end
89
+ let(:query) { "SELECT * FROM /access_times.*/" }
90
+
91
+ before do
92
+ stub_request(:get, "http://influxdb.test:9999/query").with(
93
+ :query => {:q => query, :u => "username", :p => "password", :precision => 's', :db => database},
94
+ ).to_return(:body => JSON.generate(response))
95
+ end
96
+
97
+ it "should return array with 4 elements grouped by name and tags" do
98
+ expect(subject.query(query)).to eq(expected_result)
99
+ end
100
+ end
101
+
102
+ context "with multiple series for explicit value only" do
103
+ let(:response) do
104
+ {"results"=>
105
+ [{"series"=>
106
+ [{"name"=>"access_times.service_1", "columns"=>["time", "value"], "values"=>[["2015-07-08T06:15:22Z", 873], ["2015-07-08T07:15:22Z", 327]]},
107
+ {"name"=>"access_times.service_2", "columns"=>["time", "value"], "values"=>[["2015-07-08T06:15:22Z", 606], ["2015-07-08T07:15:22Z", 943]]}]}]}
108
+ end
109
+ let(:expected_result) do
110
+ [{"name"=>"access_times.service_1", "tags"=>nil, "values"=>[{"time"=>"2015-07-08T06:15:22Z", "value"=>873}, {"time"=>"2015-07-08T07:15:22Z", "value"=>327}]},
111
+ {"name"=>"access_times.service_2", "tags"=>nil, "values"=>[{"time"=>"2015-07-08T06:15:22Z", "value"=>606}, {"time"=>"2015-07-08T07:15:22Z", "value"=>943}]}]
112
+ end
113
+ let(:query) { "SELECT value FROM /access_times.*/" }
114
+
115
+ before do
116
+ stub_request(:get, "http://influxdb.test:9999/query").with(
117
+ :query => {:q => query, :u => "username", :p => "password", :precision => 's', :db => database},
118
+ ).to_return(:body => JSON.generate(response))
119
+ end
120
+
121
+ it "should return array with 2 elements grouped by name only and no tags" do
122
+ expect(subject.query(query)).to eq(expected_result)
123
+ end
124
+ end
125
+
126
+ context "with a block" do
127
+ let(:response) do
128
+ {"results"=>
129
+ [{"series"=>
130
+ [{"name"=>"cpu", "tags"=>{"region"=>"pl"}, "columns"=>["time", "temp", "value"], "values"=>[["2015-07-07T15:13:04Z", 34, 0.343443]]},
131
+ {"name"=>"cpu", "tags"=>{"region"=>"us"}, "columns"=>["time", "temp", "value"], "values"=>[["2015-07-07T14:58:37Z", 92, 0.3445], ["2015-07-07T14:59:09Z", 68, 0.8787]]}]}]}
132
+ end
133
+
134
+ let(:expected_result) do
135
+ [{"name"=>"cpu", "tags"=>{"region"=>"pl"},
136
+ "values"=>[{"time"=>"2015-07-07T15:13:04Z", "temp"=>34, "value"=>0.343443}]},
137
+ {"name"=>"cpu", "tags"=>{"region"=>"us"},
138
+ "values"=>[{"time"=>"2015-07-07T14:58:37Z", "temp"=>92, "value"=>0.3445},
139
+ {"time"=>"2015-07-07T14:59:09Z", "temp"=>68, "value"=>0.8787}]}]
140
+ end
141
+ let(:query) { 'SELECT * FROM cpu' }
142
+
143
+ before do
144
+ stub_request(:get, "http://influxdb.test:9999/query").with(
145
+ :query => {:q => query, :u => "username", :p => "password", :precision => 's', :db => database},
146
+ ).to_return(:body => JSON.generate(response))
147
+ end
148
+
149
+ it "should accept a block and yield name, tags and points" do
150
+ results = []
151
+ subject.query(query) do |name, tags, points|
152
+ results << {'name' => name, 'tags' => tags, 'values' => points}
153
+ end
154
+ expect(results).to eq(expected_result)
155
+ end
156
+ end
157
+ end
158
+
159
+ end