flowthings 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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +9 -0
  6. data/Guardfile +77 -0
  7. data/LICENSE +202 -0
  8. data/README.md +161 -0
  9. data/Rakefile +2 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +7 -0
  12. data/flowthings.gemspec +31 -0
  13. data/lib/flowthings/client.rb +63 -0
  14. data/lib/flowthings/configuration.rb +39 -0
  15. data/lib/flowthings/connection.rb +23 -0
  16. data/lib/flowthings/crud/aggregate.rb +18 -0
  17. data/lib/flowthings/crud/base.rb +41 -0
  18. data/lib/flowthings/crud/extended_methods.rb +26 -0
  19. data/lib/flowthings/crud/find.rb +13 -0
  20. data/lib/flowthings/crud/member_update.rb +14 -0
  21. data/lib/flowthings/crud/simulate.rb +13 -0
  22. data/lib/flowthings/error.rb +30 -0
  23. data/lib/flowthings/platform_objects/api_task.rb +6 -0
  24. data/lib/flowthings/platform_objects/drop.rb +29 -0
  25. data/lib/flowthings/platform_objects/flow.rb +12 -0
  26. data/lib/flowthings/platform_objects/group.rb +10 -0
  27. data/lib/flowthings/platform_objects/identity.rb +10 -0
  28. data/lib/flowthings/platform_objects/mqtt.rb +8 -0
  29. data/lib/flowthings/platform_objects/platform_object_interface.rb +44 -0
  30. data/lib/flowthings/platform_objects/share.rb +9 -0
  31. data/lib/flowthings/platform_objects/token.rb +9 -0
  32. data/lib/flowthings/platform_objects/track.rb +12 -0
  33. data/lib/flowthings/request.rb +59 -0
  34. data/lib/flowthings/response/platform_response.rb +16 -0
  35. data/lib/flowthings/response/raise_errors.rb +42 -0
  36. data/lib/flowthings/utils/crud_utils.rb +96 -0
  37. data/lib/flowthings/utils/member.rb +0 -0
  38. data/lib/flowthings/version.rb +3 -0
  39. data/lib/flowthings.rb +7 -0
  40. data/spec/client_configuration_spec.rb +67 -0
  41. data/spec/client_spec.rb +51 -0
  42. data/spec/configuration_spec.rb +28 -0
  43. data/spec/flowthings_spec.rb +7 -0
  44. data/spec/platform_object_interface_spec.rb +12 -0
  45. data/spec/platform_objects/api_task_spec.rb +92 -0
  46. data/spec/platform_objects/drop_spec.rb +180 -0
  47. data/spec/platform_objects/flow_spec.rb +83 -0
  48. data/spec/platform_objects/platform_objects_spec.rb +73 -0
  49. data/spec/platform_objects/track_spec.rb +46 -0
  50. data/spec/spec_helper.rb +5 -0
  51. metadata +192 -0
