openbel-api 0.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gemspec +65 -0
  3. data/CHANGELOG.md +22 -0
  4. data/INSTALL.md +19 -0
  5. data/INSTALL_RUBY.md +107 -0
  6. data/LICENSE +191 -0
  7. data/README.md +208 -0
  8. data/app/openbel/api/app.rb +83 -0
  9. data/app/openbel/api/config.rb +45 -0
  10. data/app/openbel/api/config.ru +3 -0
  11. data/app/openbel/api/helpers/pager.rb +109 -0
  12. data/app/openbel/api/middleware/auth.rb +112 -0
  13. data/app/openbel/api/resources/adapters/basic_json.rb +52 -0
  14. data/app/openbel/api/resources/annotation.rb +141 -0
  15. data/app/openbel/api/resources/base.rb +16 -0
  16. data/app/openbel/api/resources/completion.rb +89 -0
  17. data/app/openbel/api/resources/evidence.rb +115 -0
  18. data/app/openbel/api/resources/evidence_transform.rb +143 -0
  19. data/app/openbel/api/resources/function.rb +98 -0
  20. data/app/openbel/api/resources/match_result.rb +79 -0
  21. data/app/openbel/api/resources/namespace.rb +174 -0
  22. data/app/openbel/api/routes/annotations.rb +168 -0
  23. data/app/openbel/api/routes/authenticate.rb +108 -0
  24. data/app/openbel/api/routes/base.rb +326 -0
  25. data/app/openbel/api/routes/datasets.rb +519 -0
  26. data/app/openbel/api/routes/evidence.rb +330 -0
  27. data/app/openbel/api/routes/expressions.rb +560 -0
  28. data/app/openbel/api/routes/functions.rb +41 -0
  29. data/app/openbel/api/routes/namespaces.rb +382 -0
  30. data/app/openbel/api/routes/root.rb +39 -0
  31. data/app/openbel/api/schemas.rb +34 -0
  32. data/app/openbel/api/schemas/annotation_collection.schema.json +20 -0
  33. data/app/openbel/api/schemas/annotation_resource.schema.json +36 -0
  34. data/app/openbel/api/schemas/annotation_value_collection.schema.json +21 -0
  35. data/app/openbel/api/schemas/annotation_value_resource.schema.json +35 -0
  36. data/app/openbel/api/schemas/completion_collection.schema.json +21 -0
  37. data/app/openbel/api/schemas/completion_resource.schema.json +146 -0
  38. data/app/openbel/api/schemas/evidence.schema.json +198 -0
  39. data/app/openbel/api/schemas/evidence_collection.schema.json +98 -0
  40. data/app/openbel/api/schemas/evidence_resource.schema.json +29 -0
  41. data/app/openbel/api/schemas/namespace_value_collection.schema.json +21 -0
  42. data/app/openbel/api/schemas/namespace_value_resource.schema.json +43 -0
  43. data/app/openbel/api/util.rb +11 -0
  44. data/bin/openbel-api +78 -0
  45. data/bin/openbel-config +46 -0
  46. data/config/async_evidence.rb +12 -0
  47. data/config/async_jena.rb +14 -0
  48. data/config/config.yml +31 -0
  49. data/config/server_config.rb +184 -0
  50. data/lib/openbel/api/cache/cache.rb +30 -0
  51. data/lib/openbel/api/config/config.rb +33 -0
  52. data/lib/openbel/api/evidence/api.rb +39 -0
  53. data/lib/openbel/api/evidence/facet_api.rb +18 -0
  54. data/lib/openbel/api/evidence/facet_filter.rb +83 -0
  55. data/lib/openbel/api/evidence/mongo.rb +247 -0
  56. data/lib/openbel/api/evidence/mongo_facet.rb +105 -0
  57. data/lib/openbel/api/helpers/dependency_graph.rb +52 -0
  58. data/lib/openbel/api/model/rdf_resource.rb +74 -0
  59. data/lib/openbel/api/plugin/cache/kyotocabinet.rb +85 -0
  60. data/lib/openbel/api/plugin/configure_plugins.rb +97 -0
  61. data/lib/openbel/api/plugin/evidence/evidence.rb +58 -0
  62. data/lib/openbel/api/plugin/plugin.rb +99 -0
  63. data/lib/openbel/api/plugin/plugin_manager.rb +20 -0
  64. data/lib/openbel/api/plugin/plugin_repository.rb +60 -0
  65. data/lib/openbel/api/storage/cache_proxy.rb +74 -0
  66. data/lib/openbel/api/storage/triple_storage.rb +43 -0
  67. metadata +379 -0
