jstp 0.5.7 → 1.0.2

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 (43) hide show
  1. data/README.md +26 -3
  2. data/jstp.gemspec +2 -1
  3. data/lib/jstp.rb +23 -11
  4. data/lib/jstp/configuration.rb +68 -0
  5. data/lib/jstp/controller.rb +49 -11
  6. data/lib/jstp/dispatch.rb +106 -0
  7. data/lib/jstp/engine.rb +77 -13
  8. data/lib/jstp/version.rb +1 -1
  9. data/lib/reader/jstp/dispatch.rb +36 -0
  10. data/lib/reader/jstp/engine.rb +66 -0
  11. data/lib/writer/jstp/dispatch.rb +95 -0
  12. data/samples/api-1.5/modular_style.rb +22 -0
  13. data/samples/api-1.5/references.rb +12 -0
  14. data/samples/api-1.5/sinatra_style.rb +18 -0
  15. data/samples/api-2.0/a_la_rack.rb +22 -0
  16. data/samples/api-2.0/clearer_sample.rb +12 -0
  17. data/samples/api-2.0/middleware.rb +23 -0
  18. data/samples/api-2.0/references.rb +11 -0
  19. data/samples/diff.rb +12 -0
  20. data/samples/hooks.rb +9 -0
  21. data/samples/micro.rb +6 -0
  22. data/samples/new_api.rb +62 -0
  23. data/samples/websocket.rb +11 -0
  24. data/spec/jstp/engine_spec.rb +39 -0
  25. data/spec/spec_helper.rb +0 -1
  26. metadata +40 -32
  27. data/features/map_a_la_rest.feature +0 -148
  28. data/features/step_definitions/map_a_la_rest_steps.rb +0 -19
  29. data/features/support/env.rb +0 -11
  30. data/lib/jstp/api.rb +0 -25
  31. data/lib/jstp/base.rb +0 -7
  32. data/lib/jstp/connector.rb +0 -17
  33. data/lib/jstp/tcp.rb +0 -12
  34. data/lib/jstp/web_socket.rb +0 -45
  35. data/lib/reader/jstp/connector.rb +0 -31
  36. data/lib/writer/jstp/connector.rb +0 -46
  37. data/spec/jstp/api_spec.rb +0 -79
  38. data/spec/jstp/base_spec.rb +0 -5
  39. data/spec/jstp/connector_spec.rb +0 -16
  40. data/spec/jstp/tcp_spec.rb +0 -7
  41. data/spec/jstp/web_socket_spec.rb +0 -78
  42. data/spec/reader/jstp/connector_spec.rb +0 -32
  43. data/spec/writer/jstp/connector_spec.rb +0 -71
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module JSTP
3
- VERSION = "0.5.7"
3
+ VERSION = "1.0.2"
4
4
  end
