Giter VIP home page Giter VIP logo

fcrepo-api-x's People

Contributors

acoburn avatar ajs6f avatar birkland avatar emetsger avatar jsavell avatar ruebot avatar wallberg avatar whikloj avatar yinlinchen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fcrepo-api-x's Issues

Engage CLAW

Islandora CLAW PHP/Camel microservices share some similar patterns to API-X.  Take a look at CLAW microservices & middleware to see where similarities and differences in API-X lie. Be the point person for communication between API-X or Islandora team members. A face-to-face may be appropriate

Create "Intro to API-X document"

This is a public-facing doc, authored by the stakeholders, intended to give an overview of API-X for those interested in assessing its suitability for meeting business needs.

Write stakeholder/evaluator guide

This is a document that describes the features, installed extensions, and evaluation steps:

Guide for stakeholders, providing instructions for evaluation tasks, see milestone doc

  • Start/run demo
  • Verify that all demo services are running
  • Look at a pre-installed  Fedora object
  • Look at a service document for a pre-installed fedora object
  • Interact with an exposed service in browser
  • Install an Amherst service
  • Deploy an extension to expose the amherst service
  • Ingest an object and verify the new service works on it
  • Compare service documents from objects that bind to different services
  • Look/execute some sparql queries
    • Find all objects that expose a particular service
    • Find all endpoints (exposed by api-x) on objects that implement a particular service
    • List all resource-scoped service endpoints for a particular object, and identify services they implement
  • Look at code snippets that try to invoke a specific service on an object
    • when given the URI for a repository object, discover the URI for the service endpoint of the service and invoke it

Allow for bypassing initialization when registry implementations/back-ends are not available.

When the API-X features start up, they want to initialize state in the Fedora repository.

When building docker images it would be useful to be able to install the API-X features at image build time.

The problem is that a Fedora repository isn't available at Docker image build time, so installing the features fails.

It would be useful to be able to suppress the initialization of the Fedora repository in this case, allowing the features to be installed in a Docker image, bypassing the initialization of the Fedora repository.

Expose a list of services and descriptions for repository objects

This is an implementation of #6 (client-side service discovery specification). For a given object, the set of services on this list is determined by applying the selection criteria defined in the extension registry model

Depends on:

  • #6 (client-side service discovery specification)

Simplifying Assumptions:

  • This initial implementation can take an arbitrarily naive approach. For example, it may be reasonable to start off by assuming that all you need in order to implement this is (a) a set of extension definitions, and (b) the contents of a repository object. Create additional github issues to expand or optimize this approach in order to satisfy the spec in a reasonable way (e.g. maintaining a cache/mapping, etc)

Testing:

  • Verify that all matching extensions appear in this list
  • Verify that updating an object so that it fails to match certain extension(s) results in the removal of these extension(s) from the list
  • Verify that updating extension selection criteria results in the appropriate additions/subtraction from this list
  • Measure the cost of generating the list of extensions for a given object.  How does it scale with the global number of extensions?

Index API-X service documents

Use camel toolbox to create a simple service that listens for messages, indexes service documents of new and updated objects

Describe the service invocation model provided by API-X core

Compare & contrast the different approaches discussed so far, write up a proposal for an invocation model to be used API-X. This could simply involve choosing an approach from below, a hybrid, or something else entirely. Seek out consensus on the chosen appproach

Add a Maintainers section to the readme

In order to be in line with other fcrepo-exts projects, the API-X code repository will need at least two people listed in a "Maintainers" section in the README document.

Determine API-X responsibilities regarding ontology resolution

See 2015-06-23 meeting minutes.

Should API-X be given the task of caching or otherwise providing durability for ontologies referenced in extensions?