@@ -0,0 +1,105 @@
1
+ require 'mongo'
2
+ require 'multi_json'
3
+ require_relative 'facet_api'
4
+ require_relative 'facet_filter'
5
+
6
+ module OpenBEL
7
+ module Evidence
8
+
9
+ class EvidenceFacets
10
+ include FacetAPI
11
+ include Mongo
12
+ include FacetFilter
13
+
14
+ def initialize(options = {})
15
+ host = options.delete(:host)
16
+ port = options.delete(:port)
17
+ db = options.delete(:database)
18
+ @db = MongoClient.new(host, port).db(db)
19
+ @evidence = @db[:evidence]
20
+ @evidence_facets = @db[:evidence_facets]
21
+ end
22
+
23
+ def create_facets(_id, query_hash)
24
+ # create and save facets, identified by query
25
+ facets_doc = _id.merge({
26
+ :facets => evidence_facets(query_hash)
27
+ })
28
+ @evidence_facets.save(facets_doc, :j => true)
29
+
30
+ # return facets document
31
+ facets_doc
32
+ end
33
+
34
+ def find_facets(query_hash, filters)
35
+ _id = {:_id => to_facets_id(filters)}
36
+ @evidence_facets.find_one(_id) || create_facets(_id, query_hash)
37
+ end
38
+
39
+ def remove_facets_by_filters(filters = [], options = {})
40
+ remove_spec =
41
+ if filters.empty?
42
+ { :_id => "" }
43
+ else
44
+ {
45
+ :_id => {
46
+ :$in => filters.map { |filter|
47
+ to_regexp(MultiJson.load(filter))
48
+ }
49
+ }
50
+ }
51
+ end
52
+ @evidence_facets.remove(remove_spec, :j => true)
53
+ end
54
+
55
+ private
56
+
57
+ def to_regexp(filter)
58
+ filter_s = "#{filter['category']}|#{filter['name']}|#{filter['value']}"
59
+ %r{.*#{Regexp.escape(filter_s)}.*}
60
+ end
61
+
62
+
63
+ def to_facets_id(filters)
64
+ filters.map { |filter|
65
+ "#{filter['category']}|#{filter['name']}|#{filter['value']}"
66
+ }.sort.join(',')
67
+ end
68
+
69
+ def evidence_facets(query_hash = nil)
70
+ pipeline =
71
+ if query_hash.is_a?(Hash) && !query_hash.empty?
72
+ [{:'$match' => query_hash}] + AGGREGATION_PIPELINE
73
+ else
74
+ AGGREGATION_PIPELINE
75
+ end
76
+ @evidence.aggregate(pipeline)
77
+ end
78
+
79
+ AGGREGATION_PIPELINE = [
80
+ {
81
+ :'$project' => {
82
+ :_id => 0,
83
+ :facets => 1
84
+ }
85
+ },
86
+ {
87
+ :'$unwind' => '$facets'
88
+ },
89
+ {
90
+ :'$group' => {
91
+ :_id => '$facets',
92
+ :count => {
93
+ :'$sum' => 1
94
+ }
95
+ }
96
+ },
97
+ {
98
+ :'$sort' => {
99
+ :count => -1
100
+ }
101
+ }
102
+ ]
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,52 @@
1
+ require 'tsort'
2
+
3
+ module OpenBEL
4
+ module Helpers
5
+
6
+ class DependencyGraph
7
+ include TSort
8
+
9
+ def initialize
10
+ @hash = Hash.new { |hash, key| hash[key] = [] }
11
+ end
12
+
13
+ def [](key)
14
+ @hash[key]
15
+ end
16
+
17
+ def add_dependency(first, *dependency_requirements)
18
+ @hash[first] ||= []
19
+ (dependency_requirements || []).flatten.each do |dep|
20
+ _add_dependency(first, dep)
21
+ end
22
+ @hash[first]
23
+ end
24
+
25
+ def delete(key)
26
+ @hash.delete(key)
27
+ end
28
+
29
+ def each_key(&block)
30
+ @hash.each_key(&block)
31
+ end
32
+
33
+ def tsort_each_child(key, &block)
34
+ @hash[key].each(&block)
35
+ end
36
+
37
+ def tsort_each_node(&block)
38
+ @hash.each_key(&block)
39
+ end
40
+
41
+ private
42
+
43
+ def _add_dependency(key1, key2)
44
+ @hash[key1] << key2
45
+ @hash[key2] = []
46
+ key2
47
+ end
48
+ end
49
+ end
50
+ end
51
+ # vim: ts=2 sts=2 sw=2 expandtab
52
+ # encoding: utf-8
@@ -0,0 +1,74 @@
1
+ module OpenBEL
2
+ module Model
3
+
4
+ VOCABULARY_RDF = 'http://www.openbel.org/vocabulary/'
5
+
6
+ def self.included base
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ def from(statements)
12
+ obj = self.new
13
+ statements.each do |sub, pred, obj_val|
14
+ index = pred.rindex('#') || pred.rindex('/')
15
+ if index
16
+ attribute = pred[index+1..-1]
17
+
18
+ # handle type statement
19
+ if attribute == 'type'
20
+ # ... the URI
21
+ if obj.respond_to?(:uri=)
22
+ obj.send(:uri=, sub)
23
+ end
24
+ # ... the BEL vocabulary type
25
+ if obj_val.start_with?(VOCABULARY_RDF) and obj.respond_to?(:type=)
26
+ obj.send(:type=, obj_val)
27
+ next
28
+ end
29
+ end
30
+ if obj.respond_to? :"#{attribute}="
31
+ obj.send(:"#{attribute}=", obj_val)
32
+ end
33
+ else
34
+ $stderr.puts "cannot parse local name for #{pred}"
35
+ end
36
+ end
37
+ (obj.respond_to? :uri and obj.uri) ? obj : nil
38
+ end
39
+ end
40
+
41
+ class RdfResource
42
+ include OpenBEL::Model
43
+
44
+ def initialize(attr_values = {})
45
+ attr_values.each { |k, v|
46
+ instance_variable_set(:"@#{k}", v)
47
+ }
48
+ end
49
+
50
+ attr_accessor :uri
51
+
52
+ def ==(other)
53
+ return false if other == nil
54
+ @uri == other.uri
55
+ end
56
+
57
+ def hash
58
+ @uri.hash
59
+ end
60
+
61
+ def to_hash
62
+ instance_variables.inject({}) { |res, attr|
63
+ res.merge({attr[1..-1] => instance_variable_get(attr)})
64
+ }
65
+ end
66
+
67
+ def to_s
68
+ @uri
69
+ end
70
+ end
71
+ end
72
+ end
73
+ # vim: ts=2 sts=2 sw=2
74
+ # encoding: utf-8
@@ -0,0 +1,85 @@
1
+ require 'pp'
2
+ require_relative '../plugin'
3
+
4
+ module OpenBEL
5
+ module Plugin
6
+
7
+ class CacheKyotoCabinet
8
+ include OpenBEL::Plugin
9
+
10
+ ID = 'kyotocabinet'
11
+ NAME = 'KyotoCabinet Cache'
12
+ DESC = 'Cache implementation using KyotoCabinet over FFI.'
13
+ MEMR_TYPES = [ :"memory-hash" ]
14
+ FILE_TYPES = [ :"file-hash" ]
15
+ TYPE_OPTION_VALUES = [ MEMR_TYPES, FILE_TYPES ].flatten
16
+ MODE_OPTION_VALUES = [ :reader, :writer, :create ]
17
+
18
+ CREATE_MUTEX = Mutex.new
19
+
20
+ def id
21
+ ID
22
+ end
23
+
24
+ def name
25
+ NAME
26
+ end
27
+
28
+ def description
29
+ DESC
30
+ end
31
+
32
+ def type
33
+ :cache
34
+ end
35
+
36
+ def on_load
37
+ require 'kyotocabinet_ffi'
38
+ end
39
+
40
+ def validate(extensions = {}, options = {})
41
+ type = options.delete(:type)
42
+ if not type
43
+ return ValidationError.new(self, :type, "Option is missing. Options are one of [#{TYPE_OPTION_VALUES.join(', ')}].")
44
+ end
45
+ type = type.to_sym
46
+ if not TYPE_OPTION_VALUES.include?(type)
47
+ return ValidationError.new(self, :type, "Value not supported. Options are one of [#{TYPE_OPTION_VALUES.join(', ')}].")
48
+ end
49
+
50
+ mode = options.delete(:mode)
51
+ if not mode
52
+ return ValidationError.new(self, :mode, "Option is missing. Options are one of [#{MODE_OPTION_VALUES.join(', ')}].")
53
+ end
54
+ mode = mode.map { |v| v.to_s.to_sym }
55
+
56
+ validation_successful
57
+ end
58
+
59
+ def configure(extensions = {}, options = {})
60
+ @options = options
61
+ end
62
+
63
+ def create_instance
64
+ CREATE_MUTEX.lock
65
+ begin
66
+ unless @instance
67
+ type = @options[:type].to_sym
68
+ mode = @options[:mode].map { |v| v.to_s.to_sym }
69
+
70
+ @instance = case type
71
+ when :"memory-hash"
72
+ KyotoCabinet::Db::MemoryHash.new mode
73
+ when :"file-hash"
74
+ KyotoCabinet::Db::PolymorphicDb::tmp_filedb(KyotoCabinet::FILE_HASH)
75
+ end
76
+ end
77
+ ensure
78
+ CREATE_MUTEX.unlock
79
+ end
80
+
81
+ @instance
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,97 @@
1
+ require_relative '../helpers/dependency_graph'
2
+
3
+ module OpenBEL
4
+ module ConfigurePlugins
5
+
6
+ def check_configuration(plugins, config)
7
+ sorted_plugin_config_ids = build_dependency_graph(config)
8
+
9
+ all_errors = []
10
+ valid_plugins = {}
11
+ sorted_plugin_config_ids.each do |plugin_config_id|
12
+ # validate plugin configuration...
13
+ plugin_config = config[plugin_config_id.to_s]
14
+
15
+ # ...check plugin defines required properties
16
+ ['type', 'plugin'].each do |p|
17
+ errors << %Q{The "#{p}" property (defined in "#{plugin_config_id}") does not define a type.} unless plugin_config.has_key?(p)
18
+ next
19
+ end
20
+ type = plugin_config['type']
21
+ plugin_id = plugin_config['plugin']
22
+
23
+ # ...check if any plugin(s) are loaded for specified type
24
+ if plugins.none? { |p| p.type.to_s.to_sym == type.to_s.to_sym }
25
+ errors << %Q{The "#{type}" type (defined in "#{plugin_config_id}") does not have any registered plugins.}
26
+ end
27
+
28
+ # ...check if plugin exists
29
+ plugin = plugins.find { |p| p.id == plugin_id }
30
+ unless plugin
31
+ errors << %Q{The "#{plugin_id}" plugin (defined in "#{plugin_config_id}") does not have any registered plugins.}
32
+ end
33
+
34
+ # ...check plugin extensions
35
+ extensions = plugin_config['extensions'] || {}
36
+ extensions.values.find_all { |ext|
37
+ not valid_plugins.has_key? ext.to_s
38
+ }.each do |ext|
39
+ all_errors << %Q{The "#{ext}" extension (defined in "#{plugin_config_id}") is not valid.}
40
+ end
41
+
42
+ # ...prepare extensions/options for plugin validation
43
+ extensions = Hash[extensions.map { |ext_type, ext_id|
44
+ [ext_type.to_s.to_sym, valid_plugins[ext_id.to_s]]
45
+ }]
46
+ options = Hash[(plugin_config['options'] || {}).map { |k, v|
47
+ [k.to_s.to_sym, v]
48
+ }]
49
+
50
+ # ...call plugin-specific validation
51
+ plugin_errors = [plugin.validate(extensions.dup, options.dup)].flatten.map(&:to_s)
52
+ if plugin_errors.empty?
53
+ valid_plugins[plugin_config_id.to_s] = plugin
54
+ else
55
+ all_errors.concat(plugin_errors)
56
+ end
57
+ # TODO Log successful plugin check if verbose.
58
+ end
59
+ all_errors
60
+ end
61
+
62
+ def configure_plugins(plugins, config)
63
+ sorted_plugin_config_ids = build_dependency_graph(config)
64
+ sorted_plugin_config_ids.inject({}) { |plugins_by_id, plugin_config_id|
65
+ plugin_config = config[plugin_config_id.to_s]
66
+
67
+ plugin_id = plugin_config['plugin']
68
+
69
+ plugin = plugins.find { |p| p.id == plugin_id }
70
+ extensions = Hash[(plugin_config['extensions'] || {}).map { |type, id|
71
+ [type.to_s.to_sym, plugins_by_id[id.to_s]]
72
+ }]
73
+ options = Hash[(plugin_config['options'] || {}).map { |k, v|
74
+ [k.to_s.to_sym, v]
75
+ }]
76
+
77
+ plugin.configure(extensions.dup, options.dup)
78
+ plugin.on_load
79
+
80
+ plugins_by_id[plugin_config_id.to_s] = plugin
81
+ plugins_by_id
82
+ }
83
+ end
84
+
85
+ private
86
+
87
+ def build_dependency_graph(config)
88
+ dependency_graph = Helpers::DependencyGraph.new
89
+ config.keys.each do |plugin_key|
90
+ block = config[plugin_key]
91
+ dependencies = (block['extensions'] || {}).each_value.to_a.map { |v| v.to_s.to_sym }
92
+ dependency_graph.add_dependency(plugin_key.to_s, *dependencies)
93
+ end
94
+ dependency_graph.tsort
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,58 @@
1
+ require_relative '../plugin'
2
+
3
+ module OpenBEL
4
+ module Plugin
5
+
6
+ class Evidence
7
+ include OpenBEL::Plugin
8
+
9
+ ID = 'evidence'
10
+ NAME = 'OpenBEL Evidence API'
11
+ DESC = 'API for accesing OpenBEL Evidence.'
12
+
13
+ def id
14
+ ID
15
+ end
16
+
17
+ def name
18
+ NAME
19
+ end
20
+
21
+ def description
22
+ DESC
23
+ end
24
+
25
+ def type
26
+ :evidence
27
+ end
28
+
29
+ def required_extensions
30
+ []
31
+ end
32
+
33
+ def optional_extensions
34
+ []
35
+ end
36
+
37
+ def on_load
38
+ require_relative '../../evidence/mongo'
39
+ end
40
+
41
+ def validate(extensions = {}, options = {})
42
+ [:host, :port, :database].map { |setting|
43
+ unless options[setting]
44
+ ValidationError.new(self, :storage, "The #{setting} setting is missing.")
45
+ end
46
+ }.compact!
47
+ end
48
+
49
+ def configure(extensions = {}, options = {})
50
+ @options = options
51
+ end
52
+
53
+ def create_instance
54
+ OpenBEL::Evidence::Evidence.new(@options)
55
+ end
56
+ end
57
+ end
58
+ end