atomsphere 0.1.6

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 25eae7b31f1b5dd9f640ec1a7942192a1fbec4c2aeffda74f9af08ce31879224
4
+ data.tar.gz: d4e1d956c1abbf2e74125b24c725b0664b8be0fc57078804e2eb120f43ab822b
5
+ SHA512:
6
+ metadata.gz: 675f2fca40b7842b44b4abdb04993cd8af67f37095d3fcc1f039ba75f151b3166a4bfaa5fc63b94ee0b3f58d91eac332ce1bbcc3454cdc7c1a819e5a8b6459f4
7
+ data.tar.gz: edfc117e3812d520b4de08efbb1eee30052f6b58bd4bb42d15ab15200516f58b06bed5c9694de61728e0a17141afe85bfd619ef6bcb24adae12bf09b62117bf6
@@ -0,0 +1,5 @@
1
+ /vendor/bundle
2
+ /.env
3
+ /.bundle
4
+ /tmp
5
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'facets'
4
+ gem 'rotp'
5
+
6
+ group :development do
7
+ gem 'pry'
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Warren Guy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,96 @@
1
+ # Boomi Atomsphere API client for Ruby
2
+
3
+ Unofficial Ruby client for the Dell Boomi Atomsphere API. Implements the JSON flavour of Boomi's "RESTish" API.
4
+
5
+ ## Status
6
+
7
+ Implements authentication (including OTP), querying, and some actions. See *Usage* below.
8
+
9
+ ## Usage
10
+
11
+ ```ruby
12
+ require 'atomsphere'
13
+ ```
14
+
15
+ ### Configuration
16
+
17
+ ```ruby
18
+ Atomsphere.configure do |config|
19
+ config.account_id = '' # Boomi account ID
20
+ config.username = '' # user name
21
+ config.password = '' # user password
22
+ config.otp_secret = '' # base32 OTP secret for two-factor auth
23
+ end
24
+ ```
25
+
26
+ Alternatively, environment variables may be used:
27
+ * `BOOMI_ACCOUNT_ID`
28
+ * `BOOMI_USERNAME`
29
+ * `BOOMI_PASSWORD`
30
+ * `BOOMI_OTP_SECRET`
31
+
32
+ ### Querying
33
+
34
+ ```ruby
35
+ # create a new query
36
+ query = Atomsphere::Query.new
37
+
38
+ # specify the object type to query
39
+ query.object_type = 'Process'
40
+
41
+ # filter for query names starting with 'Netsuite'
42
+ query.filter = Atomsphere::Query::GroupingExpression.new(
43
+ operator: :and,
44
+ nested_expression: [
45
+ Atomsphere::Query::SimpleExpression.new(
46
+ operator: :equals,
47
+ property: :name,
48
+ argument: ['Netsuite%']
49
+ )
50
+ ]
51
+ )
52
+
53
+ # run the query (fetches first page)
54
+ query.run
55
+
56
+ # see results from all pages that have been fetched
57
+ query.results
58
+
59
+ # fetch the next page (returns `false` if `last_page?` is `true`)
60
+ query.next_page
61
+
62
+ # fetch and show all pages of results (warning: loops over `next_page`)
63
+ query.all_results
64
+ ```
65
+
66
+ ### Actions
67
+
68
+ ```ruby
69
+ Atomsphere.get_assignable_roles
70
+ Atomsphere.execute_process atom_id: '12345-uuid-12345', process_id: '12345-uuid-12345'
71
+ Atomsphere.change_listener_status listener_id: '12345-uuid-12345', container_id: '12345-uuid-12345', action: :pause
72
+ ```
73
+
74
+ ## License
75
+
76
+ MIT License
77
+
78
+ Copyright (c) 2019 Warren Guy
79
+
80
+ Permission is hereby granted, free of charge, to any person obtaining a copy
81
+ of this software and associated documentation files (the "Software"), to deal
82
+ in the Software without restriction, including without limitation the rights
83
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
84
+ copies of the Software, and to permit persons to whom the Software is
85
+ furnished to do so, subject to the following conditions:
86
+
87
+ The above copyright notice and this permission notice shall be included in all
88
+ copies or substantial portions of the Software.
89
+
90
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
91
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
92
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
93
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
94
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
95
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
96
+ SOFTWARE.
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'atomsphere'
3
+ s.version = '0.1.6'
4
+ s.licenses = ['MIT']
5
+ s.summary = "Unofficial Ruby client for the Dell Boomi Atomsphere API"
6
+ s.authors = ["Warren Guy"]
7
+ s.email = 'warren@guy.net.au'
8
+ s.files = `git ls-files`.split("\n")
9
+ s.require_paths = ['lib']
10
+ s.homepage = 'https://github.com/warrenguy/atomsphere-ruby'
11
+ s.metadata = { "source_code_uri" => "https://github.com/warrenguy/atomsphere-ruby" }
12
+
13
+ s.required_ruby_version = '>= 2.2'
14
+ s.add_runtime_dependency 'rotp', '~>4'
15
+ s.add_runtime_dependency 'facets', '~>3'
16
+ end
@@ -0,0 +1,6 @@
1
+ module Atomsphere
2
+ VERSION = '0.1.6'
3
+ ROOT = "#{File.expand_path(__dir__)}/atomsphere"
4
+
5
+ %w(configuration query api action).each{ |m| require "#{ROOT}/#{m}" }
6
+ end
@@ -0,0 +1,129 @@
1
+ require 'facets/string/camelcase'
2
+ require 'facets/string/snakecase'
3
+
4
+ module Atomsphere
5
+ module Action
6
+ module ClassMethods
7
+ def self.included base
8
+ end
9
+
10
+ def initialize params={}
11
+ set_params params
12
+ validate!
13
+ end
14
+
15
+ def fields
16
+ %w(required one_of optional).map do |m|
17
+ self.class.class_variable_get :"@@#{m}"
18
+ end.flatten
19
+ end
20
+
21
+ def run
22
+ @api_response ||= api_client.send(*[
23
+ api_method,
24
+ action,
25
+ api_method.eql?(:get) ? nil : request
26
+ ].compact)
27
+
28
+ @response ||= @api_response.to_hash
29
+ self
30
+ end
31
+
32
+ private
33
+ %w(required one_of optional).each do |m|
34
+ define_method(:"#{m}") { self.class.class_variable_get(:"@@#{m}") }
35
+ end
36
+
37
+ def action
38
+ if self.class.class_variable_defined? :@@action
39
+ self.class.class_variable_get :@@action
40
+ else
41
+ self.class.name.split('::').last.lower_camelcase
42
+ end
43
+ end
44
+
45
+ def api_method
46
+ if self.class.class_variable_defined? :@@api_method
47
+ self.class.class_variable_get :@@api_method
48
+ else
49
+ :post
50
+ end
51
+ end
52
+
53
+ def set_params params
54
+ fields.each{ |f| send(:"#{f}=", params[f]) }
55
+ end
56
+
57
+ def api_client
58
+ Api::Client.new
59
+ end
60
+
61
+ def validate!
62
+ required.each do |f|
63
+ raise ArgumentError, "#{f} is required" unless send(:"#{f}")
64
+ end
65
+
66
+ one_of.each do |fs|
67
+ unless fs.map{ |f| send(:"#{f}") }.compact.size == 1
68
+ raise ArgumentError, "requires one of: #{fs.join(', ')}"
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ module InstanceMethods
75
+ def self.extended base
76
+ %w(required one_of optional).each do |m|
77
+ base.class_variable_set :"@@#{m}", []
78
+ end
79
+
80
+ method_name = base.name.split('::').last.snakecase
81
+ Atomsphere.define_singleton_method(method_name) do |*params|
82
+ base.new(*params).run
83
+ end
84
+ end
85
+
86
+ def action a
87
+ class_variable_set :@@action, a
88
+ end
89
+
90
+ def api_method m
91
+ class_variable_set :@@api_method, m
92
+ end
93
+
94
+ def required *params
95
+ params.each do |param|
96
+ class_variable_get(:@@required) << param
97
+ attr_accessor param
98
+ end
99
+ end
100
+
101
+ def optional *params
102
+ params.each do |param|
103
+ class_variable_get(:@@optional) << param
104
+ attr_accessor param
105
+ end
106
+ end
107
+
108
+ def one_of *params
109
+ if params.size < 2
110
+ raise ArgumentError, "one_of requires two or more parameters"
111
+ end
112
+
113
+ class_variable_get(:@@one_of) << [*params]
114
+ params.each{ |param| attr_accessor param }
115
+ end
116
+ end
117
+
118
+ class Action
119
+ def self.inherited(other)
120
+ other.extend InstanceMethods
121
+ other.include ClassMethods
122
+ end
123
+
124
+ attr_reader :api_response, :response
125
+ end
126
+ end
127
+ end
128
+
129
+ Dir["#{Atomsphere::ROOT}/action/*.rb"].each{ |f| require f }
@@ -0,0 +1,11 @@
1
+ module Atomsphere
2
+ module Action
3
+ class ChangeListenerStatus < Action
4
+ required :listener_id, :container_id, :action
5
+
6
+ def request
7
+ Hash[fields.map{ |f| [f, send(f)] }]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module Atomsphere
2
+ module Action
3
+ class ExecuteProcess < Action
4
+ required :atom_id
5
+ one_of :process_id, :process_name
6
+
7
+ def request
8
+ {
9
+ ProcessProperties: {
10
+ '@type': 'ProcessProperties',
11
+ ProcessProperty: [
12
+ {
13
+ '@type': '',
14
+ Name: 'priority',
15
+ Value: 'medium'
16
+ }
17
+ ]
18
+ },
19
+ atomId: atom_id
20
+ }.merge(!process_id.nil? ?
21
+ { processId: process_id } :
22
+ { processName: process_name })
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ module Atomsphere
2
+ module Action
3
+ class GetAssignableRoles < Action
4
+ api_method :get
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module Atomsphere
2
+ module Api
3
+ end
4
+
5
+ %w(response client).each{ |m| require "#{ROOT}/api/#{m}" }
6
+ end
@@ -0,0 +1,90 @@
1
+ require 'net/https'
2
+ require 'uri'
3
+ require 'json'
4
+ require 'rotp'
5
+
6
+ module Atomsphere
7
+ module Api
8
+ class Client
9
+ def initialize
10
+ validate!
11
+ end
12
+
13
+ def post path, data
14
+ header = {
15
+ 'Content-Type' => 'application/json',
16
+ 'Accept' => ' application/json'
17
+ }
18
+
19
+ request = Net::HTTP::Post.new api_uri(path), header
20
+ request.body = (String === data ? data : data.to_json)
21
+ request.basic_auth config.username, config.password
22
+
23
+ http_request request
24
+ end
25
+
26
+ def get path
27
+ header = {'Accept' => 'application/json'}
28
+
29
+ request = Net::HTTP::Get.new api_uri(path), header
30
+ request.basic_auth config.username, config.password
31
+
32
+ http_request request
33
+ end
34
+
35
+ def bulk_get path, ids
36
+ request = { type: 'GET', request: ids.map{ |id| {id: id} } }
37
+ path = [*path] << :bulk
38
+ post path, request
39
+ end
40
+
41
+ %w(query create update execute).each do |v|
42
+ define_method :"#{v}" do |path, data|
43
+ [*path] << v
44
+ post path, data
45
+ end
46
+ end
47
+
48
+ private
49
+ def validate!
50
+ raise ArgumentError, "Atomsphere not configured" if config.nil?
51
+
52
+ required_vars = Atomsphere::Configuration::REQUIRED
53
+ if (missing_vars = required_vars.select{ |v| config.send(v).nil? }).size > 0
54
+ raise ArgumentError, "Atomsphere configuration incomplete," +
55
+ " required vars missing: #{missing_vars.join('; ')}"
56
+ end
57
+ end
58
+
59
+ def config
60
+ @config ||= Atomsphere.configuration
61
+ end
62
+
63
+ def totp
64
+ ROTP::TOTP.new(config.otp_secret) if config.otp_secret
65
+ end
66
+
67
+ def generate_otp
68
+ totp.now
69
+ end
70
+
71
+ def api_uri path=nil
72
+ URI.parse config.base_uri +
73
+ config.account_id +
74
+ '/' + (Array === path ? path.join('/') : path.to_s)
75
+ end
76
+
77
+ def http
78
+ h = Net::HTTP.new api_uri.host, api_uri.port
79
+ h.use_ssl = true
80
+
81
+ h
82
+ end
83
+
84
+ def http_request request
85
+ request['X-Boomi-OTP'] = generate_otp if config.otp_secret
86
+ response = Response.new(request, http.request(request))
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,23 @@
1
+ require 'json'
2
+
3
+ module Atomsphere
4
+ module Api
5
+ class Response
6
+ attr_reader :request, :code, :response
7
+
8
+ def initialize(request, response)
9
+ @request = request
10
+ @response = response
11
+ @code = response.code if response
12
+ end
13
+
14
+ def to_hash
15
+ begin
16
+ JSON.parse @response.body
17
+ rescue JSON::ParserError
18
+ @response.body
19
+ end if @response
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ module Atomsphere
2
+ class Configuration
3
+ REQUIRED = :username, :password, :account_id
4
+ OPTIONAL = :base_uri, :otp_secret
5
+ VARS = REQUIRED + OPTIONAL
6
+
7
+ VARS.each { |v| attr_accessor v }
8
+
9
+ def initialize
10
+ @base_uri = 'https://api.boomi.com/api/rest/v1/'
11
+ end
12
+ end
13
+
14
+ class << self
15
+ attr_accessor :configuration
16
+ end
17
+
18
+ def self.configure
19
+ self.configuration ||= Configuration.new
20
+ yield configuration
21
+
22
+ configuration
23
+ end
24
+ end
25
+
26
+ Hash[Atomsphere::Configuration::VARS.map do |v|
27
+ [v, "BOOMI_#{v.upcase}"]
28
+ end].each do |v, e|
29
+ Atomsphere.configure do |config|
30
+ config.send :"#{v}=", ENV[e]
31
+ end if ENV.keys.include? e
32
+ end
@@ -0,0 +1,84 @@
1
+ module Atomsphere
2
+ class Query
3
+ attr_accessor :object_type, :filter
4
+ attr_reader :query_token, :result_pages, :page
5
+
6
+ def initialize object_type=nil
7
+ @object_type ||= object_type
8
+ @page = nil
9
+ @result_pages = []
10
+ @filter = GroupingExpression.new
11
+ end
12
+
13
+ def validate!
14
+ methods.select{ |m| m =~ /^validate_[a-z0-9_]\!$/ }.each{ |v| send(v) }
15
+ filter.validate!
16
+ true
17
+ end
18
+
19
+ def run
20
+ @result_pages[0] ||= api_client.post [object_type, :query], to_hash
21
+ @page = 0
22
+
23
+ result_pages[0]
24
+ end
25
+
26
+ def results
27
+ result_pages.map(&:to_hash).map{ |h| h['result'] }.flatten(1)
28
+ end
29
+
30
+ def all_results
31
+ next_page until last_page?
32
+ results
33
+ end
34
+
35
+ def last_page?
36
+ !page.nil? && query_token.nil?
37
+ end
38
+
39
+ def next_page
40
+ return false if last_page?
41
+ return run if page.nil?
42
+
43
+ begin
44
+ @result_pages[@page += 1] = api_client.post [object_type, :queryMore], query_token
45
+ rescue => e
46
+ @page -= 1
47
+ raise e
48
+ end
49
+
50
+ result_pages[page]
51
+ end
52
+
53
+ def to_hash
54
+ validate!
55
+
56
+ { QueryFilter: filter.to_hash }
57
+ end
58
+
59
+ def to_json
60
+ JSON.pretty_generate to_hash
61
+ end
62
+
63
+ private
64
+ def validate_object_type!
65
+ raise ArgumentError, "object_type is required" if @object_type.nil?
66
+ end
67
+
68
+ def validate_filter!
69
+ unless filter.is_a? GroupingExpression
70
+ raise ArgumentError, 'filter must be a GroupingExpression'
71
+ end
72
+ end
73
+
74
+ def api_client
75
+ Api::Client.new
76
+ end
77
+
78
+ def query_token
79
+ page.nil? ? nil : result_pages.last.to_hash['queryToken']
80
+ end
81
+ end
82
+
83
+ %w(grouping_expression simple_expression).each{ |m| require "#{ROOT}/query/#{m}" }
84
+ end
@@ -0,0 +1,66 @@
1
+ require 'json'
2
+
3
+ module Atomsphere
4
+ class Query
5
+ class GroupingExpression
6
+ attr_accessor :operator, :nested_expression
7
+
8
+ OPERATORS = :and, :or
9
+
10
+ def initialize(params={})
11
+ params = {
12
+ operator: :and,
13
+ nested_expression: []
14
+ }.merge(params)
15
+
16
+ @operator = params[:operator]
17
+ @nested_expression = params[:nested_expression]
18
+ end
19
+
20
+ def validate!
21
+ methods.select{ |m| m =~ /^validate_[a-z0-9_]\!$/ }.each{ |v| send(v) }
22
+ @nested_expression.each(&:validate!)
23
+ true
24
+ end
25
+
26
+ def to_hash
27
+ {
28
+ expression: {
29
+ operator: operator.to_s,
30
+ nestedExpression: nested_expression.
31
+ map(&:to_hash).
32
+ map{ |h| h[:expression] }
33
+ }
34
+ }
35
+ end
36
+
37
+ def to_json
38
+ JSON.pretty_generate to_hash
39
+ end
40
+
41
+ private
42
+ def validate_operators!
43
+ unless OPERATORS.include? @operator
44
+ raise ArgumentError, "operator must be one of #{OPERATORS.join(', ')}"
45
+ end
46
+ end
47
+
48
+ def validate_expressions!
49
+ raise ArgumentError, "nested_expression must be an array" unless @nested_expression.is_a?(Array)
50
+
51
+ not_expressions = @nested_expression.map(&:class).reject do |k|
52
+ [GroupingExpression, SimpleExpression].include? k
53
+ end
54
+
55
+ if not_expressions.size > 0
56
+ raise ArgumentError,
57
+ "invalid expression class(es): #{not_expressions.map(&:class).join(', ')}"
58
+ end
59
+ end
60
+
61
+ def validate_expressions_size!
62
+ raise ArgumentError, "at least one expression required" if (@nested_expression.size < 1)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,71 @@
1
+ require 'json'
2
+
3
+ module Atomsphere
4
+ class Query
5
+ class SimpleExpression
6
+ attr_accessor :operator, :property, :argument
7
+
8
+ OPERATORS = {
9
+ equals: 1,
10
+ like: 1,
11
+ not_equals: 1,
12
+ is_null: 0,
13
+ is_not_null: 0,
14
+ starts_with: 1,
15
+ between: 2,
16
+ greater_than: 1,
17
+ less_than: 1,
18
+ greater_than_or_equal: 1,
19
+ less_than_or_equal: 1
20
+ }
21
+
22
+ def initialize(params={})
23
+ params = {
24
+ operator: :equals,
25
+ property: nil,
26
+ argument: []
27
+ }.merge(params)
28
+
29
+ %w(operator property argument).each do |v|
30
+ send :"#{v}=", params[v.to_sym]
31
+ end
32
+ end
33
+
34
+ def validate!
35
+ methods.select{ |m| m =~ /^validate_[a-z0-9_]\!$/ }.each{ |v| send(v) }
36
+ true
37
+ end
38
+
39
+ def to_hash
40
+ {
41
+ expression: {
42
+ operator: operator.upcase,
43
+ property: property,
44
+ argument: [*argument]
45
+ }
46
+ }
47
+ end
48
+
49
+ def to_json
50
+ to_hash.to_json
51
+ end
52
+
53
+ private
54
+ def validate_operator!
55
+ unless OPERATORS.include? operator
56
+ raise ArgumentError, "operator must be one of #{OPERATORS.join(', ')}"
57
+ end
58
+ end
59
+
60
+ def validate_property!
61
+ raise ArgumentError, "property must be specified" unless @property
62
+ end
63
+
64
+ def validate_argument!
65
+ unless argument.is_a?(Array) && argument.size.eql?(OPERATORS[operator])
66
+ raise ArgumentError, "'#{operator}' expects #{OPERATORS[operator]} argument(s)"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: atomsphere
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6
5
+ platform: ruby
6
+ authors:
7
+ - Warren Guy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rotp
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: facets
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3'
41
+ description:
42
+ email: warren@guy.net.au
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - ".gitignore"
48
+ - Gemfile
49
+ - LICENSE
50
+ - README.md
51
+ - atomsphere.gemspec
52
+ - lib/atomsphere.rb
53
+ - lib/atomsphere/action.rb
54
+ - lib/atomsphere/action/change_listener_status.rb
55
+ - lib/atomsphere/action/execute_process.rb
56
+ - lib/atomsphere/action/get_assignable_roles.rb
57
+ - lib/atomsphere/api.rb
58
+ - lib/atomsphere/api/client.rb
59
+ - lib/atomsphere/api/response.rb
60
+ - lib/atomsphere/configuration.rb
61
+ - lib/atomsphere/query.rb
62
+ - lib/atomsphere/query/grouping_expression.rb
63
+ - lib/atomsphere/query/simple_expression.rb
64
+ homepage: https://github.com/warrenguy/atomsphere-ruby
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ source_code_uri: https://github.com/warrenguy/atomsphere-ruby
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '2.2'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubygems_version: 3.0.2
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Unofficial Ruby client for the Dell Boomi Atomsphere API
88
+ test_files: []