@@ -0,0 +1,41 @@
1
+ require 'flowthings/utils/crud_utils'
2
+
3
+ module Flowthings
4
+ module Crud
5
+ module Base
6
+ include Flowthings::CrudUtils
7
+
8
+ def create(data, params={})
9
+ path = mk_path
10
+ params = mk_params(params)
11
+ data = mk_data(data)
12
+
13
+ platform_post(path, params=params, data=data)
14
+ end
15
+
16
+ def read(id, params={})
17
+ path = mk_path({id: id})
18
+ params = mk_params(params)
19
+
20
+ platform_get(path, params=params)
21
+ end
22
+
23
+ def update(id, data, params={})
24
+ path = mk_path(id: id)
25
+ params = mk_params(params)
26
+ data = mk_data(data)
27
+
28
+ platform_put(path, params=params, data=data)
29
+ end
30
+
31
+ def destroy(id, params={})
32
+ path = mk_path({id: id})
33
+ params = mk_params(params)
34
+
35
+ platform_delete(path, params=params)
36
+ end
37
+
38
+ alias_method :delete, :destroy
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,26 @@
1
+ module Flowthings
2
+ module Crud
3
+ module ExtendedMethods
4
+ def delete_all(params={})
5
+ end
6
+
7
+ def find_many(filters={}, params={})
8
+ path = mk_path
9
+ params = mk_params(params)
10
+ data = []
11
+
12
+ @flowIds.each do flowId
13
+ if filters[flowId]
14
+ data << {"flowId" => flowId,
15
+ "params" => filters[flowId]}
16
+ else
17
+ data << {"flowId" => flowId}
18
+ end
19
+ end
20
+
21
+
22
+ platform_mget(path, params=params, data=data)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ module Flowthings
2
+ module Crud
3
+ module Find
4
+ def find(params={})
5
+ path_params = {}
6
+ path = mk_path(path_params)
7
+ params = mk_params(params)
8
+
9
+ platform_get(path, params=params)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Flowthings
2
+ module Crud
3
+ module MemberUpdate
4
+ def member_update(id, member_name, data, params)
5
+ path = mk_path({tail: member_name,
6
+ id: id})
7
+ params = mk_params(params)
8
+ data = mk_data(data)
9
+
10
+ platform_put(path, params=params, data=data)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Flowthings
2
+ module Crud
3
+ module Simulate
4
+ def simulate(data, params={})
5
+ path = mk_path({tail: "simulate"})
6
+ params = mk_params(params)
7
+ data = mk_data(data)
8
+
9
+ platform_post(path, params=params, data=data)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ module Flowthings
2
+ class Error < StandardError
3
+ def initialize(message="")
4
+ if message
5
+ super(message)
6
+ end
7
+ end
8
+ end
9
+
10
+ class Error::HttpError < Flowthings::Error
11
+ attr_reader :http_headers
12
+
13
+ def initialize(message, http_headers="")
14
+ @http_headers = http_headers
15
+ super(message)
16
+ end
17
+ end
18
+
19
+ class Error::ObjectError < Flowthings::Error; end
20
+
21
+ class Error::ServerError < Error::HttpError; end
22
+ class Error::ServiceUnavailable < Error::ServerError; end
23
+
24
+ class Error::ClientError < Error::HttpError; end
25
+ class Error::Forbidden < Error::ClientError; end
26
+ class Error::NotFound < Error::ClientError; end
27
+ class Error::BadRequest < Error::ClientError; end
28
+ class Error::RequestTooLarge < Error::ClientError; end
29
+
30
+ end
@@ -0,0 +1,6 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+
3
+ module Flowthings
4
+ class ApiTask < PlatformObjectInterface
5
+ end
6
+ end
@@ -0,0 +1,29 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+ require 'flowthings/crud/extended_methods'
3
+ require 'flowthings/crud/find'
4
+ require 'flowthings/crud/member_update'
5
+ require 'flowthings/crud/aggregate'
6
+
7
+ module Flowthings
8
+
9
+ class Drop < PlatformObjectInterface
10
+ include Flowthings::Crud::ExtendedMethods
11
+ include Flowthings::Crud::Find
12
+ include Flowthings::Crud::MemberUpdate
13
+ include Flowthings::Crud::Aggregate
14
+
15
+ attr_accessor :flowId
16
+
17
+ def initialize(flowId, connection, options={})
18
+ if flowId.kind_of? Array
19
+ @flowIds = flowId
20
+ else
21
+ @flowId = flowId
22
+ end
23
+
24
+ super connection, options
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,12 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+ require 'flowthings/crud/find'
3
+ require 'flowthings/crud/member_update'
4
+
5
+ module Flowthings
6
+
7
+ class Flow < PlatformObjectInterface
8
+ include Flowthings::Crud::Find
9
+ include Flowthings::Crud::MemberUpdate
10
+ end
11
+
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+ require 'flowthings/crud/find'
3
+
4
+ module Flowthings
5
+
6
+ class Group < PlatformObjectInterface
7
+ include Flowthings::Crud::Find
8
+ end
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+ require 'flowthings/crud/find'
3
+
4
+ module Flowthings
5
+
6
+ class Identity < PlatformObjectInterface
7
+ include Flowthings::Crud::Find
8
+ end
9
+
10
+ end
@@ -0,0 +1,8 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+
3
+ module Flowthings
4
+
5
+ class Mqtt < PlatformObjectInterface
6
+ end
7
+
8
+ end
@@ -0,0 +1,44 @@
1
+ require 'flowthings/request'
2
+ require 'flowthings/connection'
3
+ require 'flowthings/crud/base'
4
+ require 'flowthings/error'
5
+
6
+ module Flowthings
7
+
8
+ class PlatformObjectInterface
9
+
10
+ include Flowthings::Request
11
+ include Flowthings::Crud::Base
12
+
13
+ @path_array = []
14
+
15
+ # make a class variable here, a hash,
16
+ # that holds all the various endpoints in it
17
+
18
+ # then make a call here to query the object type
19
+ # and give it the right endpoint function type.
20
+
21
+ def initialize(connection, options={})
22
+ check_platform_object
23
+
24
+ Configuration::VALID_CONFIG_KEYS.each do |key|
25
+ instance_variable_set("@#{key}", options[key])
26
+ end
27
+
28
+ @connection = connection
29
+
30
+ @account_name=options[:account_name]
31
+ @account_token=options[:account_token]
32
+ end
33
+
34
+
35
+ private
36
+ def check_platform_object
37
+ if self.class == PlatformObjectInterface
38
+ raise Flowthings::Error::ObjectError, "Use the actual platform objects"
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,9 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+
3
+ module Flowthings
4
+
5
+ class Share < PlatformObjectInterface
6
+ undef_method :update
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+
3
+ module Flowthings
4
+
5
+ class Token < PlatformObjectInterface
6
+ undef_method :update
7
+ end
8
+
9
+ end
@@ -0,0 +1,12 @@
1
+ require 'flowthings/platform_objects/platform_object_interface'
2
+ require 'flowthings/crud/find'
3
+ require 'flowthings/crud/simulate'
4
+
5
+ module Flowthings
6
+
7
+ class Track < PlatformObjectInterface
8
+ include Flowthings::Crud::Find
9
+ include Flowthings::Crud::Simulate
10
+ end
11
+
12
+ end
@@ -0,0 +1,59 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+ require 'flowthings/response/raise_errors'
5
+
6
+ module Flowthings
7
+ module Request
8
+
9
+ include Flowthings::Response::RaiseErrors
10
+
11
+ private
12
+
13
+ def platform_get(path, params={}, options={})
14
+ request(:get, path, params, options)
15
+ end
16
+
17
+ def platform_post(path, data, params={}, options={})
18
+ request(:post, path, params, options, data=data)
19
+ end
20
+
21
+ def platform_put(path, data, params={}, options={})
22
+ request(:put, path, params, options, data=data)
23
+ end
24
+
25
+ def platform_mget(path, data, params={}, options={})
26
+ request(:mget, path, params, options, data=data)
27
+ end
28
+
29
+ def platform_delete(path, params={}, options={})
30
+ request(:delete, path, params, options)
31
+ end
32
+
33
+ def request(method, path, params, options, data={})
34
+
35
+ case method.to_sym
36
+ when :get, :delete
37
+ response = @connection.request(path: path,
38
+ query: params,
39
+ method: method.to_sym)
40
+ when :post, :put, :mget
41
+ body = params unless params.empty?
42
+ body = JSON.generate(body)
43
+ response = @connection.request(path: path,
44
+ query: params,
45
+ method: method.to_sym,
46
+ body: body)
47
+ end
48
+
49
+ raise_error(response)
50
+
51
+
52
+ response = response.data
53
+
54
+ response = JSON.parse response[:body]
55
+ response = response["body"]
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,16 @@
1
+ module Flowthings
2
+ class PlatformResponse
3
+ attr_reader :head, :body, :full_message, :errors, :status, :response_headers, :excon_object
4
+
5
+ def initialize(response)
6
+ @excon_object = response
7
+ @status = response.status
8
+ @response_headers = response.headers
9
+ @full_message = response.body
10
+ @head = @full_message["head"]
11
+ @body = @full_message["body"]
12
+ @errors = @head["errors"]
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,42 @@
1
+ require 'json'
2
+
3
+ module Flowthings
4
+ module Response
5
+ module RaiseErrors
6
+
7
+ private
8
+ def raise_error(response)
9
+
10
+ begin
11
+ body = JSON.parse response[:body]
12
+ rescue JSON::ParserError => e
13
+ body = response[:body]
14
+ end
15
+
16
+ status = response[:status].to_i
17
+
18
+ head = body["head"]
19
+ errors = head["errors"]
20
+
21
+
22
+ case status
23
+ when 400
24
+ raise Flowthings::Error::BadRequest.new errors, head
25
+ when 403
26
+ raise Flowthings::Error::NotFound.new errors, head
27
+ when 404
28
+ raise Flowthings::Error::NotFound.new errors, head
29
+ when 413
30
+ raise Flowthings::Error::Forbidden.new errors, head
31
+ when 500
32
+ raise Flowthings::Error::ServerError.new errors, head
33
+ when 503
34
+ raise Flowthings::Error::ServiceUnavailable.new "503 no service is available to handle this request", head
35
+ end
36
+
37
+ end
38
+
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,96 @@
1
+ module Flowthings
2
+ module CrudUtils
3
+ private
4
+ def mk_data(data, params = {})
5
+ data
6
+ end
7
+
8
+ def mk_path(params = {})
9
+ service_path = {
10
+ "Flowthings::Drop" => "drop",
11
+ "Flowthings::Flow" => "flow",
12
+ "Flowthings::Track" => "track",
13
+ "Flowthings::Identity" => "identity",
14
+ "Flowthings::Token" => "token",
15
+ "Flowthings::Share" => "share",
16
+ "Flowthings::Group" => "group",
17
+ "Flowthings::ApiTask" => "api-task",
18
+ "Flowthings::Mqtt" => "mqtt"
19
+ }
20
+
21
+ path = [@platform_version, @account_name, service_path[self.class.name]]
22
+
23
+ if @flowId
24
+ path << @flowId
25
+ end
26
+
27
+ if params[:id]
28
+ path << params[:id]
29
+ end
30
+
31
+ # a tail is somethings we put after the id on the flow.
32
+ # "/aggregate" would be an example
33
+ if params[:tail]
34
+ path << params[:tail]
35
+ end
36
+
37
+ path = "/" + path.join('/')
38
+ end
39
+
40
+ def mk_regex()
41
+
42
+ end
43
+
44
+ def mk_params(params = {})
45
+
46
+ made_params = {}
47
+
48
+ if params[:start]
49
+ made_params[:start] = params[:start]
50
+ end
51
+
52
+ if params[:limit]
53
+ made_params[:limit] = params[:limit]
54
+ end
55
+
56
+ if params[:sort]
57
+ made_params[:sort] = params[:sort]
58
+ end
59
+
60
+ if params[:order]
61
+ made_params[:order] = params[:order]
62
+ end
63
+
64
+ if params[:only]
65
+ made_params[:only] = params[:only]
66
+ end
67
+
68
+ if params[:refs]
69
+ made_params[:refs] = 1
70
+ end
71
+
72
+ if params[:hints] == false
73
+ made_params[:hints] = false
74
+ end
75
+
76
+ if params[:filter]
77
+ #we'll make this more dynamic later
78
+ made_params[:filter] = params[:filter]
79
+ end
80
+
81
+ made_params
82
+ end
83
+
84
+ def mk_filter(params = {})
85
+ # this is just a string for now
86
+ filter = []
87
+
88
+ params.each do |key, value|
89
+
90
+ end
91
+
92
+ filter
93
+ end
94
+
95
+ end
96
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ module Flowthings
2
+ VERSION = "0.1.1"
3
+ end
data/lib/flowthings.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'flowthings/version'
2
+ require 'flowthings/configuration'
3
+ require 'flowthings/client'
4
+
5
+ module Flowthings
6
+ extend Configuration
7
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Flowthings::Client do
4
+ before do
5
+ @keys = Flowthings::Configuration::VALID_CONFIG_KEYS
6
+ end
7
+
8
+ describe 'configuration' do
9
+
10
+ describe 'with module configuration' do
11
+ before do
12
+ Flowthings.configure do |config|
13
+ @keys.each do |key|
14
+ config.send("#{key}=", key)
15
+ end
16
+ end
17
+ end
18
+
19
+ after do
20
+ Flowthings.reset
21
+ end
22
+
23
+ it 'should inherit module configuration' do
24
+ api = Flowthings::Client.new
25
+
26
+ @keys.each do |key|
27
+ expect(api.send(key)).to eq(key)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe 'with class configuration' do
33
+ before do
34
+ @config = {
35
+ account_name: 'aa',
36
+ account_token: 'bb',
37
+ endpoint: 'dd',
38
+ user_agent: 'ee',
39
+ secure: 'ff',
40
+ platform_version: 'gg',
41
+ }
42
+ end
43
+
44
+ it 'should override module configuration' do
45
+ api = Flowthings::Client.new(@config)
46
+
47
+ @keys.each do |key|
48
+ expect(api.send(key)).to eq(@config[key])
49
+ end
50
+ end
51
+
52
+ it 'should override module configuration after' do
53
+ api = Flowthings::Client.new
54
+
55
+ @config.each do |key, value|
56
+ api.send("#{key}=", value)
57
+ end
58
+
59
+ @keys.each do |key|
60
+ expect(api.send("#{key}")).to eq(@config[key])
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'active_support/inflector'
3
+
4
+ describe Flowthings::Client do
5
+ services = ["api_task", "drop", "flow", "group", "identity", "mqtt", "share", "token", "track"]
6
+
7
+ describe 'interfaces' do
8
+ before do
9
+ @api = Flowthings::Client.new
10
+ end
11
+
12
+ services.each do |service|
13
+ service_class = "flowthings/" + service
14
+ service_class = service_class.camelize.constantize
15
+
16
+ describe ".#{service}" do
17
+ it "the method should exist" do
18
+ expect(@api.respond_to? "#{service}").to be true
19
+ end
20
+
21
+ it "the method should construct the proper class" do
22
+ if service == 'drop'
23
+ initialized_service = @api.send("#{service}", "d")
24
+ expect(initialized_service.class).to eq(service_class)
25
+ else
26
+ initialized_service = @api.send("#{service}")
27
+ expect(initialized_service.class).to eq(service_class)
28
+ end
29
+ end
30
+
31
+ if service == 'drop'
32
+ it "should throw an error if it is called without an argument" do
33
+ expect { @api.send("#{service}") }.to raise_error
34
+ end
35
+
36
+ it "should raise an argument error" do
37
+ expect { @api.send("#{service}") }.to raise_error(ArgumentError)
38
+ end
39
+
40
+ it "should not throw an error if it is called with an argument" do
41
+ expect { @api.send("#{service}", "d") }.not_to raise_error
42
+ end
43
+ end
44
+
45
+ end # describe block
46
+
47
+ end # services loop
48
+
49
+ end #interfaces
50
+
51
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'configuration' do
4
+
5
+ Flowthings::Configuration::VALID_CONFIG_KEYS.each do |key|
6
+ describe ".#{key}" do
7
+ it 'should return the default value' do
8
+ expect(Flowthings.send(key)).to eq(Flowthings::Configuration.const_get("DEFAULT_#{key.upcase}"))
9
+ end
10
+ end
11
+ end
12
+
13
+ after do
14
+ Flowthings.reset
15
+ end
16
+
17
+ describe '.configure' do
18
+ Flowthings::Configuration::VALID_CONFIG_KEYS.each do |key|
19
+ it "should set the #{key}" do
20
+ Flowthings.configure do |config|
21
+ config.send("#{key}=", key)
22
+ expect(Flowthings.send(key)).to eq(key)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ end