DistelliServiceFrameworkSinatra 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.
@@ -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: []