Name: simulation/lib/standalone.rb 
1:
#!/usr/bin/ruby
2:
require 'xml/smart'
3:
require 'xmlsimple'
4:
require 'riddl/client'
5:
require 'json'
6:
require 'chronic_duration'
7:
require 'time'
8:
require 'pp'
9:
require File.expand_path(File.dirname(__FILE__) + '/expectations')
10:
require File.expand_path(File.dirname(__FILE__) + '/result')
11:
 
12:
$dir = File.dirname(__FILE__) + "/../instances/#{ARGV[0]}"
13:
unless File.exists?($dir + "/model")
14:
  puts "This instance/simulation is not available!"
15:
  exit
16:
end
17:
 
18:
### expected.txt
19:
 
20:
s = Expectations.new($dir + "/model")
21:
tree = s.tree
22:
traces = s.traces
23:
 
24:
expected = ''
25:
expected << tree.to_s
26:
 
27:
ctraces = traces.calculate.sort{|a,b| b.probability <=> a.probability}
28:
ctraces.each_with_index do |t,i|
29:
  expected << "\n"
30:
  expected << "Trace #{i}: " << t.trace.inspect << "\n"
31:
  expected << "Expected Probability: #{"%0.2f" % t.probability}" << "\n"
32:
  expected << "Expected Duration:" << "\n"
33:
  expected << "  Min.: #{ChronicDuration.output(t.min_time)}" << "\n"
34:
  expected << "  Avg.: #{ChronicDuration.output(t.avg_time)}" << "\n"
35:
  expected << "  Max.: #{ChronicDuration.output(t.max_time)}" << "\n"
36:
end
37:
File.write($dir + "/expectations.txt", expected)
38:
 
39:
### result.txt
40:
 
41:
result = Result::askForInput("Offset",File.read(File.dirname(__FILE__) + "/../resources/offset.txt"),"Offset:")
42:
meta = JSON.parse(File.read($dir + "/meta"))
43:
meta['offset'] = result
44:
File.write($dir + "/meta",JSON.generate(meta))
45:
 
46:
### Move this to helpers.rb #forecast
47:
### workaround for now, as we don't have built in simulation
48:
xmpp = Riddl::Client.interface('xmpp://[email protected]', ::File.dirname(__FILE__) + '/../simulation_gateway.xml', :jid => 'jü[email protected]', :pass => 'mangler')
49:
 
50:
### Simulation
51:
resultoftraces = []
52:
meta = JSON.parse(File.read($dir + "/meta"))
53:
### each trace according to importance
54:
ctraces.each_with_index do |ct,i|
55:
  ### each activity according to order
56:
  offset = meta['offset'].strip == '' ? 0 : ChronicDuration.parse(meta['offset'])
57:
  offset = 0 if offset.nil?
58:
  resultoftraces[i] = ResultTreeNode.new("◯","Start",nil,{},{},offset,offset,offset,0,0,0,100)
59:
  resulttreenode = resultoftraces[i]
60:
  XML::Smart.open($dir + '/endpoints').find('/xmlns:value/xmlns:*').each do |k|
61:
    resulttreenode.endpoints[k.qname.name] = k.text
62:
  end
63:
 
64:
  ct.trace.each do |a|
65:
    resulttreenode.each_leaf do |tn|
66:
      case a.type
67:
        when :manipulate
68:
          success, dataelements, endpoints = Result::manipulate(tn.dataelements,tn.endpoints,{},a)
69:
          if success
70:
            tn << ResultTreeNode.new(a.tid,"successfully executed script task #{a.to_s_nice}",nil,dataelements,endpoints,tn.start_min,tn.start_avg,tn.start_max,0,0,0,100)
71:
          else
72:
            tn << ResultTreeNode.new(a.tid,"failed to executed script task #{a.to_s_nice}",nil,tn.dataelements,tn.endpoints,tn.start_min,tn.start_avg,tn.start_max,0,0,0,100)
73:
          end
74:
        when :call
75:
          tnc = []
76:
          a.endpoints.each_with_index do |ep,i|
77:
            ts = tn.start_min + tn.min
78:
            ta = tn.start_avg + tn.avg
79:
            tm = tn.start_max + tn.max
80:
            status, result = Result::forecast(xmpp,tn.dataelements,tn.endpoints,ep,a,ts,ta,tm)
81:
            if status == 200
82:
              result.each do |res,det|
83:
                success, tde, tep = Result::manipulate(tn.dataelements,tn.endpoints,res,a)
84:
                if success
85:
                  tnc << ResultTreeNode.new("#{a.tid}","successful forecast for task #{a.to_s_nice}",ep,tde,tep,ts,ta,tm,det[:min],det[:avg],det[:max],det[:prob])
86:
                else
87:
                  tnc << ResultTreeNode.new("#{a.tid}","unsuccessful forecast for task #{a.to_s_nice}",ep,tn.dataelements,tn.endpoints,ts,ta,tm,det[:min],det[:avg],det[:max],det[:prob])
88:
                end
89:
              end  
90:
            else
91:
              tnc << ResultTreeNode.new("#{a.tid}","forecast for task #{a.to_s_nice} failed",ep,tn.dataelements,tn.endpoints,ts,ta,tm,a.min,a.avg,a.max,100)
92:
            end  
93:
          end
94:
          ### Remove duplicate results, even when they come from different partners, for optimum performance
95:
          ### Results are unique, when they produce different dataflow, or have different probabilities to occur
96:
          tnc = tnc.reduce([]) do |memo,tc|
97:
            success = false
98:
            memo.each do |e|
99:
              if e.dataelements == tc.dataelements && e.prob == tc.prob
100:
                e.endpoint << ", #{tc.endpoint}"
101:
                success = true
102:
              end  
103:
            end
104:
            memo << tc unless success
105:
            memo
106:
          end
107:
          tnc.each { |tc| tn << tc }
108:
      end
109:
 
110:
      ### write temporary output to result.txt
111:
      obtained = ""
112:
      resultoftraces.each_with_index do |t,i|
113:
        obtained << "\n"
114:
        obtained << "Trace #{i}: #{ctraces[0].trace.to_s}\n\n"
115:
        obtained << t.to_s
116:
      end
117:
      File.write($dir + "/result.txt", obtained)
118:
 
119:
    end  
120:
  end
121:
end
122:
 
123:
Result::finish