Implemented WSF_RESPONSE.put_error (...) and related

Added WSF_RESPONSE.put_character
Renamed  WGI_OUTPUT_STREAM.put_character_8 as put_character  to follow style of put_string  (and not put_string_8)
Refactored the WSF_DEFAULT_SERVICE_LAUNCHER
Added WSF_DEFAULT_SERVICE to be more user friendly
Splitted the wsf/default/ libraries to have wsf/connector/... and being able to handle more than one connector in the same application
This commit is contained in:
Jocelyn Fiat
2012-03-20 10:29:55 +01:00
parent 71d5dc4795
commit 8344607eb6
63 changed files with 1238 additions and 407 deletions

View File

@@ -0,0 +1,52 @@
note
description: "[
Create this service with a callback to implement {WSF_SERVICE}.execute (req, res)
]"
date: "$Date$"
revision: "$Revision$"
class
WSF_CALLBACK_SERVICE
inherit
WSF_SERVICE
create
make
convert
make ({PROCEDURE [ANY, TUPLE [WSF_REQUEST, WSF_RESPONSE]]})
feature {NONE} -- Implementation
make (a_callback: like callback)
-- Initialize `Current'.
do
callback := a_callback
end
feature {NONE} -- Implementation
callback: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]
-- Procedure called on `execute'
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the request
do
callback.call ([req, res])
end
invariant
callback_attached: callback /= Void
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,50 @@
note
description: "Summary description for {WSF_DEFAULT_SERVICE_I}."
date: "$Date$"
revision: "$Revision$"
deferred class
WSF_DEFAULT_SERVICE_I [G -> WSF_SERVICE_LAUNCHER create make_and_launch end]
inherit
WSF_SERVICE
feature {NONE} -- Initialization
make_and_launch
local
l_launcher: G
do
create l_launcher.make_and_launch (Current, service_options)
end
service_options: detachable WSF_SERVICE_LAUNCHER_OPTIONS
feature -- Default service options
set_service_option (a_name: READABLE_STRING_GENERAL; a_value: detachable ANY)
-- Set options related to WSF_DEFAULT_SERVICE
local
opts: like service_options
do
opts := service_options
if opts = Void then
create opts.make
service_options := opts
end
opts.set_option (a_name, a_value)
ensure
attached service_options as l_options and then l_options.option (a_name) = a_value
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,41 @@
note
description: "[
Inherit from this class to implement the main entry of your web service
You just need to implement `execute', get data from the request `req'
and return a response message
]"
date: "$Date$"
revision: "$Revision$"
deferred class
WSF_RESPONSE_SERVICE
inherit
WSF_SERVICE
feature -- Response
response (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
deferred
ensure
Result_attached: Result /= Void
end
feature -- Execution
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
do
res.send (response (req))
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -10,11 +10,11 @@ note
deferred class
WSF_SERVICE
inherit
WGI_SERVICE
rename
execute as wgi_execute
end
--inherit
-- WGI_SERVICE
-- rename
-- execute as wgi_execute
-- end
feature -- Execution
@@ -26,25 +26,25 @@ feature -- Execution
deferred
end
feature {WGI_CONNECTOR} -- WGI Execution
--feature {WGI_CONNECTOR} -- WGI Execution
wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE)
local
w_res: detachable WSF_RESPONSE
w_req: detachable WSF_REQUEST
do
create w_res.make_from_wgi (res)
create w_req.make_from_wgi (req)
execute (w_req, w_res)
w_req.destroy
rescue
if w_res /= Void then
w_res.flush
end
if w_req /= Void then
w_req.destroy
end
end
-- wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE)
-- local
-- w_res: detachable WSF_RESPONSE
-- w_req: detachable WSF_REQUEST
-- do
-- create w_res.make_from_wgi (res)
-- create w_req.make_from_wgi (req)
-- execute (w_req, w_res)
-- w_req.destroy
-- rescue
-- if w_res /= Void then
-- w_res.flush
-- end
-- if w_req /= Void then
-- w_req.destroy
-- end
-- end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"

View File

