logcamp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aca5ccf7efebae1e58f0478f31513e2879476186
4
+ data.tar.gz: d71ce91b422f4b7315cfe28812bacb3eef3d9eac
5
+ SHA512:
6
+ metadata.gz: ae62badee2be9561b800df11817428d248c1c1930e3b06347930da64dd077b9a1635286351a2b2c78355f0789322d27f9723d0a467e008963c0fec04c2475d35
7
+ data.tar.gz: 0fed04155057e5889e74cd936778d5c6c1a63442f285de45d3dd2a65aedc43f53bab1fcbf0fe133efc83639dc82a02b5f515008fd4d4945ee7816f744044bab2
@@ -0,0 +1,52 @@
1
+ # Logcamp::Ruby
2
+
3
+ [![Build Status](https://semaphoreapp.com/api/v1/projects/0d7ed887-f4de-410c-a678-eb47c9c66aa8/275246/shields_badge.svg)](https://semaphoreapp.com/olimart/logcamp-ruby)
4
+
5
+ Simple gem for communicating with external API. Heavily inspired by stripe gem.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'logcamp-ruby'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install logcamp-ruby
20
+
21
+ ## Usage
22
+
23
+ In your app
24
+
25
+ 1. Set token
26
+
27
+ ```ruby
28
+ Logcamp.token = ENV['LOGCAMP_TOKEN']
29
+ ```
30
+
31
+ 2. Send event
32
+
33
+ ```ruby
34
+ Logcamp::Event.create(
35
+ status: 'event status',
36
+ message: 'notification message',
37
+ alert: true,
38
+ metadata: {
39
+ key1: value1,
40
+ key2: value2
41
+ }
42
+ )
43
+ ```
44
+
45
+ **For Sinatra app** you may need to add `require 'bundler/setup'`
46
+
47
+
48
+ ## Tests
49
+
50
+ ```ruby
51
+ rake test
52
+ ```
@@ -0,0 +1,145 @@
1
+ # Logcamp Ruby bindings
2
+ require "cgi"
3
+ require "set"
4
+ require "openssl"
5
+ require "json"
6
+ require "net/http"
7
+ require "uri"
8
+
9
+ # Version
10
+ require "logcamp/version"
11
+
12
+ # API operations
13
+ require "logcamp/api_operations/create"
14
+
15
+ # Resources
16
+ require "logcamp/logcamp_object"
17
+ require "logcamp/api_resource"
18
+ require "logcamp/event"
19
+
20
+ # Errors
21
+ require "logcamp/errors/logcamp_error"
22
+ require "logcamp/errors/api_error"
23
+ require "logcamp/errors/api_connection_error"
24
+ require "logcamp/errors/invalid_request_error"
25
+ require "logcamp/errors/invalid_metadata_error"
26
+ require "logcamp/errors/authentication_error"
27
+
28
+ module Logcamp
29
+ @api_base = "https://logcamp.herokuapp.com/api"
30
+
31
+ class << self
32
+ attr_accessor :token, :api_base, :verify_ssl_certs, :api_version
33
+ end
34
+
35
+ def self.api_url(url="")
36
+ @api_base + url
37
+ end
38
+
39
+ def self.request(method, url, token, params={}, headers={})
40
+ unless token ||= @token
41
+ raise AuthenticationError.new("No token provided")
42
+ end
43
+
44
+ if !params[:metadata].nil? && params[:metadata].class != Hash
45
+ raise InvalidMetadataError.new("Invalid metadata. Only key value pair is supported", params)
46
+ else
47
+ params[:metadata] = params[:metadata].to_json
48
+ end
49
+
50
+ url = api_url(url)
51
+
52
+ begin
53
+
54
+ uri = URI(url)
55
+ request = Net::HTTP::Post.new(uri) if method == :post
56
+
57
+ request["User-Agent"] = "Logcamp-ruby gem"
58
+ request["Authorization"] = "Token token=\"#{token}\""
59
+ request["Content-Type"] = "application/json"
60
+ request.body = params.to_json
61
+
62
+ http = Net::HTTP.new(uri.hostname, uri.port)
63
+
64
+ # see http://www.rubyinside.com/how-to-cure-nethttps-risky-default-https-behavior-4010.html
65
+ # for info about ssl verification
66
+
67
+ http.use_ssl = true if uri.scheme == "https"
68
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if uri.scheme == "https"
69
+
70
+ response = http.start {|h|
71
+ h.request(request)
72
+ }
73
+
74
+ # since http.request doesn't throw such exceptions, check them by status codes
75
+ handle_api_error(response.code, response.body)
76
+
77
+ rescue SocketError => e
78
+ handle_connection_error(e)
79
+ rescue NoMethodError => e
80
+ handle_connection_error(e)
81
+ rescue OpenSSL::SSL::SSLError => e
82
+ handle_connection_error(e)
83
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e
84
+ handle_connection_error(e)
85
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
86
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, InvalidMetadataError => e
87
+ handle_connection_error(e)
88
+ end
89
+
90
+ [response, token]
91
+ end
92
+
93
+ def self.handle_connection_error(e)
94
+ case e
95
+ when SocketError
96
+ message = "Unexpected error when trying to connect to Logcamp"
97
+ when NoMethodError
98
+ message = "Unexpected HTTP response code"
99
+ when InvalidMetadataError
100
+ message = "Invalid metadata. Only key value pair is supported"
101
+ else
102
+ message = "Unexpected error communicating with Logcamp"
103
+ end
104
+
105
+ raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
106
+ end
107
+
108
+ def self.handle_api_error(rcode, rbody)
109
+ begin
110
+ error_obj = JSON.parse(rbody)
111
+ rescue JSON::ParserError
112
+ raise general_api_error(rcode, rbody)
113
+ end
114
+
115
+ case rcode
116
+ when 400, 404, 422
117
+ raise invalid_request_error error, rcode, rbody, error_obj
118
+ when 401
119
+ raise authentication_error error, rcode, rbody, error_obj
120
+ when 500
121
+ raise api_error error, rcode, rbody, error_obj
122
+ else
123
+ # raise api_error error, rcode, rbody, error_obj
124
+ end
125
+
126
+ end
127
+
128
+ def self.invalid_request_error(error, rcode, rbody, error_obj)
129
+ InvalidRequestError.new(error[:message], error[:param], rcode,
130
+ rbody, error_obj)
131
+ end
132
+
133
+ def self.authentication_error(error, rcode, rbody, error_obj)
134
+ AuthenticationError.new(error[:message], rcode, rbody, error_obj)
135
+ end
136
+
137
+ def self.api_error(error, rcode, rbody, error_obj)
138
+ APIError.new(error[:message], rcode, rbody, error_obj)
139
+ end
140
+
141
+ def self.general_api_error(rcode, rbody)
142
+ APIError.new("Invalid response object from API: #{rbody.inspect} " +
143
+ "(HTTP response code was #{rcode})", rcode, rbody)
144
+ end
145
+ end
@@ -0,0 +1,16 @@
1
+ module Logcamp
2
+ module APIOperations
3
+ module Create
4
+ module ClassMethods
5
+ def create(params={}, token=nil)
6
+ response, token = Logcamp.request(:post, self.url, token, params)
7
+ response
8
+ end
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module Logcamp
2
+ class APIResource < LogcampObject
3
+ def self.class_name
4
+ self.name.split('::')[-1]
5
+ end
6
+
7
+ def self.url()
8
+ if self == APIResource
9
+ raise NotImplementedError.new('APIResource is an abstract class. You should perform actions on its subclasses)')
10
+ end
11
+ "/#{CGI.escape(class_name.downcase)}s"
12
+ end
13
+
14
+ def url
15
+ unless id = self['id']
16
+ raise InvalidRequestError.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{id.inspect}", 'id')
17
+ end
18
+ "#{self.class.url}/#{CGI.escape(id)}"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module Logcamp
2
+ class APIConnectionError < LogcampError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Logcamp
2
+ class APIError < LogcampError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Logcamp
2
+ class AuthenticationError < LogcampError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Logcamp
2
+ class InvalidMetadataError < LogcampError
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ module Logcamp
2
+ class InvalidRequestError < LogcampError
3
+ attr_accessor :param
4
+
5
+ def initialize(message, param, http_status=nil, http_body=nil, json_body=nil)
6
+ super(message, http_status, http_body, json_body)
7
+ @param = param
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ module Logcamp
2
+ class LogcampError < StandardError
3
+ attr_reader :message
4
+ attr_reader :http_status
5
+ attr_reader :http_body
6
+ attr_reader :json_body
7
+
8
+ def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
9
+ @message = message
10
+ @http_status = http_status
11
+ @http_body = http_body
12
+ @json_body = json_body
13
+ end
14
+
15
+ def to_s
16
+ status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
17
+ "#{status_string}#{@message}"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ module Logcamp
2
+ class Event < APIResource
3
+ include Logcamp::APIOperations::Create
4
+
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Logcamp
2
+ class LogcampObject
3
+
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Logcamp
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path("../../test_helper", __FILE__)
2
+
3
+ module Logcamp
4
+ class EventTest < Test::Unit::TestCase
5
+ should "create should return status 201" do
6
+ response = Logcamp::Event.create(status: 'success', message: 'Event occured',
7
+ alert: true,
8
+ metadata: { date: Time.now })
9
+ assert_equal "201", response.code
10
+ end
11
+
12
+ should "raise Logcamp::AuthenticationError if no token provided" do
13
+ Logcamp.token = nil
14
+ assert_raises(Logcamp::AuthenticationError) { Logcamp::Event.create }
15
+ end
16
+
17
+ should "raise Logcamp::InvalidRequestError if not enough parameters" do
18
+ begin
19
+ rescue JSON::ParserError
20
+ assert_raises(Logcamp::InvalidRequestError) { Logcamp::Event.create }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require "logcamp"
2
+ require "test/unit"
3
+ require "shoulda"
4
+
5
+ class Test::Unit::TestCase
6
+
7
+ setup do
8
+ Logcamp.token = "111"
9
+ end
10
+
11
+ teardown do
12
+ Logcamp.token = nil
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logcamp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Olivier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
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: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.8.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.8.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: shoulda
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.4.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 3.4.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 5.4.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 5.4.0
97
+ description: Aggregate app notifications in one place. Search events and share access
98
+ email:
99
+ - olivier@yafoy.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - README.md
105
+ - lib/logcamp.rb
106
+ - lib/logcamp/api_operations/create.rb
107
+ - lib/logcamp/api_resource.rb
108
+ - lib/logcamp/errors/api_connection_error.rb
109
+ - lib/logcamp/errors/api_error.rb
110
+ - lib/logcamp/errors/authentication_error.rb
111
+ - lib/logcamp/errors/invalid_metadata_error.rb
112
+ - lib/logcamp/errors/invalid_request_error.rb
113
+ - lib/logcamp/errors/logcamp_error.rb
114
+ - lib/logcamp/event.rb
115
+ - lib/logcamp/logcamp_object.rb
116
+ - lib/logcamp/version.rb
117
+ - test/logcamp/event_test.rb
118
+ - test/test_helper.rb
119
+ homepage: https://github.com/camplog/logcamp-ruby
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.4.2
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Gem to send app-generated event notifications to logcamp master application
143
+ test_files:
144
+ - test/logcamp/event_test.rb
145
+ - test/test_helper.rb