jruby-serviceproxy 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ LICENSE
2
+
3
+ The MIT License
4
+
5
+ Copyright (c) 2008 Jeremy Durham
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,27 @@
1
+ ServiceProxy
2
+
3
+ ServiceProxy is a lightweight SOAP library for Ruby.
4
+
5
+ HOW IT WORKS
6
+
7
+ Loading the library:
8
+
9
+ require 'rubygems'
10
+ require 'service_proxy/base'
11
+
12
+ GENERATING A PROXY
13
+
14
+ ServiceProxy comes with a simple generator to get started. It can be invoked
15
+ as follows:
16
+
17
+ wsdl2proxy [wsdl]
18
+
19
+ This will generate a file named default.rb, in the current directory. The class
20
+ will be named GeneratedService, and will define build and parse methods for all
21
+ of the available service methods.
22
+
23
+ Please refer to the specs for extended usage examples.
24
+
25
+ CONTRIBUTORS
26
+
27
+ Rich Cavanaugh
data/Rakefile ADDED
@@ -0,0 +1,94 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rubygems/specification'
4
+ require 'rake/rdoctask'
5
+ require 'spec/rake/spectask'
6
+ require File.join(File.dirname(__FILE__), 'lib', 'service_proxy', 'base')
7
+
8
+ NAME = "serviceproxy"
9
+ AUTHOR = "Jeremy Durham"
10
+ EMAIL = "jeremydurham@gmail.com"
11
+ HOMEPAGE = ""
12
+ SUMMARY = "Lightweight SOAP library for Ruby"
13
+
14
+ # Used by release task
15
+ GEM_NAME = NAME
16
+ PROJECT_URL = HOMEPAGE
17
+ PROJECT_SUMMARY = SUMMARY
18
+ PROJECT_DESCRIPTION = SUMMARY
19
+
20
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
21
+ GEM_VERSION = ServiceProxy::Base::VERSION + PKG_BUILD
22
+ RELEASE_NAME = "REL #{GEM_VERSION}"
23
+ #
24
+ # ==== Gemspec and installation
25
+ #
26
+
27
+ spec = Gem::Specification.new do |s|
28
+ s.name = NAME
29
+ s.version = ServiceProxy::Base::VERSION
30
+ s.platform = Gem::Platform::RUBY
31
+ s.has_rdoc = true
32
+ s.extra_rdoc_files = ["README", "LICENSE"]
33
+ s.summary = SUMMARY
34
+ s.description = s.summary
35
+ s.author = AUTHOR
36
+ s.email = EMAIL
37
+ s.homepage = HOMEPAGE
38
+ s.require_path = 'lib'
39
+ s.executables = ['wsdl2proxy']
40
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{lib,spec}/**/*")
41
+
42
+ s.add_dependency "hpricot"
43
+ end
44
+
45
+ Rake::GemPackageTask.new(spec) do |pkg|
46
+ pkg.gem_spec = spec
47
+ end
48
+
49
+ desc "install the gem locally"
50
+ task :install => [:clean, :package] do
51
+ sh %{sudo gem install pkg/#{NAME}-#{ServiceProxy::Base::VERSION} --no-update-sources}
52
+ end
53
+
54
+ desc "create a gemspec file"
55
+ task :make_spec do
56
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
57
+ file.puts spec.to_ruby
58
+ end
59
+ end
60
+
61
+ desc "Run coverage suite"
62
+ task :rcov do
63
+ require 'fileutils'
64
+ FileUtils.rm_rf("coverage") if File.directory?("coverage")
65
+ FileUtils.mkdir("coverage")
66
+ path = File.expand_path(Dir.pwd)
67
+ files = Dir["spec/**/*_spec.rb"]
68
+ files.each do |spec|
69
+ puts "Getting coverage for #{File.expand_path(spec)}"
70
+ command = %{rcov #{File.expand_path(spec)} --aggregate #{path}/coverage/data.data}
71
+ command += " --no-html" unless spec == files.last
72
+ `#{command} 2>&1`
73
+ end
74
+ end
75
+
76
+ file_list = FileList['spec/**/*_spec.rb']
77
+
78
+ desc "Run all examples"
79
+ Spec::Rake::SpecTask.new('spec') do |t|
80
+ t.spec_files = file_list
81
+ end
82
+
83
+ namespace :spec do
84
+ desc "Run all examples with RCov"
85
+ Spec::Rake::SpecTask.new('rcov') do |t|
86
+ t.spec_files = file_list
87
+ t.rcov = true
88
+ t.rcov_dir = "doc/coverage"
89
+ t.rcov_opts = ['--exclude', 'spec']
90
+ end
91
+ end
92
+
93
+ desc 'Default: run unit tests.'
94
+ task :default => 'spec'
data/bin/wsdl2proxy ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'service_proxy/base'
5
+
6
+ def underscore(camel_cased_word)
7
+ camel_cased_word.to_s.gsub(/::/, '/').
8
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
9
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
10
+ tr("-", "_").
11
+ downcase
12
+ end
13
+
14
+ unless ARGV.size > 0
15
+ puts "Usage: #{$0} [endpoint]"
16
+ exit!
17
+ end
18
+
19
+ template_filename = File.dirname(__FILE__) + '/../lib/templates/proxy.rbt'
20
+ proxy = ServiceProxy::Base.new(ARGV[0])
21
+ output_filename = 'default.rb'
22
+ output_klass_name = 'GeneratedService'
23
+ output = ''
24
+ proxy.service_methods.each do |service_method|
25
+ output << <<-EOS
26
+
27
+ def build_#{underscore(service_method)}(options)
28
+ soap_envelope(options) do |xml|
29
+ end
30
+ end
31
+
32
+ def parse_#{underscore(service_method)}(response)
33
+ Hpricot.XML(response.body)
34
+ end
35
+ EOS
36
+ end
37
+ template = File.read(template_filename)
38
+ template.gsub!(/%name%/, output_klass_name)
39
+ template.gsub!(/%body%/, output)
40
+ File.open(output_filename, 'w') { |f| f.puts template }
41
+ puts "Generated proxy #{output_filename} - You can use the proxy by executing #{output_klass_name}.new('#{ARGV[0]}')"
@@ -0,0 +1,156 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+
5
+ begin
6
+ require 'hpricot'
7
+ require 'builder'
8
+ rescue LoadError
9
+ puts "Could not load hpricot or builder. Please make sure they are installed and in your $LOAD_PATH."
10
+ end
11
+
12
+ module ServiceProxy
13
+ class Base
14
+ VERSION = '0.1.4'
15
+
16
+ attr_accessor :endpoint, :service_methods, :soap_actions, :service_uri, :http, :service_http, :uri, :debug, :wsdl, :target_namespace, :service_ports
17
+
18
+ def initialize(endpoint)
19
+ self.endpoint = endpoint
20
+ self.setup
21
+ end
22
+
23
+ def call_service(options)
24
+ method = options[:method]
25
+ headers = { 'content-type' => 'text/xml; charset=utf-8', 'SOAPAction' => self.soap_actions[method] }
26
+ body = build_request(method, options)
27
+ response = self.service_http.request_post(self.service_uri.path, body, headers)
28
+ parse_response(method, response)
29
+ end
30
+
31
+ protected
32
+
33
+ def setup
34
+ self.soap_actions = {}
35
+ self.service_methods = []
36
+ setup_uri
37
+ self.http = setup_http(self.uri)
38
+ get_wsdl
39
+ parse_wsdl
40
+ setup_namespace
41
+ end
42
+
43
+ def service_uri
44
+ @service_uri ||= self.respond_to?(:service_port) ? self.service_port : self.uri
45
+ end
46
+
47
+ def service_http
48
+ @service_http ||= unless self.service_uri == self.uri
49
+ local_http = self.setup_http(self.service_uri)
50
+ setup_https(local_http) if self.service_uri.scheme == 'https'
51
+ local_http
52
+ else
53
+ self.http
54
+ end
55
+ end
56
+
57
+ def setup_http(local_uri)
58
+ raise ArgumentError, "Endpoint URI must be valid" unless local_uri.scheme
59
+ local_http = Net::HTTP.new(local_uri.host, local_uri.port)
60
+ setup_https(local_http) if local_uri.scheme == 'https'
61
+ local_http.set_debug_output(STDOUT) if self.debug
62
+ local_http.read_timeout = 5
63
+ local_http
64
+ end
65
+
66
+ def setup_https(local_http)
67
+ local_http.use_ssl = true
68
+ local_http.verify_mode = OpenSSL::SSL::VERIFY_NONE
69
+ end
70
+
71
+ private
72
+
73
+ def setup_uri
74
+ self.uri = URI.parse(self.endpoint)
75
+ end
76
+
77
+ def get_wsdl
78
+ response = self.http.get("#{self.uri.path}?#{self.uri.query}")
79
+ self.wsdl = Hpricot.XML(response.body)
80
+ end
81
+
82
+ def parse_wsdl
83
+ method_list = []
84
+ self.wsdl.search('//soap:operation').each do |operation|
85
+ operation_name = operation.parent.get_attribute('name')
86
+ method_list << operation_name
87
+ self.soap_actions[operation_name] = operation.get_attribute('soapAction')
88
+ end
89
+ raise RuntimeError, "Could not parse WSDL" if method_list.empty?
90
+ self.service_methods = method_list.sort
91
+
92
+ port_list = {}
93
+ self.wsdl.search('//port').each do |port|
94
+ name = underscore(port['name'])
95
+ location = port.search('/[@location]').first['location']
96
+ port_list[name] = location
97
+ end
98
+ self.service_ports = port_list
99
+ end
100
+
101
+ def setup_namespace
102
+ namespace = self.wsdl.at("definitions")
103
+ namespace = self.wsdl.at("wsdl:definitions") if namespace.nil?
104
+ self.target_namespace = namespace.get_attribute("xmlns:tns")
105
+ end
106
+
107
+ def build_request(method, options)
108
+ builder = underscore("build_#{method}")
109
+ self.respond_to?(builder) ? self.send(builder, options).target! :
110
+ soap_envelope(options).target!
111
+ end
112
+
113
+ def parse_response(method, response)
114
+ parser = underscore("parse_#{method}")
115
+ self.respond_to?(parser) ? self.send(parser, response) :
116
+ raise(NoMethodError, "You must define the parse method: #{parser}")
117
+ end
118
+
119
+ def soap_envelope(options, &block)
120
+ xsd = 'http://www.w3.org/2001/XMLSchema'
121
+ env = 'http://schemas.xmlsoap.org/soap/envelope/'
122
+ xsi = 'http://www.w3.org/2001/XMLSchema-instance'
123
+ xml = Builder::XmlMarkup.new
124
+ xml.env(:Envelope, 'xmlns:xsd' => xsd, 'xmlns:env' => env, 'xmlns:xsi' => xsi) do
125
+ xml.env(:Body) do
126
+ xml.__send__(options[:method].to_sym, "xmlns" => self.target_namespace) do
127
+ yield xml if block_given?
128
+ end
129
+ end
130
+ end
131
+ xml
132
+ end
133
+
134
+ def method_missing(method, *args)
135
+ method_name = method.to_s
136
+ case method_name
137
+ when /_uri$/
138
+ sp_name = method_name.gsub(/_uri$/, '')
139
+ super unless self.service_ports.has_key?(sp_name)
140
+ URI.parse(self.service_ports[sp_name])
141
+ else
142
+ options = args.pop || {}
143
+ super unless self.service_methods.include?(method_name)
144
+ call_service(options.update(:method => method_name))
145
+ end
146
+ end
147
+
148
+ def underscore(camel_cased_word)
149
+ camel_cased_word.to_s.gsub(/::/, '/').
150
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
151
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
152
+ tr("-", "_").
153
+ downcase
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'service_proxy/base'
3
+ require 'hpricot'
4
+
5
+ class %name% < ServiceProxy::Base
6
+ %body%
7
+ end
@@ -0,0 +1,48 @@
1
+ require 'hpricot'
2
+
3
+ # Service Endpoints
4
+ class ISBNService < ServiceProxy::Base
5
+
6
+ def build_is_valid_isbn13(options)
7
+ soap_envelope(options) do |xml|
8
+ xml.sISBN(options[:isbn])
9
+ end
10
+ end
11
+
12
+ def parse_is_valid_isbn13(response)
13
+ xml = Hpricot.XML(response.body)
14
+ xml.at("m:IsValidISBN13Result").inner_text == 'true' ? true : false
15
+ end
16
+
17
+ def service_port
18
+ local_uri = URI.parse(self.isbn_service_soap_uri.to_s)
19
+ local_uri.path << "?dummy=1"
20
+ local_uri
21
+ end
22
+ end
23
+
24
+ class SHAGeneratorService < ServiceProxy::Base
25
+
26
+ def build_gen_ssha(options)
27
+ soap_envelope(options) do |xml|
28
+ xml.text(options[:text])
29
+ xml.hashtype(options[:hash_type])
30
+ end
31
+ end
32
+
33
+ def parse_gen_ssha(response)
34
+ xml = Hpricot.XML(response.body)
35
+ xml.at("return").inner_text
36
+ end
37
+ end
38
+
39
+ class InvalidSHAGeneratorService < ServiceProxy::Base
40
+
41
+ def build_gen_ssha(options)
42
+ soap_envelope(options) do |xml|
43
+ xml.text(options[:text])
44
+ xml.hashtype(options[:hash_type])
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,65 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'lib/service_proxy/base'
4
+ require 'spec/service_helper'
5
+
6
+ describe ServiceProxy do
7
+ it "should raise on an invalid URI" do
8
+ lambda { ServiceProxy::Base.new('bacon') }.should raise_error(ArgumentError)
9
+ end
10
+
11
+ it "should raise on invalid WSDL" do
12
+ lambda { ServiceProxy::Base.new('http://www.yahoo.com') }.should raise_error(RuntimeError)
13
+ end
14
+
15
+ describe "connecting to an ISBN validator" do
16
+ before do
17
+ @proxy = ISBNService.new('http://webservices.daehosting.com/services/isbnservice.wso?WSDL')
18
+ end
19
+
20
+ describe "calling IsValidISBN13" do
21
+ it "should return true for a valid ISBN" do
22
+ @proxy.IsValidISBN13(:isbn => '978-0977616633').should == true
23
+ end
24
+
25
+ it "should return false for an invalid ISBN" do
26
+ @proxy.IsValidISBN13(:isbn => '999-9999391939').should == false
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "connecting to the SHA hash generator Service" do
32
+ before do
33
+ @proxy = SHAGeneratorService.new('https://sec.neurofuzz-software.com/paos/genSSHA-SOAP.php?wsdl')
34
+ end
35
+
36
+ it "should be SSL" do
37
+ @proxy.http.use_ssl.should be_true
38
+ end
39
+
40
+ it "should generate a SSH hash" do
41
+ result = @proxy.genSSHA(:text => 'hello world', :hash_type => 'sha512')
42
+ result.should =~ /^[{SSHA512}]/
43
+ end
44
+ end
45
+
46
+ describe "making a service call without a parse method" do
47
+ before do
48
+ @proxy = InvalidSHAGeneratorService.new('https://sec.neurofuzz-software.com/paos/genSSHA-SOAP.php?wsdl')
49
+ end
50
+
51
+ it "should raise a no method error" do
52
+ lambda { result = @proxy.genSSHA(:text => 'hello world', :hash_type => 'sha512') }.should raise_error(NoMethodError)
53
+ end
54
+ end
55
+
56
+ describe "using the #service_port hook" do
57
+ before do
58
+ @proxy = ISBNService.new('http://webservices.daehosting.com/services/isbnservice.wso?WSDL')
59
+ end
60
+
61
+ it "should have the dummy query argument" do
62
+ @proxy.send(:service_uri).path.should match(/\?dummy=1/)
63
+ end
64
+ end
65
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jruby-serviceproxy
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 4
9
+ version: 0.1.4
10
+ platform: ruby
11
+ authors:
12
+ - Jeremy Durham
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2008-12-13 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: hpricot
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: builder
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :runtime
43
+ version_requirements: *id002
44
+ description: Lightweight SOAP library for Ruby
45
+ email: jeremydurham@gmail.com
46
+ executables:
47
+ - wsdl2proxy
48
+ extensions: []
49
+
50
+ extra_rdoc_files:
51
+ - README
52
+ - LICENSE
53
+ files:
54
+ - LICENSE
55
+ - README
56
+ - Rakefile
57
+ - lib/service_proxy/base.rb
58
+ - lib/templates/proxy.rbt
59
+ - spec/service_helper.rb
60
+ - spec/service_proxy_spec.rb
61
+ has_rdoc: true
62
+ homepage: ""
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options: []
67
+
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.6
88
+ signing_key:
89
+ specification_version: 2
90
+ summary: Lightweight SOAP library for Ruby
91
+ test_files: []
92
+