@@ -4,8 +4,11 @@ note
How-to:
s: WSF_DEFAULT_SERVICE_LAUNCHER
create s.make_and_launch (agent execute)
s: WSF_SERVICE_LAUNCHER
create s.make_and_launch (service)
`service' can be Current if inherit from WSF_SERVICE
or also `create {WSF_CALLBACK_SERVICE}.make (agent execute)'
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
do
@@ -29,43 +32,54 @@ note
revision: "$Revision$"
deferred class
WSF_DEFAULT_SERVICE_LAUNCHER_I
WSF_SERVICE_LAUNCHER
inherit
WSF_SERVICE
WSF_TO_WGI_SERVICE
feature {NONE} -- Initialization
frozen make (a_action: like action; a_options: like options)
frozen make (a_service: like service; a_options: like options)
do
action := a_action
make_from_service (a_service)
options := a_options
initialize
ensure
action_set: action = a_action
service_set: service = a_service
options_set: options = a_options
launchable: launchable
end
frozen make_and_launch (a_action: like action)
do
make (a_action, Void)
launch
end
frozen make_and_launch_with_options (a_action: like action; a_options: attached like options)
frozen make_and_launch (a_service: like service; a_options: like options)
require
a_options_attached: a_options /= Void
do
make (a_action, a_options)
make (a_service, a_options)
launch
end
frozen make_callback (a_callback: like {WSF_CALLBACK_SERVICE}.callback; a_options: like options)
do
make (create {WSF_CALLBACK_SERVICE}.make (a_callback), a_options)
end
frozen make_callback_and_launch (a_callback: like {WSF_CALLBACK_SERVICE}.callback; a_options: like options)
do
make (create {WSF_CALLBACK_SERVICE}.make (a_callback), a_options)
end
frozen make_and_launch_with_options (a_callback: like {WSF_CALLBACK_SERVICE}.callback; a_options: like options)
obsolete
"[2012-Mars-20] Use make_callback_and_launch (a_callback, a_options)"
do
make_callback_and_launch (a_callback, a_options)
end
initialize
-- Initialize Current using `options' if attached
-- and build the connector
require
action_set: action /= Void
service_set: service /= Void
deferred
ensure
connector_attached: connector /= Void
@@ -108,20 +122,9 @@ feature -- Execution
feature {NONE} -- Implementation
options: detachable ARRAY [detachable TUPLE [name: READABLE_STRING_GENERAL; value: detachable ANY]]
options: detachable WSF_SERVICE_LAUNCHER_OPTIONS
-- Custom options which might be support (or not) by the default service
action: PROCEDURE [ANY, TUPLE [WSF_REQUEST, WSF_RESPONSE]]
-- Action to be executed on request incoming
feature {NONE} -- Implementation: Execution
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
action.call ([req, res])
end
invariant
connector_attached: connector /= Void

View File

@@ -0,0 +1,80 @@
note
description: "[
Options used by WSF_SERVICE_LAUNCHER
For instance options supported by Nino as default connector::
port: numeric such as 8099 (or equivalent string as "8099")
base: base_url (very specific to standalone server)
force_single_threaded: use only one thread, useful for Nino
verbose: to display verbose output, useful for Nino
]"
date: "$Date$"
revision: "$Revision$"
class
WSF_SERVICE_LAUNCHER_OPTIONS
create
make,
make_from_array
convert
make_from_array ({ARRAY [TUPLE [name: READABLE_STRING_GENERAL; value: detachable ANY]]})
feature {NONE} -- Initialization
make
do
create options.make (0)
end
make_from_array (a_options: ARRAY [TUPLE [name: READABLE_STRING_GENERAL; value: detachable ANY]])
do
make
across
a_options as opt
loop
if attached opt.item as o then
set_option (o.name, o.value)
end
end
end
feature -- Access
option (a_name: READABLE_STRING_GENERAL): detachable ANY
do
Result := options.item (a_name)
end
feature -- Element change
set_option (a_name: READABLE_STRING_GENERAL; a_value: detachable ANY)
do
options.force (a_value, a_name)
end
set_verbose (b: BOOLEAN)
-- Set option "verbose" to `b'
do
set_option ("verbose", b)
end
feature {NONE} -- Implementation
options: HASH_TABLE [detachable ANY, READABLE_STRING_GENERAL]
-- Custom options which might be support (or not) by the default service
invariant
options_attached: options /= Void
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,62 @@
note
description: "[
This class is the link between WGI_SERVICE and WSF_SERVICE
It makes a WSF_SERVICE callable from the WGI_ world.
]"
date: "$Date$"
revision: "$Revision$"
class
WSF_TO_WGI_SERVICE
inherit
WGI_SERVICE
create
make_from_service
feature {NONE} -- Make
make_from_service (a_service: like service)
-- Make from WSF_SERVICE `a_service'
do
service := a_service
end
service: WSF_SERVICE
-- Associated WSF_SERVICE
feature {WGI_CONNECTOR} -- Implementation: Execution
execute (req: WGI_REQUEST; res: WGI_RESPONSE)
-- Delegate the WGI processing to the WSF_SERVICE object
-- <Precursor>
local
w_res: detachable WSF_RESPONSE
w_req: detachable WSF_REQUEST
do
create w_res.make_from_wgi (res)
create w_req.make_from_wgi (req)
service.execute (w_req, w_res)
w_req.destroy
rescue
if w_res /= Void then
w_res.flush
end
if w_req /= Void then
w_req.destroy
end
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -26,7 +26,7 @@ class
inherit
DEBUG_OUTPUT
create {WSF_SERVICE}
create {WSF_TO_WGI_SERVICE}
make_from_wgi
convert

View File

@@ -8,7 +8,7 @@ note
class
WSF_RESPONSE
create {WSF_SERVICE}
create {WSF_TO_WGI_SERVICE}
make_from_wgi
convert
@@ -117,6 +117,14 @@ feature -- Header output operation
feature -- Output operation
put_character (c: CHARACTER_8)
-- Send the character `c'
require
message_writable: message_writable
do
wgi_response.put_character (c)
end
put_string (s: READABLE_STRING_8)
-- Send the string `s'
require
@@ -269,6 +277,15 @@ feature -- Redirect
redirect_now_custom (a_url, {HTTP_STATUS_CODE}.temp_redirect, Void, [a_content, a_content_type])
end
feature -- Error reporting
put_error (a_message: READABLE_STRING_8)
-- Report error described by `a_message'
-- This might be used by the underlying connector
do
wgi_response.put_error (a_message)
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"