plumbus 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5b89f274da67d1f431e10b3d41cca145b5499b0f
4
+ data.tar.gz: d46ab230187b679ad802a982992eb2ff500315bf
5
+ SHA512:
6
+ metadata.gz: b3b36c8a6264c6c03305d4f5aa56372369fac782404e7f91fda78112e118d21cab0c99c09e42a84d9e81815ba6af549071f2fb4fedff1225f960780118fe5c4d
7
+ data.tar.gz: 6ed57aac6f1582a7b9b94b23d720c638a7d9039c05d1e077115e097c835ea6437ccfedadd7f0d6d057cdd04f160df8f8c6db0a49d38173a39774e4f6a92c2bfd
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at seotownsend@icloud.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in plumbus.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 seo
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ ![Plumbus: The micro-service bus](https://raw.githubusercontent.com/sotownsend/plumbus/master/docs/images/banner.png)
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/iarrogant.svg)](http://badge.fury.io/rb/plumbus)
4
+ [![Build Status](https://travis-ci.org/sotownsend/plumbus.svg)](https://travis-ci.org/sotownsend/plumbus)
5
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/sotownsend/plumbus/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
6
+ [![License](http://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/sotownsend/plumbus/blob/master/LICENSE)
7
+
8
+ # What is this?
9
+
10
+ Plubus is an agnostic micro-service router.
11
+
12
+ ## Features
13
+ - [x] Bring your archaic HTTP api into the micro-service age without modifying the API
14
+ - [x] *Any language, any networking or queuing library*
15
+ - [x] Distributed by design, even session information
16
+ - [x] Everything is a stream/push. Even HTTP (just a very short stream session!)
17
+ - [x] Mix & Match - Daisy-chainable
18
+
19
+
20
+ ## Example scenerio
21
+ Let's take the case where you have an aging HTTP web-service API, and a new modern sock-io client.
22
+ <div style='text-align: center'>
23
+ <img width=600 src='./docs/images/request_response_drivers.png' />
24
+ </div>
25
+
26
+ In this example, we're using an HTTP driver and sockio-driver on the request side. On the response side we have an HTTP driver & a redis-queue driver. This configuration
27
+ allows us to serve all of our services located on the redis-bus & HTTP-bus to both sockio users and HTTP users!
28
+
29
+ ## Routing schemes
30
+ Each request contains an action-name and session-id used for routing. Each response-driver maintains a running-list of available actions. If multiple action-paths are available,
31
+ a round-robin scheme is used to deliver messages. Responses are delivered based on the session-id back to the original source. This allows many responses, for a request that has
32
+ requested multiple actions which resulted in requests to multiple response backends, to deliver to the correct requester & know the status of the requester as signals are propogated
33
+ back to the responders in the event the request is closed. A session is deemed over if all responders hang-up.
34
+
35
+ ## Streaming
36
+ All connections in plumbus are streams. HTTP, as it is stateless, is just treated as a degenerate stream that closes it's session after a response is given. One of the neat-things
37
+ about plumbus is that streams are able to hit multiple responses (by virtue of a request stream has sent multiple action requests and those were routed to seperate responses). This
38
+ provides you with load-balancing on traditionally single-server streams (like sock.io).
39
+
40
+ ## Configuration
41
+ Configure is handled through a ruby file. This file contains a listing of `ports` which are just driver instances that are declared on either the request or response side.
42
+ ```ruby
43
+ port(:request, 'plumbus-http') do
44
+ #Driver specific config
45
+ end
46
+
47
+ port(:request, 'plumbus-sockio') do
48
+ #Driver specific config
49
+ end
50
+
51
+ port(:response, 'plumbus-http') do
52
+ #Driver specific config
53
+ end
54
+
55
+ port(:response, 'plumbus-redis-queue') do
56
+ #Driver specific config
57
+ end
58
+ ```
59
+
60
+ # Setup
61
+ ```js
62
+ #Setup
63
+ gem install plumbus
64
+ ```
65
+
66
+ # Usage
67
+ #### SYNOPSIS
68
+ ```js
69
+ plumbus config
70
+ ```
71
+ #### DESCRIPTION
72
+ config is a ruby file that declares backends & frontends (called ports).
73
+
74
+ ## Requirements
75
+
76
+ - Modern **nix** (FreeBSD, Mac, or Linux)
77
+ - Ruby 2.2.1 or Higher (Very important)
78
+
79
+ ## Communication
80
+ > ♥ This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
81
+
82
+ - If you **found a bug**, open an issue.
83
+ - If you **have a feature request**, open an issue.
84
+ - If you **want to contribute**, submit a pull request.
85
+
86
+ ## Installation
87
+
88
+ RVM users:
89
+ Run `gem install plumbus`
90
+
91
+ System ruby installation?
92
+ Run `sudo gem install plumbus`
93
+
94
+ ---
95
+
96
+ ## FAQ
97
+
98
+ ### When should I use plumbus?
99
+
100
+ Todo
101
+
102
+ ### Creator
103
+
104
+ - [Seo Townsend](http://github.com/sotownsend) ([@seotownsend](https://twitter.com/seotownsend))
105
+
106
+
107
+ ## License
108
+
109
+ plumbus is released under the MIT license. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/plumbus ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "plumbus"
5
+ require 'yaml'
6
+ require 'optparse'
7
+
8
+ parser = OptionParser.new do |opts|
9
+ opts.banner = "Usage: plumbus config"
10
+ end
11
+ parser.parse!
12
+
13
+ unless config_path = ARGV.pop
14
+ $stderr.puts parser
15
+ exit -1
16
+ end
17
+
18
+ Plumbus::Loader.load config_path
19
+
20
+ $stderr.puts <<HERE
21
+ (((
22
+ (( ((((
23
+ ((((((((((((((((((
24
+ (((((((((((((
25
+ (((((((((((((
26
+ (((((((((((((
27
+ ******
28
+ ******
29
+ ******
30
+ *******
31
+ **********
32
+ *************
33
+ ******************
34
+ ***************(****
35
+ *************((/((/**
36
+ *************((((((((/
37
+ *************//////(//
38
+ **********************
39
+ *********************
40
+ *******************
41
+ ****************
42
+ ***********
43
+ -----------------------------------------
44
+ HERE
45
+
46
+
47
+ while 100
48
+ $stderr.puts ">Ready to get Riggity Riggity Wrecked Son!"
49
+ sleep 1000
50
+ end
Binary file
data/lib/plumbus.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "plumbus/version"
2
+ require "plumbus/driver_facilities"
3
+ require "plumbus/driver"
4
+ require "plumbus/port"
5
+ require "plumbus/ports"
6
+ require "plumbus/loader"
7
+
8
+ require "plumbus/helpers/trim"
9
+ require "plumbus/helpers/remove_references"
10
+
11
+ module Plumbus
12
+ end
@@ -0,0 +1,28 @@
1
+ require 'active_support/inflector'
2
+
3
+ module Plumbus
4
+ module Driver
5
+ #Available drivers
6
+ @@link_table = {}
7
+
8
+ def self.load driver_name
9
+ require driver_name.to_s
10
+
11
+ return self.add_link driver_name
12
+ rescue LoadError => e
13
+ raise LoadError, "Driver named #{driver_name.inspect} failed to load. Are you sure it's installed correctly?: #{e.inspect}"
14
+ end
15
+
16
+ private
17
+
18
+ def self.add_link name
19
+ mod = name.to_s.classify.constantize
20
+ @@link_table[name.to_sym] = mod
21
+ $stderr.puts "[Driver #{name.inspect} linked]"
22
+
23
+ return mod
24
+ end
25
+
26
+ def self.link_table() return @@link_table end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ #Used by actual drivers
2
+ module Plumbus
3
+ module DriverFacilities
4
+ #This is imported into the Port (which is a driver) interface
5
+ def invalidate_supported_actions
6
+ Ports.refresh_port_routing_table self
7
+ end
8
+
9
+ def emit_message sid, action, payload
10
+ Ports.forward_message port:self, sid:sid, action:action, payload:payload
11
+ end
12
+
13
+ def raise_signal name, info
14
+ Ports.signal port:self, name:name, info:info
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ class Hash
2
+ def remove_references! obj
3
+ self.select{|k, v| [Array, Hash].include? v.class}.each do |k, v|
4
+ v.remove_references! obj
5
+ end
6
+ self.select{|k, v| not [Array, Hash].include? v.class}.each do |k, v|
7
+ if v == obj
8
+ self.delete(k)
9
+ end
10
+ end
11
+
12
+ self
13
+ end
14
+ end
15
+
16
+ class Array
17
+ def remove_references! obj
18
+ self.select{|e| [Array, Hash].include? e.class}.each do |e|
19
+ e.remove_references! obj
20
+ end
21
+
22
+ self.select{|e| not [Array, Hash].include? e.class}.each_with_index do |e, i|
23
+ if e == obj
24
+ self.delete(obj)
25
+ end
26
+ end
27
+
28
+ self
29
+ end
30
+ end
@@ -0,0 +1,45 @@
1
+ class Hash
2
+ #Removes all sub-hashes & arrays that have no objects in them.
3
+ def trim!
4
+ self.each do |k, v|
5
+ if v.class == Array
6
+
7
+ v.trim!
8
+
9
+ #Blank array, dump it
10
+ if v.count == 0
11
+ self.delete k
12
+ end
13
+ elsif v.class == Hash
14
+ v.trim!
15
+
16
+ if v.keys.count == 0
17
+ self.delete k
18
+ end
19
+ end
20
+ end
21
+
22
+ return self
23
+ end
24
+ end
25
+
26
+ class Array
27
+ def trim!
28
+ self.each do |e|
29
+ if e.class == Hash
30
+ e.trim!
31
+
32
+ if e.keys.count == 0
33
+ self.delete e
34
+ end
35
+ elsif e.class == Array
36
+ e.trim!
37
+ if e.count == 0
38
+ self.delete(e)
39
+ end
40
+ end
41
+ end
42
+
43
+ return self
44
+ end
45
+ end
@@ -0,0 +1,44 @@
1
+ module Plumbus
2
+ module Loader
3
+ def self.load path
4
+ self.unload_all
5
+ dsl = LoaderDSL.new(path)
6
+
7
+ #Load ports
8
+ dsl.ports.each do |_port|
9
+ direction = _port[:direction]
10
+ driver = _port[:driver]
11
+ config_block = _port[:config_block]
12
+
13
+ #Load driver if not already loaded
14
+ klass = Driver.load driver
15
+
16
+ #Create instance of driver module
17
+ port = Port.new(driver_module_klass: klass, direction: direction)
18
+ port.config &config_block
19
+ port.attach!
20
+ end
21
+ end
22
+
23
+ def self.unload_all
24
+ Ports.detach_all
25
+ end
26
+ end
27
+
28
+ class LoaderDSL
29
+ attr_reader :ports
30
+
31
+ def initialize src_path
32
+ @ports = []
33
+ contents = File.read(src_path)
34
+
35
+ instance_eval contents, src_path
36
+ end
37
+
38
+ def port direction, driver, &config_block
39
+ raise ArgumentError, "The given direction #{direction.inspect} was not a valid direction. Valid directions include #{Port::SUPPORTED_DIRECTIONS.inspect}" unless Port::SUPPORTED_DIRECTIONS.include? direction
40
+ raise ArgumentError, "No config block was given for the port #{direction.inspect}, #{driver.inspect}" unless config_block
41
+ @ports << {:direction => direction, :driver => driver, :config_block => config_block}
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,51 @@
1
+ require 'active_support/inflector'
2
+
3
+ #Contains the class for each port
4
+ module Plumbus
5
+ class Port
6
+ SUPPORTED_DIRECTIONS = [:request, :response]
7
+
8
+ attr_reader :driver_module_klass, :direction
9
+
10
+ def initialize driver_module_klass:, direction:
11
+ @driver_module_klass = driver_module_klass
12
+ @direction = direction
13
+
14
+ #@driver = Plumbus::PortDriver.new
15
+ extend DriverFacilities
16
+ extend "#{@driver_module_klass.name}::PlumbusHandlers".constantize
17
+ end
18
+
19
+ def attach!
20
+ Ports.attach_port self
21
+ end
22
+
23
+ #def detach!
24
+ #Ports.detach_port self
25
+ #end
26
+
27
+ def opposite_direction
28
+ @direction == :request ? :response : :request
29
+ end
30
+ end
31
+
32
+ class PortDriver
33
+ #Plumbus extended handlers
34
+ ###############################################################
35
+ def config &block
36
+ end
37
+
38
+ #Forward a message to the block for a sid
39
+ def forward_message sid, action, info
40
+ end
41
+
42
+ #Forward a signal, like disconnection
43
+ def forward_signal signal, info
44
+ end
45
+
46
+ def supported_actions
47
+ return @supported_actions
48
+ end
49
+ ###############################################################
50
+ end
51
+ end
@@ -0,0 +1,123 @@
1
+ #Ports manages the actual instances of the port classes
2
+ module Plumbus
3
+ module Ports
4
+ #Instances#########################################################
5
+ #Holds instances
6
+ @@instances = []
7
+ def self.instances; @@instances end
8
+
9
+ #Attach a port
10
+ def self.attach_port port
11
+ @@instances << port
12
+ refresh_port_routing_table port
13
+ end
14
+
15
+ def self.refresh_port_routing_table port
16
+ evict_routing_table_references port
17
+
18
+ port.supported_actions.each do |action|
19
+ action = action.to_s
20
+ @@routing_table[port.opposite_direction][action] ||= []
21
+ @@routing_table[port.opposite_direction][action] << port
22
+ end
23
+ end
24
+
25
+ def self.evict_routing_table_references port
26
+ @@routing_table[port.opposite_direction].remove_references! port
27
+ @@routing_table[port.opposite_direction].trim!
28
+ end
29
+
30
+ #def self.detach_port port
31
+ #evict_routing_table_references port
32
+ #@@instances -= [port]
33
+ #Needs to support the sid_to_ports
34
+ #end
35
+
36
+ def self.detach_all
37
+ @@instances.each do |port|
38
+ evict_routing_table_references port
39
+ end
40
+ @@instances = []
41
+ @@sid_to_ports = {}
42
+ end
43
+
44
+ #Routing###########################################################
45
+ #Holds routing table which maps from
46
+ @@routing_table = {
47
+ :request => {},
48
+ :response => {},
49
+ }
50
+
51
+ #Maps a sid into one request port and potentionally many response ports
52
+ #via [request, Set<response0, response1...>]
53
+ @@sid_to_ports = {}
54
+
55
+ #This returns the *response* (destination) ports for a request originating on the
56
+ #request side. I.e. it returns a response port.
57
+ def self.response_ports_for_request(action:)
58
+ action = action.to_s
59
+ @@routing_table[:request][action] || []
60
+ end
61
+
62
+ def self.response_port_for_request(action:)
63
+ return self.response_ports_for_request(action: action).first
64
+ end
65
+
66
+ def self.request_port_for_response(sid:)
67
+ return (@@sid_to_ports[sid] || [])[0]
68
+ end
69
+
70
+ def self.signal(port:, name:, info:)
71
+ case name
72
+ when :hangup
73
+ sid = info[:sid]
74
+ if ports = @@sid_to_ports[sid]
75
+ #Get request port (0)
76
+ req_port = ports[0]
77
+
78
+ #The request side hungup
79
+ set = ports[1]
80
+ if req_port == port
81
+ set.each do |p|
82
+ p.handle_signal :hangup_notice, {:sid => sid}
83
+ end
84
+ @@sid_to_ports.delete sid
85
+ else
86
+ #Remove ourselves (response) from response set
87
+ set.delete(port)
88
+
89
+ #Signal request of termination
90
+ if set.length == 0
91
+ @@sid_to_ports.delete sid
92
+ req_port.handle_signal :hangup_notice, {:sid => sid}
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ def self.forward_message(port:, sid:, action:, payload:)
100
+ if port.direction == :request
101
+ if req_port = response_port_for_request(action: action)
102
+ if ports = @@sid_to_ports[sid]
103
+ ports[1] << req_port
104
+ else
105
+ req_set = Set.new [req_port]
106
+ @@sid_to_ports[sid] = [port, req_set]
107
+ end
108
+ req_port.handle_message sid, action.to_s, payload
109
+ else
110
+ #undeliverable
111
+ port.handle_signal :undeliverable, {sid: sid}
112
+ end
113
+ elsif port.direction == :response
114
+ if res_port = request_port_for_response(sid: sid)
115
+ res_port.handle_message sid, action, payload
116
+ else
117
+ #undeliverable
118
+ port.handle_signal :undeliverable, {sid: sid}
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,3 @@
1
+ module Plumbus
2
+ VERSION = "0.1.0"
3
+ end
data/plumbus.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'plumbus/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "plumbus"
8
+ spec.version = Plumbus::VERSION
9
+ spec.authors = ["seo"]
10
+ spec.email = ["seotownsend@icloud.com"]
11
+
12
+
13
+ spec.summary = "Plubus is an agnostic micro-service router."
14
+ spec.homepage = "http://github.com/sotownsend/plumbus"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.4"
25
+ spec.add_development_dependency "pry", "~> 0.10"
26
+ spec.add_runtime_dependency "activesupport", "~> 4.2"
27
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: plumbus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - seo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-03-14 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: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.2'
83
+ description:
84
+ email:
85
+ - seotownsend@icloud.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - CODE_OF_CONDUCT.md
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/plumbus
99
+ - docs/images/banner.png
100
+ - docs/images/request_response_drivers.png
101
+ - lib/plumbus.rb
102
+ - lib/plumbus/driver.rb
103
+ - lib/plumbus/driver_facilities.rb
104
+ - lib/plumbus/helpers/remove_references.rb
105
+ - lib/plumbus/helpers/trim.rb
106
+ - lib/plumbus/loader.rb
107
+ - lib/plumbus/port.rb
108
+ - lib/plumbus/ports.rb
109
+ - lib/plumbus/version.rb
110
+ - plumbus.gemspec
111
+ homepage: http://github.com/sotownsend/plumbus
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.4.8
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Plubus is an agnostic micro-service router.
135
+ test_files: []