ruby2soap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODAzMDk5Nzc5NmQ0NDk4YzhhYWFjYjMxY2VjNDc3MTk0NGY2ODgzOQ==
5
+ data.tar.gz: !binary |-
6
+ MzRlMDcwYWI3YzdiNDQwMmE0ZDA2Yzg3MTFjZjUxNzQ2MDMyZjAxYw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YzM5YmU1NWRmYmRjMGRlNzlkODA3ZjRhODVmOGIyOGUxZWMyNzVhYzc0ZDI2
10
+ Yjg4NmM4OTFhYThlOTBmZmI1ZmQ1ZjUxMGJlZGQ4NzM5MzRiZmJmZWVkYjJi
11
+ N2VmMDNiNDM5NGI1NmRhMzBmZDBmZGE1Y2NiYTAwYzEwNzc5NjY=
12
+ data.tar.gz: !binary |-
13
+ NjBiMmYxYmJhNzIzZDgxNDNmYzBmNDIzOTI3OGE3MDIwOTQyMjI1ZmU5OTRm
14
+ Y2I4MmZjZDgxYzhjN2I3ZTQ5YThiM2M2NDdkNzhkMmNmYTQ1NWZjZDFlNzhj
15
+ MjgwMGRiZTg5Y2RiYmVkMGIzMjM1ODRhMDk4NjI3NmM4YjYwZTM=
data/lib/ruby2soap.rb ADDED
@@ -0,0 +1,100 @@
1
+ require 'net/http'
2
+ require 'xmlsimple'
3
+ require_relative 'wsdl\wsdl'
4
+ include Wsdl
5
+ #require 'soap/soap'
6
+ #include Soap
7
+ #include WebRequestHandler
8
+ #require_relative 'wsdl.rb'
9
+ #require_relative 'wsdl_parser.rb'
10
+ #require_relative 'soap.rb'
11
+ #include WsdlParser
12
+ #include Soap
13
+
14
+ #Dir["lib/*.rb"].each {|file|
15
+ # require file
16
+ # #require_relative file# if file != 'wcf_handler'
17
+ # #include file.gsub('.rb','')
18
+ #}
19
+
20
+ # Handle the requests to the service
21
+ class Ruby2Soap
22
+ # C'tor.
23
+ # Parse the wsdl and create a method to each WCF/WebService method
24
+ # Params:
25
+ # +service_url+:: the url of your service
26
+ # +save_cookeis+:: should save cookies of the result
27
+ def initialize(service_url,save_cookeis = true)
28
+ HTTPI.log = false
29
+ @cookies = []
30
+ @save_cookeis = save_cookeis
31
+
32
+ @uri = URI("#{service_url}")
33
+
34
+ wsdl = WsdlParser.parse(service_url)
35
+ @service_address = wsdl.location_address
36
+
37
+ wsdl.actions.each do |action|
38
+ define_wcf_action(action)
39
+ end
40
+
41
+ # maybe create class for each service and the function will be there
42
+ end
43
+
44
+ # Return the the current cookie set
45
+ def cookies
46
+ @cookies
47
+ end
48
+
49
+ private
50
+ # Define a method to the +Ruby2Soap+ object base on the method from the WSDL
51
+ # Params:
52
+ # +action+:: +SoapAction+ that have all the info about the method from the WSDL
53
+ def define_wcf_action(action)
54
+ self.class.send(:define_method ,action.name) do |data=nil,*args|
55
+ body = build_body(action, data)
56
+
57
+ res = send_wcf_action(action.soap_action,body,*args)
58
+ (@cookies << res.headers["Set-Cookie"]) if @save_cookeis
59
+
60
+ result = get_wcf_response(res,action.name)
61
+ res.singleton_class.send(:define_method,:result) do
62
+ result
63
+ end
64
+
65
+ #if(res.code == '401') # not autorized
66
+ # (raise "Please use ntlm") if res['WWW-Authenticate'].include?('NTLM')
67
+ #end
68
+
69
+ res
70
+ end
71
+
72
+ #create new method that takes the data and user and password and user ntlm
73
+ end
74
+
75
+ # Call to wcf method
76
+ # Params:
77
+ # +soap_action+:: the value of the SOAPAction header
78
+ # +body+:: the body of the HTTP request
79
+ # +args+:: metadata that indicate wich autountication to use
80
+ def send_wcf_action(soap_action,body,*args)
81
+ #req = Net::HTTP::Post.new(@uri.path)
82
+ #req = Net::HTTP::Post.new(@service_address)
83
+
84
+ #req["SOAPAction"] = soap_action
85
+ #req["Content-Type"] = "text/xml; charset=utf-8"
86
+ #req["Cookie"] = @cookies.join(',') unless @cookies.empty?
87
+ #req.body = body
88
+
89
+ yield(req) if block_given?
90
+
91
+ #get_web_response(req,@uri,*args)
92
+ # "Cookie" => (@cookies.join(',') unless @cookies.empty?)
93
+ cookies = @cookies.empty? ? "" : @cookies.join(',')
94
+ send_message_to_wcf(@service_address,
95
+ {"SOAPAction" => soap_action,
96
+ "Content-Type" => "text/xml; charset=utf-8",
97
+ "Cookie" => cookies},
98
+ body, *args)
99
+ end
100
+ end
data/lib/soap/soap.rb ADDED
@@ -0,0 +1,88 @@
1
+ require_relative './soap_action'
2
+ require_relative './soap_parameter'
3
+ require 'xmlsimple'
4
+
5
+ module Soap
6
+ # Covert the data to hash
7
+ # Params:
8
+ # +object+:: the object to covert to hash
9
+ def data_to_arr(object)
10
+ return '' if object.nil?
11
+ return [object] unless object.is_a? Hash
12
+
13
+ params = {}
14
+ object.each do |key,value|
15
+ params["#{@name_space}:#{key}"] = data_to_arr(value)
16
+ end
17
+
18
+ params
19
+ end
20
+
21
+ # Build the body that need to be send to the service when calling the soap action and return the result
22
+ # Params :
23
+ # +action+:: +SoapAction+ object that keep all the data about the soap action
24
+ # +data+:: the user data that he want to send to the server
25
+ def build_body(action , data)
26
+ @name_space = 'a'
27
+ body = {
28
+ 'soap:Envelope' => {
29
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
30
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
31
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
32
+ 'soap:Body' => {
33
+ "#{action.name}" => {
34
+ "xmlns" => WsdlParser.target_namespace
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ if(!data.nil?)
41
+ data.each do |key, value|
42
+ build_param(body['soap:Envelope']['soap:Body']["#{action.name}"],action,key,value)
43
+ end
44
+ end
45
+
46
+ XmlSimple.xml_out(body, 'RootName' => nil)
47
+ end
48
+
49
+ # Parse the server response to hash that the user will work eith
50
+ # Params:
51
+ # +res+:: +HTTPI::Response+ object that represent the response from the server
52
+ # +action_name+:: the name of the action that the response is belongs to
53
+ def get_wcf_response(res,action_name)
54
+ #res.error?
55
+ if res.code.to_i >= 400
56
+ 'error please see body'
57
+ else
58
+ result = XmlSimple.xml_in(res.body)['Body'].first["#{action_name}Response"].first["#{action_name}Result"].first
59
+ if result.class == Hash
60
+ # I dont want to return the result xml attributes
61
+ result.select!{|k,v| v.class == Array}
62
+ end
63
+
64
+ result
65
+ end
66
+ end
67
+
68
+ # Adds to the action element in the +Hash+ and add the user send data to the hash
69
+ # Params:
70
+ # +action_element+:: the action element in the hash of the body
71
+ # +action+:: +SoapAction+ object that keep all the data about the soap action
72
+ # +key+:: the name of the parameter
73
+ # +value+:: the value of the parameter
74
+ def build_param(action_element,action,key,value)
75
+ if(action.parameters.nil?)
76
+ action_element["#{key}"] = ((value.is_a? Hash) ? data_to_arr(value) : [value])
77
+ else
78
+ current_param = action.parameters.select{|p| p.name.upcase == key.to_s.upcase}.first
79
+ action_element["#{key}"] = ((value.is_a? Hash) ? data_to_arr(value) : [value])
80
+
81
+ if !current_param.namespace.nil?
82
+ action_element["#{key}"].merge!("xmlns:#{@name_space}" => current_param.namespace)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+
@@ -0,0 +1,9 @@
1
+ module Soap
2
+ class SoapAction
3
+ attr_accessor :name, :soap_action, :parameters
4
+
5
+ def self.parse()
6
+ #TODO:parse from xml to SoapParamter object
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module Soap
2
+ class SoapParamter
3
+ attr_accessor :name, :nullable, :type, :namespace
4
+
5
+ # Gets the xml element of the paramter and parse it to a +SoapParamter+ object
6
+ # Params:
7
+ # +param_element+:: +Hash+ that represent the xml element of the paramter
8
+ def self.parse(param_element)
9
+ param = SoapParamter.new
10
+ param.name = param_element['name']
11
+ param.type = param_element['type'].split(':').last
12
+ yield param if block_given?
13
+
14
+ param
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ module Web
2
+ # the secutry protocols that have support
3
+ module SecutryProtocol
4
+ NTLM = 0
5
+ GGS_API = 1
6
+ KERBEROS = 1
7
+ BASIC = 2
8
+ DIGEST = 3
9
+ end
10
+ end
@@ -0,0 +1,88 @@
1
+ require 'httpi'
2
+ require_relative './secutry_protocols'
3
+
4
+ # Handle all the communication to the service
5
+ module Web
6
+ # Send Http get rquest to a url and return his result via +HTTPI+
7
+ # Params:
8
+ # +url+:: the url to send the request to
9
+ # +headers+:: hash that keeps the headers that need to be send to the service
10
+ def get_web_response(url,headers)
11
+ request = HTTPI::Request.new(url)
12
+
13
+ request.headers = headers
14
+ response = HTTPI.get(request)
15
+
16
+ response
17
+ end
18
+
19
+ # Send http request to the service
20
+ # Params:
21
+ # +url+:: the url to send the request to
22
+ # +headers+:: hash that keeps the headers that need to be send to the service
23
+ # +body+:: the body of the HTTP request
24
+ # +args+:: metadata that indicate wich autountication to use
25
+ def send_message_to_wcf(url,headers,body,*args)
26
+ request = HTTPI::Request.new(url)
27
+ request.headers = headers
28
+ request.body = body
29
+
30
+ #TODO: change to user self.send('use_'+)
31
+ case args.first
32
+ when SecutryProtocol::NTLM
33
+ use_ntlm(request,*args)
34
+ when SecutryProtocol::GGS_API
35
+ use_kerberos(request)
36
+ when SecutryProtocol::BASIC
37
+ use_basic(request,*args)
38
+ when SecutryProtocol::DIGEST
39
+ use_digest(request,*args)
40
+ end
41
+
42
+ response = HTTPI.post(request)
43
+ response
44
+ end
45
+
46
+ private
47
+ # Use ntlm auth in the request
48
+ # Params:
49
+ # +request+:: +HTTPI::Request+ request
50
+ # +args+:: keep the data that need to be uses for the NTLM auth
51
+ def use_ntlm(request,*args)
52
+ # the first is the security name
53
+ user = args[1]
54
+ password = args[2]
55
+ domain = args[3]
56
+
57
+ request.auth.ntlm(user,password,domain)# if request.auth.ntlm?
58
+ end
59
+
60
+ # Use kerberos auth in the request
61
+ # Params:
62
+ # +request+:: +HTTPI::Request+ request
63
+ def use_kerberos(request)
64
+ request.auth.gssnegotiate
65
+ end
66
+
67
+ # Use basic auth in the request
68
+ # Params:
69
+ # +request+:: +HTTPI::Request+ request
70
+ # +args+:: keep the data that need to be uses for the basic auth
71
+ def use_basic(request,*args)
72
+ user = args[1]
73
+ password = args[2]
74
+
75
+ request.auth.basic(user,password)
76
+ end
77
+
78
+ # Use digest auth in the request
79
+ # Params:
80
+ # +request+:: +HTTPI::Request+ request
81
+ # +args+:: keep the data that need to be uses for the digest auth
82
+ def use_digest(request,*args)
83
+ user = args[1]
84
+ password = args[2]
85
+
86
+ request.auth.digest(user,password)
87
+ end
88
+ end
data/lib/wsdl/wsdl.rb ADDED
@@ -0,0 +1,7 @@
1
+ require_relative '..\wsdl\wsdl_parser'
2
+
3
+ module Wsdl
4
+ class Wsdl
5
+ attr_accessor :actions, :target_namespace, :location_address
6
+ end
7
+ end
@@ -0,0 +1,151 @@
1
+ require 'xmlsimple'
2
+ require_relative '..\soap\soap'
3
+ require_relative '..\web\web_request_handler'
4
+ include Soap
5
+ include Web
6
+
7
+ module Wsdl
8
+ class WsdlParser
9
+ # Parse the service wsdl to a +Wsdl+ object
10
+ # Params :
11
+ # +service+:: the url of the service
12
+ def self.parse(service)
13
+ @service = service
14
+ wsdl_xml = get_serivce_data('wsdl')
15
+ doc = XmlSimple.xml_in(wsdl_xml)
16
+
17
+ res = Wsdl.new
18
+ res.actions = get_soap_actions(doc)
19
+ res.location_address = get_location_address(doc)
20
+ res.target_namespace = doc['targetNamespace']
21
+
22
+ res
23
+ end
24
+
25
+ # Return the target namespace of the last wsdl parser.
26
+ # TODO: Remove this method and user tel +Wsdl+ it self to get the target namespace
27
+ def self.target_namespace
28
+ @@target_namespace
29
+ end
30
+
31
+ private
32
+ # Return the service data for specified extension (wsdl, xsd=xsd0, etc)
33
+ # Params:
34
+ # +extension+:: the extension the query the service with (wsdl, xsd=xsd0, etc)
35
+ def self.get_serivce_data(extension)
36
+ uri = URI("#{@service}")
37
+
38
+ res = get_web_response("#{@service}?#{extension}",
39
+ {"Accept" => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
40
+ "Accept-Encoding" => 'gzip,deflate,sdch'})
41
+ res.body
42
+ end
43
+
44
+ # ???
45
+ def self.get_action_datacontact(action_name)
46
+ if @xsd_namespace.nil?
47
+ xsd0 = get_serivce_data('xsd=xsd0')
48
+ doc = XmlSimple.xml_in(xsd0)
49
+
50
+ import = doc['import']
51
+ @xsd_namespace = (import.first['namespace'] unless import.nil?)
52
+ end
53
+
54
+ @xsd_namespace
55
+ end
56
+
57
+ # Return list of +SoapAction+
58
+ # Params:
59
+ # +doc+:: +Hash+ that represent the wsdl xml
60
+ def self.get_soap_actions(doc)
61
+ result = []
62
+
63
+ @@target_namespace = doc['targetNamespace']
64
+ should_read_from_xsd = !doc['types'].first['schema'].first['import'].nil?
65
+
66
+ binding = doc['binding'].first
67
+ binding['operation'].each do |opp|
68
+ action = SoapAction.new
69
+
70
+ action.name = opp['name']
71
+ action.soap_action = opp['operation'].first['soapAction']
72
+ action.parameters = get_action_params(action.name, doc, should_read_from_xsd)
73
+
74
+ result << action
75
+ end
76
+
77
+ result
78
+ end
79
+
80
+ # Return the location address of the service
81
+ # Params:
82
+ # +doc+:: +Hash+ that represent the wsdl xml
83
+ def self.get_location_address(doc)
84
+ service = doc['service']
85
+ location = service.first['port'].first['address'].first['location']
86
+
87
+ location
88
+ end
89
+
90
+ # Return the parameters that the soap actiop requires as list of +SoapParamter+ objects
91
+ # Params :
92
+ # +action_name+:: the name of the soap action
93
+ # +doc+:: hash the represent the WSDL
94
+ # +should_read_from_xsd+:: boolean that indicates whether it should read the parameters from the wsdl or imported xsd
95
+ def self.get_action_params(action_name,doc,should_read_from_xsd)
96
+ if(should_read_from_xsd)
97
+ get_action_params_from_xsd(action_name)
98
+ else
99
+ get_action_params_from_wsdl(action_name,doc)
100
+ end
101
+ end
102
+
103
+ # Parse the soap action element in the wsdl and return the parameters that the soap actiop requires as list of +SoapParamter+ objects
104
+ # Params:
105
+ # +action_name+:: the name of the soap action
106
+ # +doc+:: hash the represent the WSDL
107
+ def self.get_action_params_from_wsdl(action_name, doc)
108
+ #puts opp['input'].first
109
+ if @schema.nil?
110
+ @schema = doc['types'].first['schema'].first
111
+ end
112
+
113
+ action_element = @schema['element'].select{|e| e['name'] == action_name}.first
114
+ action_params_elements = action_element['complexType'].first['sequence'].first['element']
115
+
116
+ action_params_elements.map do |element|
117
+ SoapParamter.parse(element) do |param|
118
+ param.nullable = ['minOccurs'] == 0
119
+ end
120
+ end
121
+ end
122
+
123
+ # Parse the imported xsd and return the parameters that the soap actiop requires as list of +SoapParamter+ objects
124
+ # Params:
125
+ # +action_name+:: the name of the soap action
126
+ def self.get_action_params_from_xsd(action_name)
127
+ if @elements.nil?
128
+ #@elements = {}
129
+ xsd0 = get_serivce_data('xsd=xsd0')
130
+ doc = XmlSimple.xml_in(xsd0)
131
+
132
+ @elements = doc['element']
133
+
134
+ # the page dose not have imported shceme
135
+ return nil if @elements.nil?
136
+ end
137
+
138
+ element = @elements.select{|e| e['name'] == action_name}.first
139
+ sequence = element['complexType'].first['sequence'].first
140
+
141
+ return [] if sequence['element'].nil?
142
+ sequence['element'].map do |e|
143
+ SoapParamter.parse(e) do |param|
144
+ param.nullable = e['nillable']
145
+ namespace_element = e.select{|key,value| key.match(/xmlns(.*)/)}.first
146
+ (param.namespace = namespace_element[1]) unless namespace_element.nil?
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby2soap
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Eric Feldman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xml-simple
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httpi
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: enable communication between ruby and soap services
42
+ email: ericfeldman93@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/ruby2soap.rb
48
+ - lib/soap/soap.rb
49
+ - lib/soap/soap_action.rb
50
+ - lib/soap/soap_parameter.rb
51
+ - lib/web/secutry_protocols.rb
52
+ - lib/web/web_request_handler.rb
53
+ - lib/wsdl/wsdl.rb
54
+ - lib/wsdl/wsdl_parser.rb
55
+ homepage: https://github.com/ericman93/ruby2soap
56
+ licenses: []
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.2.1
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Communication between ruby and soap services
78
+ test_files: []