stargate 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3f25956089ca512458f7c638f448eaca0eb549f9
4
- data.tar.gz: 8d66b7d3f3b0ea725559cdff2ec898a2b9ca6cfe
3
+ metadata.gz: 5bd3b300a1db02cdc5888f43fcbb12898f39e757
4
+ data.tar.gz: aa03a1e5779f1b3d8bf6baa089a04008d13ab975
5
5
  SHA512:
6
- metadata.gz: 19179b263299e1fa3ea5d9244814df8a1dd879bd1b88a3a58513f4a7c42a4af94022c70bafedebb8f523c432b7df81fc9f8164a6b77fe401652889c1e13e5578
7
- data.tar.gz: 2c4174d187433886b768a2487aa4ec25735e06b461391d330b9b2e0b529ef1cb7136c5cd4023507998b56c0a090d104b3d5101d8a97394cbd12664164bbf003e
6
+ metadata.gz: 81aa058faf53aff8833a8151889e2f54cbab0c995f63c7064737e5d1e2911c4be64f287d1f9cb48608020460d95809a62b38d3ef481d186307b0e29048400ccd
7
+ data.tar.gz: 826bfb7249126d66fe8b4d87189c96a68758288ca4ee0a30968b7da1e7554fe4257de534f417064b88077d171eafcda84a199b22bbfa92ccd73776b23bfd2009
@@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
7
  ...
8
8
 
9
+ ## [0.1.3]
10
+
11
+ ...
12
+
9
13
  ## [0.1.2]
10
14
 
11
15
  ### Fixed
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Stargate
2
2
 
