isbm_adaptor 1.0.rc8.5 → 1.0.rc8.6
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +9 -0
- data/README.md +56 -21
- data/lib/isbm_adaptor/channel.rb +8 -1
- data/lib/isbm_adaptor/channel_management.rb +3 -8
- data/lib/isbm_adaptor/client.rb +86 -0
- data/lib/isbm_adaptor/consumer_publication.rb +6 -30
- data/lib/isbm_adaptor/consumer_request.rb +109 -0
- data/lib/isbm_adaptor/duration.rb +26 -7
- data/lib/isbm_adaptor/message.rb +12 -9
- data/lib/isbm_adaptor/provider_publication.rb +8 -10
- data/lib/isbm_adaptor/provider_request.rb +110 -0
- data/lib/isbm_adaptor/version.rb +1 -1
- data/lib/isbm_adaptor.rb +2 -0
- data/wsdls/ISBMConsumerRequestService.wsdl +349 -0
- data/wsdls/ISBMProviderRequestService.wsdl +376 -0
- metadata +18 -12
- data/lib/isbm_adaptor/service.rb +0 -42
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright 2013 Assetricity, LLC
|
2
|
+
|
3
|
+
The MIT License (MIT)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,24 +1,59 @@
|
|
1
|
-
|
2
|
-
![travis](https://travis-ci.org/assetricity/isbm_adaptor.png)
|
1
|
+
# ISBM Adaptor
|
3
2
|
|
4
|
-
|
3
|
+
[![Build Status](https://travis-ci.org/assetricity/isbm_adaptor.png)](https://travis-ci.org/assetricity/isbm_adaptor)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/assetricity/isbm_adaptor/badge.png?branch=master)](https://coveralls.io/r/assetricity/isbm_adaptor?branch=master)
|
5
|
+
[![Dependency Status](https://gemnasium.com/assetricity/isbm_adaptor.png)](https://gemnasium.com/assetricity/isbm_adaptor)
|
6
|
+
|
7
|
+
The ISBM Adaptor provides a Ruby API for the [OpenO&M ISBM specification](http://www.mimosa.org/?q=about/what-open-om).
|
8
|
+
|
9
|
+
It is based on the [Savon](http://savonrb.com) SOAP client and provides convenience methods for interaction with an ISBM Service Provider.
|
10
|
+
|
11
|
+
## Install
|
12
|
+
|
13
|
+
### Bundler
|
14
|
+
|
15
|
+
Add to the isbm_adaptor gem to your Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'isbm_adaptor'
|
19
|
+
```
|
20
|
+
|
21
|
+
This gem uses a four part version, with the first three parts following the OpenO&M ISBM specification and last part specifying a patch number. To use the pessimistic version constraint, you will want to include the four part version in your Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'isbm_adaptor', '~> 1.0.0.0'
|
25
|
+
```
|
26
|
+
|
27
|
+
### Other
|
28
|
+
|
29
|
+
The gem can also be installed via the gem install command:
|
5
30
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
31
|
+
```bash
|
32
|
+
gem install isbm_adaptor
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
Create a client object by specifying an endpoint. For example:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
client = IsbmAdaptor::ChannelManagement.new('http://example.com/ChannelManagement')
|
41
|
+
```
|
42
|
+
|
43
|
+
The standard Savon options can also be passed to the client upon creation. For example:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
client = IsbmAdaptor::ChannelManagement.new('http://example.com/ChannelManagement', log: false)
|
47
|
+
```
|
48
|
+
|
49
|
+
Use the client methods to directly send SOAP messages to the server. For example:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
client.get_channels
|
53
|
+
```
|
54
|
+
|
55
|
+
## License
|
56
|
+
|
57
|
+
Copyright 2013 Assetricity, LLC
|
24
58
|
|
59
|
+
ISBM Adaptor is released under the MIT License. See [LICENSE](https://github.com/assetricity/isbm_adaptor/blob/master/LICENSE) for details.
|
data/lib/isbm_adaptor/channel.rb
CHANGED
@@ -2,7 +2,14 @@ module IsbmAdaptor
|
|
2
2
|
class Channel
|
3
3
|
TYPES = ['Publication', 'Request']
|
4
4
|
|
5
|
-
|
5
|
+
# @return [String] the channel URI
|
6
|
+
attr_accessor :uri
|
7
|
+
|
8
|
+
# @return [String] the channel type, either 'Publication' or 'Request'
|
9
|
+
attr_accessor :type
|
10
|
+
|
11
|
+
# @return [String] the channel description
|
12
|
+
attr_accessor :description
|
6
13
|
|
7
14
|
# Creates a new Channel.
|
8
15
|
#
|
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'isbm_adaptor/
|
1
|
+
require 'isbm_adaptor/client'
|
2
2
|
require 'isbm_adaptor/channel'
|
3
3
|
|
4
4
|
module IsbmAdaptor
|
5
|
-
class ChannelManagement
|
6
|
-
include IsbmAdaptor::Service
|
7
|
-
|
5
|
+
class ChannelManagement < IsbmAdaptor::Client
|
8
6
|
# Creates a new ISBM ChannelManagement client.
|
9
7
|
#
|
10
8
|
# @param endpoint [String] the SOAP endpoint URI
|
@@ -12,10 +10,7 @@ module IsbmAdaptor
|
|
12
10
|
# @option options [Boolean] :log (true) specify whether requests are logged
|
13
11
|
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
|
14
12
|
def initialize(endpoint, options = {})
|
15
|
-
|
16
|
-
options[:endpoint] = endpoint
|
17
|
-
default_savon_options(options)
|
18
|
-
@client = Savon.client(options)
|
13
|
+
super('ISBMChannelManagementService.wsdl', endpoint, options)
|
19
14
|
end
|
20
15
|
|
21
16
|
# Creates a new channel.
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'isbm_adaptor/message'
|
2
|
+
|
3
|
+
module IsbmAdaptor
|
4
|
+
class Client
|
5
|
+
# Creates a new ISBM client.
|
6
|
+
#
|
7
|
+
# @param wsdl_file [String] the filename of the WSDL
|
8
|
+
# @param endpoint [String] the SOAP endpoint URI
|
9
|
+
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
|
10
|
+
# @option options [Boolean] :log (true) specify whether requests are logged
|
11
|
+
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
|
12
|
+
def initialize(wsdl_file, endpoint, options = {})
|
13
|
+
options[:wsdl] = wsdl_dir + wsdl_file
|
14
|
+
options[:endpoint] = endpoint
|
15
|
+
default_savon_options(options)
|
16
|
+
@client = Savon.client(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Validates the presence of the passed value.
|
20
|
+
#
|
21
|
+
# @param value [Object] presence of object to validate
|
22
|
+
# @param name [String] name of value to include in error message if not present
|
23
|
+
# @return [void]
|
24
|
+
# @raises [ArgumentError] if value is not present
|
25
|
+
def validate_presence_of(value, name)
|
26
|
+
if value.blank?
|
27
|
+
raise ArgumentError, "#{name} must be specified"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Validates the well formedness of the XML string and raises an error if
|
32
|
+
# any errors are encountered.
|
33
|
+
#
|
34
|
+
# @param xml [String] the XML string to parse
|
35
|
+
# @return [void]
|
36
|
+
def validate_xml(xml)
|
37
|
+
doc = Nokogiri.XML(xml)
|
38
|
+
raise ArgumentError, "XML is not well formed: #{xml}" unless doc.errors.empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates an IsbmAdaptor::Message from a ISBM response.
|
42
|
+
#
|
43
|
+
# @param response [Savon::Response] the ISBM response
|
44
|
+
# @return [IsbmAdaptor::Message] the extracted message
|
45
|
+
def extract_message(response)
|
46
|
+
# Extract the message element
|
47
|
+
# e.g. /Envelope/Body/ReadPublicationResponse/PublicationMessage
|
48
|
+
message = response.doc.root.element_children.first.element_children.first.element_children.first
|
49
|
+
|
50
|
+
return nil unless message
|
51
|
+
|
52
|
+
id = message.element_children[0].text
|
53
|
+
content = message.element_children[1].element_children.first
|
54
|
+
topics = message.element_children[2..-1].map {|e| e.text}
|
55
|
+
|
56
|
+
# Retain any ancestor namespaces in case they are applicable for the element and/or children
|
57
|
+
# This is because content#to_xml does not output ancestor namespaces
|
58
|
+
content.namespaces.each do |key, value|
|
59
|
+
prefix = key.gsub(/xmlns:?/, '')
|
60
|
+
prefix = nil if prefix.empty?
|
61
|
+
content.add_namespace_definition(prefix, value)
|
62
|
+
end
|
63
|
+
|
64
|
+
IsbmAdaptor::Message.new(id, content, topics)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Indicates the directory of the ISBM WSDL files
|
70
|
+
#
|
71
|
+
# @return [String] directory of ISBM WSDL files
|
72
|
+
def wsdl_dir
|
73
|
+
File.expand_path(File.dirname(__FILE__)) + '/../../wsdls/'
|
74
|
+
end
|
75
|
+
|
76
|
+
# Sets default values for certain Savon options.
|
77
|
+
#
|
78
|
+
# @param options [Hash] the options to set defaults on
|
79
|
+
# @return [Hash] options hash with defaults set
|
80
|
+
def default_savon_options(options)
|
81
|
+
options[:logger] = Rails.logger if defined?(Rails)
|
82
|
+
options[:log] ||= true
|
83
|
+
options[:pretty_print_xml] ||= false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -1,9 +1,7 @@
|
|
1
|
-
require 'isbm_adaptor/
|
2
|
-
require 'isbm_adaptor/message'
|
1
|
+
require 'isbm_adaptor/client'
|
3
2
|
|
4
3
|
module IsbmAdaptor
|
5
|
-
class ConsumerPublication
|
6
|
-
include IsbmAdaptor::Service
|
4
|
+
class ConsumerPublication < IsbmAdaptor::Client
|
7
5
|
|
8
6
|
# Creates a new ISBM ConsumerPublication client.
|
9
7
|
#
|
@@ -12,15 +10,14 @@ module IsbmAdaptor
|
|
12
10
|
# @option options [Boolean] :log (true) specify whether requests are logged
|
13
11
|
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
|
14
12
|
def initialize(endpoint, options = {})
|
15
|
-
|
16
|
-
options[:endpoint] = endpoint
|
17
|
-
default_savon_options(options)
|
18
|
-
@client = Savon.client(options)
|
13
|
+
super('ISBMConsumerPublicationService.wsdl', endpoint, options)
|
19
14
|
end
|
20
15
|
|
21
16
|
# Opens a subscription session for a channel.
|
22
17
|
#
|
18
|
+
# @param uri [String] the channel URI
|
23
19
|
# @param topics [Array<String>] an array of topics
|
20
|
+
# @param listener_uri [String] the URI for notification callbacks
|
24
21
|
# @return [String] the session id
|
25
22
|
# @raise [ArgumentError] if uri or topics are nil/empty
|
26
23
|
def open_session(uri, topics, listener_uri = nil)
|
@@ -53,30 +50,9 @@ module IsbmAdaptor
|
|
53
50
|
|
54
51
|
message = { 'SessionID' => session_id }
|
55
52
|
message['LastMessageID'] = last_message_id unless last_message_id.nil?
|
56
|
-
|
57
53
|
response = @client.call(:read_publication, message: message)
|
58
54
|
|
59
|
-
|
60
|
-
message = nil
|
61
|
-
if hash
|
62
|
-
id = hash[:message_id]
|
63
|
-
topics = hash[:topic]
|
64
|
-
|
65
|
-
# Extract the child element in message content
|
66
|
-
# //isbm:ReadPublicationResponse/isbm:PublicationMessage/isbm:MessageContent/child::*
|
67
|
-
content = response.doc.root.element_children.first.element_children.first.element_children.first.element_children[1].element_children.first
|
68
|
-
|
69
|
-
# Retain any ancestor namespaces in case they are applicable for the element and/or children
|
70
|
-
# This is because content#to_xml does not output ancestor namespaces
|
71
|
-
content.namespaces.each do |key, value|
|
72
|
-
prefix = key.gsub(/xmlns:?/, '')
|
73
|
-
prefix = nil if prefix.empty?
|
74
|
-
content.add_namespace_definition(prefix, value)
|
75
|
-
end
|
76
|
-
|
77
|
-
message = IsbmAdaptor::Message.new(id, content, topics)
|
78
|
-
end
|
79
|
-
message
|
55
|
+
extract_message(response)
|
80
56
|
end
|
81
57
|
|
82
58
|
# Closes a subscription session.
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'isbm_adaptor/client'
|
2
|
+
|
3
|
+
module IsbmAdaptor
|
4
|
+
class ConsumerRequest < IsbmAdaptor::Client
|
5
|
+
|
6
|
+
# Creates a new ISBM ConsumerRequest client.
|
7
|
+
#
|
8
|
+
# @param endpoint [String] the SOAP endpoint URI
|
9
|
+
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
|
10
|
+
# @option options [Boolean] :log (true) specify whether requests are logged
|
11
|
+
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
|
12
|
+
def initialize(endpoint, options = {})
|
13
|
+
super('ISBMConsumerRequestService.wsdl', endpoint, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Opens a consumer request session for a channel for posting requests and
|
17
|
+
# reading responses.
|
18
|
+
#
|
19
|
+
# @param uri [String] the channel URI
|
20
|
+
# @param listener_uri [String] the URI for notification callbacks
|
21
|
+
# @return [String] the session id
|
22
|
+
# @raise [ArgumentError] if uri is nil/empty
|
23
|
+
def open_session(uri, listener_uri = nil)
|
24
|
+
validate_presence_of uri, 'Channel URI'
|
25
|
+
|
26
|
+
message = { 'ChannelURI' => uri }
|
27
|
+
message['ListenerURI'] = listener_uri if listener_uri
|
28
|
+
|
29
|
+
response = @client.call(:open_consumer_request_session, message: message)
|
30
|
+
|
31
|
+
response.to_hash[:open_consumer_request_session_response][:session_id].to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
# Posts a request message on a channel.
|
35
|
+
#
|
36
|
+
# @param session_id [String] the session id
|
37
|
+
# @param content [String] a valid XML string as message contents
|
38
|
+
# @param topic [String] the topic
|
39
|
+
# @return [String] the request message id
|
40
|
+
# @raise [ArgumentError] if session_id, content or topics are nil/empty, or
|
41
|
+
# content is not valid XML
|
42
|
+
def post_request(session_id, content, topic)
|
43
|
+
validate_presence_of session_id, 'Session Id'
|
44
|
+
validate_presence_of content, 'Content'
|
45
|
+
validate_presence_of topic, 'Topic'
|
46
|
+
validate_xml content
|
47
|
+
|
48
|
+
# Use Builder to generate XML body as we need to concatenate XML message content
|
49
|
+
xml = Builder::XmlMarkup.new
|
50
|
+
xml.isbm :SessionID, session_id
|
51
|
+
xml.isbm :MessageContent do
|
52
|
+
xml << content
|
53
|
+
end
|
54
|
+
xml.isbm :Topic, topic
|
55
|
+
|
56
|
+
response = @client.call(:post_request, message: xml.target!)
|
57
|
+
|
58
|
+
response.to_hash[:post_request_response][:message_id].to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the first response message, if any, in the message queue
|
62
|
+
# associated with the request.
|
63
|
+
#
|
64
|
+
# @param session_id [String] the session id
|
65
|
+
# @param request_message_id [String] the id of the original request message
|
66
|
+
# @return [Message] the first message in the queue for the session.
|
67
|
+
# nil if no message.
|
68
|
+
# @raise [ArgumentError] if session_id or request_message_id are nil/empty
|
69
|
+
def read_response(session_id, request_message_id)
|
70
|
+
validate_presence_of session_id, 'Session Id'
|
71
|
+
validate_presence_of request_message_id, 'Request Message Id'
|
72
|
+
|
73
|
+
message = { 'SessionID' => session_id, 'RequestMessageID' => request_message_id }
|
74
|
+
response = @client.call(:read_response, message: message)
|
75
|
+
|
76
|
+
extract_message(response)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Deletes the first response message, if any, in the message queue
|
80
|
+
# associated with the request.
|
81
|
+
#
|
82
|
+
# @param session_id [String] the session id
|
83
|
+
# @param request_message_id [String] the id of the original request message
|
84
|
+
# @return [void]
|
85
|
+
# @raise [ArgumentError] if session_id is nil/empty
|
86
|
+
def remove_response(session_id, request_message_id)
|
87
|
+
validate_presence_of session_id, 'Session Id'
|
88
|
+
validate_presence_of request_message_id, 'Request Message Id'
|
89
|
+
|
90
|
+
message = { 'SessionID' => session_id, 'RequestMessageID' => request_message_id }
|
91
|
+
@client.call(:remove_response, message: message)
|
92
|
+
|
93
|
+
return true
|
94
|
+
end
|
95
|
+
|
96
|
+
# Closes a consumer request session.
|
97
|
+
#
|
98
|
+
# @param session_id [String] the session id
|
99
|
+
# @return [void]
|
100
|
+
# @raise [ArgumentError] if session_id is nil/empty
|
101
|
+
def close_session(session_id)
|
102
|
+
validate_presence_of session_id, 'Session Id'
|
103
|
+
|
104
|
+
@client.call(:close_consumer_request_session, message: { 'SessionID' => session_id })
|
105
|
+
|
106
|
+
return true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -1,6 +1,22 @@
|
|
1
1
|
module IsbmAdaptor
|
2
2
|
class Duration
|
3
|
-
|
3
|
+
# @return [Numeric] the years component of the duration
|
4
|
+
attr_accessor :years
|
5
|
+
|
6
|
+
# @return [Numeric] the months component of the duration
|
7
|
+
attr_accessor :months
|
8
|
+
|
9
|
+
# @return [Numeric] the days component of the duration
|
10
|
+
attr_accessor :days
|
11
|
+
|
12
|
+
# @return [Numeric] the hours component of the duration
|
13
|
+
attr_accessor :hours
|
14
|
+
|
15
|
+
# @return [Numeric] the minutes component of the duration
|
16
|
+
attr_accessor :minutes
|
17
|
+
|
18
|
+
# @return [Numeric] the seconds component of the duration
|
19
|
+
attr_accessor :seconds
|
4
20
|
|
5
21
|
# Creates a new Duration based on specified time components.
|
6
22
|
#
|
@@ -50,15 +66,18 @@ module IsbmAdaptor
|
|
50
66
|
result
|
51
67
|
end
|
52
68
|
|
69
|
+
# Creates a hash of the time components. Any keys with nil values are
|
70
|
+
# excluded from the result.
|
71
|
+
#
|
53
72
|
# @return [Hash] all specified time components
|
54
73
|
def to_hash
|
55
74
|
hash = {}
|
56
|
-
hash
|
57
|
-
hash
|
58
|
-
hash
|
59
|
-
hash
|
60
|
-
hash
|
61
|
-
hash
|
75
|
+
hash[:years] = @years if @years
|
76
|
+
hash[:months] = @months if @months
|
77
|
+
hash[:days] = @days if @days
|
78
|
+
hash[:hours] = @hours if @hours
|
79
|
+
hash[:minutes] = @minutes if @minutes
|
80
|
+
hash[:seconds] = @seconds if @seconds
|
62
81
|
hash
|
63
82
|
end
|
64
83
|
|
data/lib/isbm_adaptor/message.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
1
|
module IsbmAdaptor
|
2
2
|
class Message
|
3
|
-
|
3
|
+
# @return [String] the id of the message
|
4
|
+
attr_accessor :id
|
5
|
+
|
6
|
+
# @return [String] the XML content of the message
|
7
|
+
attr_accessor :content
|
8
|
+
|
9
|
+
# @return [Array<String>] topics associated with the message
|
10
|
+
attr_accessor :topics
|
4
11
|
|
5
12
|
# Creates a new ISBM Message container.
|
6
13
|
#
|
7
14
|
# @param id [String] message id
|
8
15
|
# @param content [String] XML content
|
9
|
-
# @param topics [Array<String
|
16
|
+
# @param topics [Array<String>, String] collection of topics or single topic
|
10
17
|
def initialize(id, content, topics)
|
11
|
-
@id = id
|
18
|
+
@id = id
|
12
19
|
@content = content
|
13
|
-
|
14
|
-
@topics.each { |t| t.to_s }
|
15
|
-
else
|
16
|
-
@topics = [topics.to_s]
|
17
|
-
end
|
20
|
+
@topics = [topics].flatten
|
18
21
|
end
|
19
22
|
end
|
20
|
-
end
|
23
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
|
-
require 'isbm_adaptor/
|
1
|
+
require 'isbm_adaptor/client'
|
2
2
|
require 'isbm_adaptor/duration'
|
3
3
|
|
4
4
|
module IsbmAdaptor
|
5
|
-
class ProviderPublication
|
6
|
-
include IsbmAdaptor::Service
|
5
|
+
class ProviderPublication < IsbmAdaptor::Client
|
7
6
|
|
8
7
|
# Creates a new ISBM ProviderPublication client.
|
9
8
|
#
|
@@ -12,15 +11,12 @@ module IsbmAdaptor
|
|
12
11
|
# @option options [Boolean] :log (true) specify whether requests are logged
|
13
12
|
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
|
14
13
|
def initialize(endpoint, options = {})
|
15
|
-
|
16
|
-
options[:endpoint] = endpoint
|
17
|
-
default_savon_options(options)
|
18
|
-
@client = Savon.client(options)
|
14
|
+
super('ISBMProviderPublicationService.wsdl', endpoint, options)
|
19
15
|
end
|
20
16
|
|
21
17
|
# Opens a publication session for a channel.
|
22
18
|
#
|
23
|
-
# @param [String]
|
19
|
+
# @param uri [String] the channel URI
|
24
20
|
# @return [String] the session id
|
25
21
|
# @raise [ArgumentError] if uri is nil/empty
|
26
22
|
def open_session(uri)
|
@@ -33,18 +29,20 @@ module IsbmAdaptor
|
|
33
29
|
|
34
30
|
# Posts a publication message.
|
35
31
|
#
|
32
|
+
# @param session_id [String] the session id
|
36
33
|
# @param content [String] a valid XML string as message contents
|
37
34
|
# @param topics [Array<String>, String] a collection of topics or single topic
|
38
35
|
# @param expiry [Duration] when the message should expire
|
39
36
|
# @return [String] the message id
|
40
|
-
# @raise [ArgumentError] if session_id, content
|
37
|
+
# @raise [ArgumentError] if session_id, content or topics are nil/empty, or
|
38
|
+
# content is not valid XML
|
41
39
|
def post_publication(session_id, content, topics, expiry = nil)
|
42
40
|
validate_presence_of session_id, 'Session Id'
|
43
41
|
validate_presence_of content, 'Content'
|
44
42
|
validate_presence_of topics, 'Topics'
|
45
43
|
validate_xml content
|
46
44
|
|
47
|
-
topics = [topics]
|
45
|
+
topics = [topics].flatten
|
48
46
|
|
49
47
|
# Use Builder to generate XML body as we need to concatenate XML message content
|
50
48
|
xml = Builder::XmlMarkup.new
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'isbm_adaptor/client'
|
2
|
+
|
3
|
+
module IsbmAdaptor
|
4
|
+
class ProviderRequest < IsbmAdaptor::Client
|
5
|
+
|
6
|
+
# Creates a new ISBM ProviderRequest client.
|
7
|
+
#
|
8
|
+
# @param endpoint [String] the SOAP endpoint URI
|
9
|
+
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
|
10
|
+
# @option options [Boolean] :log (true) specify whether requests are logged
|
11
|
+
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
|
12
|
+
def initialize(endpoint, options = {})
|
13
|
+
super('ISBMProviderRequestService.wsdl', endpoint, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Opens a provider request session for a channel for reading requests and
|
17
|
+
# posting responses.
|
18
|
+
#
|
19
|
+
# @param uri [String] the channel URI
|
20
|
+
# @param topics [Array<String>] an array of topics
|
21
|
+
# @param listener_uri [String] the URI for notification callbacks
|
22
|
+
# @return [String] the session id
|
23
|
+
# @raise [ArgumentError] if uri or topics are nil/empty
|
24
|
+
def open_session(uri, topics, listener_uri = nil)
|
25
|
+
validate_presence_of uri, 'Channel URI'
|
26
|
+
validate_presence_of topics, 'Topics'
|
27
|
+
|
28
|
+
# Use Builder to generate XML body as we may have multiple Topic elements
|
29
|
+
xml = Builder::XmlMarkup.new
|
30
|
+
xml.isbm :ChannelURI, uri
|
31
|
+
topics.each do |topic|
|
32
|
+
xml.isbm :Topic, topic
|
33
|
+
end
|
34
|
+
xml.isbm :ListenerURI, listener_uri unless listener_uri.nil?
|
35
|
+
|
36
|
+
response = @client.call(:open_provider_request_session, message: xml.target!)
|
37
|
+
|
38
|
+
response.to_hash[:open_provider_request_session_response][:session_id].to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the first request message in the message queue for the session.
|
42
|
+
# Note: this service does not remove the message from the message queue.
|
43
|
+
#
|
44
|
+
# @param session_id [String] the session id
|
45
|
+
# @return [Message] the first message in the queue for the session.
|
46
|
+
# nil if no message.
|
47
|
+
# @raise [ArgumentError] if session_id is nil/empty
|
48
|
+
def read_request(session_id)
|
49
|
+
validate_presence_of session_id, 'Session Id'
|
50
|
+
|
51
|
+
message = { 'SessionID' => session_id }
|
52
|
+
response = @client.call(:read_request, message: message)
|
53
|
+
|
54
|
+
extract_message(response)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Deletes the first request message, if any, in the message queue for the session.
|
58
|
+
#
|
59
|
+
# @param session_id [String] the session id
|
60
|
+
# @return [void]
|
61
|
+
# @raise [ArgumentError] if session_id is nil/empty
|
62
|
+
def remove_request(session_id)
|
63
|
+
validate_presence_of session_id, 'Session Id'
|
64
|
+
|
65
|
+
@client.call(:remove_request, message: { 'SessionID' => session_id })
|
66
|
+
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
|
70
|
+
# Posts a response message on a channel.
|
71
|
+
#
|
72
|
+
# @param session_id [String] the session id
|
73
|
+
# @param request_message_id [String] the id of the original request message
|
74
|
+
# @param content [String] a valid XML string as message contents
|
75
|
+
# @return [String] the response message id
|
76
|
+
# @raise [ArgumentError] if session_id, request_message_id or content are
|
77
|
+
# nil/empty, or content is not valid XML
|
78
|
+
def post_response(session_id, request_message_id, content)
|
79
|
+
validate_presence_of session_id, 'Session Id'
|
80
|
+
validate_presence_of request_message_id, 'Request Message Id'
|
81
|
+
validate_presence_of content, 'Content'
|
82
|
+
validate_xml content
|
83
|
+
|
84
|
+
# Use Builder to generate XML body as we need to concatenate XML message content
|
85
|
+
xml = Builder::XmlMarkup.new
|
86
|
+
xml.isbm :SessionID, session_id
|
87
|
+
xml.isbm :RequestMessageID, request_message_id
|
88
|
+
xml.isbm :MessageContent do
|
89
|
+
xml << content
|
90
|
+
end
|
91
|
+
|
92
|
+
response = @client.call(:post_response, message: xml.target!)
|
93
|
+
|
94
|
+
response.to_hash[:post_response_response][:message_id].to_s
|
95
|
+
end
|
96
|
+
|
97
|
+
# Closes a provider request session.
|
98
|
+
#
|
99
|
+
# @param session_id [String] the session id
|
100
|
+
# @return [void]
|
101
|
+
# @raise [ArgumentError] if session_id is nil/empty
|
102
|
+
def close_session(session_id)
|
103
|
+
validate_presence_of session_id, 'Session Id'
|
104
|
+
|
105
|
+
@client.call(:close_provider_request_session, message: { 'SessionID' => session_id })
|
106
|
+
|
107
|
+
return true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/lib/isbm_adaptor/version.rb
CHANGED
data/lib/isbm_adaptor.rb
CHANGED
@@ -6,5 +6,7 @@ module IsbmAdaptor
|
|
6
6
|
autoload :ChannelManagement, 'isbm_adaptor/channel_management'
|
7
7
|
autoload :ProviderPublication, 'isbm_adaptor/provider_publication'
|
8
8
|
autoload :ConsumerPublication, 'isbm_adaptor/consumer_publication'
|
9
|
+
autoload :ProviderRequest, 'isbm_adaptor/provider_request'
|
10
|
+
autoload :ConsumerRequest, 'isbm_adaptor/consumer_request'
|
9
11
|
autoload :Duration, 'isbm_adaptor/duration'
|
10
12
|
end
|