The concern is that since ontologies are used for purposes of extension binding (e.g. reasoning, see extension definition & binding, and ontologies can be imported via owl:imports, ontology resolution failures could impact service binding. It is likely the case that any sane implementation will perform some sort of caching - but should API-X be making any guarantees?

Extract proof-of-concept code and demo material into a separate repository

As the API-X codebase matures, it becomes more difficult to manage the proof-of-concept related material from the core code. Not only can it be more difficult to manage, but it also doesn't make sense to keep mature code together with code that is intended to demonstrate nascent concepts. Down the road, it may make sense to promote the API-X code from the "labs" repository, but leave the proofs-of-concept behind.

Ideally, the proof-of-concept (POC) related items can be separated into a distinct repository, for the reasons discussed above. The POC repository should maintain its history from this repository.

Create OPTIONS extension loader

Create simple mechanism (service?) that loads extension into API-X based on URI of an Amherst service. An extension definition document is present in the body of OPTIONS requests

  • Gets extension definition via OPTIONS to the Amherst service, registers extension and service in API-X

Implement mechanism for routing URIs exposed on objects

Implement mechanism for routing URIs exposed on objects (e.g. /path/to/object/ext:extension/), and proxied by API-X.  

Simplifying assumptions:

  • Ignore selection criteria for the moment
  • assume that a request is routed to an extension based on URI matching alone, and that registering an extension at an exposed URI makes it available for all objects.

Depends on:

  • #5 (Extension registration/configuration model) so that a particular URI can be mapped to the extension that exposes it.  This information should be present in the registry entry for an extension.
  • #4 (Service invocation model)

Testing

  • Verify request is routed to service, response is routed back to caller

Set up travis builds, jenkins

Contact Andrew Woods for setting up Jenkins to deploy snaps into sonatype.

Artifacts intended for release:
groupid: org.fcrepo.apix

proof-of-concept artifacts
groupid: org.fcrepo.apix.poc

Specify client-side service discovery on repository objects

  • There is currently a proposal on the table for adding a Link rel=”service” header, linking to a service discovery resource that enumerates, describes, and links to services exposed on a particular object.   The services on this list would be dynamically generated from registered extensions that match a given object based on provided selection criteria
  • SSWAP provides a mechanism by which clients can discover services/resources by submitting a resource query graph
  • For RDFSource resources, it may be possible/desirable to link to service URIs in the resource body, akin to adding “server managed triples” to its representation.

Fix Travis failures

As noted in #42, builds are consistently successful when run locally on developer machines, but fail for various (not necessarily consistent) causes when executed on Travis

Peg docker images to specific versions in docker-compose.yaml

For the milestone release, the docker-compose.yaml should refer to concrete versions of an image, not :latest.

Some consideration should be made regarding the docker image tags used for this milestone, depending on how long we think the milestone should continue to be viable.

Retrieving large file results in 500

Upon retrieving a ~15 mb binary through API-X (works fine through Fedora):
$ curl -i http://apix/fcrepo/rest/images/porsche.jpg
HTTP/1.1 500 Server Error
Content-Type: text/plain; charset=ISO-8859-1
Transfer-Encoding: chunked
Server: Jetty(9.2.17.v20160517)

org.apache.camel.CamelExchangeException: JettyClient failed cause by: Buffering capacity exceeded. Exchange[ID-5dabce1f8a67-39534-1478205115914-2-29]. Caused by: [java.lang.IllegalArgumentException - Buffering capacity exceeded]
at org.apache.camel.component.jetty9.JettyContentExchange9.doTaskCompleted(JettyContentExchange9.java:155)
at org.apache.camel.component.jetty9.JettyContentExchange9$2.onComplete(JettyContentExchange9.java:221)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:193)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:185)
at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:453)
at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:434)
at org.eclipse.jetty.client.HttpReceiver.responseHeaders(HttpReceiver.java:278)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.headerComplete(HttpReceiverOverHTTP.java:228)
at org.eclipse.jetty.http.HttpParser.parseHeaders(HttpParser.java:1036)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1257)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.parse(HttpReceiverOverHTTP.java:156)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:117)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:69)
at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:89)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:123)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Buffering capacity exceeded
at org.eclipse.jetty.client.util.BufferingResponseListener.onHeaders(BufferingResponseListener.java:75)
at org.eclipse.jetty.client.ResponseNotifier.notifyHeaders(ResponseNotifier.java:103)
at org.eclipse.jetty.client.ResponseNotifier.notifyHeaders(ResponseNotifier.java:95)
at org.eclipse.jetty.client.HttpReceiver.responseHeaders(HttpReceiver.java:257)
... 12 more

Distributed API-X instances

Determine shared state, configuration, and  communication needs between instances of API-X core.  Determine key patterns and use cases (e.g. load balance, failover)

Implement mechanism for routing requests for Fedora resources, filtered by an extension

(see patterns doc)

