1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
require 'zip'
class JobEvent
include VipPack
def initialize
@ecs=HttpEcs.instance
end
##
# Process a *sys/events* job event.
# This is the entrypoint of job event processing.
def process(jobevbody)
Rails.logger.info "***** JobEvent#process: eventbody=#{jobevbody}"
case jobevbody[0]['status']
when "created","updated"
jobr= @ecs.connection[jobevbody[0]['ressource']].delete
job_headers= jobr.headers
job=JSON.parse(jobr)
Rails.logger.info "***** JobEvent#process: EvaluationJob: #{JSON.pretty_generate(job)}"
exercise = JSON.parse fetch_exercise(job)
evaluation = JSON.parse fetch_evaluation(job)
solution = JSON.parse fetch_solution(job)
exercise,solution = merge(exercise, evaluation, solution, job, job_headers)
computation_backend = job["EvaluationJob"]["target"]["mid"]
compute(exercise, solution, computation_backend)
end
end
private
##
# Fetch an exercise from ECS.
def fetch_exercise(job)
# URI#path returns the path with leading "/"
/#{APP_CONFIG["resources"]["exercises"]["name"]}.*$/ =~ URI(job["EvaluationJob"]["resources"]["exercise"]).path[1..-1]
path = $~.to_s
Rails.logger.info "***** JobEvent#fetch_exercise: exercise path #{path}"
exercise= @ecs.connection[path].delete
exercise = unpack(exercise.body) if packed?(exercise.body)
Rails.logger.info "***** JobEvent#fetch_exercise: #{path} = #{exercise}"
exercise
end
##
# Fetch an evaluation from ECS.
def fetch_evaluation(job)
# URI#path returns the path with leading "/"
/#{APP_CONFIG["resources"]["evaluations"]["name"]}.*$/ =~ URI(job["EvaluationJob"]["resources"]["evaluation"]).path[1..-1]
path = $~.to_s
evaluation= @ecs.connection[path].delete
evaluation = unpack(evaluation.body) if packed?(evaluation.body)
Rails.logger.info "***** JobEvent#fetch_evaluation: #{path} = #{evaluation}"
evaluation
end
##
# Fetch a solution from ECS.
def fetch_solution(job)
# URI#path returns the path with leading "/"
/#{APP_CONFIG["resources"]["solutions"]["name"]}.*$/ =~ URI(job["EvaluationJob"]["resources"]["solution"]).path[1..-1]
path = $~.to_s
solution= @ecs.connection[path].delete
solution = unpack(solution.body) if packed?(solution.body)
Rails.logger.info "***** JobEvent#fetch_solution: #{path} = #{solution}"
solution
end
##
# Substitute evaluation code snippets with appropriate exercise code
# snippets.
def merge(exercise, evaluation, solution, job, job_headers)
jobid= job["EvaluationJob"]["identifier"]
job_sender= job_headers[:x_ecssender]
evaluation["Evaluation"]["elements"].each do |ev|
exercise["Exercise"]["elements"].map! do |ex|
if ex["identifier"] == ev["identifier"]
ex=ev
else
ex
end
end
end
solution["Solution"]["evaluationService"]= { :jobID => jobid, :jobSender => job_sender }
Rails.logger.info "***** JobEvent#merge exercise: #{exercise.to_json}"
Rails.logger.info "***** JobEvent#merge solution: #{solution.to_json}"
return exercise, solution
end
##
# Calls the computation backend with membership_id *mid*.
def compute(exercise, solution, mid)
response= @ecs.connection[APP_CONFIG["resources"]["exercises"]["name"]].post exercise.to_json, {"X-EcsReceiverMemberships" => mid}
solution["Solution"]["exercise"]= response.headers[:location]
Rails.logger.info "***** JobEvent#compute substitute exersice URL in solution to: #{solution["Solution"]["exercise"]}"
if exercise["Exercise"]["routing"]
routing_path = APP_CONFIG["resources"]["servicename"]+"/"+exercise["Exercise"]["routing"]["solutionQueue"]
else
routing_path = APP_CONFIG["resources"]["solutions"]["name"]
end
Rails.logger.info "***** JobEvent#compute routing path for solution: #{routing_path}"
@ecs.connection[routing_path].post solution.to_json, {"X-EcsReceiverMemberships" => mid} do |response, request, result|
Rails.logger.info "***** JobEvent#compute solution post response: #{response.headers}"
end
end
end
|