jstp 0.5.7 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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