isbm_adaptor 1.0.rc8.6 → 1.0.rc8.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7ec831745863947e859edd665925317d42dbf1b7
4
+ data.tar.gz: 686b8452491a4b96b490af5f271283e11031f397
5
+ SHA512:
6
+ metadata.gz: 7a204979a05e7f25d2567de9c38807969900544c2fd9b8f37e9be7acdd57f91ae137f56a3bef269281b4a7a169adbfd57c5446add2c282ea94f9cbac8bd1c7f1
7
+ data.tar.gz: 3b9290ce1d6100f169fa6ff9b9dfd5060444063fabc6833f8ab8435dea7c547c43031506e391555a13a137b47d5bb6aab95384580aa2d8d1e7b112ed6aa815be
data/LICENSE CHANGED
@@ -1,9 +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.
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,59 +1,133 @@
1
- # ISBM Adaptor
2
-
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:
30
-
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
58
-
59
- ISBM Adaptor is released under the MIT License. See [LICENSE](https://github.com/assetricity/isbm_adaptor/blob/master/LICENSE) for details.
1
+ # ISBM Adaptor
2
+
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
+ [![Code Climate](https://codeclimate.com/github/assetricity/isbm_adaptor.png)](https://codeclimate.com/github/assetricity/isbm_adaptor)
6
+ [![Dependency Status](https://gemnasium.com/assetricity/isbm_adaptor.png)](https://gemnasium.com/assetricity/isbm_adaptor)
7
+
8
+ The ISBM Adaptor provides a Ruby API for the [OpenO&M ISBM specification](http://www.mimosa.org/?q=about/what-open-om).
9
+
10
+ It is based on the [Savon](http://savonrb.com) SOAP client and provides convenience methods for interaction with an ISBM Service Provider.
11
+
12
+ ## Install
13
+
14
+ ### Bundler
15
+
16
+ Add to the isbm_adaptor gem to your Gemfile:
17
+
18
+ ```ruby
19
+ gem 'isbm_adaptor'
20
+ ```
21
+
22
+ 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:
23
+
24
+ ```ruby
25
+ gem 'isbm_adaptor', '~> 1.0.0.0'
26
+ ```
27
+
28
+ ### Other
29
+
30
+ The gem can also be installed via the gem install command:
31
+
32
+ ```bash
33
+ gem install isbm_adaptor
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ Create a client object by specifying an endpoint. For example:
39
+
40
+ ```ruby
41
+ client = IsbmAdaptor::ChannelManagement.new('http://example.com/ChannelManagement')
42
+ ```
43
+
44
+ The standard [Savon options](http://savonrb.com/version2/globals.html) can also be passed to the client upon creation. For example:
45
+
46
+ ```ruby
47
+ client = IsbmAdaptor::ChannelManagement.new('http://example.com/ChannelManagement', log: true)
48
+ ```
49
+
50
+ Use the client methods to directly send SOAP messages to the server. For example:
51
+
52
+ ```ruby
53
+ client.get_channels
54
+ ```
55
+
56
+ ### Publish/Subscribe Example
57
+
58
+ The following shows an example of creating a publication channel, subscribing to the channel and posting a message on the channel.
59
+
60
+ ```ruby
61
+ require 'isbm_adaptor'
62
+
63
+ channel_management_endpoint = 'http://example.com/ChannelManagement'
64
+ consumer_publication_endpoint = 'http://example.com/ConsumerPublication'
65
+ provider_publication_endpoint = 'http://example.com/ProviderPublication'
66
+
67
+ uri = 'unique/publication/uri'
68
+ topic = 'unique/topic'
69
+ message_content = '<message/>'
70
+
71
+ channel_client = IsbmAdaptor::ChannelManagement.new(channel_management_endpoint)
72
+ channel_client.create_channel(uri, :publication)
73
+
74
+ subscribe_client = IsbmAdaptor::ConsumerPublication.new(consumer_publication_endpoint)
75
+ subscribe_session_id = subscribe_client.open_session(uri, [topic])
76
+
77
+ publish_client = IsbmAdaptor::ProviderPublication.new(provider_publication_endpoint)
78
+ publish_session_id = publish_client.open_session(uri)
79
+ publish_client.post_publication(publish_session_id, message_content, topic)
80
+
81
+ message = subscribe_client.read_publication(subscribe_session_id)
82
+ puts message.content.to_s
83
+
84
+ publish_client.close_session(publish_session_id)
85
+ subscribe_client.close_session(subscribe_session_id)
86
+ channel_client.delete_channel(uri)
87
+ ```
88
+
89
+ ### Request/Response Example
90
+
91
+ The following shows an example of creating a request channel, sending a request and then sending a response.
92
+
93
+ ```ruby
94
+ require 'isbm_adaptor'
95
+
96
+ channel_management_endpoint = 'http://example.com/ChannelManagement'
97
+ provider_request_endpoint = 'http://example.com/ProviderRequest'
98
+ consumer_request_endpoint = 'http://example.com/ConsumerRequest'
99
+
100
+ uri = 'unique/request/uri'
101
+ topic = 'unique/topic'
102
+ request_content = '<request/>'
103
+ response_content = '<response/>'
104
+
105
+ channel_client = IsbmAdaptor::ChannelManagement.new(channel_management_endpoint)
106
+ channel_client.create_channel(uri, :request)
107
+
108
+ response_client = IsbmAdaptor::ProviderRequest.new(provider_request_endpoint)
109
+ response_session_id = response_client.open_session(uri, [topic])
110
+
111
+ request_client = IsbmAdaptor::ConsumerRequest.new(consumer_request_endpoint)
112
+ request_session_id = request_client.open_session(uri)
113
+ request_message_id = request_client.post_request(request_session_id, request_content, topic)
114
+
115
+ request_message = response_client.read_request(response_session_id)
116
+ puts request_message.content.to_s
117
+ response_client.remove_request(response_session_id)
118
+ response_client.post_response(response_session_id, request_message.id, response_content)
119
+
120
+ response_message = request_client.read_response(request_session_id, request_message_id)
121
+ puts response_message.content.to_s
122
+ request_client.remove_response(request_session_id, request_message_id)
123
+
124
+ request_client.close_session(request_session_id)
125
+ response_client.close_session(response_session_id)
126
+ channel_client.delete_channel(uri)
127
+ ```
128
+
129
+ ## License
130
+
131
+ Copyright 2013 [Assetricity, LLC](http://assetricity.com)
132
+
133
+ ISBM Adaptor is released under the MIT License. See [LICENSE](https://github.com/assetricity/isbm_adaptor/blob/master/LICENSE) for details.
@@ -1,37 +1,38 @@
1
- module IsbmAdaptor
2
- class Channel
3
- TYPES = ['Publication', 'Request']
4
-
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
13
-
14
- # Creates a new Channel.
15
- #
16
- # @param uri [String] the channel URI
17
- # @param type [String] the channel type, either 'Publication' or 'Request'
18
- # @param description [String] the channel description
19
- def initialize(uri, type, description)
20
- @uri = uri.to_s
21
- @type = type
22
- @description = description.to_s unless description.nil?
23
- end
24
-
25
- # Creates a new Channel based on a hash.
26
- #
27
- # @options hash [String] :channel_uri the channel URI
28
- # @options hash [String] :channel_type the channel type, either 'Publication' or 'Request'
29
- # @options hash [String] :channel_description the channel description
30
- def self.from_hash(hash)
31
- uri = hash[:channel_uri]
32
- type = hash[:channel_type]
33
- description = hash[:channel_description]
34
- new(uri, type, description)
35
- end
36
- end
37
- end
1
+ module IsbmAdaptor
2
+ class Channel
3
+ # Channel types permitted by the ISBM specification
4
+ TYPES = ['Publication', 'Request']
5
+
6
+ # @return [String] the channel URI
7
+ attr_accessor :uri
8
+
9
+ # @return [String] the channel type, either 'Publication' or 'Request'
10
+ attr_accessor :type
11
+
12
+ # @return [String] the channel description
13
+ attr_accessor :description
14
+
15
+ # Creates a new Channel.
16
+ #
17
+ # @param uri [String] the channel URI
18
+ # @param type [String] the channel type, either 'Publication' or 'Request'
19
+ # @param description [String] the channel description
20
+ def initialize(uri, type, description)
21
+ @uri = uri.to_s
22
+ @type = type
23
+ @description = description.to_s unless description.nil?
24
+ end
25
+
26
+ # Creates a new Channel based on a hash.
27
+ #
28
+ # @option hash [String] :channel_uri the channel URI
29
+ # @option hash [String] :channel_type the channel type, either 'Publication' or 'Request'
30
+ # @option hash [String] :channel_description the channel description
31
+ def self.from_hash(hash)
32
+ uri = hash[:channel_uri]
33
+ type = hash[:channel_type]
34
+ description = hash[:channel_description]
35
+ new(uri, type, description)
36
+ end
37
+ end
38
+ end
@@ -1,78 +1,78 @@
1
- require 'isbm_adaptor/client'
2
- require 'isbm_adaptor/channel'
3
-
4
- module IsbmAdaptor
5
- class ChannelManagement < IsbmAdaptor::Client
6
- # Creates a new ISBM ChannelManagement 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('ISBMChannelManagementService.wsdl', endpoint, options)
14
- end
15
-
16
- # Creates a new channel.
17
- #
18
- # @param uri [String] the channel URI
19
- # @param type [Symbol] the channel type, either publication or request (symbol or titleized string)
20
- # @param description [String] the channel description, defaults to nil
21
- # @return [void]
22
- # @raise [ArgumentError] if uri or type are nil/empty or type is not a valid Symbol
23
- def create_channel(uri, type, description = nil)
24
- validate_presence_of uri, 'Channel URI'
25
- validate_presence_of type, 'Channel Type'
26
- channel_type = type.to_s.downcase.capitalize
27
- raise ArgumentError, "#{channel_type} is not a valid type. Must be either Publication or Request." unless IsbmAdaptor::Channel::TYPES.include?(channel_type)
28
-
29
- message = { 'ChannelURI' => uri,
30
- 'ChannelType' => channel_type }
31
- message['ChannelDescription'] = description unless description.nil?
32
-
33
- @client.call(:create_channel, message: message)
34
-
35
- return true
36
- end
37
-
38
- # Deletes the specified channel.
39
- #
40
- # @param uri [String] the channel URI
41
- # @return [void]
42
- # @raise [ArgumentError] if uri is nil/empty
43
- def delete_channel(uri)
44
- validate_presence_of uri, 'Channel URI'
45
-
46
- @client.call(:delete_channel, message: { 'ChannelURI' => uri })
47
-
48
- return true
49
- end
50
-
51
- # Gets information about the specified channel
52
- #
53
- # @param uri [String] the channel URI
54
- # @return [Channel] the queried channel
55
- # @raise [ArgumentError] if uri is nil/empty
56
- def get_channel(uri)
57
- validate_presence_of uri, 'Channel URI'
58
-
59
- response = @client.call(:get_channel, message: { 'ChannelURI' => uri })
60
-
61
- hash = response.to_hash[:get_channel_response][:channel]
62
- IsbmAdaptor::Channel.from_hash(hash)
63
- end
64
-
65
- # Gets information about all channels
66
- #
67
- # @return [Array<Channel>] all channels on the ISBM
68
- def get_channels
69
- response = @client.call(:get_channels)
70
-
71
- channels = response.to_hash[:get_channels_response][:channel]
72
- channels = [channels].compact unless channels.is_a?(Array)
73
- channels.map do |hash|
74
- IsbmAdaptor::Channel.from_hash(hash)
75
- end
76
- end
77
- end
78
- end
1
+ require 'isbm_adaptor/client'
2
+ require 'isbm_adaptor/channel'
3
+
4
+ module IsbmAdaptor
5
+ class ChannelManagement < IsbmAdaptor::Client
6
+ # Creates a new ISBM ChannelManagement 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('ISBMChannelManagementService.wsdl', endpoint, options)
14
+ end
15
+
16
+ # Creates a new channel.
17
+ #
18
+ # @param uri [String] the channel URI
19
+ # @param type [Symbol] the channel type, either publication or request (symbol or titleized string)
20
+ # @param description [String] the channel description, defaults to nil
21
+ # @return [void]
22
+ # @raise [ArgumentError] if uri or type are blank or type is not a valid Symbol
23
+ def create_channel(uri, type, description = nil)
24
+ validate_presence_of uri, 'Channel URI'
25
+ validate_presence_of type, 'Channel Type'
26
+ channel_type = type.to_s.downcase.capitalize
27
+ raise ArgumentError, "#{channel_type} is not a valid type. Must be either Publication or Request." unless IsbmAdaptor::Channel::TYPES.include?(channel_type)
28
+
29
+ message = { 'ChannelURI' => uri,
30
+ 'ChannelType' => channel_type }
31
+ message['ChannelDescription'] = description unless description.nil?
32
+
33
+ @client.call(:create_channel, message: message)
34
+
35
+ return true
36
+ end
37
+
38
+ # Deletes the specified channel.
39
+ #
40
+ # @param uri [String] the channel URI
41
+ # @return [void]
42
+ # @raise [ArgumentError] if uri is blank
43
+ def delete_channel(uri)
44
+ validate_presence_of uri, 'Channel URI'
45
+
46
+ @client.call(:delete_channel, message: { 'ChannelURI' => uri })
47
+
48
+ return true
49
+ end
50
+
51
+ # Gets information about the specified channel
52
+ #
53
+ # @param uri [String] the channel URI
54
+ # @return [Channel] the queried channel
55
+ # @raise [ArgumentError] if uri is blank
56
+ def get_channel(uri)
57
+ validate_presence_of uri, 'Channel URI'
58
+
59
+ response = @client.call(:get_channel, message: { 'ChannelURI' => uri })
60
+
61
+ hash = response.to_hash[:get_channel_response][:channel]
62
+ IsbmAdaptor::Channel.from_hash(hash)
63
+ end
64
+
65
+ # Gets information about all channels
66
+ #
67
+ # @return [Array<Channel>] all channels on the ISBM
68
+ def get_channels
69
+ response = @client.call(:get_channels)
70
+
71
+ channels = response.to_hash[:get_channels_response][:channel]
72
+ channels = [channels].compact unless channels.is_a?(Array)
73
+ channels.map do |hash|
74
+ IsbmAdaptor::Channel.from_hash(hash)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,86 +1,93 @@
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
+ 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
+ # @raise [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
57
+ # and/or children. This is because content.to_xml does not output ancestor
58
+ # namespaces.
59
+ # There may be unnecessary namespaces carried across (e.g. ISBM, SOAP), but we
60
+ # can't tell if the content uses them without parsing the content itself.
61
+ content.namespaces.each do |key, value|
62
+ prefix = key.gsub(/xmlns:?/, '')
63
+ prefix = nil if prefix.empty?
64
+ content.add_namespace_definition(prefix, value)
65
+ end
66
+
67
+ # Wrap content in a separate Nokogiri document. This allows the ability to
68
+ # validate the content against a schema.
69
+ doc = Nokogiri::XML(content.to_xml)
70
+
71
+ IsbmAdaptor::Message.new(id, doc, topics)
72
+ end
73
+
74
+ private
75
+
76
+ # Indicates the directory of the ISBM WSDL files
77
+ #
78
+ # @return [String] directory of ISBM WSDL files
79
+ def wsdl_dir
80
+ File.expand_path(File.dirname(__FILE__)) + '/../../wsdls/'
81
+ end
82
+
83
+ # Sets default values for certain Savon options.
84
+ #
85
+ # @param options [Hash] the options to set defaults on
86
+ # @return [Hash] options hash with defaults set
87
+ def default_savon_options(options)
88
+ options[:logger] = Rails.logger if options[:logger].nil? && defined?(Rails)
89
+ options[:log] = false if options[:log].nil?
90
+ options[:pretty_print_xml] = true if options[:pretty_print_xml].nil?
91
+ end
92
+ end
93
+ end