EDI Translator (relocated and combined)
authoratz <atz@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 9 Jun 2010 21:43:58 +0000 (21:43 +0000)
committeratz <atz@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 9 Jun 2010 21:43:58 +0000 (21:43 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@16642 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/edi_translator/README [new file with mode: 0644]
Open-ILS/src/edi_translator/edi_webrick.bash [new file with mode: 0755]
Open-ILS/src/edi_translator/edi_webrick.cnf [new file with mode: 0644]
Open-ILS/src/edi_translator/edi_webrick.rb [new file with mode: 0755]
Open-ILS/src/edi_translator/install.sh [new file with mode: 0755]

diff --git a/Open-ILS/src/edi_translator/README b/Open-ILS/src/edi_translator/README
new file mode 100644 (file)
index 0000000..16c6c5b
--- /dev/null
@@ -0,0 +1,43 @@
+EDI Translator XML-RPC Service (for Evergreen)
+
+Copyright 2010
+License: GNU Public License v 2.0 or later
+
+Author: Joe Atzberger
+        Equinox Software, Inc.
+
+For ease of interpretation, Evergreen needs a service to convert between raw EDI and a 
+more commonly used JSON-based notation.  Here we have the script (edi_webrick.rb) to
+do that.  The Translator will be called on both inbound and outbound EDI messages,
+translating to JSON (JEDI) for edi_fetcher.pl and to EDI for edi_pusher.pl,
+respectively.
+
+Files:
+    edi_webrick.bash - wrapper script for setting ENV, calling edi_webrick.rb
+    edi_webrick.cnf  - edi_webrick.rb config script
+    edi_webrick.rb   - the main EDI translator daemon script
+    install.sh       - dependency installer (for debian lenny)
+    README           - this file
+
+This service can be run on a local or remote system that has the proper ruby environment
+established.  See the install.sh script for an example of how to install the needed ruby
+components (on debian lenny linux).  
+
+There is no such thing (yet?) as "push" from a vendor of their EDI responses.  Basically
+they just put responses in an FTP directory somewhere that you are expected to check.  It
+would be cool if there were a better way to do that like consuming some RSS feed or 
+remote API callbacks.  
+
+Evergreen will only support one delivery address per PO.  That limitation is based
+on the mapping to the delivery address via the ordering_agency org_unit.  If items
+need to be shipped someplace else, then they need a different PO, for now at least.
+
+If we want to support multiple vendor profiles, then we drop the unique constraint
+on SAN, add a new one on SAN + profile_code.  Profile code then goes in the template.
+The template logic could get rather complex to support all the optional data elements.
+
+mbklein says:
+'order' mapper won't work for EDIFACT versions later than D.96A, because of a change
+to the structure of the BGM segment.  But as long as all the supported vendors will
+accept a D.96A ORDERS (which I think they do), that's not a problem.
+
diff --git a/Open-ILS/src/edi_translator/edi_webrick.bash b/Open-ILS/src/edi_translator/edi_webrick.bash
new file mode 100755 (executable)
index 0000000..732d50a
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# A wrapper for the ruby-script
+
+
+function die_msg {
+    echo $1;
+    exit 1;
+}
+
+lib='./acq_edi/lib';
+script='./edi_webrick.rb';
+
+[ -r "$script" ] || die_msg "Cannot read script at $script";
+#[ -d "$lib"    ] || die_msg "Cannot find lib at $lib";
+# This doesn't work?
+#      export RUBYLIB=$lib
+
+# This is necessary 
+echo export RUBYOPT=rubygems
+     export RUBYOPT=rubygems
+echo ruby $script '&'
+     ruby $script &
diff --git a/Open-ILS/src/edi_translator/edi_webrick.cnf b/Open-ILS/src/edi_translator/edi_webrick.cnf
new file mode 100644 (file)
index 0000000..6b97c1a
--- /dev/null
@@ -0,0 +1,3 @@
+host = localhost
+port = 9191
+file = true
diff --git a/Open-ILS/src/edi_translator/edi_webrick.rb b/Open-ILS/src/edi_translator/edi_webrick.rb
new file mode 100755 (executable)
index 0000000..b1386a3
--- /dev/null
@@ -0,0 +1,112 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+require 'optparse'
+require 'parseconfig'
+require 'stringio'
+require 'webrick'
+require 'xmlrpc/server'
+
+require 'openils/mapper'
+require 'edi/edi2json'
+# require 'edi/mapper'
+
+base = File.basename($0, '.rb')
+
+# Defaults
+defaults = {
+  'port'      => 9191,
+  'config'    => "./#{base}.cnf",
+  'namespace' => "/EDI",
+# 'defcon'    => 0,         # uncomment the 2 decons here, and one in the config file to see the collision/interaction
+}
+
+options = {
+#  'defcon'    => 3,
+}
+
+# Parse command line to override defaults
+
+OptionParser.new do |opts|
+  opts.banner = "Usage: #{$0} [options]"
+
+  opts.on("-c", "--config [/path/to/file]", "Config file           (default: #{defaults['config']})"   ) do |x|
+    options['config'] = x
+  end
+
+  opts.on("-n", "--namespace [/web/path]",  "Web request namespace (default: #{defaults['namespace']})") do |x|
+    options['namespace'] = x
+  end
+
+  opts.on("-p", "--port [PORT]",            "Port number           (default: #{defaults['port']})"     ) do |x|
+    options['port'] = x
+  end
+
+  opts.on("-v", "--[no-]verbose", "Set verbosity") do |x|
+    options['verbose'] = x
+  end
+
+  opts.on("-d", "--defaults",   "Show defaults") do |x|
+    puts "## Default values:"
+    defaults.each { |key, value| printf "%10s = %s\n", key, value }
+    exit
+  end
+
+  opts.on("-D", "--dumpconfig", "Show effective settings from command-line, config file or defaults") do |x|
+    options['dumpconfig'] = x
+  end
+
+  opts.on_tail("-h", "--help",  "Show this message") do
+    puts opts
+    exit
+  end
+
+end.parse!
+
+if options['verbose']
+  puts "OPTIONS: " ; p options
+  puts "Reading config file #{options['config'] || defaults['config']}"
+  # puts "\n ARGV: " ; p ARGV
+end
+
+# Read config file, then integrate 
+c = ParseConfig.new(options['config'] || defaults['config'])
+# puts c.methods().sort ; print "\n\n"
+
+keylist = ["host", "port", "config", "namespace", "verbose"] | c.get_params() | defaults.keys | options.keys
+
+for key in keylist
+  src =  options.has_key?(key) ? 'command-line' : \
+              c.get_value(key) ? 'config file'  : \
+        defaults.has_key?(key) ? 'default'      : 'NOWHERE!'
+
+  options[key] ||= c.get_value(key) || defaults[key]
+  printf "%10s = %-22s (%12s)\n", key, options[key], src if options['dumpconfig']
+end
+
+# after this, all values we care about are in the options hash
+
+# create a servlet to handle XML-RPC requests:
+servlet = XMLRPC::WEBrickServlet.new
+servlet.add_handler("upper_case") { |a_string| a_string.upcase   }
+servlet.add_handler("lower_case") { |a_string| a_string.downcase }
+servlet.add_handler("edi2json"  ) { |a_string|
+  File.open('/tmp/ruby_edi2json.tmp', 'w') {|f| f.write(a_string) }      # debugging, so we can compare what we rec'd w/ the orig. file
+  interchange = StringIO.open(a_string){ |io| EDI::E::Interchange.parse(io) }
+  # interchange.header.cS002.d0004 = 'sender'
+  # interchange.header.cS003.d0010 = 'recipient'
+  interchange.to_json
+}
+servlet.add_handler("json2edi"  ) { |a_string|
+  File.open('/tmp/ruby_json2edi.tmp', 'w') {|f| f.write(a_string) }      # debugging, so we can compare what we rec'd w/ the orig. file
+  @map = OpenILS::Mapper.from_json(a_string)
+  @map.finalize.to_s
+}
+servlet.add_introspection
+
+# create a WEBrick instance to host the servlets
+server = WEBrick::HTTPServer.new(:Port => options['port'])
+trap("INT"){ server.shutdown }
+server.mount(options['namespace'], servlet)
+server.start
+
diff --git a/Open-ILS/src/edi_translator/install.sh b/Open-ILS/src/edi_translator/install.sh
new file mode 100755 (executable)
index 0000000..8e125e6
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# JEDI converter scripts installation
+#
+# Debian Lenny dependencies
+#
+# The rubygems package from Debian apt sources is crippled and cannot update.
+# The result is that we need to replace it with the current version.
+
+
+# apt-get install libgemplugin-ruby  # recommended by some pages as a workaround, but already satisfied by ruby-full
+sudo apt-get install ruby-full ruby-dev rubygems    # maybe ruby-full is overkill?
+sudo gem install rubygems-update                    # unnecessary if we do ruby setub.rb below
+
+# runaround for debian's crippled rubygems package:
+mkdir rubygems
+pushd rubygems
+svn checkout svn://rubyforge.org/var/svn/rubygems/trunk
+cd trunk
+sudo ruby setup.rb
+sudo update_rubygems
+popd
+
+sudo gem install parseconfig rspec edi4r edi4r-tdid json rcov openils-mapper # mkmf
+