copperegg-revealmetrics 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -19
- data/lib/copperegg/revealmetrics.rb +17 -0
- data/lib/copperegg/revealmetrics/api.rb +28 -0
- data/lib/copperegg/revealmetrics/custom_dashboard.rb +142 -0
- data/lib/copperegg/revealmetrics/metric_group.rb +127 -0
- data/lib/copperegg/revealmetrics/metric_sample.rb +26 -0
- data/lib/copperegg/revealmetrics/mixins/persistence.rb +124 -0
- data/lib/copperegg/revealmetrics/tag.rb +97 -0
- data/lib/copperegg/revealmetrics/ver.rb +7 -0
- data/test/custom_dashboard_test.rb +28 -28
- data/test/metric_group_test.rb +11 -11
- data/test/metric_sample_test.rb +2 -2
- data/test/tag_test.rb +12 -12
- metadata +9 -9
- data/lib/copperegg.rb +0 -13
- data/lib/copperegg/api.rb +0 -24
- data/lib/copperegg/custom_dashboard.rb +0 -138
- data/lib/copperegg/metric_group.rb +0 -123
- data/lib/copperegg/metric_sample.rb +0 -22
- data/lib/copperegg/mixins/persistence.rb +0 -118
- data/lib/copperegg/tag.rb +0 -94
- data/lib/copperegg/ver.rb +0 -3
@@ -0,0 +1,26 @@
|
|
1
|
+
module Copperegg
|
2
|
+
module Revealmetrics
|
3
|
+
|
4
|
+
class MetricSample
|
5
|
+
include Copperegg::Revealmetrics::Mixins::Persistence
|
6
|
+
|
7
|
+
resource "samples"
|
8
|
+
|
9
|
+
def self.save(group_name, identifier, timestamp, metric_values)
|
10
|
+
request(:id => group_name, :identifier => identifier, :timestamp => timestamp, :values => metric_values, :request_type => "post")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.samples(group_name, metrics, starttime=nil, duration=nil, sample_size=nil)
|
14
|
+
metrics = [metrics] unless metrics.is_a?(Array)
|
15
|
+
params = {}
|
16
|
+
params[:starttime] = starttime if starttime
|
17
|
+
params[:duration] = duration if duration
|
18
|
+
params[:sample_size] = sample_size if sample_size
|
19
|
+
params[:queries] = {group_name => [{:metrics => metrics}]}
|
20
|
+
|
21
|
+
request(params.merge(:request_type => "get"))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Copperegg
|
2
|
+
module Revealmetrics
|
3
|
+
|
4
|
+
class ValidationError < Exception;
|
5
|
+
end
|
6
|
+
|
7
|
+
class HttpError < Exception;
|
8
|
+
end
|
9
|
+
|
10
|
+
module Mixins
|
11
|
+
module Persistence
|
12
|
+
def self.included(klass)
|
13
|
+
klass.class_eval do
|
14
|
+
class << self
|
15
|
+
attr_reader :resource_name
|
16
|
+
|
17
|
+
def find(*args)
|
18
|
+
params = args.last.class == Hash ? args.pop : {}
|
19
|
+
id = args.first
|
20
|
+
response = request(params.merge(:request_type => "get", :id => id))
|
21
|
+
if response.code == "200"
|
22
|
+
json = JSON.parse(response.body)
|
23
|
+
if json.is_a?(Array)
|
24
|
+
json.map { |attributes| new(attributes) }
|
25
|
+
else
|
26
|
+
new(json)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create(params)
|
32
|
+
params.delete(:id)
|
33
|
+
params.delete("id")
|
34
|
+
new(params).save
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(id)
|
38
|
+
request(:id => id, :request_type => "delete")
|
39
|
+
end
|
40
|
+
|
41
|
+
def request(params={})
|
42
|
+
request_type = params.delete(:request_type)
|
43
|
+
raise "invalid type `#{request_type}`" if !%w(get post put delete).include?(request_type)
|
44
|
+
id = params.delete(:id)
|
45
|
+
|
46
|
+
uri = id ? URI.parse("#{Api.uri}/#{self.resource_name}/#{id}.json") : URI.parse("#{Api.uri}/#{self.resource_name}.json")
|
47
|
+
|
48
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
49
|
+
http.use_ssl = uri.scheme == 'https'
|
50
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if !Api.ssl_verify_peer
|
51
|
+
|
52
|
+
request = Net::HTTP.const_get(request_type.capitalize).new(uri.request_uri)
|
53
|
+
request.body = JSON.generate(params) unless params.empty?
|
54
|
+
request.basic_auth(Api.apikey, "U")
|
55
|
+
request["Content-Type"] = "application/json"
|
56
|
+
|
57
|
+
begin
|
58
|
+
response = http.request(request)
|
59
|
+
rescue Exception => e
|
60
|
+
raise e
|
61
|
+
end
|
62
|
+
|
63
|
+
response
|
64
|
+
end
|
65
|
+
|
66
|
+
def request_200(params={})
|
67
|
+
response = request(params)
|
68
|
+
unless response.code === "200"
|
69
|
+
raise HttpError.new("HTTP request failed with code `#{response.code}`: `#{response.body}`")
|
70
|
+
end
|
71
|
+
response
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def resource(value)
|
77
|
+
@resource_name = value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
attr_reader :id, :error
|
84
|
+
|
85
|
+
def initialize(attributes={})
|
86
|
+
load_attributes(attributes)
|
87
|
+
end
|
88
|
+
|
89
|
+
def save
|
90
|
+
if valid?
|
91
|
+
response = persisted? ? update : create
|
92
|
+
attributes = JSON.parse(response.body)
|
93
|
+
if response.code != "200"
|
94
|
+
@error = attributes.merge("code" => response.code)
|
95
|
+
else
|
96
|
+
load_attributes(attributes)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
raise ValidationError.new(@error)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def delete
|
104
|
+
self.class.request(:id => @id, :request_type => "delete")
|
105
|
+
end
|
106
|
+
|
107
|
+
def persisted?
|
108
|
+
!@id.nil?
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def create
|
114
|
+
self.class.request(to_hash.merge(:request_type => "post"))
|
115
|
+
end
|
116
|
+
|
117
|
+
def update
|
118
|
+
self.class.request(to_hash.merge(:id => @id, :request_type => "put"))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Copperegg
|
2
|
+
module Revealmetrics
|
3
|
+
|
4
|
+
class Tag
|
5
|
+
include Copperegg::Revealmetrics::Mixins::Persistence
|
6
|
+
|
7
|
+
resource "tags"
|
8
|
+
|
9
|
+
attr_accessor :name, :objects
|
10
|
+
|
11
|
+
def load_attributes(attributes)
|
12
|
+
@objects_original = []
|
13
|
+
|
14
|
+
attributes.each do |name, value|
|
15
|
+
if name.to_s == "id"
|
16
|
+
@id = value
|
17
|
+
elsif !respond_to?("#{name}=")
|
18
|
+
next
|
19
|
+
elsif name.to_s == "objects"
|
20
|
+
@objects = value.map { |object| object["idv"].to_s.gsub(/\|$/, "") }
|
21
|
+
@objects_original = @objects.clone
|
22
|
+
else
|
23
|
+
send "#{name}=", value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def name
|
29
|
+
@name || @id
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid?
|
33
|
+
@error = nil
|
34
|
+
|
35
|
+
if self.name.nil? || self.name.to_s.strip.empty?
|
36
|
+
@error = "Name can't be blank."
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
if self.name.to_s.match(/[^\w-]/)
|
41
|
+
@error = "Name contains invalid characters."
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
|
45
|
+
if self.objects.nil? || self.objects.empty?
|
46
|
+
@error = "You must define at least one object."
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
|
50
|
+
unless self.objects.kind_of?(Array)
|
51
|
+
@error = "Invalid objects field."
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
|
55
|
+
if self.objects.any? { |object| !object.kind_of?(String) }
|
56
|
+
@error = "Invalid object identifier."
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete
|
64
|
+
self.class.request_200({:id => name, :request_type => "delete"})
|
65
|
+
end
|
66
|
+
|
67
|
+
def save
|
68
|
+
unless valid?
|
69
|
+
raise ValidationError.new(@error)
|
70
|
+
end
|
71
|
+
|
72
|
+
remove_objects(@objects_original - @objects)
|
73
|
+
add_objects(@objects - @objects_original)
|
74
|
+
@objects_original = @objects
|
75
|
+
end
|
76
|
+
|
77
|
+
def update
|
78
|
+
save
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_hash
|
82
|
+
{"tag" => name, "ids" => objects}
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def remove_objects(ids)
|
88
|
+
self.class.request_200({:id => name, :ids => ids, :request_type => "delete"}) unless ids.empty?
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_objects(ids)
|
92
|
+
self.class.request_200({:tag => name, :ids => ids, :request_type => "post"}) unless ids.empty?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -1,108 +1,108 @@
|
|
1
1
|
require "test/unit"
|
2
|
-
require "copperegg"
|
2
|
+
require "copperegg/revealmetrics"
|
3
3
|
|
4
4
|
class CustomDashboardTest < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def test_name_accessor_and_setter
|
7
|
-
dashboard =
|
7
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
8
8
|
|
9
9
|
assert_equal "My Dashboard", dashboard.name
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_save_should_fail_if_name_is_not_set
|
13
|
-
dashboard =
|
13
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new
|
14
14
|
|
15
|
-
error = assert_raise(
|
15
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
16
16
|
assert_equal "Name can't be blank.", error.message
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_save_should_fail_for_an_invalid_widget_type
|
20
|
-
dashboard =
|
21
|
-
dashboard.data["widgets"]["0"] = {:type => "foo", :style => "value", :match => "tag", :match_param => ["test"],
|
20
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
21
|
+
dashboard.data["widgets"]["0"] = {:type => "foo", :style => "value", :match => "tag", :match_param => ["test"],
|
22
22
|
:metric => {"my_metric_group" => [[0, "metric1"]]}}
|
23
23
|
|
24
|
-
error = assert_raise(
|
24
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
25
25
|
assert_equal "Invalid widget type foo.", error.message
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_save_should_fail_for_an_invalid_widget_style
|
29
|
-
dashboard =
|
30
|
-
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "foo", :match => "tag", :match_param => ["test"],
|
29
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
30
|
+
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "foo", :match => "tag", :match_param => ["test"],
|
31
31
|
:metric => {"my_metric_group" => [[0, "metric1"]]}}
|
32
32
|
|
33
|
-
error = assert_raise(
|
33
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
34
34
|
assert_equal "Invalid widget style foo.", error.message
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_save_should_ail_for_an_invalidvwidget_match
|
38
|
-
dashboard =
|
38
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
39
39
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "foo", :match_param => ["test"],
|
40
40
|
:metric => {"my_metric_group" => [[0, "metric1"]]}}
|
41
41
|
|
42
|
-
error = assert_raise(
|
42
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
43
43
|
assert_equal "Invalid widget match foo.", error.message
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_save_should_fail_for_a_missing_match_parameter
|
47
|
-
dashboard =
|
47
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
48
48
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "select", :metric => {"my_metric_group" => [[0, "metric1"]]}}
|
49
49
|
|
50
|
-
error = assert_raise(
|
50
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
51
51
|
assert_equal "Missing match parameter.", error.message
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_save_should_fail_if_metric_is_not_a_hash
|
55
|
-
dashboard =
|
55
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
56
56
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => ["my_metric_group", 0, "metric1"]}
|
57
57
|
|
58
|
-
error = assert_raise(
|
58
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
59
59
|
assert_match /invalid widget metric/i, error.message
|
60
60
|
end
|
61
61
|
|
62
62
|
def test_save_should_fail_if_metric_does_not_contain_an_array
|
63
|
-
dashboard =
|
63
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
64
64
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => "metric1"}}
|
65
65
|
|
66
|
-
error = assert_raise(
|
66
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
67
67
|
assert_match /invalid widget metric/i, error.message
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_save_should_fail_if_metric_contains_an_empty_array
|
71
|
-
dashboard =
|
71
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
72
72
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => []}}
|
73
73
|
|
74
|
-
error = assert_raise(
|
74
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
75
75
|
assert_match /invalid widget metric/i, error.message
|
76
76
|
end
|
77
77
|
|
78
78
|
def test_save_should_fail_if_metric_contains_an_array_with_invalid_values
|
79
|
-
dashboard =
|
79
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
80
80
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => ["metric1"]}}
|
81
81
|
|
82
|
-
error = assert_raise(
|
82
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
83
83
|
assert_match /invalid widget metric/i, error.message
|
84
84
|
end
|
85
85
|
|
86
86
|
def test_save_should_fail_if_metric_contains_an_array_with_an_invalid_position
|
87
|
-
dashboard =
|
87
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
88
88
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [["four", "metric1"]]}}
|
89
89
|
|
90
|
-
error = assert_raise(
|
90
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
91
91
|
assert_match /invalid widget metric/i, error.message
|
92
92
|
end
|
93
93
|
|
94
94
|
def test_save_should_fail_if_metric_contains_an_array_with_no_metric_name
|
95
|
-
dashboard =
|
95
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
96
96
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[0]]}}
|
97
97
|
|
98
|
-
error = assert_raise(
|
98
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { dashboard.save }
|
99
99
|
assert_match /invalid widget metric/i, error.message
|
100
100
|
end
|
101
101
|
|
102
102
|
def test_to_hash
|
103
|
-
dashboard =
|
103
|
+
dashboard = Copperegg::Revealmetrics::CustomDashboard.new(:name => "My Dashboard")
|
104
104
|
dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[1, "metric1"]]}}
|
105
|
-
|
105
|
+
|
106
106
|
assert dashboard.valid?
|
107
107
|
|
108
108
|
hash = dashboard.to_hash
|
data/test/metric_group_test.rb
CHANGED
@@ -1,44 +1,44 @@
|
|
1
1
|
require "test/unit"
|
2
|
-
require "copperegg"
|
2
|
+
require "copperegg/revealmetrics"
|
3
3
|
|
4
4
|
class MetricGroupTest < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def test_name_accessor_and_setter
|
7
|
-
metric_group =
|
7
|
+
metric_group = Copperegg::Revealmetrics::MetricGroup.new(:name => "my_metric_group")
|
8
8
|
|
9
9
|
assert_equal "my_metric_group", metric_group.name
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_save_should_fail_if_name_is_blank
|
13
|
-
metric_group =
|
13
|
+
metric_group = Copperegg::Revealmetrics::MetricGroup.new
|
14
14
|
|
15
|
-
error = assert_raise(
|
15
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { metric_group.save }
|
16
16
|
assert_equal "Name can't be blank.", error.message
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_save_should_fail_if_no_metrics_are_declared
|
20
|
-
metric_group =
|
20
|
+
metric_group = Copperegg::Revealmetrics::MetricGroup.new(:name => "my_metric_group")
|
21
21
|
|
22
|
-
error = assert_raise(
|
22
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { metric_group.save }
|
23
23
|
assert_equal "You must define at least one metric.", error.message
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_save_should_fail_if_metrics_include_non_metric
|
27
|
-
metric_group =
|
27
|
+
metric_group = Copperegg::Revealmetrics::MetricGroup.new(:name => "my_metric_group", :metrics => ["metric"])
|
28
28
|
|
29
|
-
error = assert_raise(
|
29
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { metric_group.save }
|
30
30
|
assert_equal "Metric expected.", error.message
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_save_should_fail_for_invalid_metric
|
34
|
-
metric_group =
|
34
|
+
metric_group = Copperegg::Revealmetrics::MetricGroup.new(:name => "my_metric_group", :metrics => [{:name => "test", :type => "invalid"}])
|
35
35
|
|
36
|
-
error = assert_raise(
|
36
|
+
error = assert_raise(Copperegg::Revealmetrics::ValidationError) { metric_group.save }
|
37
37
|
assert_equal "Invalid metric type invalid.", error.message
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_to_hash
|
41
|
-
metric_group =
|
41
|
+
metric_group = Copperegg::Revealmetrics::MetricGroup.new(:name => "test", :label => "Test Metric", :frequency => 5)
|
42
42
|
metric_group.metrics << {:type => "ce_counter", :name => "metric1", :label => "Metric 1", :unit => "ticks"}
|
43
43
|
metric_group.metrics << {:type => "ce_counter_f", :name => "metric2", :label => "Metric 2"}
|
44
44
|
|