Class: DotNetServices::Session
- Inherits:
-
Object
- Object
- DotNetServices::Session
- Defined in:
- lib/dot_net_services/session.rb
Overview
The Session class is used for communicating with endpoints of .NET Services bus.
Usage examples
A Session instance represents a .NET Services bus endpoint. Typically, you create it by calling Session#open and then exchange HTTP messages using methods like #get, #post, etc. It looks like this:
Send a GET with no parameters:
session = Session.open('/MySolution/MyService', :username => 'MySolution', :password => 'my_password')
get_response = session.get
# ... process response, which is a Net::HTTP::Response instance
Send a GET with ?age=21&sex=Male query string:
get_with_query_response = session.get :age => 21, :sex => "Male"
Send a POST with name=Joe&email=joe@the_plumber.com (URL-encoded form) as a body:
post_response = session.post :name => 'Joe', :email => 'joe@the_plumber.com'
So far, Session API is similar to Net::HTTP::Session. Which is the whole point of the REST style communication - it is all just HTTP! However, there is one small twist. HTTP::Session represents a server (host and port). DotNetServices::Session represents a service endpoint. Which is a URL, not a server. In fact, all .NET Services endpoints have the same server, servicebus.windows.net. So an endpoint address is really just a path on that server.
And sometimes you need to send requests to a path under the endpoint. For example, to update the name of customer #12345, you would do a POST to /MySolution/Customer/12345 with &name=Dave body. Creating a new Session for that is both counterintuitive and expensive (see the Details section below). For this reason, DotNetServices::Session has methods like post_to_url:
result = session.post_to_url(12345, :name => 'Dave')
Details
When a session is created, it’s given the URL of an endpoint (that looks like /SolutionName/path/to/service), and username / password. These are solution’s username and password, needed to prove to the bus that your consumer is a part of this solution. If the solution allows anonymous access, username / password are not necessary.
When a session is opened (or is asked to send a first request to the endpoint), the session authenticates itself to the .NET Services using Identity Service [accesscontrol.windows.net], and obtains a security token from it.
Security token is a Base64-encoded string. Unless an endpoint allows unauthenticated access, any request that comes to the endpoint must have this security token attached to it (as X-MS-Identity-Token HTTP header). DotNetServices::Session takes care of this responsibility, as well as renewing stale tokens.
Session also has methods get_from_relay and post_to_relay, that are used for communicating to the .NET Services bus management endpoint. These methods (createmb, retrieve, query) are used by MessageBuffer, an application normally shouldn’t need to use them directly.
Guidelines
Obtaining a security token is an expensive operation, so it is not recommended to create a new instance of a Session for every outgoing request to the endpoint. It’s better to use one Session instance per endpoint. Session takes care of expiring security tokens autoimatically, so Session instances don’t go stale even after long periods of inactivity.
Instance Attribute Summary collapse
-
#authenticator ⇒ Object
readonly
Returns the value of attribute authenticator.
Class Method Summary collapse
-
.open(endpoint, auth_data = nil, &block) ⇒ Object
Open a .Net Services session at the
endpoint
.
Instance Method Summary collapse
-
#authenticate ⇒ Object
Acquire a security token from the Identity Service.
-
#createmb ⇒ Object
Create a new message buffer (sends an X-CREATEMB to the service management endpoint).
-
#delete ⇒ Object
Delete an endpoint (sends a DELETE to the service management endpoint).
-
#endpoint ⇒ Object
The URL of a .NET services endpoint this Session is connected to.
-
#get(query_options = nil) ⇒ Object
Send a GET request to the .NET Services endpoint.
-
#get_from_relay(query_options = nil) ⇒ Object
Sends a GET to the service management endpoint.
- #get_from_url(url, query_options = nil) ⇒ Object
-
#initialize(endpoint, auth_data = nil) ⇒ Session
constructor
Initialize a new .NET Session at the
endpoint
. -
#open ⇒ Object
See DotNetServices::Session.open.
-
#post(data = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Send a POST request to the .NET Services endpoint.
-
#post_to_relay(data = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Sends a POST to the service management endpoint.
-
#post_to_url(url, data = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Sends a POST request to a path below .NET Services endpoint.
-
#retrieve(query_options = {}) ⇒ Object
Retrieve the next message from the message buffer (sends an X-RETRIEVE to the service management endpoint).
-
#subscribe(request_options) ⇒ Object
Subscribe a message buffer to a virtual endpoint (sends an X-SUBSCRIBE to the VMB management endpoint).
-
#unsubscribe(request_options) ⇒ Object
Unsubscribe a message buffer from a virtual endpoint (sends an X-UNSUBSCRIBE to the VMB management endpoint).
Constructor Details
#initialize(endpoint, auth_data = nil) ⇒ Session
Initialize a new .NET Session at the endpoint
.
If auth_data
is provided, remember it. Acquiring authentication token is postponed until it’s needed.
89 90 91 92 |
# File 'lib/dot_net_services/session.rb', line 89 def initialize(endpoint, auth_data=nil) @endpoint_uri = setup_endpoint(endpoint) @authenticator = Authentication.setup(auth_data) end |
Instance Attribute Details
#authenticator ⇒ Object (readonly)
Returns the value of attribute authenticator.
68 69 70 |
# File 'lib/dot_net_services/session.rb', line 68 def authenticator @authenticator end |
Class Method Details
.open(endpoint, auth_data = nil, &block) ⇒ Object
Open a .Net Services session at the endpoint
.
If auth_data
is provided, authenticates the session with the identity service using it. In this version, auth_data
should be a hash containing :username
and :password
keys. Other authentication mechanisms (InformationCard, X.509 certificates etc) that the Identity service provides are not exposed via a REST interface, therefore are not available to this library.
If #open is called with a block, it passes the session instance as an argument to the block and returns the result of the block. If there is no block, session instance is returned instead.
80 81 82 |
# File 'lib/dot_net_services/session.rb', line 80 def open(endpoint, auth_data = nil, &block) Session.new(endpoint, auth_data).open(&block) end |
Instance Method Details
#authenticate ⇒ Object
Acquire a security token from the Identity Service.
This method will do nothing if:
-
this session already holds a security token and the token has not expired yet, or
-
the session was created without auth_data (anonymous session)
119 120 121 |
# File 'lib/dot_net_services/session.rb', line 119 def authenticate @authenticator.authenticate end |
#createmb ⇒ Object
Create a new message buffer (sends an X-CREATEMB to the service management endpoint).
This is used by MessageBuffer for VMB management. Applications should use MessageBuffer#open.
203 204 205 206 207 |
# File 'lib/dot_net_services/session.rb', line 203 def createmb request = Net::HTTP::CreateMB.new(@endpoint_uri.path) route_to_relay(request) enhance_and_execute(request) end |
#delete ⇒ Object
Delete an endpoint (sends a DELETE to the service management endpoint).
This is used by MessageBuffer for VMB management. Applications should use MessageBuffer#delete.
245 246 247 248 249 |
# File 'lib/dot_net_services/session.rb', line 245 def delete request = Net::HTTP::Delete.new(@endpoint_uri.path) route_to_relay(request) enhance_and_execute(request) end |
#endpoint ⇒ Object
The URL of a .NET services endpoint this Session is connected to.
252 253 254 |
# File 'lib/dot_net_services/session.rb', line 252 def endpoint @endpoint_uri.to_s end |
#get(query_options = nil) ⇒ Object
Send a GET request to the .NET Services endpoint.
If query options are provided, they should be a hash, and they are converted to a query string and attached to the GET request target URL. Thus, session.get(:foo => ‘bar’) sends a GET to ##endpoint?foo=bar
128 129 130 |
# File 'lib/dot_net_services/session.rb', line 128 def get(=nil) get_from_url(nil, ) end |
#get_from_relay(query_options = nil) ⇒ Object
Sends a GET to the service management endpoint.
This is used by MessageBuffer for VMB management. Applications shouldn’t need to use this method.
142 143 144 145 146 147 |
# File 'lib/dot_net_services/session.rb', line 142 def get_from_relay(=nil) uri = setup_query_string(nil, ) get_request = Net::HTTP::Get.new(uri.request_uri) route_to_relay(get_request) enhance_and_execute(get_request) end |
#get_from_url(url, query_options = nil) ⇒ Object
133 134 135 136 137 |
# File 'lib/dot_net_services/session.rb', line 133 def get_from_url(url, =nil) uri = setup_query_string(url, ) get_request = Net::HTTP::Get.new(uri.request_uri) enhance_and_execute(get_request) end |
#open ⇒ Object
See DotNetServices::Session.open.
109 110 111 112 |
# File 'lib/dot_net_services/session.rb', line 109 def open authenticate block_given? ? yield(self) : self end |
#post(data = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Send a POST request to the .NET Services endpoint.
If data
is a Hash it is converted to a URL-encoded form, otherwise it is placed in the post body without any conversion.
content_type
by default is set to application/x-www-form-urlencoded
, which is appropriate when data
is a Hash. In any other case, you should specify content_type
explicitly.
156 157 158 |
# File 'lib/dot_net_services/session.rb', line 156 def post(data=nil, content_type='application/x-www-form-urlencoded') post_to_url("", data, content_type) end |
#post_to_relay(data = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Sends a POST to the service management endpoint.
This is used by MessageBuffer for VMB management. Applications should use MessageBuffer#keep_alive.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/dot_net_services/session.rb', line 185 def post_to_relay(data=nil, content_type='application/x-www-form-urlencoded') post_request = Net::HTTP::Post.new(@endpoint_uri.path) if data post_request.content_type = content_type if content_type == 'application/x-www-form-urlencoded' post_request.form_data = data else post_request.body = data end end route_to_relay(post_request) enhance_and_execute(post_request) end |
#post_to_url(url, data = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Sends a POST request to a path below .NET Services endpoint.
If an application neeeds to send a POST to a service that uses URL to receive data, it should use this method instead of creating a new session for every new request. For example, if a service endpoint is called /Solution/Maps, and it’s URL template is /Solution/Maps/country/province/city, a way to create a map of Calgary would be:
session.post_to_url('/Canada/Calgary', map_data, content_type=...)
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/dot_net_services/session.rb', line 168 def post_to_url(url, data=nil, content_type='application/x-www-form-urlencoded') post_request = Net::HTTP::Post.new(@endpoint_uri.path + url.to_s) if data post_request.content_type = content_type if content_type == 'application/x-www-form-urlencoded' post_request.form_data = data else post_request.body = data end end enhance_and_execute(post_request) end |
#retrieve(query_options = {}) ⇒ Object
Retrieve the next message from the message buffer (sends an X-RETRIEVE to the service management endpoint).
This is used by MessageBuffer for VMB management. Applications should use MessageBuffer#poll.
232 233 234 235 236 237 238 239 |
# File 'lib/dot_net_services/session.rb', line 232 def retrieve(={}) = stringify_and_downcase_keys() ['timeout'] ||= 15 uri = setup_query_string(nil, ) request = Net::HTTP::Retrieve.new(uri.request_uri) route_to_relay(request) enhance_and_execute(request) end |
#subscribe(request_options) ⇒ Object
Subscribe a message buffer to a virtual endpoint (sends an X-SUBSCRIBE to the VMB management endpoint).
This is used by MessageBuffer for VMB management. Applications should use MessageBuffer#open.
212 213 214 215 216 217 |
# File 'lib/dot_net_services/session.rb', line 212 def subscribe() uri = setup_query_string(nil, ) request = Net::HTTP::Subscribe.new(uri.request_uri) route_to_relay(request) enhance_and_execute(request) end |
#unsubscribe(request_options) ⇒ Object
Unsubscribe a message buffer from a virtual endpoint (sends an X-UNSUBSCRIBE to the VMB management endpoint).
This is used by MessageBuffer for VMB management. Applications should use MessageBuffer#open.
222 223 224 225 226 227 |
# File 'lib/dot_net_services/session.rb', line 222 def unsubscribe() uri = setup_query_string(nil, ) request = Net::HTTP::Unsubscribe.new(uri.request_uri) route_to_relay(request) enhance_and_execute(request) end |