ruby-rdf / rdf-ldp Goto Github PK
View Code? Open in Web Editor NEWA suite of LDP software and middleware for RDF.rb & Rack
License: The Unlicense
A suite of LDP software and middleware for RDF.rb & Rack
License: The Unlicense
Using RubyGems 2.5.1, I tried the following instructions from README.md
.
$ gem install rdf-ldp
$ lamprey
I received the following error.
.../.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/specification.rb:2158:in `method_missing': undefined method `this' for #<Gem::Specification:0xd14f20 rdf-ldp-0.6.0> (NoMethodError)
from .../.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/specification.rb:1057:in `find_active_stub_by_path'
from .../.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:64:in `require'
from .../.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.6.0/bin/lamprey:3:in `<top (required)>'
from .../.rvm/gems/ruby-2.3.0/bin/lamprey:23:in `load'
from .../.rvm/gems/ruby-2.3.0/bin/lamprey:23:in `<main>'
from .../.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval'
from .../.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>'
Updating RubyGems seems to solve the problem.
$ gem update --system
...
$ gem -v
2.6.4
$ lamprey
== Sinatra (v1.4.7) has taken the stage on 4567 for development with backup from Puma
Puma starting in single mode...
* Version 3.4.0 (ruby 2.3.0-p0), codename: Owl Bowl Brawl
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:4567
Use Ctrl-C to stop
With the introduction of PATCH
and Last-Modified
, there has started to be some creeping code duplication surrounding updates. This should be cleaned up to prevent it from spreading.
DirectContainer#create
and IndirectContainer#create
both require multiple transactions in cases where they automatically add default triples membership and/or inserted content relation triples.
We should resolve this so the behavior is consistently transactional and skewed reads are impossible; this is complicated by variable read isolation semantics for transactions.
#59 seems to fix #56, but makes RDF::LDP::RDFSource.parse_graph
, and therefore RDF::LDP::RDFSource.create
, no longer support strings as the first parameter. This seems to be intentional, but not reflected in the documentation of the mentioned methods and the example rack config in README.md.
$ rackup
.../.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.7.0/lib/rdf/ldp/rdf_source.rb:247:in `parse_graph': undefined method `rewind' for "":String (NoMethodError)
from .../.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.7.0/lib/rdf/ldp/rdf_source.rb:101:in `block in create'
from .../.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.7.0/lib/rdf/ldp/resource.rb:225:in `block in create'
from .../.rvm/gems/ruby-2.3.0/gems/rdf-2.0.1/lib/rdf/mixin/transactable.rb:56:in `transaction'
from .../.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.7.0/lib/rdf/ldp/resource.rb:223:in `create'
from .../.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.7.0/lib/rdf/ldp/rdf_source.rb:100:in `create'
from .../.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.7.0/lib/rdf/ldp/container.rb:43:in `create'
from .../sandbox/ruby/rdf-ldp/config.ru:19:in `block in <main>'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/builder.rb:55:in `instance_eval'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/builder.rb:55:in `initialize'
from .../sandbox/ruby/rdf-ldp/config.ru:in `new'
from .../sandbox/ruby/rdf-ldp/config.ru:in `<main>'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/builder.rb:49:in `eval'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/builder.rb:49:in `new_from_string'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/builder.rb:40:in `parse_file'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/server.rb:299:in `build_app_and_options_from_config'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/server.rb:208:in `app'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/server.rb:336:in `wrapped_app'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/server.rb:272:in `start'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/server.rb:147:in `start'
from .../.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/bin/rackup:4:in `<top (required)>'
from .../.rvm/gems/ruby-2.3.0/bin/rackup:22:in `load'
from .../.rvm/gems/ruby-2.3.0/bin/rackup:22:in `<main>'
from .../.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval'
from .../.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>'
The existing PATCH approaches I know of are SPARQL 1.1 Update and LDPatch.
Should we aim to pursue Update as an initial format, with the idea that we could also support LDPatch in the future? Are there other options we should consider?
I've put some work into RDF::Blazegraph
as a possible recommended backend.
I believe the requirements are:
It would be nice to have a fully public domain backend but Rack
and Sinatra
are under MIT, either way.
At #10, we expressed some interest in supporting LDPatch as a format for HTTP PATCH. Any work on this is dependent on an implementation somewhere upstream in RDF.rb.
LDP allows that LDP servers may choose to allow the creation of new resources using HTTP PUT.
It's not necessarily clear what the best approach to handling containment would be, if we choose to support this. Other servers handle it in various ways, with visible trade-offs. My inclination is to allow clients to create new, uncontained ("free floating") resources with any interaction model by PUTing to an unused URI.
In Container#post
we choose to give the created resource as the response body. When doing this, we also return the headers for the new resource as well.
LDP 5.2.1.4 requires returning a Container
Link header for all responses in requests to containers. The current behavior is in contravention of this.
Should POST responses be altered to include the Link header as required by 5.2.1.4? If so, should they also continue to return the ETag for the created resource?
The examples in the spec vary. Example 11/12 shows the container header; Example 15/16 do not. None of the examples in LDP Primer show a container header.
Test HTTP verb conformance and data consistency when running on a threaded server like Puma.
What is the best approach for benchmarking LDP?
patch
methods in RDFSource
and Container
pass a Rack::Lint::InputWrapper
object to either LD::Patch.parse
or SPARQL.execute
depending on the Content-Type. These methods don't support Rack::Lint::InputWrapper
, and both fail to execute the valid queries properly.
LD Patch requests have no effect on the resource graph (while they should), and SPARQL Update requests cause the following error.
$ curl -v --request PATCH -d @/home/user/example_patch_sparql.txt http://localhost:9292/ --header "Content-Type:application/sparql-update"
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9292 (#0)
> PATCH / HTTP/1.1
> Host: localhost:9292
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type:application/sparql-update
> Content-Length: 125
>
* upload completely sent off: 125 out of 125 bytes
< HTTP/1.1 500 Internal Server Error
< Content-Type: text/plain
< Content-Length: 3458
<
NoMethodError: undefined method `execute' for nil:NilClass
Did you mean? exec
~/.rvm/gems/ruby-2.3.0/gems/sparql-2.0.0/lib/sparql.rb:90:in `execute'
~/.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.6.0/lib/rdf/ldp/rdf_source.rb:202:in `sparql_update'
~/thesis/prototype/poc_server/app/rdf_source.rb:8:in `patch'
~/thesis/prototype/poc_server/app/resource.rb:23:in `patch'
~/.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.6.0/lib/rdf/ldp/resource.rb:426:in `request'
~/.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.6.0/lib/rack/ldp.rb:108:in `call'
~/thesis/prototype/poc_server/app/middleware/header_handler.rb:20:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.6.0/lib/rack/ldp.rb:75:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rdf-ldp-0.6.0/lib/rack/ldp.rb:56:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-linkeddata-1.1.0/lib/rack/linkeddata/conneg.rb:52:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/nulllogger.rb:9:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/head.rb:13:in `call'
~/.rvm/gems/ruby-2.3.0/gems/sinatra-1.4.7/lib/sinatra/show_exceptions.rb:25:in `call'
~/.rvm/gems/ruby-2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:182:in `call'
~/.rvm/gems/ruby-2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:2013:in `call'
~/.rvm/gems/ruby-2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1487:in `block in call'
~/.rvm/gems/ruby-2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1787:in `synchronize'
~/.rvm/gems/ruby-2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1487:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/tempfile_reaper.rb:15:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/lint.rb:49:in `_call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/lint.rb:37:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/showexceptions.rb:24:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/commonlogger.rb:33:in `call'
~/.rvm/gems/ruby-2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:219:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/chunked.rb:54:in `call'
~/.rvm/gems/ruby-2.3.0/gems/rack-1.6.4/lib/rack/content_length.rb:15:in `call'
~/.rvm/gems/ruby-2.3.0/gems/puma-3.4.0/lib/puma/configuration.rb:224:in `call'
~/.rvm/gems/ruby-2.3.0/gems/puma-3.4.0/lib/puma/server.rb:569:in `handle_request'
~/.rvm/gems/ruby-2.3.0/gems/puma-3.4.0/lib/puma/server.rb:406:in `process_client'
~/.rvm/gems/ruby-2.3.0/gems/puma-3.4.0/lib/puma/server.rb:271:in `block in run'
* Connection #0 to host localhost left intact
Where /home/user/example_patch_sparql.txt
has the following content:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT { <http://example/egbook> dc:title "This is an example title" } WHERE {}
Simply passing env['rack.input'].read
instead of env['rack.input']
seems to resolve the issue, since both methods support strings.
Allow configuration to select and connect to the backend when starting up Lamprey with bin/lamprey
.
See: fcrepo4-labs/derby#8
I am trying to come up with a simple cURL command to post a new resource and the following is giving me "RDF::LDP::NotFound"
curl -X POST -H "Accept: text/turtle" -d demo.ttl localhost:4567
Where the content of demo.ttl is
<> <http://purl.org/dc/elements/1.1/title> "demo" .
Any idea what I need to post to create resource?
The error on the server indicates
2015-09-09 17:40:05 - RDF::LDP::NotFound - RDF::LDP::NotFound:
/Users/hjc14/.gem/ruby/2.2.2/gems/rdf-ldp-0.3.0/lib/rdf/ldp/resource.rb:87:in `find'
/Users/hjc14/dev/rdf-ldp/app/lamprey.rb:28:in `block in <class:Lamprey>'
I have not stepped into the code, I'll try to get to that later, but if you have any ideas I would welcome them.
We're passing the tests under Rubinius. This ticket is to get the server running under Puma on Rubinius and scope out concurrency needs to feed back into RDF.rb and other RDF::Repository
projects.
See also: #47
The RDF.rb 2.0 beta is nearing. Once it is out, we should move RDF::LDP in that direction.
It will be necessary to support the 1.1 branch as for at least a short period, since it now powers https://github.com/fcrepo4-labs/derby, and integration tests for https://github.com/projecthydra/ldp.
LDP sec. 7.2 has guidance on include-parameter
and omit
hints for Prefer
headers. A default handling for these hints should be implemented as a middleware layer.
According to the README.md this should work:
$ gem install rdf-ldp
$ lamprey
But instead I get the following error
/Users/hjc14/.rubies/ruby-2.2.2/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:121:in `require': cannot load such file -- lamprey (LoadError)
from /Users/hjc14/.rubies/ruby-2.2.2/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:121:in `require'
from /Users/hjc14/.gem/ruby/2.2.2/gems/rdf-ldp-0.3.0/bin/lamprey:3:in `<top (required)>'
from /Users/hjc14/.gem/ruby/2.2.2/bin/lamprey:23:in `load'
from /Users/hjc14/.gem/ruby/2.2.2/bin/lamprey:23:in `<main>'
There is a cost to skolemization on the ruby-side, but it removes the issue of blank node compatibility from backends.
I want to add this to make RDF::Blazegraph
viable for this use case, and add some benchmark specs to make backend tests easy to apply.
Tests passing, runs on Ruby between 2.6 and 3.1 and RDF.rb/linkeddata 3.2. I have no rights to push to Rubygems.
RDF.rb 2.0 supports transactional reads. We should use them.
Depends on #46.
The README contains some documentation for setting up a custom LDP server with Rackup, but simply points to app/lamprey
for details.
A proper practical example should be added.
The main blocker for this is Sinatra, which has updated on master but is missing a release.
We'll want to decide which range of versions for Rack and Sinatra to support post release. Information on Rack's major release is thin on the ground, so we may need to do some legwork on this.
HTTP ETags currently require a full access of the resource plus a fairly complex hashing function.
We had discussed the possibility of simply storing a dcterms:modified
timestamp and basing the ETag on that. This option could be much cheaper (depending on the size of the RDFSource's graph), and would open the door to supporting If-Modified-Since
in #17.
We are currently marking resources as "deleted" (as a result of DELETE
requests; and leading to Gone
responses) by adding a triple <> rdf:type owl:Nothing
to the resource's #metagraph
. This is probably a bit ontologically heavy.
Perhaps a better approach is <> ns:deleted true
, where ns
is some internal namespace? An initial search (and asking around) didn't turn up a general solution for this.
Direct Containers make some interpretations of the LDP spec. We should carefully document their intended behavior in CONSTRAINED_BY.MD
and consider any changes we want to make soon.
We have a few problems with ETag handling:
If-Match
, we use weak.If-Match
(since we don't generate strong ETags).Discussion of this issue within the LDP WG is in this thread.
LDP recommends support of HTTP PATCH for Resources, especially for updating Containers.
At #10, we agreed to an initial implementation supporting SPARQL 1.1 Update format.
Conditional HTTP GET
with If-None-Match
header. Consider supporting If-Modified-Since
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.