3
- [![Status](https://codeship.com/projects/XXX/status?branch=master)](https://codeship.com/projects/XXX)
3
+ [![Codeship Status for jobandtalent/stargate](https://codeship.com/projects/7bd04ac0-a02a-0133-8adf-6af23f5d89a3/status?branch=master)](https://codeship.com/projects/128080)
4
+
5
+ ![Stargate](http://i.imgur.com/NTASGkO.jpg)
4
6
 
5
7
  Stargate is a portal between ruby (and in the future not any) apps. It facilitates creating internal micro-services
6
8
  and allows to scale your logic pretty much infinitely.
@@ -34,7 +36,7 @@ class are executed locally or remotely. Fire, get results, forget. No thinking o
34
36
  Add this line to your application's Gemfile:
35
37
 
36
38
  ```ruby
37
- gem 'stargate', '0.1.2'
39
+ gem 'stargate', '0.1.3'
38
40
  ```
39
41
 
40
42
  And then execute:
@@ -43,7 +45,7 @@ And then execute:
43
45
 
44
46
  Or install it yourself as:
45
47
 
46
- $ gem install stargate --version 0.1.2
48
+ $ gem install stargate --version 0.1.3
47
49
 
48
50
  ## Usage
49
51
 
@@ -1,5 +1,3 @@
1
- require 'stargate/server/engine/sinatra'
2
-
3
1
  module NightsWatch
4
2
  class NewBrother
5
3
  def self.oath
@@ -28,6 +26,9 @@ module NightsWatch
28
26
  end
29
27
  end
30
28
 
29
+ require 'stargate'
30
+ require 'stargate/server/engine/sinatra'
31
+
31
32
  registry = Stargate::Server::Registry.new do
32
33
  version 1 do
33
34
  serve NightsWatch::NewBrother do
@@ -1,8 +1,16 @@
1
1
  module Kernel
2
+ # Public: Loads remote definitions from given URL and injects them in local namespace.
3
+ #
4
+ # Example:
5
+ #
6
+ # require_remote('http+json://example.com/v1#timeout=0.3')
7
+ #
8
+ # Returns nothing.
2
9
  def require_remote(url)
3
10
  @required_remotes ||= []
4
11
  return if @required_remotes.include?(url)
5
12
  injector = Stargate::Client::Injector.new(url)
6
13
  @required_remotes << url
14
+ nil
7
15
  end
8
16
  end
@@ -1,5 +1,7 @@
1
1
  module Stargate
2
2
  module Client
3
+ # Internal: The job of Injector is to inject remote definitions to local namespace. It does it by
4
+ # creating new namespaces dynamically and injecting Proxy classes to remote objects.
3
5
  class Injector
4
6
  include Logging
5
7
  include Stargate::Client
@@ -10,23 +10,37 @@ module Stargate
10
10
 
11
11
  @@transports = {}
12
12
 
13
+ # Public: List of registered transports (protocol implementations).
13
14
  def self.transports
14
15
  @@transports
15
16
  end
16
17
 
18
+ # Public: Registers new implementation for given protocols.
17
19
  def self.register(protocols, transport)
18
20
  protocols.each { |protocol| transports[protocol] = transport }
19
21
  end
20
22
 
23
+ # Public: Finds implementation for given protocol.
24
+ #
25
+ # Returns transport if found.
26
+ # Raises UnsupportedProtocolError if not found.
21
27
  def self.[](protocol)
22
28
  transports[protocol.downcase] or raise UnsupportedProtocolError, "Unsupported protocol: #{protocol}"
23
29
  end
24
30
 
31
+ # Public: Codec used to serialize/deserialize payload.
25
32
  attr_reader :codec
33
+
34
+ # Public: Remote URL of the endpoint.
26
35
  attr_reader :uri
36
+
37
+ # Public: URL without credentials part.
27
38
  attr_reader :safe_uri
39
+
40
+ # Public: Transport configuration.
28
41
  attr_reader :options
29
42
 
43
+ # Public: Constructor.
30
44
  def initialize(codec, uri)
31
45
  @codec = codec
32
46
  @uri = uri
@@ -35,10 +49,12 @@ module Stargate
35
49
  @unmarshaller = Unmarshaller.new
36
50
  end
37
51
 
52
+ # Public: Shall load all definitions from remote server.
38
53
  def fetch_definitions
39
54
  raise NotImplementedError
40
55
  end
41
56
 
57
+ # Public: Shall execute class method with given arguments. Executes method remotely of course.
42
58
  def call(klass, method, *args)
43
59
  raise NotImplementedError
44
60
  end
@@ -49,14 +65,19 @@ module Stargate
49
65
  { timeout: DEFAULT_TIMEOUT }
50
66
  end
51
67
 
68
+ # Internal: A helper to unpack loaded data.
52
69
  def unpack_payload(data)
53
70
  @unmarshaller.unmarshal(data)
54
71
  end
55
72
 
73
+ # Internal: A helper to unpack remote definitions.
56
74
  def unpack_definitions(definitions)
57
75
  definitions.map { |metadata| ::Stargate::Metadata.from_hash(metadata) }
58
76
  end
59
77
 
78
+ # Internal: Parses options from URI fragment. Example http+json://example.com/v1#timeout=0.3
79
+ #
80
+ # Returns hash with options.
60
81
  def parse_options_from_uri_fragment
61
82
  uri.fragment.to_s.split(';').inject({}) do |options, entry|
62
83
  k, v = entry.split('=')
@@ -2,6 +2,7 @@ require 'rest-client'
2
2
 
3
3
  module Stargate
4
4
  module Client
5
+ # Internal:: HTTP protocol implementation based on Sinatra engine implemented on the Server side.
5
6
  class Protocol::HTTP < Protocol
6
7
  def fetch_definitions
7
8
  log.debug("Loading remote definitions", url: safe_uri.to_s)
@@ -2,6 +2,7 @@ require 'rest-client'
2
2
 
3
3
  module Stargate
4
4
  module Client
5
+ # Internal: A client implementation compatible with Inproc server engine.
5
6
  class Protocol::Inproc < Protocol
6
7
  RegistryNotFoundError = Class.new(::Stargate::Client::Error)
7
8
 
@@ -1,10 +1,17 @@
1
1
  module Stargate
2
2
  module Client
3
+ # Internal: Here's where the magic happens. The proxy class connects local method calls with
4
+ # remote endpoints. Basically whenever any of registered (provided by remote definitions) methods
5
+ # is called, proxy forwards this call to remote location and returns obtained results adapted
6
+ # to local context.
3
7
  class Proxy
8
+ # Internal: Magic for metaprogramming tricks.
4
9
  def self.metaclass
5
10
  class << self; self; end
6
11
  end
7
12
 
13
+ # Internal: Configures portal for given protocol. Takes class metadata to define all entry
14
+ # point class methods, object attributes and readers.
8
15
  def self.configure_stargate_portal(protocol, metadata)
9
16
  metaclass.instance_eval do
10
17
  metadata.class_methods.each do |method|
@@ -22,10 +29,12 @@ module Stargate
22
29
  define_readers(*metadata.readers)
23
30
  end
24
31
 
32
+ # Internal: Helper to define all attributres (accessors).
25
33
  def self.define_attributes(*names)
26
- names.each { |name| attr_accessor(name) }
34
+ attr_accessor(*names)
27
35
  end
28
36
 
37
+ # Internal: Helper to define reader methods.
29
38
  def self.define_readers(*names)
30
39
  names.each do |name|
31
40
  name = name.to_s
@@ -35,6 +44,9 @@ module Stargate
35
44
  end
36
45
  end
37
46
 
47
+ # Public: Constructor. Proxy class ignores remote constructor definition. Local proxy is always
48
+ # treaded as a data structure only and thus it's convenient to initialize it with attributes
49
+ # to set.
38
50
  def initialize(attributes = {})
39
51
  attributes.each do |name,value|
40
52
  instance_variable_set("@#{name}", value)
@@ -11,18 +11,22 @@ module Stargate
11
11
 
12
12
  @@codecs = {}
13
13
 
14
+ # Internal: Returns all registered codecs.
14
15
  def self.codecs
15
16
  @@codecs
16
17
  end
17
18
 
19
+ # Public: Register new codec.
18
20
  def self.register(codec)
19
21
  codecs[codec.content_type.to_s] = codec
20
22
  end
21
23
 
24
+ # Public: Find codec by given identifier.
22
25
  def self.find_by_id(id)
23
26
  codecs.values.find { |codec| codec.id == id.to_sym } or raise UndefinedCodecError, "No such codec: #{id}"
24
27
  end
25
28
 
29
+ # Public: Find codec for given content type.
26
30
  def self.[](content_type)
27
31
  codecs[content_type.to_s] or raise UndefinedCodecError, "No codec for type: #{content_type}"
28
32
  end
@@ -1,7 +1,16 @@
1
1
  module Stargate
2
+ # Internal: We need a way to store information about registered classes. Each served class
3
+ # defines itself with the following information:
4
+ #
5
+ # * Class name (eventually serving alias)
6
+ # * List of exposed class methods
7
+ # * List of instance attributes (accessors)
8
+ # * List of instance methods (cacheable reader methods)
9
+ #
2
10
  class Metadata
3
11
  include Serialization
4
12
 
13
+ # Internal: Loads metadata information from hash.
5
14
  def self.from_hash(hash)
6
15
  hash.symbolize_keys!
7
16
 
@@ -12,10 +21,10 @@ module Stargate
12
21
  end
13
22
  end
14
23
 
15
- attr_reader :klass
16
-
17
- attr_reader :name
24
+ # The class to be served and it's serving alias.
25
+ attr_reader :klass, :name
18
26
 
27
+ # Public: Constructor.
19
28
  def initialize(klass, name, &block)
20
29
  @klass, @name = klass, name
21
30
  @class_methods = []
@@ -25,10 +34,6 @@ module Stargate
25
34
  instance_eval(&block) if block_given?
26
35
  end
27
36
 
28
- def active_record?
29
- @active_record
30
- end
31
-
32
37
  def class_methods(*names)
33
38
  load_or_add(:class_methods, *names)
34
39
  end
@@ -56,10 +61,7 @@ module Stargate
56
61
 
57
62
  private
58
63
 
59
- def klass_is_an_active_record?
60
- defined?(::ActiveRecord) && klass && klass < ::ActiveRecord::Base
61
- end
62
-
64
+ # Internal: A helper to define single access methods (getter/setter DSL methods).
63
65
  def load_or_add(method, *args)
64
66
  value = instance_variable_get("@#{method}")
65
67
  args.empty? ? value : value.concat(args.flatten.map(&:to_sym))
@@ -1,5 +1,7 @@
1
1
  module Stargate
2
2
  module Server
3
+ # Internal: We need a way to call registered stuff. This little service handles it. Caller is
4
+ # defined per registry version and operates only within its context.
3
5
  class Caller
4
6
  include Logging
5
7
  include Stargate::Marshal
@@ -3,6 +3,7 @@ require 'stargate/server'
3
3
  module Stargate
4
4
  module Server
5
5
  module Engine
6
+ # Public: Testing, in-process (more accurately in-app) engine to interchange information.
6
7
  class Inproc
7
8
  def self.register(name, registry)
8
9
  registry.each do |version_number, actual_registry|
@@ -3,6 +3,8 @@ require 'stargate/server'
3
3
  module Stargate
4
4
  module Server
5
5
  module Engine
6
+ # Public: Sinatra transport. Very simple implementation of a transport that speaks non-REST interface.
7
+ # Sorta RPC transport over HTTP implemented with Sinatra.
6
8
  class Sinatra
7
9
  include Logging
8
10
 
@@ -1,19 +1,36 @@
1
1
  module Stargate
2
2
  module Server
3
+ # Internal: Registry contains list of versions, each with defined served classes.
4
+ #
5
+ # Example:
6
+ #
7
+ # Stargate::Server::Registry.new do
8
+ # version 1 do
9
+ # serve MyClass do
10
+ # class_methods :foo, :bar
11
+ # attributes :foo, :bar, :baz
12
+ # end
13
+ # end
14
+ # end
15
+ #
3
16
  class Registry
4
17
  include Enumerable
5
18
 
19
+ # Public: List of registry versions.
6
20
  attr_reader :versions
7
21
 
22
+ # Public: Constructor.
8
23
  def initialize(&block)
9
24
  @versions = {}
10
25
  instance_eval(&block) if block_given?
11
26
  end
12
27
 
28
+ # Public: Defines new version. Executes with internal DSL.
13
29
  def version(number, &block)
14
30
  @versions[number] ||= RegistryVersion.new(number, &block)
15
31
  end
16
32
 
33
+ # Public: Returns given registry version.
17
34
  def [](version)
18
35
  versions[version] or raise RegistryVersionUndefinedError, "No such registry version: #{version}"
19
36
  end
@@ -2,15 +2,20 @@ require 'forwardable'
2
2
 
3
3
  module Stargate
4
4
  module Server
5
+ # Internal: Here's where all information about served classes are stored. Registered classes information
6
+ # is stored in form of Stargate::Metadata.
5
7
  class RegistryVersion
6
8
  include Logging
7
9
  include Enumerable
8
10
  include Serialization
9
11
 
12
+ # Public: Registry version number.
10
13
  attr_reader :version
11
14
 
15
+ # Public: Registered definitions (list of metadata).
12
16
  attr_reader :definitions
13
17
 
18
+ # Public: Constructor.
14
19
  def initialize(version = 1, &block)
15
20
  @version = version
16
21
  @definitions = []
@@ -18,6 +23,10 @@ module Stargate
18
23
  instance_eval(&block) if block_given?
19
24
  end
20
25
 
26
+ # Public: Registers given class in this registry. A class can be registered with different name using
27
+ # the `:as` params key.
28
+ #
29
+ # Raises ClassAlreadyRegisteredError if class is already registered.
21
30
  def serve(klass, params = {}, &block)
22
31
  raise ClassAlreadyRegisteredError, "Class already registered: #{klass.name}" if registered?(klass)
23
32
 
@@ -29,15 +38,24 @@ module Stargate
29
38
  self
30
39
  end
31
40
 
41
+ # Internal: Returns true when given class is already registered.
32
42
  def registered?(klass)
33
43
  @definitions.find { |metadata| metadata.klass == klass }
34
44
  end
35
45
 
46
+ # Internal: Finds metadata information for given object (namely for the class of given object).
47
+ #
48
+ # Returns Stargate::Metadata if found.
49
+ # Raises ClassNotExposedError if not found.
36
50
  def metadata_for(obj)
37
51
  metadata = @definitions.find { |metadata| metadata.klass == obj.class }
38
52
  metadata or raise ClassNotExposedError, "Class not registered: #{obj.class.name}"
39
53
  end
40
54
 
55
+ # Internal: Finds metadata information for given class.
56
+ #
57
+ # Returns Stargate::Metadata if found.
58
+ # Raises ClassNotExposedError if not found.
41
59
  def [](klass_name)
42
60
  metadata = @definitions.find { |metadata| metadata.name == klass_name }
43
61
  metadata or raise ClassNotExposedError, "Class not registered under name: #{klass_name}"
@@ -1,3 +1,3 @@
1
1
  module Stargate
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.3'
3
3
  end
@@ -37,6 +37,5 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency "activesupport", "~> 4.0", ">= 3.0"
38
38
  spec.add_dependency "sinatra", "~> 1.4"
39
39
  spec.add_dependency "rest-client", "~> 1.8"
40
- spec.add_dependency "log4r", "~> 1.1"
41
- spec.add_dependency "perfume", "~> 0.3", ">= 0.3.1"
40
+ spec.add_dependency "gallus"
42
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stargate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - jobandtalent
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-01-15 00:00:00.000000000 Z
12
+ date: 2016-01-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -268,39 +268,19 @@ dependencies:
268
268
  - !ruby/object:Gem::Version
269
269
  version: '1.8'
270
270
  - !ruby/object:Gem::Dependency
271
- name: log4r
271
+ name: gallus
272
272
  requirement: !ruby/object:Gem::Requirement
273
273
  requirements:
274
- - - "~>"
275
- - !ruby/object:Gem::Version
276
- version: '1.1'
277
- type: :runtime
278
- prerelease: false
279
- version_requirements: !ruby/object:Gem::Requirement
280
- requirements:
281
- - - "~>"
282
- - !ruby/object:Gem::Version
283
- version: '1.1'
284
- - !ruby/object:Gem::Dependency
285
- name: perfume
286
- requirement: !ruby/object:Gem::Requirement
287
- requirements:
288
- - - "~>"
289
- - !ruby/object:Gem::Version
290
- version: '0.3'
291
274
  - - ">="
292
275
  - !ruby/object:Gem::Version
293
- version: 0.3.1
276
+ version: '0'
294
277
  type: :runtime
295
278
  prerelease: false
296
279
  version_requirements: !ruby/object:Gem::Requirement
297
280
  requirements:
298
- - - "~>"
299
- - !ruby/object:Gem::Version
300
- version: '0.3'
301
281
  - - ">="
302
282
  - !ruby/object:Gem::Version
303
- version: 0.3.1
283
+ version: '0'
304
284
  description: Stargate opens a portal to call remote methods via simple and reliable
305
285
  RPC protocols.
306
286
  email:
@@ -337,7 +317,6 @@ files:
337
317
  - lib/stargate/codec/bencode.rb
338
318
  - lib/stargate/codec/json.rb
339
319
  - lib/stargate/codec/message_pack.rb
340
- - lib/stargate/errors.rb
341
320
  - lib/stargate/marshal.rb
342
321
  - lib/stargate/marshal/marshaller.rb
343
322
  - lib/stargate/marshal/payload.rb
@@ -1,4 +0,0 @@
1
- module Stargate
2
- # Public: Base error.
3
- Error = Class.new(StandardError)
4
- end