reorganize API helper a bit, refactor pipeline status page as /factory_jobs
authorTom Clegg <tom@clinicalfuture.com>
Sun, 20 Jan 2013 23:35:19 +0000 (15:35 -0800)
committerTom Clegg <tom@clinicalfuture.com>
Sun, 20 Jan 2013 23:35:19 +0000 (15:35 -0800)
app/models/orvos_api_client.rb [new file with mode: 0644]
app/models/orvos_base.rb
app/models/orvos_resource_list.rb [new file with mode: 0644]
config/initializers/orvos_api_client.rb [new file with mode: 0644]
config/routes.rb

diff --git a/app/models/orvos_api_client.rb b/app/models/orvos_api_client.rb
new file mode 100644 (file)
index 0000000..7b3a0ca
--- /dev/null
@@ -0,0 +1,70 @@
+class OrvosApiClient
+  def api(resources_kind, action, data=nil)
+    dataargs = []
+    if !data.nil?
+      data.each do |k,v|
+        dataargs << '-d'
+        if v.is_a? String or v.nil?
+          dataargs << "#{k}=#{v}"
+        elsif v == true or v == false
+          dataargs << "#{k}=#{v ? 1 : 0}"
+        else
+          dataargs << "#{k}=#{JSON.generate v}"
+        end
+      end
+    end
+    json = nil
+    resources_kind = class_kind(resources_kind).pluralize if resources_kind.is_a? Class
+    url = "#{self.orvos_v1_base}/#{resources_kind}#{action}"
+    IO.popen([ENV,
+              'curl',
+              '-sk',
+              *dataargs,
+              url],
+             'r') do |io|
+      json = io.read
+    end
+    resp = JSON.parse json, :symbolize_names => true
+    if resp[:errors]
+      raise "API errors:\n#{resp[:errors].join "\n"}\n"
+    end
+    resp
+  end
+
+  def unpack_api_response(j, kind=nil)
+    if j.is_a? Hash and j[:items].is_a? Array and j[:kind].match(/(_list|List)$/)
+      j[:items].collect { |x| unpack_api_response x, j[:kind] }
+    elsif j.is_a? Hash and (kind || j[:kind])
+      oclass = self.kind_class(kind || j[:kind])
+      if oclass
+        j.keys.each do |k|
+          childkind = j["#{k.to_s}_kind".to_sym]
+          if childkind
+            j[k] = self.unpack_api_response(j[k], childkind)
+          end
+        end
+        oclass.new(j)
+      else
+        j
+      end
+    else
+      j
+    end
+  end
+
+  def orvos_v1_base
+    @orvos_v1_base ||= Rails.configuration.orvos_v1_base
+  end
+
+  def orvos_schema
+    @orvos_schema ||= api 'schema', ''
+  end
+
+  def kind_class(kind)
+    kind.match(/^orvos\#(.+?)(_list|List)?$/)[1].pluralize.classify.constantize rescue nil
+  end
+
+  def class_kind(resource_class)
+    resource_class.to_s.underscore
+  end
+end
index cd31bd4503c134a3f99a6a124911c18a8eb67083..6c883481770e8e17fb89961eb10e222741704a8d 100644 (file)
@@ -1,12 +1,11 @@
 class OrvosBase < ActiveRecord::Base
   self.abstract_class = true
 
-  @@orvos_v1_base = Rails.configuration.orvos_v1_base
   def self.columns
     return @columns unless @columns.nil?
     @columns = []
-    return @columns if orvos_schema[self.to_s.to_sym].nil?
-    orvos_schema[self.to_s.to_sym].each do |coldef|
+    return @columns if $orvos_api_client.orvos_schema[self.to_s.to_sym].nil?
+    $orvos_api_client.orvos_schema[self.to_s.to_sym].each do |coldef|
       k = coldef[:name].to_sym
       if coldef[:type] == coldef[:type].downcase
         @columns << column(k, coldef[:type].to_sym)
@@ -23,17 +22,17 @@ class OrvosBase < ActiveRecord::Base
   def self.column(name, sql_type = nil, default = nil, null = true)
     ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
   end
-  def self.all
-    unpack_api_response(api(''))
-  end
   def self.find(uuid)
-    new(api('/' + uuid))
+    new($orvos_api_client.api(self, '/' + uuid))
+  end
+  def self.where(*args)
+    OrvosResourceList.new(self).where(*args)
+  end
+  def self.eager(*args)
+    OrvosResourceList.new(self).eager(*args)
   end
-  def self.where(cond)
-    self.unpack_api_response(self.api '', {
-                               _method: 'GET',
-                               where: cond
-                             })
+  def self.all(*args)
+    OrvosResourceList.new(self).all(*args)
   end
   def save
     obdata = {}
@@ -45,9 +44,9 @@ class OrvosBase < ActiveRecord::Base
     postdata = { self.class.to_s.underscore => obdata }
     if etag
       postdata['_method'] = 'PUT'
-      resp = self.class.api('/' + uuid, postdata)
+      resp = $orvos_api_client.api(self.class, '/' + uuid, postdata)
     else
-      resp = self.class.api('', postdata)
+      resp = $orvos_api_client.api(self.class, '', postdata)
     end
     return false if !resp[:etag] || !resp[:uuid]
     @etag = resp[:etag]
@@ -85,26 +84,24 @@ class OrvosBase < ActiveRecord::Base
         ok
       end
     end
-    @metadata = self.class.api '', { _method: 'GET', where: o, eager: true }, { resource_path: 'metadata' }
-    @metadata = self.class.unpack_api_response(@metadata)
+    @metadata = $orvos_api_client.api Metadatum, '', { _method: 'GET', where: o, eager: true }
+    @metadata = $orvos_api_client.unpack_api_response(@metadata)
   end
   def all_metadata
     return @all_metadata if @all_metadata
-    res = self.class.api '', {
+    res = $orvos_api_client.api Metadatum, '', {
       _method: 'GET',
       where: {
         tail_kind: self.kind,
         tail: self.uuid
       },
       eager: true
-    }, {
-      resource_path: 'metadata'
     }
-    @all_metadata = self.class.unpack_api_response(res)
+    @all_metadata = $orvos_api_client.unpack_api_response(res)
   end
   def reload
     raise "No such object" if !uuid
-    api('/' + uuid).each do |k,v|
+    $orvos_api_client.api(self, '/' + uuid).each do |k,v|
       self.instance_variable_set('@' + k.to_s, v)
     end
     @all_metadata = nil
@@ -120,63 +117,4 @@ class OrvosBase < ActiveRecord::Base
     @etag = nil
     self
   end
-
-  def self.api(action, data=nil, o={})
-    dataargs = []
-    if !data.nil?
-      data.each do |k,v|
-        dataargs << '-d'
-        if v.is_a? String or v.nil?
-          dataargs << "#{k}=#{v}"
-        elsif v == true or v == false
-          dataargs << "#{k}=#{v ? 1 : 0}"
-        else
-          dataargs << "#{k}=#{JSON.generate v}"
-        end
-      end
-    end
-    json = nil
-    IO.popen([ENV,
-              'curl',
-              '-sk',
-              *dataargs,
-              "#{@@orvos_v1_base}/#{o[:resource_path] || self.to_s.underscore.pluralize}#{action}"],
-             'r') do |io|
-      json = io.read
-    end
-    resp = JSON.parse json, :symbolize_names => true
-    if resp[:errors]
-      raise "API errors:\n#{resp[:errors].join "\n"}\n"
-    end
-    resp
-  end
-
-  def self.orvos_schema
-    $orvos_schema ||= api '', nil, {resource_path: 'schema'}
-  end
-
-  def self.kind_class(kind)
-    kind.match(/^orvos\#(.+?)(_list|List)?$/)[1].pluralize.classify.constantize rescue nil
-  end
-
-  def self.unpack_api_response(j, kind=nil)
-    if j.is_a? Hash and j[:items].is_a? Array and j[:kind].match(/(_list|List)$/)
-      j[:items].collect { |x| unpack_api_response x, j[:kind] }
-    elsif j.is_a? Hash and (kind || j[:kind])
-      oclass = self.kind_class(kind || j[:kind])
-      if oclass
-        j.keys.each do |k|
-          childkind = j["#{k.to_s}_kind".to_sym]
-          if childkind
-            j[k] = self.unpack_api_response(j[k], childkind)
-          end
-        end
-        oclass.new(j)
-      else
-        j
-      end
-    else
-      j
-    end
-  end
 end
diff --git a/app/models/orvos_resource_list.rb b/app/models/orvos_resource_list.rb
new file mode 100644 (file)
index 0000000..181a21c
--- /dev/null
@@ -0,0 +1,55 @@
+class OrvosResourceList
+  def initialize(resource_class)
+    @resource_class = resource_class
+  end
+
+  def eager(bool=true)
+    @eager = bool
+    self
+  end
+
+  def where(cond)
+    cond = cond.dup
+    cond.keys.each do |uuid_key|
+      if cond[uuid_key] and (cond[uuid_key].is_a? Array or
+                             cond[uuid_key].is_a? OrvosBase)
+        # Coerce cond[uuid_key] to an array of uuid strings.  This
+        # allows caller the convenience of passing an array of real
+        # objects and uuids in cond[uuid_key].
+        if !cond[uuid_key].is_a? Array
+          cond[uuid_key] = [cond[uuid_key]]
+        end
+        cond[uuid_key] = cond[uuid_key].collect do |item|
+          if item.is_a? OrvosBase
+            item.uuid
+          else
+            item
+          end
+        end
+      end
+    end
+    cond.keys.select { |x| x.match /_kind$/ }.each do |kind_key|
+      if cond[kind_key].is_a? Class
+        cond = cond.merge({ kind_key => 'orvos#' + $orvos_api_client.class_kind(cond[kind_key]) })
+      end
+    end
+    res = $orvos_api_client.api @resource_class, '', {
+      _method: 'GET',
+      where: cond,
+      eager: (@eager ? '1' : '0')
+    }
+    @results = $orvos_api_client.unpack_api_response res
+  end
+
+  def all
+    res = $orvos_api_client.api @resource_class, '', {
+      _method: 'GET',
+      eager: (@eager ? '1' : '0')
+    }
+    @results = $orvos_api_client.unpack_api_response res
+  end
+
+  def to_ary
+    @results
+  end
+end
diff --git a/config/initializers/orvos_api_client.rb b/config/initializers/orvos_api_client.rb
new file mode 100644 (file)
index 0000000..0da9d21
--- /dev/null
@@ -0,0 +1 @@
+$orvos_api_client = OrvosApiClient.new
index d19f23daa469ce5b263ccd44f3ec7fca79a7655f..c95c16c276ac7834708cdf6bb6503bf52b82aa34 100644 (file)
@@ -1,4 +1,7 @@
 Vcffarm::Application.routes.draw do
+  resources :factory_jobs
+
+
   resources :uploaded_datasets