[Pydev-cvs] awb/src/Python/ruleEngine/acme_scripting/src/lib/cougaar experiment.rb,NONE,1.1 py_socie
Brought to you by:
fabioz
From: Dana M. <dan...@us...> - 2004-08-25 21:03:55
|
Update of /cvsroot/pydev/awb/src/Python/ruleEngine/acme_scripting/src/lib/cougaar In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30772/src/Python/ruleEngine/acme_scripting/src/lib/cougaar Added Files: experiment.rb py_society_builder.rb scripting.rb society_builder.rb society_control.rb society_model.rb society_rule_engine.rb society_utils.rb Log Message: wholesale commit --- NEW FILE: society_control.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * </copyright> =end module Cougaar class NodeController def initialize(run, timeout, debug) @run = run @debug = debug @timeout = timeout @pids = {} @run['pids'] = @pids end def add_cougaar_event_params @xml_model = @run["loader"] == "XML" @node_type = "" @node_type = "xml_" if @xml_model @run.society.each_active_host do |host| host.each_node do |node| node.add_parameter("-Dorg.cougaar.event.host=127.0.0.1") node.add_parameter("-Dorg.cougaar.event.port=5300") node.add_parameter("-Dorg.cougaar.event.experiment=#{@run.comms.experiment_name}") end end end def start_all_nodes(action) nodes = [] @run.society.each_active_host do |host| host.each_node do |node| nameserver = false host.each_facet(:role) do |facet| nameserver = true if facet[:role].downcase=="nameserver" end if nameserver nodes.unshift node else nodes << node end end end msgs = {} nodes.each do |node| if @xml_model post_node_xml(node) msgs[node] = launch_xml_node(node) else msgs[node] = launch_db_node(node) end end nodes.each do |node| @run.info_message "Sending message to #{node.host.name} -- [command[start_#{@node_type}node]#{msgs[node]}] \n" if @debug result = @run.comms.new_message(node.host).set_body("command[start_#{@node_type}node]#{msgs[node]}").request(@timeout) if result.nil? @run.error_message "Could not start node #{node.name} on host #{node.host.host_name}" else @pids[node.name] = result.body node.active=true end end end def stop_all_nodes(action) nameserver_nodes = [] @run.society.each_host do |host| host.each_node do |node| nameserver = false host.each_facet(:role) do |facet| if facet[:role].downcase=="nameserver" nameserver_nodes << node nameserver = true end end stop_node(node) unless nameserver end end nameserver_nodes.each { |node| stop_node(node) } @pids.clear end def stop_node(node) host = node.host @run.info_message "Sending message to #{host.name} -- command[stop_#{@node_type}node]#{@pids[node.name]} \n" if @debug result = @run.comms.new_message(host).set_body("command[stop_#{@node_type}node]#{@pids[node.name]}").request(60) if result.nil? @run.info_message "Could not stop node #{node.name}(#{@pids[node.name]}) on host #{host.host_name}" else node.active=false end end def restart_node(action, node) if @xml_model msg_body = launch_xml_node(node, "xml") else msg_body = launch_db_node(node) end @run.info_message "RESTART: Sending message to #{node.host.name} -- [command[start_#{@node_type}node]#{msg_body}] \n" if @debug result = @run.comms.new_message(node.host).set_body("command[start_#{@node_type}node]#{msg_body}").request(@timeout) if result.nil? @run.error_message "Could not start node #{node.name} on host #{node.host.host_name}" else node.active = true @pids[node.name] = result.body end end def kill_node(action, node) pid = @pids[node.name] if pid @pids.delete(node.name) @run.info_message "KILL: Sending message to #{node.host.name} -- command[stop_#{@node_type}node]#{pid} \n" if @debug result = @run.comms.new_message(node.host).set_body("command[stop_#{@node_type}node]#{pid}").request(60) if result.nil? @run.error_message "Could not kill node #{node.name}(#{pid}) on host #{node.host.host_name}" else node.active = false node.agents.each do |agent| agent.set_killed end end else @run.error_message "Could not kill node #{node.name}...node does not have an active PID." end end def launch_db_node(node) return node.parameters.join("\n") end def launch_xml_node(node, kind='rb') return node.name+".#{kind}" end def post_node_xml(node) node_society = Cougaar::Model::Society.new( "society-for-#{node.name}" ) do |society| society.add_host( node.host.name ) do |host| host.add_node( node.clone(host) ) end end node_society.remove_all_facets result = Cougaar::Communications::HTTP.post("http://#{node.host.uri_name}:9444/xmlnode/#{node.name}.rb", node_society.to_ruby, "x-application/ruby") @run.info_message result if @debug end end module Actions class KeepSocietySynchronized < Cougaar::Action PRIOR_STATES = ["CommunicationsRunning"] RESULTANT_STATE = "SocietyRunning" DOCUMENTATION = Cougaar.document { @description = "Maintain a synchronization of Agents-Nodes-Hosts from Lifecycle CougaarEvents." @example = "do_action 'KeepSocietySynchronized'" } def perform @run.comms.on_cougaar_event do |event| if event.component=="SimpleAgent" || event.component=="ClusterImpl" || event.component=="Events" match = /.*AgentLifecycle\(([^\)]*)\) Agent\(([^\)]*)\) Node\(([^\)]*)\) Host\(([^\)]*)\)/.match(event.data) if match cycle, agent_name, node_name, host_name = match[1,4] if cycle == "Started" && @run.society.agents[agent_name] node = @run.society.agents[agent_name].node @run.society.agents[agent_name].set_running if node_name != node.name @run.society.agents[agent_name].move_to(node_name) @run.info_message "Moving agent: #{agent_name} to node: #{node_name}" # If the agent wasn't moved but actually restarted, # then it might still exist on the old Node. This blocks # quiescence and can use up memory. # Get it out of the quiescence-way - ubug 13539 # Note that this is not needed. The removing # of the agent below triggers a checkQuiescence itself # result = Cougaar::Communications::HTTP.get("#{node.uri}/agentQuiescenceState?dead=#{agent_name}", 60) # Remove it to free up resources - See ubug 13550 Thread.new(node.uri, node.name, agent_name) do |uri, node_name, agent| result = Cougaar::Communications::HTTP.get("#{uri}/move?op=Remove&mobileAgent=#{agent}&destNode=#{node_name}&action=Add", 60) end # FIXME: look at the result to see if this actually did something # If it did, log that fact # Note that you have to poll the /move servlet as it # works asynchronously. Get the UID out of the first # result (the one marked In Progress), and then look for # DOES_NOT_EXIST vs SUCCESSFUL or REMOVED later end end end end end end end class LogCougaarEvents < Cougaar::Action PRIOR_STATES = ["CommunicationsRunning"] DOCUMENTATION = Cougaar.document { @description = "Send all CougaarEvents to the run.log." @example = "do_action 'LogCougaarEvents'" } def perform @run.comms.on_cougaar_event do |event| ::Cougaar.logger.info event.to_s end end end class LoadComponent < Cougaar::Action PRIOR_STATES = ["SocietyRunning"] DOCUMENTATION = Cougaar.document { @description = "Adds or removes a component to/from an agent" @parameters = [ {:agentname=> "Name of the agent to add the component to"}, {:action=> "add or remove"}, {:component=>"the component"} ] @example = "do_action 'LoadComponent', '1-AD', 'add', 'org.cougaar.logistics.plugin.trans.RescindWatcher'" } def initialize(run, agentname, action, classname) super(run) @agentname = agentname @action = action @classname = classname end def perform @run.society.each_agent do |agent| if @agentname == agent.name then data, uri = Cougaar::Communications::HTTP.get("#{agent.uri}/load?op=#{@action}&insertionPoint=Node.AgentManager.Agent.PluginManager.Plugin&classname=#{@classname}", 60) end end end end class StartSociety < Cougaar::Action PRIOR_STATES = ["CommunicationsRunning"] RESULTANT_STATE = "SocietyRunning" DOCUMENTATION = Cougaar.document { @description = "Start a society from XML or CSmart." @parameters = [ {:timeout => "default=120, Number of seconds to wait to start each node before failing."}, {:debug => "default=false, If true, outputs messages sent to start nodes."} ] @example = "do_action 'StartSociety', 300, true" } def initialize(run, timeout=120, debug=false) super(run) unless timeout.kind_of?(Numeric) && (debug==true || debug==false) raise_failure "StartSociety usage: do_action 'StartSociety', timeout (default 120), debug (default false)" end @run['node_controller'] = ::Cougaar::NodeController.new(run, timeout, debug) end def perform time = Time.now.gmtime @run.society.each_node do |node| node.replace_parameter(/Dorg.cougaar.core.society.startTime/, "-Dorg.cougaar.core.society.startTime=\"#{time.strftime('%m/%d/%Y %H:%M:%S')}\"") end @run['node_controller'].add_cougaar_event_params @run['node_controller'].start_all_nodes(self) @run.add_to_interrupt_stack do do_action "StopSociety" end end end class StopSociety < Cougaar::Action PRIOR_STATES = ["SocietyRunning"] RESULTANT_STATE = "SocietyStopped" DOCUMENTATION = Cougaar.document { @description = "Stop a running society." @example = "do_action 'StopSociety'" } def perform @run['node_controller'].stop_all_nodes(self) end end class RestartNodes < Cougaar::Action PRIOR_STATES = ["SocietyRunning"] DOCUMENTATION = Cougaar.document { @description = "Restarts stopped node(s)." @parameters = [ :nodes => "*parameters, The list of nodes to restart" ] @example = "do_action 'RestartNodes', 'FWD-A', 'FWD-B'" } def initialize(run, *nodes) super(run) @nodes = nodes end def to_s return super.to_s+"(#{@nodes.join(', ')})" end def perform @nodes.each do |node| cougaar_node = @run.society.nodes[node] if cougaar_node @run['node_controller'].restart_node(self, cougaar_node) else @run.error_message "Cannot restart node #{node}, node unknown." end end end end class KillNodes < Cougaar::Action PRIOR_STATES = ["SocietyRunning"] DOCUMENTATION = Cougaar.document { @description = "Kills running node(s)." @parameters = [ :nodes => "*parameters, The list of nodes to kill" ] @example = "do_action 'KillNodes', 'FWD-A', 'FWD-B'" } def initialize(run, *nodes) super(run) @nodes = nodes end def to_s return super.to_s+"(#{@nodes.join(', ')})" end def perform @nodes.each do |node| cougaar_node = @run.society.nodes[node] if cougaar_node @run['node_controller'].kill_node(self, cougaar_node) else @run.error_message "Cannot kill node #{node}, node unknown." end end end end class MoveAgent < Cougaar::Action PRIOR_STATES = ["SocietyRunning"] DOCUMENTATION = Cougaar.document { @description = "Moves an Agent from its current node to the supplied node." @parameters = [ {:agent => "String, The name of the Agent to move."}, {:node => "String, The name of the Node to move the agent to."} ] @example = "do_action 'MoveAgent', '1-35-ARBN', 'FWD-B'" } def initialize(run, agent, node) super(run) @agent = agent @node = node end def perform # example format of move http request # http://sv116:8800/$1-35-ARBN/move?op=Move&mobileAgent=1-35-ARBN&originNode=&destNode=FWD-D&isForceRestart=false&action=Add # begin # First do a bunch of error checking if (@run.society.nodes[@node] == nil) @run.info_message "No node #{@node} to move #{@agent} to!" elsif (@run.society.agents[@agent] == nil) @run.info_message "No agent #{@agent} in society to move to #{@node}!" else # Could (should?) also check if the agent is already on the named node # Note we could ask the Node to move the agent, to avoid any timing issues. But that # seems to leave ugly WARNs and ERRORs in the logs that have no real harm # uri = "#{@run.society.agents[@agent].node.uri}/move?op=Move&mobileAgent=#{@agent}&originNode=&destNode=#{@node}&isForceRestart=false&action=Add" uri = "#{@run.society.agents[@agent].uri}/move?op=Move&mobileAgent=#{@agent}&originNode=&destNode=#{@node}&isForceRestart=false&action=Add" result = Cougaar::Communications::HTTP.get(uri) unless result @run.error_message "Error moving agent #{@agent} using uri #{uri}" return end end rescue @run.error_message "Could not move agent #{@agent} to #{@node} via HTTP\n#{$!.to_s}" return end end def to_s super.to_s+"('#{@agent}', '#{@node}')" end end end module States class SocietyLoaded < Cougaar::NOOPState DOCUMENTATION = Cougaar.document { @description = "Indicates that the society was loaded from XML, a Ruby script or a CSmart database." } end class SocietyRunning < Cougaar::NOOPState DOCUMENTATION = Cougaar.document { @description = "Indicates that the society started." } end class SocietyStopped < Cougaar::NOOPState DOCUMENTATION = Cougaar.document { @description = "Indicates that the society stopped." } end class RunStopped < Cougaar::State DEFAULT_TIMEOUT = 20.minutes PRIOR_STATES = ["SocietyStopped"] DOCUMENTATION = Cougaar.document { @description = "Indicates that the run was stopped." } def process while(true) return if @run.stopped? sleep 2 end @run.info_message "Run Stopped" end end end end --- NEW FILE: society_rule_engine.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * </copyright> =end module Cougaar module Actions class TransformSociety < Cougaar::Action PRIOR_STATES = ["SocietyLoaded"] DOCUMENTATION = Cougaar.document { @description = "Transforms the society with a list of rules." @parameters = [ {:verbose => "required, If true, displays the transformations performed. (true | false)"}, {:rules => "*rules, The rules to run. Can be file names or directory names."} ] @example = "do_action 'TransformSociety', true, 'config/rules/isat/tic_env.rule', 'config/rules/logistics'" } def initialize(run, verbose, *rules) super(run) raise "Must supply rules to transform society" if rules.size==0 @verbose = verbose @rules = rules end def perform @rules.each { |rule| @run.info_message "Applying #{rule}" } @engine = Cougaar::Model::RuleEngine.new(@run.society) @engine.load_rules(@rules.join(";")) @rules.each do |rulefile| if File.directory?(rulefile) Dir.glob(File.join(rulefile, "*.rule")).sort.each do |file| @run.archive_file(file, "Rule file used to transform the society") end else @run.archive_file(rulefile, "Rule file used to transform the society") end end @engine.enable_stdout if @verbose @engine.execute end end end end module Cougaar module Model class RuleEngine MAXLOOP = 300 attr_accessor :max_loop, :society, :abort_on_warning attr_reader :monitor def initialize(society, max_loop = MAXLOOP) @society = society @monitor = RuleMonitor.new(society) @max_loop = max_loop @rules = [] @stdout_enabled = false @abort_on_warning = false end def enable_stdout @stdout_enabled = true end def load_rules(list) list.split(";").each do |item| raise "Unknown file or directory: #{item}" unless File.exist?(item) if File.stat(item).directory? rules = Dir.glob(File.join(item, "*.rule")).sort else rules = [item] end rules.each do |rule_file| File.open(rule_file) do |file| rule = file.read begin @rules << Rule.new(rule_file, rule) rescue Exception => error output_warning "Error loading rule #{rule_file}: #{error}\n#{error.backtrace.join("\n")}" end end end end end def add_rule(name, proc = nil, &block) rule = Rule.new(name, proc, &block) @rules << rule rule end def execute $debug_society_model = true loop = true count = 0 while(loop && count < @max_loop) @monitor.clear @rules.each do |rule| @monitor.current_rule = rule puts "Executing rule: #{rule.name}." if @stdout_enabled rule.execute(self, @society) @monitor.report if @stdout_enabled @monitor.clear_counters if @stdout_enabled end loop = @monitor.modified? count += 1 end if count >= @max_loop output_warning "Detected endless loop in rule applciation." end if @stdout_enabled unused_rules = [] @rules.each do |rule| unused_rules << rule.name unless rule.modified_society? end if unused_rules.size > 0 output_warning "The rule(s)s: #{unused_rules.join(', ')} did not modify the society." end end @monitor.finish end def output_warning(message) message = "Rule Engine Warning: #{message}" if abort_on_warning raise "\n#{message}" else puts message end end end class Rule attr_accessor :name, :description, :fire_count, :modified_society attr_reader :society def initialize(name, proc=nil, &block) @name = name proc = block unless proc @rule = proc @modified_society = false end def modified_society? @modified_society end def execute(engine, society) @society = society begin if @rule.kind_of?(String) instance_eval(@rule) else @rule.call(self, society) end rescue Exception => error engine.output_warning "Error executing rule #{@name}: #{error}\n#{error.backtrace.join("\n")}" end end end class RuleMonitor < SocietyMonitor attr_accessor :current_rule def modified? return @modified end def clear @modified = false clear_counters end def clear_counters @hosts_added = @hosts_removed = 0 @nodes_added = @nodes_removed = 0 @agents_added = @agents_removed = 0 @components_added = @components_removed = 0 end def initialize(society) super() @society = society clear end def host_added(host) return unless host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @hosts_added += 1 end def host_removed(host) return unless host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @hosts_removed += 1 end def node_added(node) return unless node.host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @nodes_added += 1 end def node_removed(node) return unless node.host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @nodes_removed += 1 end def agent_added(agent) return unless agent.node.host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @agents_added += 1 end def agent_removed(agent) return unless agent.node.host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @agents_removed += 1 end def component_added(component) return unless component.agent.node.host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @components_added += 1 end def component_removed(component) return unless component.agent.node.host.society = @society @modified = true @current_rule.modified_society = true if @current_rule @components_removed += 1 end def report ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Added #{@hosts_added} hosts.")) if @hosts_added > 0 ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Removed #{@hosts_removed} hosts.")) if @hosts_removed > 0 ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Added #{@nodes_added} nodes.")) if @nodes_added > 0 ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Removed #{@nodes_removed} nodes.")) if @nodes_removed > 0 ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Added #{@agents_added} agents.")) if @agents_added > 0 ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Removed #{@agents_removed} agents.")) if @agents_removed > 0 ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Added #{@components_added} components.")) if @components_added > 0 ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Removed #{@components_removed} components.")) if @components_removed > 0 end end end end --- NEW FILE: society_model.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, [...1452 lines suppressed...] @society = society @query = block end ## # Calls the query with the supplied name: # query['name'] #=> value # # name:: [String] The name to pass to the block # return:: [Object] The query block's result # def [](name) @query.call(name) end end end # Model end # Cougaar --- NEW FILE: society_builder.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * </copyright> =end require 'rexml/document' require 'cougaar/experiment' require 'cougaar/society_model' module Cougaar class SocietyBuilder attr_reader :doc attr_accessor :filename def initialize(doc) @doc = doc end def self.from_xml_file(filename) file = File.new(filename) builder = SocietyBuilder.new(REXML::Document.new(file)) builder.filename = filename file.close() builder end def self.from_ruby_file(filename) builder = SocietyBuilder.new(filename) builder.filename = filename builder end def self.from_string(str) SocietyBuilder.new(REXML::Document.new(str)) end def to_xml_file(filename=nil) filename = @filename if filename.nil? File.open(filename, "wb") {|file| file.puts(self.society.to_xml)} end def to_ruby_file(filename=nil) filename = @filename if filename.nil? File.open(filename, "wb") {|file| file.puts(self.society.to_ruby)} end def to_s self.society.to_xml end def to_xml self.society.to_xml end def society return @society if @society if doc.kind_of? String load_ruby else parse_xml end @society end def load_ruby f = File.new(@doc) @society = eval f.read f.close() end def parse_xml @society = Model::Society.new(doc.root.attributes['name']) do |society| #add facets to host @doc.root.elements.each("facet") do |element| society.add_facet do |facet| element.attributes.each { |a, v| facet[a] = v } facet.cdata = element.text.strip if element.text end end @doc.elements.each("society/host") do |host_element| society.add_host(host_element.attributes['name']) do |host| #add facets to host host_element.elements.each("facet") do |element| host.add_facet do |facet| element.attributes.each { |a, v| facet[a] = v } facet.cdata = element.text.strip if element.text end end host_element.elements.each("node") do |node_element| host.add_node(node_element.attributes['name']) do |node| element = node_element.elements["class"] node.classname = element.text.strip if element #add attributes to node node_element.elements.each("facet") do |element| node.add_facet do |facet| element.attributes.each { |a, v| facet[a] = v } facet.cdata = element.text.strip if element.text end end #add parameters to node node_element.elements.each("vm_parameter") do |element| node.add_parameter(element.text.strip) end node_element.elements.each("env_parameter") do |element| node.add_env_parameter(element.text.strip) end node_element.elements.each("prog_parameter") do |element| node.add_prog_parameter(element.text.strip) end #add componenets to node node_element.elements.each("component") do |comp_element| node.agent.add_component(comp_element.attributes['name']) do |comp| comp.classname = comp_element.attributes['class'] comp.priority = comp_element.attributes['priority'] comp.insertionpoint = comp_element.attributes['insertionpoint'] comp_element.elements.each("order") do |arg_element| comp.order = arg_element.text.strip.to_i end #order_element #add arguments to component comp_element.elements.each("argument") do |arg_element| comp.add_argument(arg_element.text.strip) end #arg_element end #comp end #comp_element #add agents to node node_element.elements.each("agent") do |agent_element| node.add_agent(agent_element.attributes['name']) do |agent| agent.classname = agent_element.attributes['class'] #add attributes to agent agent_element.elements.each("facet") do |element| agent.add_facet do |facet| element.attributes.each { |a, v| facet[a] = v } facet.cdata = element.text.strip if element.text end end #add components to agent agent_element.elements.each("component") do |comp_element| agent.add_component(comp_element.attributes['name']) do |comp| comp.classname = comp_element.attributes['class'] comp.priority = comp_element.attributes['priority'] comp.insertionpoint = comp_element.attributes['insertionpoint'] comp_element.elements.each("order") do |arg_element| comp.order = arg_element.text.strip.to_i end #order_element #add arguments to component comp_element.elements.each("argument") do |arg_element| comp.add_argument(arg_element.text.strip) end end #comp end #comp_element end #agent end #agent_element end #node end #node_element end #host end #host_element end #society end #method parse end #class SocietyBuilder end #module Cougaar module Cougaar module Actions class LoadSocietyFromScript < Cougaar::Action RESULTANT_STATE = "SocietyLoaded" DOCUMENTATION = Cougaar.document { @description = "Load a society definition from a Ruby society file." @parameters = [ :filename => "required, The Ruby file name" ] @example = "do_action 'LoadSocietyFromScript', 'full-1ad.rb'" } def initialize(run, filename) super(run) @filename = filename end def perform raise_failure "Unknown Ruby file: #{@filename}" unless File.exist?(@filename) begin builder = Cougaar::SocietyBuilder.from_ruby_file(@filename) rescue raise_failure "Could not build society from Ruby file: #{@filename}", $! end @run.society = builder.society @run.archive_file(@filename, "Initial society file") @run["loader"] = "XML" end def to_s return super.to_s + "('#{@filename}')" end end class SaveCurrentSociety < Cougaar::Action PRIOR_STATES = ["SocietyLoaded"] DOCUMENTATION = Cougaar.document { @description = "Save the current (in memory) society to XML/Ruby." @parameters = [ :filename => "required, The XML/Ruby file name." ] @example = "do_action 'SaveCurrentSociety', 'full-1ad.xml'" } def initialize(run, filename) super(run) @filename = filename end def to_s return super.to_s+"('#{@filename}')" end def perform begin File.open(@filename, "w") do |file| if (File.basename(@filename)!=File.basename(@filename, ".xml")) file.puts @run.society.to_xml else file.puts @run.society.to_ruby end end @run.archive_and_remove_file(@filename, "Saved instance of society in memory") rescue @run.error_message "Could not write society to #{@filename}" end end end class LoadSocietyFromXML < Cougaar::Action RESULTANT_STATE = "SocietyLoaded" DOCUMENTATION = Cougaar.document { @description = "Load a society definition from an XML." @parameters = [ :filename => "required, The XML file name" ] @example = "do_action 'LoadSocietyFromXML', 'full-1ad.xml'" } def initialize(run, filename) super(run) @filename = filename end def perform raise_failure "Unknown XML file: #{@filename}" unless File.exist?(@filename) begin builder = Cougaar::SocietyBuilder.from_xml_file(@filename) rescue raise_failure "Could not build society from XML file: #{@filename}", $! end @run.society = builder.society @run.archive_file(@filename, "Initial society file") @run["loader"] = "XML" end def to_s return super.to_s + "('#{@filename}')" end end class LoadSocietyFromMemory < Cougaar::Action RESULTANT_STATE = "SocietyLoaded" DOCUMENTATION = Cougaar.document { @description = "Load a society stored in Cougaar.in_memory_society." @example = "do_action 'LoadSocietyFromMember'" } def initialize(run) super(run) end def perform raise_failure "In memory society not set" unless Cougaar.in_memory_society @run.society = Cougaar.in_memory_society @run["loader"] = "XML" end end end end --- NEW FILE: scripting.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * </copyright> =end require 'thread' $stdout.sync = true class Integer def seconds(value=0) return to_i+value end alias_method :second, :seconds def minutes(value=0) return to_i*60+value end alias_method :minute, :minutes def hours(value=0) return to_i*60*60+value end alias_method :hour, :hours def days(value=0) return to_i*24*60*60+value end alias_method :day, :days end module Cougaar class SimpleFileLogger LEVELS = ['disabled', 'error', 'info', 'debug'] def initialize(logName, logFile, logLevel) @logName = logName @logFile = logFile self.logLevel = logLevel @file = File.new(logFile, "a") @file.sync = true @mutex = Mutex.new end def logLevel=(logLevel) logLevel = LEVELS[logLevel] if logLevel.kind_of? Numeric @logLevel = logLevel.downcase case @logLevel when 'disabled' @logLevelInt = 0 when 'error' @logLevelInt = 1 when 'info' @logLevelInt = 2 when 'debug' @logLevelInt = 3 else raise "Unknown Logger level: #{@logLevel}" end end def close @file.close end def time Time.now.gmtime.to_s end def error(message) return if @logLevelInt < 1 write "[ERROR] #{time} :: #{message}" end def info(message) return if @logLevelInt < 2 write "[INFO] #{time} :: #{message}" end def debug(message) return if @logLevelInt < 3 write "[DEBUG] #{time} :: #{message}" end def write(line) @mutex.synchronize do @file.puts line end end end class Documentation attr_accessor :description, :example def initialize(&block) instance_eval(&block) cleanup end def cleanup if @description list = @description.split("\n") newlist = [] list.each { |v| newlist << v.strip } @description = newlist.join(" ") end if @example list = @example.split("\n") if list.size > 1 && list[0].strip=="" count = 0 list[1].each_byte do |byte| count+=1 if byte==32 break if byte != 32 end newlist = [] list[1..-1].each { |v| newlist << v[count..-1] } @example = newlist.join("\n") end end end def has_parameters? if @parameters return true else return false end end def has_block_yields? if @block_yields return true else return false end end def parameter_names result = [] if @parameters @parameters.each do |item| result << item.keys[0] end end return result end def block_yield_names result = [] if @block_yields @block_yields.each do |item| result << item.keys[0] end end return result end def each_block_yield if @block_yields @block_yields.each do |item| key = item.keys[0] yield key, item[key] end end end def each_parameter if @parameters @parameters.each do |item| key = item.keys[0] yield key, item[key] end end end end def self.document(&block) Cougaar::Documentation.new(&block) end def self.logger unless @logger File.delete('run.log') if File.exist?('run.log') @logger = SimpleFileLogger.new("ACME Run", "run.log", "info") end @logger end def self.debug? return self.constants.include?("DEBUG") && DEBUG end end require 'cougaar/society_model' #~ require 'cougaar/experiment' #~ require 'cougaar/society_utils' require 'cougaar/society_builder' #~ require 'cougaar/communications' #~ require 'cougaar/communities' #~ require 'cougaar/society_control' require 'cougaar/society_rule_engine' #~ require 'cougaar/persistence' #~ require 'cougaar/run_logging' --- NEW FILE: experiment.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, [...1534 lines suppressed...] EXPERIMENT_POST_DATA = <<-MULTIPART --BOUNDARY Content-Disposition: form-data; name="priority" PRIORITY --BOUNDARY Content-Disposition: form-data; name="definition_file"; filename="FILENAME" Content-Type: application/octet-stream EXPERIMENT --BOUNDARY Content-Disposition: form-data; name="definition_text" --BOUNDARY-- MULTIPART end end --- NEW FILE: society_utils.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * </copyright> =end require 'cougaar/experiment' module Cougaar module Actions class LayoutSociety < ::Cougaar::Action PRIOR_STATES = ["SocietyLoaded"] DOCUMENTATION = Cougaar.document { @description = "Layout a loaded society using the supplied layout and optional hosts file." @parameters = [ {:layout => "The layout file (valid society file in .xml or .rb)."}, {:hosts => "default=nil, If present, uses the hosts from this file instead of those in the layout file."} ] @example = "do_action 'LayoutSociety', '1ad-layout.xml', 'sa-hosts.xml'" } def initialize(run, layout, hosts=nil) super(run) @layout = layout @hosts = hosts @layout = ::Cougaar::Model::SocietyLayout.new @layout.layout_file = layout @layout.hosts_file = hosts @layout.load_files end def perform @run.info_message "Layout file #{@layout.layout_file}" @run.archive_file(@layout.layout_file, "Layout file for the society run") if @hosts @run.info_message "Hosts file #{@layout.hosts_file}" @run.archive_file(@layout.hosts_file, "Hosts file for the society run") else @run.info_message "No hosts file used for layout" end @layout.society = @run.society @layout.layout end end end module Model class SocietyComparison attr_accessor :society1, :society2, :differences def initialize(society1, society2) @society1 = society1 @society2 = society2 @differences = [] end class RemovalDifference def initialize(object) super(kind, object) @var = var @value1 = value1 @value2 = value2 end end class InstanceDifference def initialize(object, var, value1, value2) super(kind, object) @var = var @value1 = value1 @value2 = value2 end end def instance_diff(object, var, value1, value2) @differences << InstanceDifference.new(object, var, value1, value2) end def component_removed(list) @differences << Instance end def diff diff_hosts diff_nodes diff_agents return self end private def diff_hosts society1_hosts = [] society1.each_host {|host| society1_hosts << host.name} society2_hosts = [] society2.each_host {|host| society2_hosts << host.name} removed_hosts = society1_hosts - society2_hosts added_hosts = society2_hosts - society1_hosts end def diff_nodes society1_nodes = [] society1.each_node {|node| society1_nodes << node.name} society2_nodes = [] society2.each_node {|node| society2_nodes << node.name} removed_nodes = society1_nodes - society2_nodes added_nodes = society2_nodes - society1_nodes end def diff_agents society1_agents = [] society1.each_agent {|agent| society1_agents << agent.name} society2_agents = [] society2.each_agent {|agent| society2_agents << agent.name} removed_agents = society1_agents - society2_agents added_agents = society2_agents - society1_agents end end class SocietyLayout attr_accessor :society_file, :layout_file, :hosts_file, :society def self.from_files(society_file, layout_file, hosts_file = nil) layout = SocietyLayout.new layout.society_file = society_file layout.layout_file = layout_file layout.hosts_file = hosts_file layout.load_files return layout end def self.from_society(society, layout_file, hosts_file = nil) layout = SocietyLayout.new layout.society = society layout.layout_file = layout_file layout.hosts_file = hosts_file layout.load_files return layout end def load_files @society = load_file(@society_file) if @society_file @society_layout = load_file(@layout_file) if @layout_file @society_hosts = load_file(@hosts_file) if @hosts_file end def layout # build temporary host and node and move all agents to it guid = Time.now.to_i @society.add_host("host-#{guid}") { |host| host.add_node("node-#{guid}") } agentlist = [] @society.each_agent { |agent| agentlist << agent } agentlist.each {|agent| agent.move_to("node-#{guid}")} # remove all existing hosts/nodes purgelist = [] @society.each_host { |host| purgelist << host unless host.name=="host-#{guid}" } purgelist.each { |host| society.remove_host(host) } # build a list of available hosts hostlist = nil hostgroups = nil unused_hostlist = nil if @society_hosts hostgroups = {} unused_hostlist = [] @society_hosts.each_host do |host| target = false host.each_facet(:service) do |facet| target = true if facet[:service].downcase=='acme' end if target group = host.get_facet(:group) if group list = hostgroups[group] list ||= [] list << host hostgroups[group]=list else list = hostgroups[:ungrouped] list ||= [] list << host hostgroups[:ungrouped] = list end else unused_hostlist << host end end end # copy layout and host society's facets to the society... @society_layout.each_facet { |facet| @society.add_facet(facet.clone) } @society_hosts.each_facet { |facet| @society.add_facet(facet.clone) } if @society_hosts # perform layout @society_layout.each_host do |host| if @society_hosts if host.has_facet?(:group) target_host = hostgroups[host.get_facet(:group)].shift #puts "Group #{host.get_facet(:group)} has #{hostgroups[host.get_facet(:group)].size} hosts left" unless target_host raise "Not enough hosts in #{@host_file} for group #{host.get_facet(:group)} in the society layout file #{@layout_file}" end else target_host = hostgroups[:ungrouped].shift #puts "Group ungrouped has #{hostgroups[:ungrouped].size} hosts left" unless target_host raise "Not enough hosts in #{@host_file} for ungrouped in the society layout file #{@layout_file}" end end else target_host = host end @society.add_host(target_host.name) do |newhost| host.each_facet { |facet| newhost.add_facet(facet.clone) } if target_host!=host target_host.each_facet { |facet| newhost.add_facet(facet.clone) } end host.each_node do |node| newhost.add_node(node.name) do |newnode| node.each_facet { |facet| newnode.add_facet(facet.clone) } end node.each_agent do |agent| to_move = @society.agents[agent.name] if to_move to_move.move_to(node.name) # add layout society's agent facets to the agent agent.each_facet {|facet| to_move.add_facet(facet.clone)} else ExperimentMonitor.notify(ExperimentMonitor::InfoNotification.new("Layout specifies agent '#{agent.name}' that is not defined in the society")) end end end end end if unused_hostlist unused_hostlist.each do |host| @society.add_host(host.name) do |newhost| host.each_facet { |facet| newhost.add_facet(facet.clone) } end end end # check to make sure we laid out all the agents agentlist = [] @society.nodes["node-#{guid}"].each_agent { |agent| agentlist << agent } if agentlist.size>0 names = agentlist.collect { |agent| agent.name } raise "Did not layout the agents: #{ names.join(', ') }" end @society.remove_host("host-#{guid}") end def to_ruby_file(filename) f = File.open(filename, "w") f.puts(@society.to_ruby) f.close end def to_xml_file(filename) f = File.open(filename, "w") f.puts(@society.to_xml) f.close end def tree @society.each_host do |host| puts host.name host.each_node do |node| puts " "+node.name node.each_agent do |agent| puts " "+agent.name end end end end def load_file(file) if file[-3..-1] == '.rb' return Cougaar::SocietyBuilder.from_ruby_file(file).society else return Cougaar::SocietyBuilder.from_xml_file(file).society end end end ## # The SocietyMonitor collects chagnes to the cougaar society and # reports them to instances. # # class SocietyMonitor @@monitors = [] def self.add(monitor) @@monitors << monitor end def self.remove(monitor) @@monitors.delete(monitor) end def self.each_monitor @@monitors.each {|monitor| yield monitor} end def finish SocietyMonitor.remove(self) end def initialize SocietyMonitor.add(self) end def host_added(host) ; end def host_removed(host) ; end def node_added(node) ; end def node_removed(node) ; end def agent_added(agent) ; end def agent_removed(agent) ; end def component_added(component) ; end def component_removed(component) ; end def self.enable_stdout m = SocietyMonitor.new def m.host_added(host) puts "Host added #{host.host_name} < #{host.society.name}" end def m.host_removed(host) puts "Host removed #{host.host_name} < #{host.society.name}" end def m.node_added(node) puts "Node added #{node.name} < #{node.host.host_name} < #{node.host.society.name}" end def m.node_removed(node) puts "Node removed #{node.name} < #{node.host.host_name} < #{node.host.society.name}" end def m.agent_added(agent) puts "Agent added #{agent.name} < #{agent.node.name} < #{agent.node.host.host_name} < #{agent.node.host.society.name}" end def m.agent_removed(agent) puts "Agent removed #{agent.name} < #{agnet.node.name} on #{agent.node.host.host_name} < #{agent.node.host.society.name}" end def m.component_added(component) puts "Component added #{component.name} < #{component.agent.name} < #{component.agent.node.name} < #{component.agent.node.host.host_name} < #{component.agent.node.host.society.name}" end def m.agent_removed(agent) puts "Component removed #{component.name} < #{component.agent.name} < #{component.agent.node.name} < #{component.agent.node.host.host_name} < #{component.agent.node.host.society.name}" end end end end end --- NEW FILE: py_society_builder.rb --- =begin * <copyright> * Copyright 2001-2004 InfoEther LLC * Copyright 2001-2004 BBN Technologies * * under sponsorship of the Defense Advanced Research Projects * Agency (DARPA). * * You can redistribute this software and/or modify it under the * terms of the Cougaar Open Source License as published on the * Cougaar Open Source Website (www.cougaar.org <www.cougaar.org> ). * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * </copyright> =end # py_society_builder.rb # Builds a society object from a string of Ruby code arriving # via stdin, transforms it according to rules passed in as args, # then outputs the new society to stdout as a string of xml. #~ $:.unshift ".." #~ $:.unshift "../../../../acme_service/src/redist" $:.unshift "ruleEngine/acme_scripting/src/lib" $:.unshift "ruleEngine/acme_service/src/redist" require 'cougaar/scripting' require 'cougaar/society_rule_engine' society = eval $stdin.read engine = Cougaar::Model::RuleEngine.new(society) engine.load_rules(ARGV.join(";")) #engine.enable_stdout if @verbose engine.execute puts society.to_xml |