DistelliServiceFrameworkSinatra 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,215 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sinatra/base'
4
+ require 'logging'
5
+ require 'distelli/serviceinterface'
6
+ require 'distelli/servicemarshallers'
7
+
8
+ module Rack
9
+ class CommonLogger
10
+ def call(env)
11
+ # do nothing
12
+ @app.call(env)
13
+ end
14
+ end
15
+ end
16
+
17
+ module Distelli
18
+ class ServiceBase < Sinatra::Base
19
+
20
+ my_layout = Logging::Layouts::Pattern.new(:pattern => "%d:[%l]:[%t]:[%c]:%m\n")
21
+ rf_appender = Logging::Appenders::RollingFile.new('TestRubyService', :filename => './logs/TestRubyService.log', :layout => my_layout, :roll_by => 'date', :age => '3600')
22
+ disable :raise_errors
23
+ disable :show_exceptions
24
+ disable :dump_errors
25
+
26
+ # Parse the json config file and get the application name and
27
+ # version to set the log file name
28
+
29
+ LOGGER = Logging.logger[:root]
30
+ LOGGER.add_appenders(rf_appender)
31
+ LOGGER.level = :debug
32
+ LOGGER.debug("TestRubyService initialized!")
33
+
34
+ def initialize()
35
+ super()
36
+ @xml_marshaller = Distelli::XmlMarshaller.new
37
+ @json_marshaller = Distelli::JsonMarshaller.new
38
+ end
39
+
40
+ def add_object(obj)
41
+ LOGGER.debug("Adding Model object: "+obj.inspect.to_s)
42
+ @xml_marshaller.add_object(obj)
43
+ @json_marshaller.add_object(obj)
44
+ end
45
+
46
+ def register_model(obj_list)
47
+ obj_list.each do |obj|
48
+ add_object(obj)
49
+ end
50
+ end
51
+
52
+ def unmarshall_request()
53
+ content_type = request[ServiceConstants::CONTENT_TYPE_HEADER]
54
+ if content_type == ServiceConstants::CONTENT_TYPE_JSON
55
+ return @json_marshaller.unmarshall(request.body)
56
+ elsif content_type == ServiceConstants::CONTENT_TYPE_XML
57
+ return @xml_marshaller.unmarshall(request.body)
58
+ else
59
+ return request.body
60
+ end
61
+ end
62
+
63
+ def marshall_response(response, extra_headers=nil, http_code=nil)
64
+ response_type = get_response_type(request)
65
+ if http_code != nil
66
+ status http_code
67
+ end
68
+
69
+ headers_hash = Hash.new
70
+ headers_hash[ServiceConstants::SERVER_HEADER] = "DistelliWS"
71
+ headers_hash[ServiceConstants::REQUEST_ID_HEADER] = get_request_id()
72
+
73
+ if extra_headers != nil
74
+ headers_hash.update(extra_headers)
75
+ end
76
+
77
+ if response_type == ServiceConstants::RESPONSE_TYPE_JSON
78
+ headers_hash[ServiceConstants::CONTENT_TYPE_HEADER] = ServiceConstants::CONTENT_TYPE_JSON
79
+ headers(headers_hash)
80
+ return @json_marshaller.marshall(response)
81
+ elsif response_type == ServiceConstants::RESPONSE_TYPE_XML
82
+ headers_hash[ServiceConstants::CONTENT_TYPE_HEADER] = ServiceConstants::CONTENT_TYPE_XML
83
+ headers(headers_hash)
84
+ return @xml_marshaller.marshall(response)
85
+ else
86
+ raise StandardError.new("Invalid Response type: "+response_type)
87
+ end
88
+ end
89
+
90
+ def marshall_error(error)
91
+ response_type = get_response_type(request)
92
+ if error.is_a?(Distelli::BaseException)
93
+ status error.http_code
94
+ else
95
+ error = Distelli::ServerError.new("Cannot marshall error of type "+error.class.name+" Defaulting to ServerError")
96
+ status error.http_code
97
+ end
98
+
99
+ headers_hash = Hash.new
100
+ headers_hash[ServiceConstants::SERVER_HEADER] = "DistelliWS"
101
+ headers_hash[ServiceConstants::REQUEST_ID_HEADER] = get_request_id()
102
+
103
+ if response_type == ServiceConstants::RESPONSE_TYPE_JSON
104
+ headers_hash[ServiceConstants::CONTENT_TYPE_HEADER] = ServiceConstants::CONTENT_TYPE_JSON
105
+ headers(headers_hash)
106
+ return @json_marshaller.marshall_error(error)
107
+ elsif response_type == ServiceConstants::RESPONSE_TYPE_XML
108
+ headers_hash[ServiceConstants::CONTENT_TYPE_HEADER] = ServiceConstants::CONTENT_TYPE_JSON
109
+ headers(headers_hash)
110
+ return @xml_marshaller.marshall_error(error)
111
+ else
112
+ LOGGER.error("Invalid Response Type: "+response_type)
113
+ error = ServerError.new("Invalid response type: "+response_type)
114
+ status error.http_code
115
+ headers_hash[ServiceConstants::CONTENT_TYPE_HEADER] = ServiceConstants::CONTENT_TYPE_JSON
116
+ headers(headers_hash)
117
+ return @json_marshaller.marshall_error(error)
118
+ end
119
+ end
120
+
121
+ private
122
+ def validate_response_type(response_type)
123
+ if response_type == nil
124
+ return ServiceConstants::RESPONSE_TYPE_JSON
125
+ end
126
+ if response_type == ServiceConstants::RESPONSE_TYPE_JSON
127
+ return response_type
128
+ elsif response_type == ServiceConstants::RESPONSE_TYPE_XML
129
+ return response_type
130
+ else
131
+ LOGGER.error("Invalid response type: "+response_type+" Defaulting to "+ServiceConstants::RESPONSE_TYPE_JSON)
132
+ return ServiceConstants::RESPONSE_TYPE_JSON
133
+ end
134
+ end
135
+
136
+ def get_request_id()
137
+ request_id = request[ServiceConstants::REQUEST_ID_HEADER]
138
+ if request_id != nil
139
+ return request_id
140
+ end
141
+ params = request.params()
142
+ request_id = params[ServiceConstants::REQUEST_ID_PARAM]
143
+ if request_id != nil
144
+ return request_id
145
+ end
146
+
147
+ # Create a new request id
148
+ request_id = SecureRandom.uuid
149
+ request[ServiceConstants::REQUEST_ID_HEADER] = request_id
150
+ return request_id
151
+ end
152
+
153
+ def get_response_type(request)
154
+ response_type = request[ServiceConstants::RESPONSE_TYPE_HEADER]
155
+ if response_type != nil
156
+ return validate_response_type(response_type)
157
+ end
158
+
159
+ response_type = nil
160
+ params = request.params()
161
+ if params != nil
162
+ response_type = params[ServiceConstants::RESPONSE_TYPE_PARAM]
163
+ end
164
+ return validate_response_type(response_type)
165
+ end
166
+
167
+ def get_operation(request)
168
+ # First check to see if there is the operation header.
169
+ # If there is then thats the operation
170
+ # If not then check to see if there is the operation query param
171
+ # If it is then thats the operation
172
+ # else the operation is null
173
+ op_name = request[ServiceConstants::OPERATION_HEADER]
174
+ if op_name != nil
175
+ return op_name
176
+ end
177
+
178
+ params = request.params()
179
+ if params == nil
180
+ return nil
181
+ end
182
+ return params[ServiceConstants::OPERATION_PARAM]
183
+ end
184
+
185
+ ######################################
186
+ # Error Handlers
187
+ ######################################
188
+ error do
189
+ # Marshall the error as a server error
190
+ ex = env['sinatra.error']
191
+ LOGGER.error('Unhandled Exception: '+ex.inspect+ex.backtrace.join("\n"))
192
+ return marshall_error(ex)
193
+ end
194
+
195
+ error Distelli::ClientError do
196
+ # Marshall the Client Error Exception and set the response code
197
+ ce = env['sinatra.error']
198
+ marshall_error(ce)
199
+ end
200
+
201
+ error Distelli::ServerError do
202
+ # Marshall the Server Error Exception and set the response code
203
+ se = env['sinatra.error']
204
+ return marshall_error(se)
205
+ end
206
+
207
+ not_found do
208
+ # Marshall a Client Error Exception and set the 400 response code
209
+ op_name = get_operation(request)
210
+
211
+ error = MalformedRequest.new(request.request_method+" not supported on resource: "+request.path)
212
+ return marshall_error(error)
213
+ end
214
+ end
215
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: DistelliServiceFrameworkSinatra
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rahul Singh
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: DistelliServiceInterface
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: logging
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Distelli Service Framework for Ruby Sinatra based servers
63
+ email: rsingh@distelli.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - lib/distelli/serviceframeworksinatra.rb
69
+ homepage: http://www.distelli.com/
70
+ licenses: []
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.23
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: Distelli Service Framework classes for Sinatra
93
+ test_files: []