simplews 1.5.3 → 1.6.0

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/bin/start_ws ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/ruby
2
+ require 'rubygems'
3
+ require 'simplews'
4
+ require "optparse"
5
+
6
+ options = {}
7
+ OptionParser.new do |opts|
8
+ opts.banner = "Usage: #{ $_ } [options] <config_file>"
9
+
10
+ opts.on("-h", "--host HOST", String, "Select host interface, localhost by default") do |host|
11
+ options[:host] = host
12
+ end
13
+
14
+ opts.on("-p", "--port PORT", Integer, "Select interface port, 1984 by default") do |port|
15
+ options[:port] = port
16
+ end
17
+
18
+ opts.on("-n", "--name NAME", String, "Select the name of the web server interface, SimpleWS by default") do |name|
19
+ options[:name] = name
20
+ end
21
+
22
+ opts.on("-d", "--description DESCRIPTION", String, "Description of the service") do |description|
23
+ options[:description] = description
24
+ end
25
+
26
+ opts.on("-w", "--wsdl FILENAME", String, "Save the WSDL file") do |filename|
27
+ options[:wsdl] = filename
28
+ end
29
+
30
+ end.parse!
31
+
32
+ filename = ARGV[0]
33
+
34
+ server = SimpleWS.new(options[:name], options[:description], options[:host], options[:port]) do
35
+ actions = File.open(filename)do |f| f.read end
36
+ eval actions
37
+ end
38
+
39
+ if options[:wsdl]
40
+ File.open(options[:wsdl], 'w') do |f| f.write server.wsdl end
41
+ end
42
+
43
+ trap('INT'){
44
+ puts "Stopping server"
45
+ server.shutdown
46
+ }
47
+
48
+ server.start
49
+
50
+
@@ -0,0 +1,220 @@
1
+ require 'rake'
2
+
3
+ # Include the step_dependencies and step_def methods to simplify Pipelines. Steps depend on
4
+ # the step strictly above by default. The output of the step is save marshaled,
5
+ # except for Strings which are save as text. The input of the step, the output
6
+ # of the previous step if availabe is accessed with the input method
7
+ #
8
+ # Example::
9
+ #
10
+ # step_def :text do
11
+ # "Text to revert"
12
+ # end
13
+ #
14
+ # step_def :revert do
15
+ # text = input
16
+ # text.reverse
17
+ # end
18
+ #
19
+ module Rake::Pipeline
20
+
21
+ module Rake::Pipeline::Step
22
+
23
+ class << self
24
+
25
+ @@step_descriptions = {}
26
+ def step_descriptions
27
+ @@step_descriptions
28
+ end
29
+
30
+ def add_description(re, step, message)
31
+ @@step_descriptions[re] = "#{ step }: #{ message }"
32
+ end
33
+
34
+ @@last_step = nil
35
+ def step_dependencies(name, dependencies = nil)
36
+
37
+ re = Regexp.new(/(?:^|\/)#{name}\/.*$/)
38
+
39
+ # Take the last_description and associate it with the name
40
+ if Rake.application.last_description
41
+ add_description(re, name, Rake.application.last_description)
42
+ end
43
+
44
+ if dependencies.nil? && ! @@last_step.nil?
45
+ dependencies = @@last_step
46
+ end
47
+ @@last_step = name
48
+
49
+ # Generate the Hash definition
50
+ case
51
+ when dependencies.nil?
52
+ re
53
+ when String === dependencies || Symbol === dependencies
54
+ {re => lambda{|filename| filename.sub(name.to_s,dependencies.to_s) }}
55
+ when Array === dependencies
56
+ {re => lambda{|filename| dependencies.collect{|dep| filename.sub(name.to_s, dep.to_s) } }}
57
+ when Proc === dependencies
58
+ {re => dependencies}
59
+ end
60
+
61
+ end
62
+
63
+ def parse_filename(filename)
64
+ filename.match(/^(.*?)([^\/]*)\/([^\/]*)$/)
65
+ {
66
+ :prefix => $1,
67
+ :step => $2,
68
+ :job => $3,
69
+ }
70
+ end
71
+ end
72
+ end
73
+
74
+ module Rake::Pipeline::Info
75
+
76
+ def self.info_file(filename)
77
+ info = Rake::Pipeline::Step.parse_filename(filename)
78
+ "#{info[:prefix]}/.info/#{info[:job]}.yaml"
79
+ end
80
+
81
+ def self.load_info(t)
82
+ filename = t.name
83
+ info_filename = info_file(filename)
84
+
85
+ if File.exists? info_filename
86
+ YAML.load(File.open(info_filename))
87
+ else
88
+ {}
89
+ end
90
+ end
91
+
92
+ def self.save_info(t, info = {})
93
+ filename = t.name
94
+ info_filename = info_file(filename)
95
+
96
+ FileUtils.mkdir_p File.dirname(info_filename) unless File.exists? File.dirname(info_filename)
97
+ File.open(info_filename,'w'){|file|
98
+ file.write YAML.dump info
99
+ }
100
+ end
101
+ end
102
+
103
+ @@steps = []
104
+
105
+ def steps
106
+ @@steps
107
+ end
108
+
109
+
110
+ NON_ASCII_PRINTABLE = /[^\x20-\x7e\s]/
111
+ def is_binary?(file)
112
+ binary = file.read(1024) =~ NON_ASCII_PRINTABLE
113
+ file.rewind
114
+ binary
115
+ end
116
+
117
+ def step_descriptions
118
+ Rake::Pipeline::Step.step_descriptions
119
+ end
120
+
121
+
122
+ def step_dependencies(*args)
123
+ Rake::Pipeline::Step.step_dependencies(*args)
124
+ end
125
+
126
+ def infile(t, &block)
127
+ File.open(t.prerequisites.first) do |f|
128
+ block.call(f)
129
+ end
130
+ end
131
+
132
+ def outfile(t, &block)
133
+ File.open(t.name, 'w') do |f|
134
+ block.call(f)
135
+ end
136
+ end
137
+
138
+ def load_input(t, step = nil)
139
+ if step
140
+ info = Rake::Pipeline::Step.parse_filename(t.name)
141
+ filename = "#{info[:prefix]}/#{step}/#{info[:job]}"
142
+ File.open(filename){|f|
143
+ if is_binary?(f)
144
+ Marshal.load(f)
145
+ else
146
+ f.read
147
+ end
148
+ }
149
+ else
150
+ return nil if t.prerequisites.first.nil?
151
+ infile(t){|f|
152
+ if is_binary?(f)
153
+ Marshal.load(f)
154
+ else
155
+ f.read
156
+ end
157
+ }
158
+ end
159
+ end
160
+
161
+ def save_output(t, output)
162
+ case
163
+ when output.nil?
164
+ nil
165
+ when String === output
166
+ outfile(t){|f| f.write output }
167
+ else
168
+ outfile(t){|f| f.write Marshal.dump(output) }
169
+ end
170
+
171
+ end
172
+
173
+ # We cannot load the input variable before the block.call, so we need another method
174
+
175
+ # Load the input data from the previous step
176
+ def input(step = nil)
177
+ load_input(@@current_task, step) if @@current_task
178
+ end
179
+
180
+ if defined? SimpleWS::Jobs
181
+ def method_missing(symbol, *args)
182
+ $_current_job.send(symbol, *args)
183
+ end
184
+ else
185
+ # Add values to the info file
186
+ def info(values = {})
187
+ puts "Using rake info"
188
+
189
+ info = Rake::Pipeline::Info.load_info(@@current_task)
190
+ info = info.merge values
191
+ Rake::Pipeline::Info.save_info(@@current_task, info)
192
+ info
193
+ end
194
+ end
195
+
196
+
197
+
198
+
199
+ # Define a new step, it depends on the previously defined by default. It
200
+ # saves the output of the block so it can be loaded by the input method of
201
+ # the next step
202
+ def step_def(name, dependencies = nil, &block)
203
+ @@steps << name
204
+ rule step_dependencies(name, dependencies) do |t|
205
+
206
+ # Save the task object to be able to load the input
207
+ @@current_task = t
208
+
209
+ output = block.call(t)
210
+
211
+ save_output(t, output)
212
+ end
213
+
214
+ end
215
+ end
216
+
217
+ if __FILE__ == $0
218
+
219
+ p Rake::Pipeline::Info.info_file('work/diseases/t')
220
+ end
data/lib/simplews/jobs.rb CHANGED
@@ -386,7 +386,7 @@ class SimpleWS::Jobs < SimpleWS
386
386
  @workdir
387
387
  end
388
388
 
389
- def initialize(name, description, host = 'localhost' , port = '8081', workdir = nil, *args)
389
+ def initialize(name = nil, description = nil, host = nil, port = nil, workdir = nil, *args)
390
390
  super(name, description, host, port, *args)
391
391
 
392
392
  @workdir = workdir || "/tmp/#{ name }"
data/lib/simplews/rake.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'simplews/jobs'
4
4
  require 'rake'
5
+ require 'fileutils'
5
6
 
6
7
  class SimpleWS::Jobs::Scheduler::Job
7
8
 
@@ -45,6 +46,11 @@ class SimpleWS::Jobs::Scheduler::Job
45
46
  EOC
46
47
 
47
48
  load rakefile
49
+ @@steps.each{|step|
50
+ step_dirname = File.join(workdir, step.to_s)
51
+ FileUtils.mkdir_p step_dirname unless File.exists? step_dirname
52
+ }
53
+
48
54
  if defined? Rake::Pipeline
49
55
  Rake::Pipeline::step_descriptions.each{|re, description|
50
56
  if description.match(/(.*): (.*)/)
data/lib/simplews.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'rubygems'
2
+ gem 'soap4r'
1
3
  require 'soap/rpc/standaloneServer'
2
4
  require 'builder'
3
5
 
@@ -77,14 +79,22 @@ class SimpleWS < SOAP::RPC::StandaloneServer
77
79
  driver
78
80
  end
79
81
 
82
+ attr_accessor :description
83
+
80
84
  # Creates an instance of a Server. The parameter +name+ specifies the
81
85
  # +namespace+ used in the +WSDL+, +description+ is the description
82
86
  # also included in the +WSDL+. The parameters +host+ and +port+,
83
87
  # specify where the server will be listening, they are parameters of
84
88
  # the +super+ class SOAP::RPC::StandaloneServer, they are made
85
89
  # explicit here because they are included in the +WSDL+ as well.
86
- def initialize(name="WS", description="", host="localhost", port="1984", *args)
90
+ def initialize(name=nil, description=nil, host=nil, port=nil, *args, &block)
91
+ name ||= self.class.to_s
92
+ description ||= "Web Server for #{ name }"
93
+ host ||= "localhost"
94
+ port ||= "1984"
95
+
87
96
  super(description, "urn:#{ name }", host, port, *args)
97
+
88
98
  @host = host
89
99
  @port = port
90
100
  @name = name
@@ -93,12 +103,26 @@ class SimpleWS < SOAP::RPC::StandaloneServer
93
103
  @operations = []
94
104
  @bindings = []
95
105
 
106
+ if block_given?
107
+ instance_eval &block
108
+ end
109
+
110
+ puts "Server #{ name } at #{ host }:#{ port }"
111
+
96
112
  serve :wsdl, %w(), :return => :string
97
113
  METHODS.each{|name, info|
98
114
  serve name, info[:args], info[:types], &info[:block]
99
115
  }
100
116
  end
101
117
 
118
+ def name=(name)
119
+ @name = name
120
+ appname = name
121
+ default_namespace = "urn:#{name}"
122
+ end
123
+
124
+
125
+
102
126
 
103
127
  # This method tells the server to provide a method named by the +name+
104
128
  # parameter, with arguments listed in the +args+ parameter. The
@@ -174,7 +198,7 @@ class SimpleWS < SOAP::RPC::StandaloneServer
174
198
  end
175
199
  @messages << message
176
200
  message = Builder::XmlMarkup.new(:indent => 2).message :name => "#{ name }Response" do |xml|
177
- type = types[:return] || types["return"]
201
+ type = types[:return] || types["return"] || :string
178
202
  if type
179
203
  type = type.to_sym
180
204
  xml.part :name => 'return', :type => TYPES2WSDL[type]
@@ -231,7 +255,7 @@ targetNamespace="${NAME}-NS">
231
255
  </restriction>
232
256
  </complexContent>
233
257
  </complexType>
234
- </schema>
258
+ </schema>
235
259
  </types>
236
260
 
237
261
  ${MESSAGES}
@@ -260,7 +284,6 @@ EOT
260
284
  :integer => 'xsd:integer',
261
285
  :float => 'xsd:float',
262
286
  :array => 'tns:ArrayOfString',
263
- :hash => 'tns:Map',
264
287
  :binary => 'xsd:base64Binary',
265
288
  }
266
289
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplews
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
@@ -9,9 +9,19 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-16 00:00:00 +01:00
13
- default_executable:
12
+ date: 2009-12-30 00:00:00 +01:00
13
+ default_executable: start_ws
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: soap4r
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.5.8
24
+ version:
15
25
  - !ruby/object:Gem::Dependency
16
26
  name: rand
17
27
  type: :runtime
@@ -34,14 +44,15 @@ dependencies:
34
44
  version:
35
45
  description: Generates WSDL automatically. It manages jobs as asynchronous processes
36
46
  email: miguel.vazquez@fdi.ucm.es
37
- executables: []
38
-
47
+ executables:
48
+ - start_ws
39
49
  extensions: []
40
50
 
41
51
  extra_rdoc_files:
42
52
  - LICENSE
43
53
  - README.rdoc
44
54
  files:
55
+ - lib/rake_pipeline.rb
45
56
  - lib/simplews.rb
46
57
  - lib/simplews/jobs.rb
47
58
  - lib/simplews/rake.rb