cherby 0.0.2 → 0.0.3
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.
- data/cherby.gemspec +1 -2
- data/lib/cherby/business_object.rb +46 -10
- data/lib/cherby/cherwell.rb +35 -8
- data/lib/cherby/exceptions.rb +10 -1
- data/lib/cherby/incident.rb +1 -0
- data/spec/business_object_spec.rb +68 -2
- data/spec/cherwell_spec.rb +30 -9
- data/spec/data/empty.xml +1 -0
- data/spec/spec_helper.rb +15 -12
- metadata +3 -20
- data/spec/xml/method_response_result.mustache +0 -4
- data/spec/xml/soap_envelope.mustache +0 -6
data/cherby.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "cherby"
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.3"
|
4
4
|
s.summary = "Cherwell-Ruby bridge"
|
5
5
|
s.description = <<-EOS
|
6
6
|
Cherby is a Ruby wrapper for the Cherwell Web Service.
|
@@ -14,7 +14,6 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.add_dependency 'savon', '>= 2.3.0'
|
15
15
|
s.add_dependency 'yajl-ruby'
|
16
16
|
s.add_dependency 'nokogiri'
|
17
|
-
s.add_dependency 'mustache'
|
18
17
|
|
19
18
|
s.add_development_dependency "rake"
|
20
19
|
s.add_development_dependency "simplecov"
|
@@ -34,9 +34,27 @@ module Cherby
|
|
34
34
|
|
35
35
|
attr_reader :dom
|
36
36
|
|
37
|
-
# Create a new instance
|
37
|
+
# Create a new BusinessObject instance from the given XML string.
|
38
38
|
def initialize(xml)
|
39
39
|
@dom = Nokogiri::XML(xml)
|
40
|
+
check_dom_format!
|
41
|
+
end
|
42
|
+
|
43
|
+
# Ensure the @dom is in the expected format for BusinessObjects.
|
44
|
+
#
|
45
|
+
# @raise [Cherby::BadFormat]
|
46
|
+
# If the DOM's structure is incorrect
|
47
|
+
#
|
48
|
+
def check_dom_format!
|
49
|
+
# Ensure XML is in expected format for BusinessObjects
|
50
|
+
if @dom.css('BusinessObject').empty?
|
51
|
+
raise Cherby::BadFormat.new(
|
52
|
+
"BusinessObject XML is missing 'BusinessObject' element")
|
53
|
+
elsif @dom.css('BusinessObject > FieldList').empty?
|
54
|
+
raise Cherby::BadFormat.new(
|
55
|
+
"BusinessObject XML is missing 'BusinessObject > FieldList' element")
|
56
|
+
end
|
57
|
+
return true
|
40
58
|
end
|
41
59
|
|
42
60
|
# Return the XML representation of this BusinessObject
|
@@ -45,9 +63,30 @@ module Cherby
|
|
45
63
|
end
|
46
64
|
|
47
65
|
# Return the node of the field with the given name.
|
66
|
+
#
|
67
|
+
# @param [String] field_name
|
68
|
+
# The `Name` attribute of the `Field` element to get.
|
69
|
+
#
|
70
|
+
# @return [Nokogiri::XML::Node, nil]
|
71
|
+
# The node for the `Field` element, or `nil` if no Field
|
72
|
+
# with the given `Name` exists.
|
73
|
+
#
|
48
74
|
def get_field_node(field_name)
|
75
|
+
check_dom_format!
|
49
76
|
selector = "BusinessObject > FieldList > Field[@Name=#{field_name}]"
|
50
|
-
|
77
|
+
return @dom.css(selector).first
|
78
|
+
end
|
79
|
+
|
80
|
+
# Get a `Field` node with the given name, or create one if it doesn't exist.
|
81
|
+
#
|
82
|
+
# @param [String] field_name
|
83
|
+
# The `Name` attribute of the `Field` element to get or create.
|
84
|
+
#
|
85
|
+
# @return [Nokogiri::XML::Node]
|
86
|
+
# The node for the existing or new `Field` element.
|
87
|
+
#
|
88
|
+
def get_or_create_field_node(field_name)
|
89
|
+
element = get_field_node(field_name)
|
51
90
|
if element.nil?
|
52
91
|
element = Nokogiri::XML::Node.new('Field', @dom)
|
53
92
|
element['Name'] = field_name
|
@@ -126,19 +165,16 @@ module Cherby
|
|
126
165
|
end
|
127
166
|
|
128
167
|
# Return the content in the field with the given name.
|
129
|
-
# TODO: Exception for unknown field name
|
130
168
|
def [](field_name)
|
131
|
-
|
132
|
-
|
133
|
-
|
169
|
+
field = get_field_node(field_name)
|
170
|
+
return field.content if field
|
171
|
+
return nil
|
134
172
|
end
|
135
173
|
|
136
174
|
# Modify the content in the field with the given name.
|
137
|
-
# TODO: Exception for unknown field name
|
138
175
|
def []=(field_name, value)
|
139
|
-
|
140
|
-
|
141
|
-
end
|
176
|
+
field = get_or_create_field_node(field_name)
|
177
|
+
field.content = value.to_s
|
142
178
|
end
|
143
179
|
|
144
180
|
# Copy designated fields from one BusinessObject to another.
|
data/lib/cherby/cherwell.rb
CHANGED
@@ -41,7 +41,7 @@ module Cherby
|
|
41
41
|
# @return [Boolean]
|
42
42
|
# `true` if login was successful
|
43
43
|
#
|
44
|
-
# @raise [LoginFailed]
|
44
|
+
# @raise [Cherby::LoginFailed]
|
45
45
|
# If login failed for any reason
|
46
46
|
#
|
47
47
|
def login(username=nil, password=nil)
|
@@ -53,7 +53,7 @@ module Cherby
|
|
53
53
|
response = @client.call(:login, :message => creds)
|
54
54
|
rescue => e
|
55
55
|
# This can happen if a bad URL is given
|
56
|
-
raise LoginFailed, e.message
|
56
|
+
raise Cherby::LoginFailed, e.message
|
57
57
|
else
|
58
58
|
if response.body[:login_response][:login_result] == true
|
59
59
|
# FIXME: Using the workaround described in this issue:
|
@@ -66,7 +66,7 @@ module Cherby
|
|
66
66
|
return true
|
67
67
|
# This can happen if invalid credentials are given
|
68
68
|
else
|
69
|
-
raise LoginFailed, "Cherwell returned false status"
|
69
|
+
raise Cherby::LoginFailed, "Cherwell returned false status"
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -85,9 +85,18 @@ module Cherby
|
|
85
85
|
#
|
86
86
|
# @return [Incident]
|
87
87
|
#
|
88
|
+
# @raise [Cherby::NotFound]
|
89
|
+
# If an error occurs when fetching the incident.
|
90
|
+
# The `message` attribute includes the error from Cherwell.
|
91
|
+
#
|
88
92
|
def incident(id)
|
89
93
|
incident_xml = get_object_xml('Incident', id)
|
90
|
-
|
94
|
+
error = self.last_error
|
95
|
+
if error
|
96
|
+
raise Cherby::NotFound.new("Cannot find Incident '#{id}': #{error}")
|
97
|
+
else
|
98
|
+
return Incident.new(incident_xml.to_s)
|
99
|
+
end
|
91
100
|
end
|
92
101
|
|
93
102
|
# Get the Cherwell task with the given public ID, and return a Task
|
@@ -95,9 +104,18 @@ module Cherby
|
|
95
104
|
#
|
96
105
|
# @return [Task]
|
97
106
|
#
|
107
|
+
# @raise [Cherby::NotFound]
|
108
|
+
# If an error occurs when fetching the task.
|
109
|
+
# The `message` attribute includes the error from Cherwell.
|
110
|
+
#
|
98
111
|
def task(id)
|
99
112
|
task_xml = get_object_xml('Task', id)
|
100
|
-
|
113
|
+
error = self.last_error
|
114
|
+
if error
|
115
|
+
raise Cherby::NotFound.new("Cannot find Task '#{id}': #{error}")
|
116
|
+
else
|
117
|
+
return Task.new(task_xml.to_s)
|
118
|
+
end
|
101
119
|
end
|
102
120
|
|
103
121
|
# Get a business object based on its public ID or RecID, and return the
|
@@ -127,6 +145,9 @@ module Cherby
|
|
127
145
|
# @return [String]
|
128
146
|
# Raw XML response string.
|
129
147
|
#
|
148
|
+
# @raise [Cherby::SoapError]
|
149
|
+
# If a Savon::SOAPFault occurs when making the request.
|
150
|
+
#
|
130
151
|
def get_object_xml(object_type, id)
|
131
152
|
# Assemble the SOAP body
|
132
153
|
body = {:busObNameOrId => object_type}
|
@@ -143,13 +164,19 @@ module Cherby
|
|
143
164
|
|
144
165
|
begin
|
145
166
|
result = @client.call_wrap(method, body)
|
146
|
-
rescue Savon::
|
147
|
-
raise SoapError
|
167
|
+
rescue Savon::SOAPFault => e
|
168
|
+
raise Cherby::SoapError.new(
|
169
|
+
"SOAPFault from method '#{method}'", e.http)
|
148
170
|
else
|
149
|
-
return result
|
171
|
+
return result.to_s
|
150
172
|
end
|
151
173
|
end
|
152
174
|
|
175
|
+
# Get a BusinessObject instance
|
176
|
+
def get_business_object(object_type, id)
|
177
|
+
xml = self.get_object_xml(object_type, id)
|
178
|
+
return BusinessObject.new(xml)
|
179
|
+
end
|
153
180
|
|
154
181
|
# Update a given Cherwell object by submitting its XML to the SOAP
|
155
182
|
# interface.
|
data/lib/cherby/exceptions.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
module Cherby
|
2
2
|
class CherbyError < RuntimeError; end
|
3
3
|
class LoginFailed < CherbyError; end
|
4
|
-
class
|
4
|
+
class NotFound < CherbyError; end
|
5
|
+
class BadFormat < CherbyError; end
|
6
|
+
|
7
|
+
class SoapError < CherbyError
|
8
|
+
attr_reader :http
|
9
|
+
def initialize(message, http=nil)
|
10
|
+
super(message)
|
11
|
+
@http = http
|
12
|
+
end
|
13
|
+
end
|
5
14
|
end # module Cherby
|
6
15
|
|
data/lib/cherby/incident.rb
CHANGED
@@ -75,14 +75,44 @@ describe Cherby::BusinessObject do
|
|
75
75
|
last_name.content.should == "Idle"
|
76
76
|
end
|
77
77
|
|
78
|
+
it "raises BadFormat if XML is missing FieldList" do
|
79
|
+
xml = %Q{
|
80
|
+
<BusinessObject Name="MySubclass">
|
81
|
+
<Whatever/>
|
82
|
+
</BusinessObject>
|
83
|
+
}
|
84
|
+
lambda do
|
85
|
+
@obj = MySubclass.new(xml)
|
86
|
+
end.should raise_error(
|
87
|
+
Cherby::BadFormat, /missing 'BusinessObject > FieldList'/)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "raises BadFormat if XML is missing BusinessObject" do
|
91
|
+
xml = %Q{
|
92
|
+
<Whatever Name="MySubclass"/>
|
93
|
+
}
|
94
|
+
lambda do
|
95
|
+
@obj = MySubclass.new(xml)
|
96
|
+
end.should raise_error(
|
97
|
+
Cherby::BadFormat, /missing 'BusinessObject'/)
|
98
|
+
end
|
78
99
|
end #initialize
|
79
100
|
|
101
|
+
describe "#check_dom_format!" do
|
102
|
+
it "TODO"
|
103
|
+
end #check_dom_format!
|
104
|
+
|
80
105
|
describe "#[]" do
|
81
106
|
it "returns the value in the named field" do
|
82
107
|
obj = MySubclass.create({'First' => 'Eric', 'Last' => 'Idle'})
|
83
108
|
obj['First'].should == 'Eric'
|
84
109
|
obj['Last'].should == 'Idle'
|
85
110
|
end
|
111
|
+
|
112
|
+
it "returns nil if the field doesn't exist" do
|
113
|
+
obj = MySubclass.create({'First' => 'Eric', 'Last' => 'Idle'})
|
114
|
+
obj['Middle'].should be_nil
|
115
|
+
end
|
86
116
|
end #[]
|
87
117
|
|
88
118
|
describe "#[]=" do
|
@@ -169,6 +199,11 @@ describe Cherby::BusinessObject do
|
|
169
199
|
@obj = MySubclass.new(xml)
|
170
200
|
end
|
171
201
|
|
202
|
+
it "checks the DOM format" do
|
203
|
+
@obj.should_receive(:check_dom_format!).and_return(true)
|
204
|
+
@obj.get_field_node('First')
|
205
|
+
end
|
206
|
+
|
172
207
|
it "returns the Field having the given Name" do
|
173
208
|
first_node = @obj.get_field_node('First')
|
174
209
|
first_node.should be_a(Nokogiri::XML::Node)
|
@@ -176,13 +211,44 @@ describe Cherby::BusinessObject do
|
|
176
211
|
first_node.inner_html.should == 'Eric'
|
177
212
|
end
|
178
213
|
|
179
|
-
it "
|
214
|
+
it "returns nil if the field doesn't exist" do
|
180
215
|
middle_node = @obj.get_field_node('Middle')
|
216
|
+
middle_node.should be_nil
|
217
|
+
end
|
218
|
+
end #get_field_node
|
219
|
+
|
220
|
+
describe "#get_or_create_field_node" do
|
221
|
+
before(:each) do
|
222
|
+
xml = %Q{
|
223
|
+
<BusinessObject Name="MySubclass">
|
224
|
+
<FieldList>
|
225
|
+
<Field Name="First">Eric</Field>
|
226
|
+
<Field Name="Last">Idle</Field>
|
227
|
+
</FieldList>
|
228
|
+
</BusinessObject>
|
229
|
+
}
|
230
|
+
@obj = MySubclass.new(xml)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "checks the DOM format" do
|
234
|
+
@obj.should_receive(:check_dom_format!).and_return(true)
|
235
|
+
@obj.get_or_create_field_node('First')
|
236
|
+
end
|
237
|
+
|
238
|
+
it "returns the Field having the given Name" do
|
239
|
+
first_node = @obj.get_or_create_field_node('First')
|
240
|
+
first_node.should be_a(Nokogiri::XML::Node)
|
241
|
+
first_node.attr('Name').should == 'First'
|
242
|
+
first_node.inner_html.should == 'Eric'
|
243
|
+
end
|
244
|
+
|
245
|
+
it "creates a new Field if it doesn't exist" do
|
246
|
+
middle_node = @obj.get_or_create_field_node('Middle')
|
181
247
|
middle_node.should be_a(Nokogiri::XML::Node)
|
182
248
|
middle_node.attr('Name').should == 'Middle'
|
183
249
|
middle_node.inner_html.should == ''
|
184
250
|
end
|
185
|
-
end #
|
251
|
+
end #get_or_create_field_node
|
186
252
|
|
187
253
|
describe "#field_values" do
|
188
254
|
before(:each) do
|
data/spec/cherwell_spec.rb
CHANGED
@@ -77,22 +77,52 @@ describe Cherby::Cherwell do
|
|
77
77
|
it "returns a Cherby::Incident instance" do
|
78
78
|
incident_id = '51949'
|
79
79
|
incident_xml = File.read(File.join(DATA_DIR, 'incident.xml'))
|
80
|
+
@cherwell.stub(:last_error => nil)
|
80
81
|
@cherwell.stub(:get_object_xml).
|
81
82
|
with('Incident', incident_id).
|
82
83
|
and_return(incident_xml)
|
83
84
|
@cherwell.incident(incident_id).should be_a(Cherby::Incident)
|
84
85
|
end
|
86
|
+
|
87
|
+
it "raises Cherby::NotFound if incident is not found" do
|
88
|
+
incident_id = '99999'
|
89
|
+
empty_xml = File.read(File.join(DATA_DIR, 'empty.xml'))
|
90
|
+
@cherwell.stub(:get_object_xml).
|
91
|
+
with('Incident', incident_id).
|
92
|
+
and_return(empty_xml)
|
93
|
+
|
94
|
+
error = "Specified Business Object not found"
|
95
|
+
@cherwell.stub(:last_error => error)
|
96
|
+
lambda do
|
97
|
+
@cherwell.incident(incident_id)
|
98
|
+
end.should raise_error(Cherby::NotFound, /#{error}/)
|
99
|
+
end
|
85
100
|
end #incident
|
86
101
|
|
87
102
|
describe "#task" do
|
88
103
|
it "returns a Cherby::Task instance" do
|
89
104
|
task_id = '12345'
|
90
105
|
task_xml = File.read(File.join(DATA_DIR, 'task.xml'))
|
106
|
+
@cherwell.stub(:last_error => nil)
|
91
107
|
@cherwell.stub(:get_object_xml).
|
92
108
|
with('Task', task_id).
|
93
109
|
and_return(task_xml)
|
94
110
|
@cherwell.task(task_id).should be_a(Cherby::Task)
|
95
111
|
end
|
112
|
+
|
113
|
+
it "raises a Cherby::NotFound if task is not found" do
|
114
|
+
task_id = '99999'
|
115
|
+
empty_xml = File.read(File.join(DATA_DIR, 'empty.xml'))
|
116
|
+
@cherwell.stub(:get_object_xml).
|
117
|
+
with('Task', task_id).
|
118
|
+
and_return(empty_xml)
|
119
|
+
|
120
|
+
error = "Specified Business Object not found"
|
121
|
+
@cherwell.stub(:last_error => error)
|
122
|
+
lambda do
|
123
|
+
@cherwell.task(task_id)
|
124
|
+
end.should raise_error(Cherby::NotFound, /#{error}/)
|
125
|
+
end
|
96
126
|
end #task
|
97
127
|
|
98
128
|
describe "#get_object_xml" do
|
@@ -142,15 +172,6 @@ describe Cherby::Cherwell do
|
|
142
172
|
result = @cherwell.get_object_xml(@name, @public_id)
|
143
173
|
result.should == xml
|
144
174
|
end
|
145
|
-
|
146
|
-
it "raises a Cherby::SoapError if a Savon::Error occurs" do
|
147
|
-
soap_fault = Savon::Error.new("Kaboom")
|
148
|
-
@cherwell.client.stub(:call).and_raise(soap_fault)
|
149
|
-
lambda do
|
150
|
-
@cherwell.get_object_xml(@name, @public_id)
|
151
|
-
end.should raise_error(
|
152
|
-
Cherby::SoapError, /Kaboom/)
|
153
|
-
end
|
154
175
|
end #get_object_xml
|
155
176
|
|
156
177
|
describe "#update_object_xml" do
|
data/spec/data/empty.xml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version="1.0"?>
|
data/spec/spec_helper.rb
CHANGED
@@ -3,7 +3,6 @@ require 'simplecov'
|
|
3
3
|
SimpleCov.start if ENV['COVERAGE']
|
4
4
|
|
5
5
|
require 'rspec'
|
6
|
-
require 'mustache'
|
7
6
|
|
8
7
|
ROOT_DIR = File.absolute_path(File.join(File.dirname(__FILE__), '..'))
|
9
8
|
LIB_DIR = File.join(ROOT_DIR, 'lib')
|
@@ -14,19 +13,23 @@ CONFIG_FILE = File.join(ROOT_DIR, 'config', 'test-config.yml')
|
|
14
13
|
CHERWELL_WSDL = File.join(DATA_DIR, 'cherwell.wsdl')
|
15
14
|
$LOAD_PATH.unshift(LIB_DIR)
|
16
15
|
|
17
|
-
class XMLTemplate < Mustache
|
18
|
-
self.template_path = XML_DIR
|
19
|
-
end
|
20
|
-
|
21
16
|
RSpec.configure do |config|
|
22
|
-
def xml_envelope(body)
|
23
|
-
return XMLTemplate.render_file('soap_envelope', :body => body)
|
24
|
-
end
|
25
|
-
|
26
17
|
def xml_response(method, body)
|
27
|
-
|
28
|
-
'
|
29
|
-
|
18
|
+
env_attrs = {
|
19
|
+
'xmlns:soap' => "http://schemas.xmlsoap.org/soap/envelope/",
|
20
|
+
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
|
21
|
+
'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema",
|
22
|
+
}
|
23
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
24
|
+
xml['soap'].Envelope(env_attrs) do |env|
|
25
|
+
env.Body do
|
26
|
+
env.send(:"#{method}Response", 'xmlns' => 'http://cherwellsoftware.com') do
|
27
|
+
env.send(:"#{method}Result", body)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
return builder.to_xml
|
30
33
|
end
|
31
34
|
|
32
35
|
def savon_response(method, body)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cherby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httpclient
|
@@ -75,22 +75,6 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: mustache
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
|
-
requirements:
|
83
|
-
- - ! '>='
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
86
|
-
type: :runtime
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ! '>='
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
94
78
|
- !ruby/object:Gem::Dependency
|
95
79
|
name: rake
|
96
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -215,6 +199,7 @@ files:
|
|
215
199
|
- spec/cherwell_spec.rb
|
216
200
|
- spec/client_spec.rb
|
217
201
|
- spec/data/cherwell.wsdl
|
202
|
+
- spec/data/empty.xml
|
218
203
|
- spec/data/incident.xml
|
219
204
|
- spec/data/login_false.xml
|
220
205
|
- spec/data/login_true.xml
|
@@ -223,8 +208,6 @@ files:
|
|
223
208
|
- spec/journal_note_spec.rb
|
224
209
|
- spec/spec_helper.rb
|
225
210
|
- spec/task_spec.rb
|
226
|
-
- spec/xml/method_response_result.mustache
|
227
|
-
- spec/xml/soap_envelope.mustache
|
228
211
|
- tasks/pry.rake
|
229
212
|
- tasks/spec.rake
|
230
213
|
homepage: http://github.com/a-e/cherby
|
@@ -1,6 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
2
|
-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
3
|
-
<soap:Body>
|
4
|
-
{{{body}}}
|
5
|
-
</soap:Body>
|
6
|
-
</soap:Envelope>
|