Simplifying assumptions:

  • Assume that zero or one global extension will be registered (that is to say, if an extension is registered, then it applies to all requests to Fedora resources).

Depends on:

  • #4 (service invocation model)

Testing:

  • Extension returns an error (e.g. like failed validation of request),
  • Extension modifies request (e.g. adds a triple to a POST/PUT; akin to adding a “server managed” triple managed by the extension).  
  • Extension modifies response (e.g. add an http header, modify body,
  • Extension short-circuits Fedora (e.g. crafts own response, as in caching use case), Add/remove extension.

Determine statistics reporting requirements for API-X

See comments on design doc draft

Regarding Service Discovery & Binding:

Such a management interface should provide an API for monitoring the running components and probably gather some metrics about things like request service time and failure conditions. For example via JMX or an HTTP API.

This issue is to determine if API-X needs to provide an interface for monitoring components and retrieving metrics, and what form that may take. Can any existing technologies and standards be leveraged for this?

Wiki gardening

Refactor the design page into a proper, informative landing page for API-X design with links to the appropriate documentation and goings on

Describe how API-X can interact with existing service registry and discovery technologies

(e.g. consensus-based distributed registry, DNS-based discovery).  

  • API-X would seem to have a clear role in publishing a list of services available on a given object on the web as linked data, (e.g via a link rel and service document).  Backend services might leverage discovery via this mechanism, or may prefer a native approach that uses some other existing technology
  • Consider Zookeeper/curator, consul, Eureka

Set up initial integration tests

Select appropriate Maven plugin for launching api-x core, services, and Fedora for integration testing.  Presumably, this will involve running Docker images akin to those defined in docker-compose.yml

Performing GET on a non-empty [api-x] 'services' indirect container results in 500

To reproduce:

  1. bring up api-x milestone
  2. GET the services container (/fcrepo/apix/services)
  3. put a resource in the container
  4. GET the services container (HEAD will work, but GET does not)

Similar behavior using either Fedora 4.6.0 or 4.7.0 in the 'fcrepo' container.

HTTP/1.1 500 Server Error
Content-Type: text/turtle
Accept: /
Accept-Patch: application/sparql-update
Accept-Post: text/turtle,text/rdf+n3,text/n3,application/rdf+xml,application/n-triples,multipart/form-data,application/sparql-update
Allow: MOVE,COPY,DELETE,POST,HEAD,GET,PUT,PATCH,OPTIONS
breadcrumbId: ID-9039a37c0da5-41693-1478206589033-2-200
ETag: W/"85a2b321e51df70cfa3b5706b4b8b1446998cf00"
Last-Modified: Thu, 03 Nov 2016 21:08:28 GMT
Link: http://www.w3.org/ns/ldp#Container;rel="type"
Link: http://www.w3.org/ns/ldp#IndirectContainer;rel="type"
Link: http://www.w3.org/ns/ldp#Resource;rel="type"
Link: http://192.168.99.100/discovery/apix/indirect4; rel="service"
Preference-Applied: return=representation
Server: Jetty(9.2.3.v20140905)
Vary: Prefer
Vary: Accept, Range, Accept-Encoding, Accept-Language
Transfer-Encoding: chunked

java.lang.NullPointerException
at com.google.common.collect.ImmutableBiMap.copyOf(ImmutableBiMap.java:201)
at org.fcrepo.kernel.modeshape.rdf.converters.PropertyConverter.getPropertyNameFromPredicate(PropertyConverter.java:148)
at org.fcrepo.kernel.modeshape.rdf.converters.PropertyConverter.getPropertyNameFromPredicate(PropertyConverter.java:102)
at org.fcrepo.kernel.modeshape.rdf.impl.LdpContainerRdfContext.lambda$memberRelations$108(LdpContainerRdfContext.java:131)
at org.fcrepo.kernel.modeshape.utils.UncheckedFunction.apply(UncheckedFunction.java:37)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267)
at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:419)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1812)
at java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:294)
at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
at java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:731)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:731)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:728)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:731)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:731)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:728)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:735)
at java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:294)
at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:169)
at java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
at java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
at org.openrdf.rio.Rio.write(Rio.java:564)
at org.fcrepo.http.commons.responses.RdfStreamStreamingOutput.write(RdfStreamStreamingOutput.java:150)
at org.fcrepo.http.commons.responses.RdfStreamStreamingOutput.write(RdfStreamStreamingOutput.java:118)
at org.fcrepo.http.commons.responses.RdfStreamProvider.writeTo(RdfStreamProvider.java:102)
at org.fcrepo.http.commons.responses.RdfStreamProvider.writeTo(RdfStreamProvider.java:58)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:711)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:444)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:434)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:329)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:769)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:610)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:539)
at java.lang.Thread.run(Thread.java:745)
esm:~/workspaces/apix/repository-extension-services/acrepo-exts-image/src/main/resources (master)*$

