rhoconnect 3.0.5 → 3.0.6
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/CHANGELOG.md +7 -1
- data/Gemfile.lock +9 -9
- data/README.md +4 -4
- data/Rakefile +41 -28
- data/bench/bench_runner.rb +4 -5
- data/bench/benchapp/Gemfile +1 -1
- data/bench/benchapp/Gemfile.lock +26 -27
- data/bench/benchapp/config.ru +4 -0
- data/bench/benchapp/log/passenger.3000.log +1 -0
- data/bench/benchapp/log/passenger.9292.log +59 -0
- data/bench/benchapp/settings/settings.yml +2 -0
- data/bench/benchapp/tmp/pids/passenger.3000.pid.lock +0 -0
- data/bench/benchapp/tmp/pids/passenger.9292.pid.lock +0 -0
- data/bench/distr_bench/distr_bench +7 -0
- data/bench/distr_bench/distr_bench_main +99 -0
- data/bench/distr_bench/run_distr_client.sh +12 -0
- data/bench/distr_bench/run_test_query_script.sh +50 -0
- data/bench/lib/bench/bench_result_processor.rb +90 -0
- data/bench/lib/bench/cli.rb +35 -2
- data/bench/lib/bench/logging.rb +2 -0
- data/bench/lib/bench/runner.rb +4 -2
- data/bench/lib/bench/session.rb +3 -1
- data/bench/lib/bench/statistics.rb +41 -1
- data/bench/lib/bench/timer.rb +7 -0
- data/bench/lib/bench/utils.rb +8 -0
- data/bench/lib/bench.rb +35 -9
- data/bench/lib/testdata/0-data.txt +0 -0
- data/bench/lib/testdata/1-data.txt +0 -0
- data/bench/lib/testdata/10-data.txt +15 -0
- data/bench/lib/testdata/2-data.txt +3 -0
- data/bench/lib/testdata/25-data.txt +39 -0
- data/bench/lib/testdata/250-data.txt +353 -0
- data/bench/lib/testdata/3-data.txt +4 -0
- data/bench/lib/testdata/5-data.txt +7 -8
- data/bench/lib/testdata/50-data.txt +70 -0
- data/bench/lib/testdata/500-data.txt +711 -0
- data/bench/prepare_bench +45 -0
- data/bench/run_bench.sh +3 -3
- data/bench/run_blob_script.sh +1 -1
- data/bench/run_cud_script.sh +1 -1
- data/bench/run_query_md_script.sh +1 -1
- data/bench/run_query_only_script.sh +1 -1
- data/bench/run_query_script.sh +1 -1
- data/bench/run_test_query_script.sh +30 -0
- data/bench/run_test_source_script.sh +21 -0
- data/bench/scripts/test_query_script.rb +64 -0
- data/bench/scripts/test_source_script.rb +27 -0
- data/bin/rhoconnect-benchmark +13 -0
- data/doc/client-objc.txt +236 -1
- data/doc/client.txt +132 -0
- data/doc/extending-rhoconnect-server.txt +79 -0
- data/doc/install.txt +1 -1
- data/doc/java-plugin.txt +291 -0
- data/doc/rest-api.txt +3 -1
- data/installer/unix-like/create_texts.rb +73 -16
- data/installer/unix-like/pre_install.sh +1 -1
- data/installer/unix-like/rho_connect_install_constants.rb +1 -1
- data/installer/utils/constants.rb +2 -2
- data/installer/utils/nix_install_test.rb +85 -75
- data/installer/utils/package_upload/repos.rake +82 -2
- data/installer/windows/rhosync.nsi +5 -5
- data/lib/rhoconnect/api/application/queue_updates.rb +14 -0
- data/lib/rhoconnect/api/source/set_db_doc.rb +3 -1
- data/lib/rhoconnect/server.rb +9 -17
- data/lib/rhoconnect/version.rb +1 -1
- data/rhoconnect.gemspec +1 -1
- data/spec/api/admin/get_api_token_spec.rb +6 -0
- data/spec/api/source/set_db_doc_spec.rb +13 -0
- data/spec/server/server_spec.rb +27 -1
- data/tasks/redis.rake +2 -2
- metadata +73 -48
- data/examples/simple/dump.rdb +0 -0
- data/installer/utils/package_upload/repos.rb +0 -83
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'yaml'
|
|
4
|
+
require 'gruff'
|
|
5
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..','lib'))
|
|
6
|
+
require 'bench'
|
|
7
|
+
|
|
8
|
+
# 1) load all result YAML files
|
|
9
|
+
current_dir = Dir.pwd
|
|
10
|
+
results_dir = ARGV[0]
|
|
11
|
+
if results_dir.nil?
|
|
12
|
+
puts "Bench Result Processor: No result directory is provided - Skipping ..."
|
|
13
|
+
exit(1)
|
|
14
|
+
end
|
|
15
|
+
Dir.chdir results_dir
|
|
16
|
+
results_dir = Dir.pwd
|
|
17
|
+
|
|
18
|
+
Dir.chdir current_dir
|
|
19
|
+
output_dir = ARGV[1]
|
|
20
|
+
output_dir ||= 'images'
|
|
21
|
+
begin
|
|
22
|
+
Dir.mkdir output_dir
|
|
23
|
+
rescue
|
|
24
|
+
end
|
|
25
|
+
Dir.chdir output_dir
|
|
26
|
+
output_dir = Dir.pwd
|
|
27
|
+
|
|
28
|
+
# load meta.yaml
|
|
29
|
+
meta_hash = YAML.load_file("#{results_dir}/meta.yml") if File.exists?("#{results_dir}/meta.yml")
|
|
30
|
+
if meta_hash.nil?
|
|
31
|
+
puts "Bench Result Processor: No valid meta.yml file is found in the result directory - Skipping ..."
|
|
32
|
+
exit(1)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
@metrics = meta_hash[:metrics]
|
|
36
|
+
if @metrics.nil?
|
|
37
|
+
puts "Bench Result Processor: No valid metrics are found in the result directory - Skipping ..."
|
|
38
|
+
exit(1)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if meta_hash[:x_keys].nil?
|
|
42
|
+
puts "Bench Result Processor: No valid x_keys are found in the result directory - Skipping ..."
|
|
43
|
+
exit(1)
|
|
44
|
+
end
|
|
45
|
+
@x_keys = meta_hash[:x_keys].keys
|
|
46
|
+
@x_keys = @x_keys.sort_by(&Bench.sort_natural_order)
|
|
47
|
+
|
|
48
|
+
# initialize graphs for each metric
|
|
49
|
+
graphs = {}
|
|
50
|
+
title = meta_hash[:label]
|
|
51
|
+
@metrics.each do |name,index|
|
|
52
|
+
g = Gruff::Line.new
|
|
53
|
+
g.title = "#{title} (#{name})"
|
|
54
|
+
g.labels = meta_hash[:x_keys].invert
|
|
55
|
+
graphs[index] = g
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# load all result files
|
|
59
|
+
Dir.foreach(results_dir) do |entry|
|
|
60
|
+
begin
|
|
61
|
+
next unless entry =~ /bench.*result/
|
|
62
|
+
|
|
63
|
+
res_hash = YAML.load_file(File.join(results_dir, entry))
|
|
64
|
+
next if res_hash.nil? or res_hash.empty?
|
|
65
|
+
|
|
66
|
+
marker = entry.split('.').last.to_s
|
|
67
|
+
|
|
68
|
+
g_data = Array.new(@metrics.size) { Array.new }
|
|
69
|
+
@x_keys.each do |x_key|
|
|
70
|
+
results = res_hash[x_key]
|
|
71
|
+
results ||= Array.new(@metrics.size, 0.0)
|
|
72
|
+
results.each_with_index do |res, index|
|
|
73
|
+
g_data[index] << ("%0.4f" % res).to_f
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
graphs.each do |index, graph|
|
|
78
|
+
graph.data("#{marker}", g_data[index])
|
|
79
|
+
end
|
|
80
|
+
rescue Exception => e
|
|
81
|
+
puts " Benchmark processing resulted in Error : " + e.backtrace.join("\n")
|
|
82
|
+
throw e
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# write out resulting graphs
|
|
87
|
+
@metrics.each do |name, index|
|
|
88
|
+
puts "writing #{output_dir}/#{name}.png"
|
|
89
|
+
graphs[index].write "#{output_dir}/#{name}.png"
|
|
90
|
+
end
|
data/bench/lib/bench/cli.rb
CHANGED
|
@@ -4,12 +4,45 @@ module Bench
|
|
|
4
4
|
class Cli < Thor
|
|
5
5
|
include Logging
|
|
6
6
|
desc "start path/to/bench/script", "Start performance test"
|
|
7
|
-
def start(script,login,password='')
|
|
7
|
+
def start(script,login,password='',*params)
|
|
8
|
+
server = params[0] unless params[0].nil?
|
|
9
|
+
server ||= 'default'
|
|
10
|
+
if server != 'default'
|
|
11
|
+
Bench.base_url = server
|
|
12
|
+
end
|
|
13
|
+
Bench.result_filename = params[1] unless params[1].nil?
|
|
14
|
+
Bench.concurrency = params[2].to_i unless params[2].nil?
|
|
15
|
+
Bench.iterations = params[3].to_i unless params[3].nil?
|
|
16
|
+
Bench.datasize = params[4].to_i unless params[4].nil?
|
|
8
17
|
Bench.admin_login = login
|
|
9
18
|
Bench.admin_password = password
|
|
10
19
|
load(script)
|
|
11
20
|
Statistics.new(Bench.concurrency,Bench.iterations,
|
|
12
|
-
Bench.total_time,Bench.sessions).process.print_stats
|
|
21
|
+
Bench.total_time,Bench.start_time,Bench.end_time,Bench.sessions).process.print_stats.save_results
|
|
22
|
+
bench_log "Bench completed..."
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class DistributedCli < Thor
|
|
27
|
+
include Logging
|
|
28
|
+
desc "start path/to/bench/script", "Start performance test"
|
|
29
|
+
def start(script,login,password='',*params)
|
|
30
|
+
server = params[0] unless params[0].nil?
|
|
31
|
+
server ||= 'default'
|
|
32
|
+
if server != 'default'
|
|
33
|
+
Bench.base_url = server
|
|
34
|
+
end
|
|
35
|
+
Bench.sync_key = params[1] unless params[1].nil?
|
|
36
|
+
Bench.save_to_redis = true
|
|
37
|
+
Bench.processor_id = "#{Socket.gethostname}_#{Process.pid}"
|
|
38
|
+
Bench.concurrency = params[2].to_i unless params[2].nil?
|
|
39
|
+
Bench.iterations = params[3].to_i unless params[3].nil?
|
|
40
|
+
Bench.datasize = params[4].to_i unless params[4].nil?
|
|
41
|
+
Bench.admin_login = login
|
|
42
|
+
Bench.admin_password = password
|
|
43
|
+
load(script)
|
|
44
|
+
Statistics.new(Bench.concurrency,Bench.iterations,
|
|
45
|
+
Bench.total_time,Bench.start_time,Bench.end_time,Bench.sessions).process.print_stats.save_to_redis
|
|
13
46
|
bench_log "Bench completed..."
|
|
14
47
|
end
|
|
15
48
|
end
|
data/bench/lib/bench/logging.rb
CHANGED
data/bench/lib/bench/runner.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Bench
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def test(concurrency,iterations,&block)
|
|
13
|
-
|
|
13
|
+
total_times = times do
|
|
14
14
|
0.upto(concurrency - 1) do |thread_id|
|
|
15
15
|
sleep rand(2)
|
|
16
16
|
threads << Thread.new(block) do |t|
|
|
@@ -33,7 +33,9 @@ module Bench
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
Bench.sessions = @sessions
|
|
36
|
-
Bench.total_time =
|
|
36
|
+
Bench.total_time = total_times[0]
|
|
37
|
+
Bench.start_time = total_times[1]
|
|
38
|
+
Bench.end_time = total_times[2]
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
=begin
|
data/bench/lib/bench/session.rb
CHANGED
|
@@ -33,7 +33,9 @@ module Bench
|
|
|
33
33
|
result.last_response = send(verb,url,headers)
|
|
34
34
|
@last_result = result
|
|
35
35
|
end
|
|
36
|
-
|
|
36
|
+
if request_logging
|
|
37
|
+
bench_log "#{log_prefix} #{verb.to_s.upcase.gsub(/_/,'')} #{url} #{@last_result.code} #{result.time}"
|
|
38
|
+
end
|
|
37
39
|
rescue RestClient::Exception => e
|
|
38
40
|
result.error = e
|
|
39
41
|
bench_log "#{log_prefix} #{verb.to_s.upcase.gsub(/_/,'')} #{url}"
|
|
@@ -2,11 +2,13 @@ module Bench
|
|
|
2
2
|
class Statistics
|
|
3
3
|
include Logging
|
|
4
4
|
|
|
5
|
-
def initialize(concurrency,iterations,total_time,sessions)
|
|
5
|
+
def initialize(concurrency,iterations,total_time,start_time,end_time,sessions)
|
|
6
6
|
@sessions = sessions
|
|
7
7
|
@rows = {} # row key is result.marker;
|
|
8
8
|
@total_count = 0
|
|
9
9
|
@total_time = total_time
|
|
10
|
+
@start_time = start_time
|
|
11
|
+
@end_time = end_time
|
|
10
12
|
@concurrency,@iterations = concurrency,iterations
|
|
11
13
|
end
|
|
12
14
|
|
|
@@ -16,6 +18,8 @@ module Bench
|
|
|
16
18
|
results.each do |result|
|
|
17
19
|
@rows[result.marker] ||= {}
|
|
18
20
|
row = @rows[result.marker]
|
|
21
|
+
row[:times] ||= []
|
|
22
|
+
row[:times] << result.time
|
|
19
23
|
row[:min] ||= 0.0
|
|
20
24
|
row[:max] ||= 0.0
|
|
21
25
|
row[:count] ||= 0
|
|
@@ -43,14 +47,50 @@ module Bench
|
|
|
43
47
|
bench_log "Statistics:"
|
|
44
48
|
@rows.each do |marker,row|
|
|
45
49
|
bench_log "Request %-15s: min: %0.4f, max: %0.4f, avg: %0.4f, err: %d, verification err: %d" % [marker, row[:min], row[:max], average(row), row[:errors], row[:verification_errors]]
|
|
50
|
+
row[:times].sort!
|
|
51
|
+
[0.25, 0.50, 0.75, 0.9, 0.95].each do |p|
|
|
52
|
+
index = (p*(row[:times].size - 1) + 1).to_i
|
|
53
|
+
bench_log "\t#{p*100}% <= #{row[:times][index]}"
|
|
54
|
+
end
|
|
46
55
|
end
|
|
47
56
|
bench_log "State of MD : #{Bench.verify_error == 0 ? true : false}"
|
|
57
|
+
bench_log "Payload (#records) : #{Bench.datasize}" unless Bench.datasize.nil?
|
|
48
58
|
bench_log "Concurrency : #{@concurrency}"
|
|
49
59
|
bench_log "Iterations : #{@iterations}"
|
|
50
60
|
bench_log "Total Count : #{@total_count}"
|
|
51
61
|
bench_log "Total Time : #{@total_time}"
|
|
62
|
+
bench_log "Av.Time : #{average(@rows[Bench.main_marker])}" unless Bench.main_marker.nil?
|
|
52
63
|
bench_log "Throughput(req/s) : #{@total_count / @total_time}"
|
|
53
64
|
bench_log "Throughput(req/min): #{(@total_count / @total_time) * 60.0}"
|
|
65
|
+
self
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def save_results
|
|
69
|
+
return self if Bench.result_filename.nil?
|
|
70
|
+
|
|
71
|
+
res_hash = YAML.load_file(Bench.result_filename) if File.exist?(Bench.result_filename)
|
|
72
|
+
res_hash ||= {}
|
|
73
|
+
res_hash[@concurrency.to_s] = [@total_count/@total_time]
|
|
74
|
+
res_hash[@concurrency.to_s] << average(@rows[Bench.main_marker]) unless Bench.main_marker.nil?
|
|
75
|
+
File.open(Bench.result_filename, 'w' ) do |file|
|
|
76
|
+
file.write res_hash.to_yaml unless res_hash.empty?
|
|
77
|
+
end
|
|
78
|
+
self
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# save session times into redis doc
|
|
82
|
+
def save_to_redis
|
|
83
|
+
return self unless Bench.save_to_redis
|
|
84
|
+
|
|
85
|
+
stats = {}
|
|
86
|
+
throughput_data = {:start_time => @start_time.to_f,
|
|
87
|
+
:end_time => @end_time.to_f,
|
|
88
|
+
:count => @total_count}
|
|
89
|
+
times_data = @rows[Bench.main_marker][:times] unless Bench.main_marker.nil?
|
|
90
|
+
stats[Bench.processor_id] = {:payload => Bench.datasize, :times => times_data.join(',')}
|
|
91
|
+
stats[Bench.processor_id].merge!(throughput_data)
|
|
92
|
+
Bench.set_server_state("bench_statistics_data",stats,true)
|
|
93
|
+
self
|
|
54
94
|
end
|
|
55
95
|
end
|
|
56
96
|
end
|
data/bench/lib/bench/timer.rb
CHANGED
data/bench/lib/bench/utils.rb
CHANGED
|
@@ -2,6 +2,14 @@ module Bench
|
|
|
2
2
|
module Utils
|
|
3
3
|
include Logging
|
|
4
4
|
|
|
5
|
+
def sort_natural_order(nocase=false)
|
|
6
|
+
proc do |str|
|
|
7
|
+
i = true
|
|
8
|
+
str = str.upcase if nocase
|
|
9
|
+
str.gsub(/\s+/, '').split(/(\d+)/).map {|x| (i = !i) ? x.to_i : x}
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
5
13
|
def compare(name1,s1,name2,s2)
|
|
6
14
|
r1 = diff([],name1,s1,name2,s2)
|
|
7
15
|
r2 = diff([],name2,s2,name1,s1)
|
data/bench/lib/bench.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'rest_client'
|
|
2
|
-
require 'json'
|
|
3
2
|
require 'zip/zip'
|
|
4
3
|
$:.unshift File.dirname(__FILE__)
|
|
5
4
|
require 'bench/timer'
|
|
@@ -27,9 +26,13 @@ module Bench
|
|
|
27
26
|
|
|
28
27
|
attr_accessor :concurrency, :iterations, :admin_login
|
|
29
28
|
attr_accessor :admin_password, :user_name
|
|
30
|
-
attr_accessor :password, :
|
|
29
|
+
attr_accessor :password, :base_url, :host, :token
|
|
31
30
|
attr_accessor :total_time, :sessions, :verify_error
|
|
32
|
-
attr_accessor :adapter_name
|
|
31
|
+
attr_accessor :adapter_name, :datasize, :result_filename
|
|
32
|
+
attr_accessor :main_marker, :start_time, :end_time
|
|
33
|
+
|
|
34
|
+
# these attributes for distributed testing
|
|
35
|
+
attr_accessor :processor_id, :save_to_redis, :sync_key
|
|
33
36
|
|
|
34
37
|
def config
|
|
35
38
|
begin
|
|
@@ -41,13 +44,30 @@ module Bench
|
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
|
|
47
|
+
def synchronize
|
|
48
|
+
begin
|
|
49
|
+
yield self
|
|
50
|
+
rescue Exception => e
|
|
51
|
+
puts "error in synchronize: #{e.inspect}"
|
|
52
|
+
raise e
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
44
56
|
def get_server_state(doc)
|
|
45
57
|
token = get_token
|
|
58
|
+
params = {:api_token => token, :doc => doc}
|
|
46
59
|
@body = RestClient.post("#{@host}/api/source/get_db_doc",
|
|
47
|
-
|
|
60
|
+
params.to_json, :content_type => :json)
|
|
48
61
|
JSON.parse(@body.to_s)
|
|
49
62
|
end
|
|
50
63
|
|
|
64
|
+
def get_server_value(doc)
|
|
65
|
+
token = get_token
|
|
66
|
+
params = {:api_token => token, :doc => doc, :data_type => 'string'}
|
|
67
|
+
@body = RestClient.post("#{@host}/api/source/get_db_doc",
|
|
68
|
+
params.to_json, :content_type => :json)
|
|
69
|
+
end
|
|
70
|
+
|
|
51
71
|
def reset_app
|
|
52
72
|
RestClient.post("#{@host}/api/admin/reset",{:api_token => get_token}.to_json, :content_type => :json)
|
|
53
73
|
end
|
|
@@ -60,10 +80,14 @@ module Bench
|
|
|
60
80
|
:content_type => :json)
|
|
61
81
|
end
|
|
62
82
|
|
|
63
|
-
def set_server_state(doc,data)
|
|
83
|
+
def set_server_state(doc,data,append=false)
|
|
64
84
|
token = get_token
|
|
85
|
+
params = {:api_token => token, :doc => doc, :data => data, :append => append}
|
|
86
|
+
if data.is_a? String
|
|
87
|
+
params[:data_type] = 'string'
|
|
88
|
+
end
|
|
65
89
|
RestClient.post("#{@host}/api/source/set_db_doc",
|
|
66
|
-
|
|
90
|
+
params.to_json, :content_type => :json)
|
|
67
91
|
end
|
|
68
92
|
|
|
69
93
|
def reset_refresh_time(source_name,poll_interval=nil)
|
|
@@ -84,9 +108,11 @@ module Bench
|
|
|
84
108
|
end
|
|
85
109
|
|
|
86
110
|
def get_test_server(app_name = nil)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
111
|
+
if @base_url.nil?
|
|
112
|
+
app_name = 'benchapp' unless app_name
|
|
113
|
+
load_settings(File.join(File.dirname(__FILE__),'..',app_name,'settings','settings.yml'))
|
|
114
|
+
@base_url = $settings[:development][:syncserver].gsub(/\/$/,'')
|
|
115
|
+
end
|
|
90
116
|
uri = URI.parse(@base_url)
|
|
91
117
|
port = (uri.port and uri.port != 80) ? ":"+uri.port.to_s : ""
|
|
92
118
|
@host = "#{uri.scheme}://#{uri.host}#{port}"
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{"%ba6ae657fdb945dbb31a9e88901c34e3{"
|
|
2
|
+
Email"collin@hotmail.com"%ec3b697c638f451f91271f15a162d4c4{@" Mraz@
|
|
3
|
+
"Distribution Worker@"
|
|
4
|
+
Jessy@"254-249-0520 x823@"Morar, Turner and Witting@"%ec3b697c638f451f91271f15a162d4c4@"wilfred@gmail.com"%433f0607f695480ca8fb2ed62288274b{@"
|
|
5
|
+
"Technical Vice President@"Leilani@"609.739.2116 x33454@"
|
|
6
|
+
"Banking Superintendent@"Heaven@"(205)937-2087@"Williamson Inc@"%8c115ca8f13e4dabb5bdf9bd49ae09f7@"stan@gmail.com"%8714f3ee057a4f81907e23b2ae861a41{@"Stanton@
|
|
7
|
+
"Chief Mechanic@"Priscilla@"(049)684-9908@"McGlynn-Paucek@"%8714f3ee057a4f81907e23b2ae861a41@"edgar@hotmail.com"%4d9d94c8c89e45f19e6f526d0e325da8{@"
|
|
8
|
+
Lesch@
|
|
9
|
+
"Electronics Nurse@"
|
|
10
|
+
"Quality Assurance Director@"Nia@"263-570-9397@"Braun Inc@"%fe2b4da2487e43eab2c51937867c0038@"ora.hackett@hotmail.com"%d1329cb0bda747a8a3027cde2bfb0a2c{@"Sporer@
|
|
11
|
+
"Head Technologist@"
|
|
12
|
+
Issac@"(604)041-1675 x977@"Stroman Inc@"%d1329cb0bda747a8a3027cde2bfb0a2c@"mozell@hotmail.com"%5d0c8ab731d3455baf098cfa4520b725{@"Padberg@
|
|
13
|
+
"Administrative Mechanic@"
|
|
14
|
+
Tyler@"(184)117-5343 x276@"Brown-Jacobson@"%5d0c8ab731d3455baf098cfa4520b725@"janelle@hotmail.com"%ff296946a04647d7ad8cad315a370d88{@"Volkman@
|
|
15
|
+
"&Advertising Production Supervisor@"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{"%745f7eba5bdc4b5394d86704bdbb13f8{"
|
|
2
|
+
Email"mya.welch@gmail.com"%b7b55988f2ba48089846d51fa29ccd3d{@"Jacobi@
|
|
3
|
+
"Laboratory Clerk@"Buford@"395-947-1236@"Abbott, Mann and Casper@"%b7b55988f2ba48089846d51fa29ccd3d@"thora_beatty@yahoo.com"%72833fead8b8438b9da511601cc2bea9{@"Hilpert@
|
|
4
|
+
"Distribution Planner@"
|
|
5
|
+
Cesar@"845-974-3924@"Crooks and Sons@"%72833fead8b8438b9da511601cc2bea9@"jacynthe.erdman@gmail.com"%2b9d52a78eac41be91184d5c90f1a71a{@"Kerluke@
|
|
6
|
+
"Production Technologist@"Marcellus@"462.764.4095 x0038@"!Hermann, Stanton and Stroman@"%2b9d52a78eac41be91184d5c90f1a71a@"layne@gmail.com"%0743364453504b91bb747790ac67cfaa{@"
|
|
7
|
+
"Maintenance Supervisor@"Vivian@"748-079-4465@"Weissnat LLC@"%0743364453504b91bb747790ac67cfaa@"napoleon.beier@hotmail.com"%313ff12bbdf847ff9ae46196361c6a06{@"
|
|
8
|
+
Wolff@
|
|
9
|
+
"%Quality Assurance Superintendent@" Judy@"1-646-220-9427@"Pagac, Kshlerin and Jast@"%313ff12bbdf847ff9ae46196361c6a06@"#constantin_lockman@hotmail.com"%719c6bda435f4402ae054e00a5488ec0{@"Kemmer@
|
|
10
|
+
"Chief Supervisor@"Mozell@"1-687-357-4506 x2642@"Becker LLC@"%719c6bda435f4402ae054e00a5488ec0@"mossie@hotmail.com"%f60acc705f774a7db82614a8379aaf89{@"Durgan@
|
|
11
|
+
"#Computer Production Supervisor@" Emma@"(807)711-1773@"O'Kon-Ernser@"%f60acc705f774a7db82614a8379aaf89@"maybelle@gmail.com"%677e0cb3e4774214891a75ce8c7d2186{@"
|
|
12
|
+
Ebert@
|
|
13
|
+
"Medical Helper@"Adaline@"1-829-209-7633@"
|
|
14
|
+
"Maintenance Mechanic@"
|
|
15
|
+
Keith@"238-580-8865 x3897@"Kuphal-Kautzer@"%a18a521497ba470fbc33105a411f8086@"grover@gmail.com"%11774584e300418fa7e756ab019653f8{@" Hane@
|
|
16
|
+
",Quality Assurance Production Supervisor@"
|
|
17
|
+
Zoila@"1-874-687-3044@"Morar-Schmitt@"%11774584e300418fa7e756ab019653f8@" daphney_mueller@hotmail.com"%34e7aa9a287d456f9039b319286dc5fb{@"Douglas@
|
|
18
|
+
"Financial Director@"Damian@"915.644.9796 x73099@"Glover, Hand and Lueilwitz@"%34e7aa9a287d456f9039b319286dc5fb@"luz.nicolas@yahoo.com"%579b4154f352499fbbbd94a9dbf74123{@"
|
|
19
|
+
"Assistant Director@"Yolanda@"(149)019-1565@"Kling, DuBuque and Fahey@"%579b4154f352499fbbbd94a9dbf74123@" joanie_thompson@hotmail.com"%40ec578ade8b47d7afb021ee76a9918a{@" Lang@
|
|
20
|
+
" Quality Assurance Executive@" Lula@"1-027-576-0242 x26553@"Rempel Inc@"%40ec578ade8b47d7afb021ee76a9918a@"peter@gmail.com"%1374a69e9cb44e5d8a9718afef48319e{@"Abernathy@
|
|
21
|
+
"!Environmental Superintendent@"Thelma@"681.351.3293@"%Williamson, Schmeler and Reichel@"%1374a69e9cb44e5d8a9718afef48319e@"ryann@gmail.com"%04976051884044b3898b432df5bf5d2c{@"Douglas@
|
|
22
|
+
"Banking Engineer@"Meghan@"179-501-0324@"!Schaefer, Bogisich and Bogan@"%04976051884044b3898b432df5bf5d2c@"collin_halvorson@yahoo.com"%f0f02fad738442168cca3c86e759b523{@"Ankunding@
|
|
23
|
+
"Maintenance Foreman@" Sean@"1-841-705-6222@"Runolfsdottir-Vandervort@"%f0f02fad738442168cca3c86e759b523@" lauretta_glover@hotmail.com"%76f4ec2512b646a8ac9bbd858bd97461{@"Legros@
|
|
24
|
+
"Production Helper@"
|
|
25
|
+
Marta@"(113)776-0880 x1162@"Cummerata Group@"%76f4ec2512b646a8ac9bbd858bd97461@"jacky_ernser@yahoo.com"%28d1f8d66d6442388d4877414365696a{@"VonRueden@
|
|
26
|
+
"Electronics Clerk@"
|
|
27
|
+
Fiona@"(520)711-6249 x75737@"Borer, Lemke and Schuppe@"%28d1f8d66d6442388d4877414365696a@"bennie@hotmail.com"%e7104e868fd74ef9a2863cc24459a1c9{@"Zemlak@
|
|
28
|
+
"Distribution Supervisor@"Hester@"743-122-4646 x2642@"Daugherty Group@"%e7104e868fd74ef9a2863cc24459a1c9@"shaina.jenkins@gmail.com"%0c83cd53e06b4eac8312463bae2e1663{@"
|
|
29
|
+
Ortiz@
|
|
30
|
+
"Assistant Technician@"
|
|
31
|
+
"General Recruiter@"Danial@"1-651-973-7918 x6691@"Gaylord LLC@"%f636bcdd6af841269dd63d3d6ccc1f79@"pearl@gmail.com"%d15e38056def43d8ae7d3f233bcb6abc{@"
|
|
32
|
+
Terry@
|
|
33
|
+
"Distribution Helper@"
|
|
34
|
+
Juana@"(870)146-6842 x777@"'Schuppe, Wintheiser and Hodkiewicz@"%d15e38056def43d8ae7d3f233bcb6abc@"raheem@gmail.com"%e0a892ff16a544f4b6d510b017448386{@"
|
|
35
|
+
Welch@
|
|
36
|
+
"Chief Buyer@"Jay@"(544)927-7766@"Bins-Beer@"%e0a892ff16a544f4b6d510b017448386@"neal.wyman@hotmail.com"%708d263cde3d456895b554a784b15b33{@"
|
|
37
|
+
Hintz@
|
|
38
|
+
"Production Vice President@"
|
|
39
|
+
Aylin@"214-142-6776 x691@" Luettgen, Volkman and Bosco@"%708d263cde3d456895b554a784b15b33@"malika@gmail.com
|