@@ -0,0 +1,36 @@
1
+ # http://www.youtube.com/watch?v=pXPzZezGu8k
2
+ module Reader
3
+ module JSTP
4
+ class Dispatch < Discoverer::Pattern
5
+ def hash the_hash
6
+ the_hash.each do |key, value|
7
+ @source[key] = value
8
+ end
9
+
10
+ @source
11
+ end
12
+
13
+ # Actually, is JSON
14
+ def string the_string
15
+ Oj.load(the_string).each do |key, value|
16
+ @source[key] = value
17
+ end
18
+
19
+ @source
20
+ end
21
+
22
+ def array the_array
23
+ @source.method = the_array.first if the_array.first
24
+ @source.resource = the_array[1] if the_array[1]
25
+ @source.body = the_array[2] if the_array[2]
26
+ if the_array[3]
27
+ the_array[3].each do |key, value|
28
+ @source[key] = value
29
+ end
30
+ end
31
+
32
+ @source
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,66 @@
1
+ module Reader
2
+ module JSTP
3
+ class Engine
4
+ def initialize source
5
+ @config = ::JSTP::Configuration.instance
6
+ @source = source
7
+ end
8
+
9
+ # Start the server with the websocket strategy
10
+ def websocket
11
+ EM.run do
12
+ EM::WebSocket
13
+ .start host: "0.0.0.0", port: @config.port.inbound do |server|
14
+
15
+ server.onopen do
16
+ @source.clients[UUID.new.generate] = server
17
+ if @source.respond_to? :open
18
+ @source.open server, @source.clients.key(server)
19
+ end
20
+ end
21
+
22
+ server.onmessage do |message|
23
+ begin
24
+ @message = ::JSTP::Dispatch.new message
25
+ @source.dispatch(@message, server)
26
+ rescue Exception => exception
27
+ log_exception exception, @message
28
+ end
29
+ end
30
+
31
+ server.onclose do
32
+ if @source.respond_to? :close
33
+ @source.close server, @source.clients.key(server)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ # Start the server with the TCP strategy
41
+ def tcp
42
+ @server = TCPServer.open @config.port.inbound
43
+ loop {
44
+ Thread.start(@server.accept) { |client|
45
+ begin
46
+ @source.clients[UUID.new.generate] = client
47
+ @message = ::JSTP::Dispatch.new client.gets
48
+ @source.dispatch @message, client
49
+ client.close
50
+ rescue Exception => exception
51
+ log_exception exception, @message
52
+ client.close
53
+ end
54
+ }
55
+ }
56
+ end
57
+
58
+ private
59
+ def log_exception exception, message
60
+ @config.logger.error "#{exception.class}: #{exception.message}"
61
+ @config.logger.debug exception.backtrace.to_s
62
+ @config.logger.debug Oj.dump message if message
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,95 @@
1
+ module Writer
2
+ module JSTP
3
+ class Dispatch < Discoverer::Pattern
4
+
5
+ def initialize source
6
+ super source
7
+ @config = ::JSTP::Configuration.instance
8
+ end
9
+
10
+ # Dispatch this applying the websocket strategy
11
+ def websocket port = nil
12
+ host = @source["resource"].first
13
+ path = @source["resource"][1..-1].join('/')
14
+ if port.nil?
15
+ connection_uri = "ws://#{host}:#{@config.port.outbound}/#{path}"
16
+ else
17
+ connection_uri = "ws://#{host}:#{port}/#{path}"
18
+ end
19
+
20
+ begin
21
+ ws = EM::WebSocketClient.connect connection_uri
22
+ ws.callback do
23
+ ws.send_msg @source.to.json
24
+ @config.logger.debug @source.to_s
25
+ ws.close_connection_after_writing
26
+ end
27
+ rescue RuntimeError => e
28
+ EM.run do
29
+ ws = EM::WebSocketClient.connect connection_uri
30
+
31
+ ws.callback do
32
+ ws.send_msg @source.to.json
33
+ @config.logger.debug @source.to_s
34
+ ws.close_connection_after_writing
35
+ end
36
+
37
+ ws.disconnect do
38
+ EM::stop_event_loop
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ # Dispatch thid applying the TCP strategy
45
+ def tcp port = nil
46
+ if port.nil?
47
+ client = TCPSocket.open @source["resource"].first, @config.port.outbound
48
+ else
49
+ client = TCPSocket.open @source["resource"].first, port
50
+ end
51
+
52
+ client.puts @source.to.json
53
+ @config.logger.debug @source.to_s
54
+ client.close
55
+ end
56
+
57
+ def json
58
+ Oj.dump @source
59
+ end
60
+
61
+ def string
62
+ response = "#{@source.method} #{@source.resource.join('/')} #{@source.protocol.join('/')}\n"
63
+ @source.each do |key, value|
64
+ unless key == "method" || key == "resource" || key == "protocol" || key == "body"
65
+ if value.is_a? Array
66
+ response += "#{key}: #{value.join('/')}\n"
67
+ else
68
+ response += "#{key}: #{value}\n"
69
+ end
70
+ end
71
+ end
72
+
73
+ unless @source.body.nil?
74
+ response += "\n"
75
+ if @source.body.is_a? Hash
76
+ @source.body.each do |key, value|
77
+ response += "#{key}: #{Oj.dump(value)}\n"
78
+ end
79
+ else
80
+ response += Oj.dump @source.body
81
+ end
82
+ end
83
+ response
84
+ end
85
+
86
+ def short
87
+ unless @source.body
88
+ "#{@source.method} #{@source.resource.join('/')}"
89
+ else
90
+ "#{@source.method} #{@source.resource.join('/')}?#{Oj.dump(@source.body)}"
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,22 @@
1
+ class MyEngine < JSTP::Engine
2
+
3
+ strategy.inbound :websocket
4
+ port.inbound 44444
5
+ logger Logger.new $stdout
6
+
7
+ resource :user do
8
+ get do
9
+ end
10
+
11
+ post do
12
+ end
13
+
14
+ resource :source do
15
+ get do
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ MyEngine.run
@@ -0,0 +1,12 @@
1
+ resource :Useful do
2
+ delete do
3
+ # Do something
4
+ end
5
+ end
6
+
7
+ resource :Node do
8
+ put do
9
+ get 'other.host/Node', data: "this goes in the body"
10
+ delete Useful, id: "this goes to self"
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ strategy.inbound :websocket
2
+ port.inbound 44444
3
+ logger Logger.new $stdout
4
+
5
+ resource :user do
6
+ get do
7
+ end
8
+
9
+ post do
10
+ end
11
+
12
+ resource :source do
13
+ get do
14
+ end
15
+ end
16
+ end
17
+
18
+ # It runs automatically
@@ -0,0 +1,22 @@
1
+ resource :User do
2
+ get do
3
+ # Something
4
+ end
5
+
6
+ delete do
7
+ # Something
8
+ end
9
+
10
+ resource :Rating do
11
+ put do
12
+ end
13
+ end
14
+ end
15
+
16
+ resource :Article do
17
+ get do
18
+ # Something with article
19
+ end
20
+
21
+ resource User # Includes User here. Along with Rating within
22
+ end
@@ -0,0 +1,12 @@
1
+ class Article < JSTP::Resource
2
+ def get
3
+ end
4
+ end
5
+
6
+ class Blog < JSTP::Resource
7
+ resource Article # Declaratively set Article as a resource within Blog
8
+ end
9
+
10
+ Blog.new # Starts Blog as the engine
11
+
12
+ # The JSTP::Resource class its a combination of Engine and Controller
@@ -0,0 +1,23 @@
1
+ class TokenEmptier < JSTP::Resource
2
+ get do
3
+ original.token = [] # Not useful, just first thing to cross mind
4
+ end
5
+
6
+ all do # Same as def all
7
+ puts "This will be printed everytime"
8
+ end
9
+ end
10
+
11
+ class App < JSTP::Resource
12
+ use TokenEmptier
13
+
14
+ get do
15
+ # => "This will be printed everytime"
16
+ # from TokenEmptier#all
17
+ puts token # => nil
18
+ end
19
+ end
20
+
21
+ App.new
22
+
23
+ # Nice, huh?
@@ -0,0 +1,11 @@
1
+ resource :Boat do
2
+ get do
3
+ # Something
4
+ end
5
+ end
6
+
7
+ resource :Dock do
8
+ put do
9
+ get Boat, "cool other data"
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ JSTP.config do |c|
2
+ c.strategy inbound: :websocket
3
+ c.port inbound: 44444, outbound: 33333
4
+ end
5
+
6
+ class Diff < JSTP::Engine
7
+ class Proxy < JSTP::Controller
8
+ def put
9
+ dispatch(:get, "localhost/User/7").to.tcp
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ class Eng < JSTP::Engine
2
+ def open client, token
3
+ # A new client has connected and this gets executed
4
+ end
5
+
6
+ def close client, token
7
+ # A client has disconnected and this gets executed
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ class Eng < JSTP::Engine
2
+ class User < JSTP::Controller
3
+ def get
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,62 @@
1
+ # {
2
+ # "protocol": ["JSTP", "0.1"],
3
+ # "method": "GET",
4
+ # "resource": ["localhost", "User", "4"],
5
+ # "timestamp": 1536345124,
6
+ # "token": ["8ugw324", "34fqwer"],
7
+ # "X-Server": "EventMachine",
8
+ # "referer": ["google.com", "search"]
9
+ # "body": {
10
+ # "name": "Xavier"
11
+ # }
12
+ # }
13
+
14
+ class Localhost < JSTP::Engine
15
+ class User < JSTP::Controller
16
+ def get
17
+ protocol # => ["JSTP", "0.1"]
18
+ method # => "GET"
19
+ resource # => ["localhost", "User", "4"]
20
+ query # => ["4"]
21
+ timestamp # => 1536345124
22
+ referer # => ["google.com", "search"]
23
+ token # => ["8ugw324", "34fqwer"]
24
+ headers # => {"token" => ..., timestamp => ..., "X-Server" => ...}
25
+ body # => {"name" => "Xavier"}
26
+ original # => {"protocol" => ..., method" => "GET", "resource" => ...}
27
+
28
+ dispatch(
29
+ :post,
30
+ "remote.host/Login/success",
31
+ { "message" => "Login successful for user #{body['name']}" },
32
+ { "X-Greet" => "Hello" }
33
+ ).to.websocket
34
+ # => {
35
+ # "protocol": ["JSTP", "0.1"],
36
+ # "method": "POST",
37
+ # "resource": ["remote.host", "Login", "success"],
38
+ # "timestamp": 1536358924,
39
+ # "token": ["8ugw324", "34fqwer"],
40
+ # "X-Greet": "Hello",
41
+ # "body": {
42
+ # "message": "Login successful for user Xavier"
43
+ # }
44
+ # }
45
+
46
+ original.to_s
47
+ # =>
48
+ # GET localhost/User/4
49
+ # timestamp: 1536345124
50
+ # token: 8ugw324/34fqwer
51
+ # X-Server: EventMachine
52
+ # referer: google.com/search
53
+ #
54
+ # name: Xavier
55
+
56
+ original.to.short
57
+ # => GET localhost/User/4?name:Xavier
58
+ end
59
+ end
60
+ end
61
+
62
+ Localhost.new
@@ -0,0 +1,11 @@
1
+ JSTP.config do |config|
2
+ config.strategy inbound: :websocket
3
+ end
4
+
5
+ class WebS < JSTP::Engine
6
+ class Article < JSTP::Controller
7
+ def post
8
+ puts body
9
+ end
10
+ end
11
+ end