Pre-loading of demonstration objects

The API-X demo will need to have demonstration objects pre-loaded, just needs to be implemented. Whether this happens at image build time or at container runtime is TBD.

Specify extension and service registration API and model

  • Enumerate all known extensions
  • CRUD extension definitions and configuration
    • URIs exposed by extension, if applicable
    • Resources filtered by extension, if applicable - request/response to resource may be mutated by extension
    • Binding/selection criteria - which objects can the extension provide a service?
    • URI(s) for service implementing the extension
  • See See SD&B POC page
  • Could some of this be satisfied simply via LDP resources in the repository?  If so, much of this task may to specifying an ontology rather than an API per se.  Maintaining a list of services implementing an extension may be suited to an API, extension definitions could possibly be repository resources.

Investigate possible Fedora memory leak

Investigate possible Fedora memory leak and seemingly related latency anomalies that complicate isolating latency effects due to API-X

  • Continuously performing a GET on a Fedora resource results in increasingly poor 95th, 99th percentile latency figures; 200+ms 95th percentile latencies,  20ms 50th percentile observed after approximately 30 minutes of a single thread performing GET as fast as possible
  • Very slow memory leak, monotonically increasing number of ConcurrentHashMaps from somewhere in Modeshape
  • Engage performance/scalability community?

Describe deployment process for extensions

  • What needs to happen through a http registration API?  
  • Are there aspects of deployment that are implementation-specific (e.g. deploying camel route in blueprint)?  
  • How do local deployment specifics relate to the extension registration process, and what sort of burden is on the repository administrator?
  • Distribution (sharing) of extensions

Produce glossary of terms

Decide its canonical location (wiki, github?).  Make sure definitions and descriptions reflect consensus of API-X stakeholders. Current thinking on this is the best home for this would be in the github repo, in an .md file

  • Extension vs service
  • Routing
  • Exposed URI

Implement simple service binding/selection

Part of an extension definition in the registry will describe objects that can be bound to a given extension.

Simplifying assumptions:

  •  This initial implementation can be arbitrarily dumb and simple; querying Fedora (or a triple store) at will whenever it’s necessary to do so.  Once this is complete, create a github issue for optimizing the binding process (e.g. maintaining a cache) if it seems necessary.

Depends on:

  • #5 (extension and service registration model)

Testing:

  • Verify that the framework binds extensions when it should, doesn’t bind when it shouldn’t.
  • Update binding criteria in registry, verify that binding impl respects these changes
  • Delete extension, verify that binding impl can no longer bind to it

Create simple API-X updater/listener

Use camel toolbox to create simple updater service that listens for messages, notifies API-X when objects are added/deleted/modified

There is already an org.fcrepo.apix.model.components.Updateable interface. This listener would listen for messages from the repository, and trigger all Updateable services when appropriate

Determine when re-write of RDFSource request/response bodies are required, and implement

As API-X provides a proxy endpoint for Fedora, repository resources exposed through API-X have different URIs than their fedora counterparts.  When relative URIs are used in requests and response, there is no issue.  Absolute URIs may need to be rewritten in request and response bodies.  This is akin to mod_proxy_html, except for rdf.

Testing:  

  • PATCH, POST, PUT, GET in supported media types (turtle, n-triples, sparql update) where absolute URIs are present
    • Measure latency/throughput impact of doing this

Implement composition/chaining of extensions

This pattern is necessary when multiple extensions are bound to a single resource
If it’s not part of the registry model already, find out how to deterministically arrive at the order in which the request/response are routed through extensions

Depends on:

  • #5 (registry model)

Simplifying assumptions:

  • Assume that composition/chaining is only a concern when filtering requests to/from repository resources (e.g. it does not apply to exposed URIs)

Testing:

  • Verify that order of extensions is deterministic

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.