openbel-api 0.4.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gemspec +65 -0
- data/CHANGELOG.md +22 -0
- data/INSTALL.md +19 -0
- data/INSTALL_RUBY.md +107 -0
- data/LICENSE +191 -0
- data/README.md +208 -0
- data/app/openbel/api/app.rb +83 -0
- data/app/openbel/api/config.rb +45 -0
- data/app/openbel/api/config.ru +3 -0
- data/app/openbel/api/helpers/pager.rb +109 -0
- data/app/openbel/api/middleware/auth.rb +112 -0
- data/app/openbel/api/resources/adapters/basic_json.rb +52 -0
- data/app/openbel/api/resources/annotation.rb +141 -0
- data/app/openbel/api/resources/base.rb +16 -0
- data/app/openbel/api/resources/completion.rb +89 -0
- data/app/openbel/api/resources/evidence.rb +115 -0
- data/app/openbel/api/resources/evidence_transform.rb +143 -0
- data/app/openbel/api/resources/function.rb +98 -0
- data/app/openbel/api/resources/match_result.rb +79 -0
- data/app/openbel/api/resources/namespace.rb +174 -0
- data/app/openbel/api/routes/annotations.rb +168 -0
- data/app/openbel/api/routes/authenticate.rb +108 -0
- data/app/openbel/api/routes/base.rb +326 -0
- data/app/openbel/api/routes/datasets.rb +519 -0
- data/app/openbel/api/routes/evidence.rb +330 -0
- data/app/openbel/api/routes/expressions.rb +560 -0
- data/app/openbel/api/routes/functions.rb +41 -0
- data/app/openbel/api/routes/namespaces.rb +382 -0
- data/app/openbel/api/routes/root.rb +39 -0
- data/app/openbel/api/schemas.rb +34 -0
- data/app/openbel/api/schemas/annotation_collection.schema.json +20 -0
- data/app/openbel/api/schemas/annotation_resource.schema.json +36 -0
- data/app/openbel/api/schemas/annotation_value_collection.schema.json +21 -0
- data/app/openbel/api/schemas/annotation_value_resource.schema.json +35 -0
- data/app/openbel/api/schemas/completion_collection.schema.json +21 -0
- data/app/openbel/api/schemas/completion_resource.schema.json +146 -0
- data/app/openbel/api/schemas/evidence.schema.json +198 -0
- data/app/openbel/api/schemas/evidence_collection.schema.json +98 -0
- data/app/openbel/api/schemas/evidence_resource.schema.json +29 -0
- data/app/openbel/api/schemas/namespace_value_collection.schema.json +21 -0
- data/app/openbel/api/schemas/namespace_value_resource.schema.json +43 -0
- data/app/openbel/api/util.rb +11 -0
- data/bin/openbel-api +78 -0
- data/bin/openbel-config +46 -0
- data/config/async_evidence.rb +12 -0
- data/config/async_jena.rb +14 -0
- data/config/config.yml +31 -0
- data/config/server_config.rb +184 -0
- data/lib/openbel/api/cache/cache.rb +30 -0
- data/lib/openbel/api/config/config.rb +33 -0
- data/lib/openbel/api/evidence/api.rb +39 -0
- data/lib/openbel/api/evidence/facet_api.rb +18 -0
- data/lib/openbel/api/evidence/facet_filter.rb +83 -0
- data/lib/openbel/api/evidence/mongo.rb +247 -0
- data/lib/openbel/api/evidence/mongo_facet.rb +105 -0
- data/lib/openbel/api/helpers/dependency_graph.rb +52 -0
- data/lib/openbel/api/model/rdf_resource.rb +74 -0
- data/lib/openbel/api/plugin/cache/kyotocabinet.rb +85 -0
- data/lib/openbel/api/plugin/configure_plugins.rb +97 -0
- data/lib/openbel/api/plugin/evidence/evidence.rb +58 -0
- data/lib/openbel/api/plugin/plugin.rb +99 -0
- data/lib/openbel/api/plugin/plugin_manager.rb +20 -0
- data/lib/openbel/api/plugin/plugin_repository.rb +60 -0
- data/lib/openbel/api/storage/cache_proxy.rb +74 -0
- data/lib/openbel/api/storage/triple_storage.rb +43 -0
- metadata +379 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module OpenBEL::Cache
|
2
|
+
module Cache
|
3
|
+
|
4
|
+
def [](key)
|
5
|
+
read(key)
|
6
|
+
end
|
7
|
+
|
8
|
+
def []=(key, value)
|
9
|
+
write(key, value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def clear
|
13
|
+
purge
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def read(key)
|
19
|
+
fail NotImplementedError.new, "#{__method__} is not implemented"
|
20
|
+
end
|
21
|
+
|
22
|
+
def write(key, value)
|
23
|
+
fail NotImplementedError.new, "#{__method__} is not implemented"
|
24
|
+
end
|
25
|
+
|
26
|
+
def purge
|
27
|
+
fail NotImplementedError.new, "#{__method__} is not implemented"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require_relative '../plugin/plugin_manager'
|
3
|
+
|
4
|
+
module OpenBEL
|
5
|
+
module Config
|
6
|
+
|
7
|
+
CFG_VAR = 'OPENBEL_SERVER_CONFIG'
|
8
|
+
PLUGIN_PATHS = 'plugin_paths'
|
9
|
+
|
10
|
+
def self.load(config_file=nil)
|
11
|
+
config_file = ENV[CFG_VAR] || config_file
|
12
|
+
fail %Q{The configuration file is empty.} unless config_file
|
13
|
+
|
14
|
+
config = File.open(config_file, 'r:UTF-8') do |cf|
|
15
|
+
{}.merge(YAML::load(cf))
|
16
|
+
end
|
17
|
+
|
18
|
+
plugin_manager = PluginManager.new
|
19
|
+
plugin_manager.with_plugins_from([config.delete(PLUGIN_PATHS)].flatten.compact.map(&:to_s))
|
20
|
+
plugins = plugin_manager.to_a
|
21
|
+
|
22
|
+
errors = plugin_manager.check_configuration(plugins, config)
|
23
|
+
|
24
|
+
if !errors.empty?
|
25
|
+
fail RuntimeError.new(errors.join("\n"))
|
26
|
+
end
|
27
|
+
|
28
|
+
plugin_manager.configure_plugins(plugins.dup, config.dup)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
# vim: ts=2 sts=2 sw=2 expandtab
|
33
|
+
# encoding: utf-8
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module OpenBEL
|
2
|
+
module Evidence
|
3
|
+
module API
|
4
|
+
|
5
|
+
# single or array
|
6
|
+
def create_evidence(evidence)
|
7
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_evidence_by_id(id)
|
11
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_evidence(filters = [], offset = 0, length = 0, facet = false)
|
15
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
16
|
+
end
|
17
|
+
|
18
|
+
def count_evidence(filters = [])
|
19
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_evidence_by_id(id, evidence_update)
|
23
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
24
|
+
end
|
25
|
+
|
26
|
+
def update_evidence_by_query(query, evidence_update)
|
27
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete_evidence_by_id(id)
|
31
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete_evidence_by_query(query)
|
35
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module OpenBEL
|
2
|
+
module Evidence
|
3
|
+
module FacetAPI
|
4
|
+
|
5
|
+
def create_facets(evidence)
|
6
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
7
|
+
end
|
8
|
+
|
9
|
+
def find_facets_by_filters(filters = [])
|
10
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
11
|
+
end
|
12
|
+
|
13
|
+
def remove_facets_by_filters(filters = [])
|
14
|
+
fail NotImplementedError, "#{__method__} is not implemented"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module OpenBEL
|
4
|
+
module Evidence
|
5
|
+
module FacetFilter
|
6
|
+
|
7
|
+
EMPTY = []
|
8
|
+
EVIDENCE_PARTS = [:citation, :experiment_context, :metadata]
|
9
|
+
|
10
|
+
def map_evidence_facets(evidence)
|
11
|
+
EVIDENCE_PARTS.reduce([]) { |facets, evidence_part|
|
12
|
+
part = evidence.send(evidence_part)
|
13
|
+
new_facets = self.send(:"map_#{evidence_part}_facets", part)
|
14
|
+
facets.concat(new_facets)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def map_citation_facets(citation)
|
19
|
+
if citation and citation.id
|
20
|
+
[
|
21
|
+
self.make_filter(:citation, :id, citation.id)
|
22
|
+
]
|
23
|
+
else
|
24
|
+
EMPTY
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def map_experiment_context_facets(experiment_context)
|
29
|
+
if experiment_context
|
30
|
+
experiment_context.flat_map { |annotation|
|
31
|
+
name = annotation[:name]
|
32
|
+
value = annotation[:value]
|
33
|
+
if value.respond_to?(:each)
|
34
|
+
value.map { |v|
|
35
|
+
[:experiment_context, name, v]
|
36
|
+
}
|
37
|
+
else
|
38
|
+
# HACK: nested array will be flattened out by flat_map;
|
39
|
+
# otherwise we would have each data value unrolled
|
40
|
+
[[:experiment_context, name, value]]
|
41
|
+
end
|
42
|
+
}.select { |(_, _, value)|
|
43
|
+
value != nil
|
44
|
+
}.map { |filter|
|
45
|
+
self.make_filter(*filter)
|
46
|
+
}
|
47
|
+
else
|
48
|
+
EMPTY
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def map_metadata_facets(metadata)
|
53
|
+
if metadata
|
54
|
+
metadata.flat_map { |name, value|
|
55
|
+
if value.respond_to?(:each)
|
56
|
+
value.map { |v|
|
57
|
+
[:metadata, name, v]
|
58
|
+
}
|
59
|
+
else
|
60
|
+
# HACK: nested array will be flattened out by flat_map;
|
61
|
+
# otherwise we would have each data value unrolled
|
62
|
+
[[:metadata, name, value]]
|
63
|
+
end
|
64
|
+
}.select { |_, _, value|
|
65
|
+
value != nil
|
66
|
+
}.map { |filter|
|
67
|
+
self.make_filter(*filter)
|
68
|
+
}
|
69
|
+
else
|
70
|
+
EMPTY
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def make_filter(category, name, value)
|
75
|
+
MultiJson.dump({
|
76
|
+
:category => category,
|
77
|
+
:name => name,
|
78
|
+
:value => value,
|
79
|
+
})
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
require 'bel'
|
2
|
+
require 'mongo'
|
3
|
+
require_relative 'api'
|
4
|
+
require_relative 'mongo_facet'
|
5
|
+
|
6
|
+
module OpenBEL
|
7
|
+
module Evidence
|
8
|
+
|
9
|
+
class Evidence
|
10
|
+
include API
|
11
|
+
include Mongo
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
host = options.delete(:host)
|
15
|
+
port = options.delete(:port)
|
16
|
+
db = options.delete(:database)
|
17
|
+
@db = MongoClient.new(host, port).db(db)
|
18
|
+
@collection = @db[:evidence]
|
19
|
+
@collection.ensure_index(
|
20
|
+
{:"bel_statement" => Mongo::ASCENDING },
|
21
|
+
:background => true
|
22
|
+
)
|
23
|
+
@collection.ensure_index(
|
24
|
+
{:"$**" => Mongo::TEXT },
|
25
|
+
:background => true
|
26
|
+
)
|
27
|
+
@evidence_facets = EvidenceFacets.new(
|
28
|
+
:host => host,
|
29
|
+
:port => port,
|
30
|
+
:database => db
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_evidence(evidence)
|
35
|
+
# insert evidence; acknowledge journal
|
36
|
+
if evidence.respond_to?(:each_pair)
|
37
|
+
_id = @collection.insert(evidence, :w => 1, :j => true)
|
38
|
+
|
39
|
+
# remove evidence_facets after insert to facets
|
40
|
+
remove_evidence_facets(_id)
|
41
|
+
_id
|
42
|
+
elsif evidence.respond_to?(:each)
|
43
|
+
@collection.insert(evidence.to_a, :w => 1, :j => true)
|
44
|
+
else
|
45
|
+
raise "Evidence type #{evidence.class} cannot be inserted into Mongo."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_evidence_by_id(value)
|
50
|
+
@collection.find_one(to_id(value))
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_evidence(filters = [], offset = 0, length = 0, facet = false)
|
54
|
+
query_hash = to_query(filters)
|
55
|
+
query_opts = query_options(
|
56
|
+
query_hash,
|
57
|
+
:skip => offset,
|
58
|
+
:limit => length,
|
59
|
+
:sort => [
|
60
|
+
[:bel_statement, :asc]
|
61
|
+
]
|
62
|
+
)
|
63
|
+
|
64
|
+
results = {
|
65
|
+
:cursor => @collection.find(query_hash, query_opts)
|
66
|
+
}
|
67
|
+
if facet
|
68
|
+
facets_doc = @evidence_facets.find_facets(query_hash, filters)
|
69
|
+
results[:facets] = facets_doc["facets"]
|
70
|
+
end
|
71
|
+
|
72
|
+
results
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_dataset_evidence(dataset, filters = [], offset = 0, length = 0, facet = false)
|
76
|
+
query_hash = to_query(filters)
|
77
|
+
query_hash[:$and] ||= []
|
78
|
+
query_hash[:$and].unshift({
|
79
|
+
:_dataset => dataset[:identifier]
|
80
|
+
})
|
81
|
+
|
82
|
+
query_opts = query_options(
|
83
|
+
query_hash,
|
84
|
+
:skip => offset,
|
85
|
+
:limit => length,
|
86
|
+
:sort => [
|
87
|
+
[:bel_statement, :asc]
|
88
|
+
]
|
89
|
+
)
|
90
|
+
|
91
|
+
results = {
|
92
|
+
:cursor => @collection.find(query_hash, query_opts)
|
93
|
+
}
|
94
|
+
if facet
|
95
|
+
facets_doc = @evidence_facets.find_facets(query_hash, filters)
|
96
|
+
results[:facets] = facets_doc["facets"]
|
97
|
+
end
|
98
|
+
|
99
|
+
results
|
100
|
+
end
|
101
|
+
|
102
|
+
def count_evidence(filters = [])
|
103
|
+
query_hash = to_query(filters)
|
104
|
+
@collection.count(:query => query_hash)
|
105
|
+
end
|
106
|
+
|
107
|
+
def update_evidence_by_id(value, evidence)
|
108
|
+
# add ObjectId to update
|
109
|
+
_id = BSON::ObjectId(value)
|
110
|
+
evidence_h = evidence.to_h
|
111
|
+
evidence_h[:_id] = _id
|
112
|
+
|
113
|
+
# save evidence; acknowledge journal
|
114
|
+
@collection.save(evidence_h, :j => true)
|
115
|
+
|
116
|
+
# remove evidence_facets after update to facets
|
117
|
+
remove_evidence_facets(_id)
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
|
121
|
+
def delete_dataset(identifier)
|
122
|
+
@collection.ensure_index(
|
123
|
+
{:"_dataset" => Mongo::ASCENDING },
|
124
|
+
:background => true
|
125
|
+
)
|
126
|
+
|
127
|
+
@collection.remove(
|
128
|
+
{ :"_dataset" => identifier },
|
129
|
+
:j => true
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def delete_evidence(value)
|
134
|
+
if value.respond_to?(:each)
|
135
|
+
value.each do |v|
|
136
|
+
delete_evidence_by_id(v)
|
137
|
+
end
|
138
|
+
else
|
139
|
+
delete_evidence_by_id(value)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def delete_evidence_by_query(query)
|
144
|
+
@collection.remove(
|
145
|
+
query,
|
146
|
+
:j => true
|
147
|
+
)
|
148
|
+
end
|
149
|
+
|
150
|
+
def delete_evidence_by_id(value)
|
151
|
+
# convert to ObjectId
|
152
|
+
begin
|
153
|
+
_id = to_id(value)
|
154
|
+
rescue BSON::InvalidObjectId
|
155
|
+
# indicate that a delete was unsuccessful
|
156
|
+
false
|
157
|
+
end
|
158
|
+
|
159
|
+
# remove evidence_facets before evidence removal
|
160
|
+
remove_evidence_facets(_id)
|
161
|
+
|
162
|
+
# remove evidence; returns true
|
163
|
+
@collection.remove(
|
164
|
+
{
|
165
|
+
:_id => _id
|
166
|
+
},
|
167
|
+
:j => true
|
168
|
+
)
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def to_query(filters = [])
|
174
|
+
if !filters || filters.empty?
|
175
|
+
return {}
|
176
|
+
end
|
177
|
+
|
178
|
+
query_hash = {
|
179
|
+
:$and => filters.map { |filter|
|
180
|
+
category = filter['category']
|
181
|
+
name = filter['name']
|
182
|
+
value = filter['value']
|
183
|
+
|
184
|
+
if category == 'fts' && name == 'search'
|
185
|
+
{:$text => { :$search => value }}
|
186
|
+
elsif category == 'experiment_context'
|
187
|
+
{
|
188
|
+
:experiment_context => {
|
189
|
+
:$elemMatch => {
|
190
|
+
:name => name.to_s,
|
191
|
+
:value => value.to_s
|
192
|
+
}
|
193
|
+
}
|
194
|
+
}
|
195
|
+
elsif category == 'metadata'
|
196
|
+
{
|
197
|
+
:metadata => {
|
198
|
+
:$elemMatch => {
|
199
|
+
:name => name.to_s,
|
200
|
+
:value => value.to_s
|
201
|
+
}
|
202
|
+
}
|
203
|
+
}
|
204
|
+
else
|
205
|
+
{
|
206
|
+
"#{filter['category']}.#{filter['name']}" => filter['value'].to_s
|
207
|
+
}
|
208
|
+
end
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
query_hash
|
213
|
+
end
|
214
|
+
|
215
|
+
def query_options(query_hash, options = {})
|
216
|
+
if query_hash[:$text]
|
217
|
+
options[:fields] = [
|
218
|
+
{
|
219
|
+
:score => {
|
220
|
+
:$meta => "textScore"
|
221
|
+
}
|
222
|
+
}
|
223
|
+
]
|
224
|
+
options[:sort].unshift(
|
225
|
+
[:score, {:$meta => "textScore"}]
|
226
|
+
)
|
227
|
+
end
|
228
|
+
options
|
229
|
+
end
|
230
|
+
|
231
|
+
def to_id(value)
|
232
|
+
BSON::ObjectId(value.to_s)
|
233
|
+
end
|
234
|
+
|
235
|
+
def remove_evidence_facets(_id)
|
236
|
+
evidence = @collection.find_one(_id, {
|
237
|
+
:fields => [ 'facets' ]
|
238
|
+
})
|
239
|
+
|
240
|
+
if evidence && evidence.has_key?('facets')
|
241
|
+
@evidence_facets.remove_facets_by_filters(evidence['facets'])
|
242
|
+
@evidence_facets.remove_facets_by_filters
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|