Skip to content

Use Cases & Requirements: Discovery and Compatibility with 2.0

Andrew Berezovskyi edited this page Nov 1, 2018 · 1 revision

See discovery spec:

Approach

This exploration effort will look to define a minimal definition needed for OSLC implementations to expose capabilities to consumers/clients. The previous constructs defined in Core V2 (ServiceProviderCatalog, ServiceProvider, Service, OAuthConfiguration, QueryCapability, CreationFactory, ...) are all evaluated. The primary goal is to support a minimal amount of concepts on top of things like LDP Containers, to expose them and data about those containers (non member properties) such as resource types, dialogs, shapes, etc.

Motivating Use Cases

  1. QM Project owner in QM tool wants to link test cases to Bugzilla bugs

  2. Tool XYZ wants to expose its own resource types and dialogs but doesn't align with OSLC domain

  3. Tool XYZ exposes many kinds of resources (Requirements, Defects, Stories, PlanItems)

  4. Registry or index may want to locate "all tools that offer defect tracking"

Proposal

Look to start with the basics, in this case it would be a ldp:DirectContainer (or ldp:BasicContainer would do). This would map away the QueryCapability, CreationFactory and Dialog aligned with a single concept: ldp:Container. Things like oslc:ServiceProviderCatalog could simply ldp:DirectContainer (a container of containers).

Triple vs Link Header

There are number of patterns on how a client may discover a capability.

  1. HTTP response header

  2. Content

  3. Combination HTTP verb (OPTIONS), headers and content

  4. a single "document" (aka root container, public root URL, oslc:ServiceProvider, ... )

Response header

One can thing of response headers as just "meta"-data about the HTTP response on a given resource (Request-URI).

These are commonly used for very meta things:

  • etag, lastModified, content type, content encoding, etc

  • paging headers (next, prev, first, ...)

  • operations supported: POST, PUT, ...

  • Prefer preferences applied

  • Types of resource (ldp:Resource, ldp:BasicContainer, ...)

Response headers can streamline or eliminate some subsequent requests, therefore it would be ideal to respond with them for almost all HTTP request operations (POST, HEAD, GET, ...). They are also valuable when the data can not be encoded or expressed in the response entity body of the resource, for example if the resource is a non-RDF resource (LDP-NR).

Content

This is useful when the resource is already expressed in RDF, such as LDP Containers. Encoding the capability or discovery of it in the content could be quite valuable for scenarios where the content is indexed and used for queries. So if you may need to query across data to ask such questions as: "which containers support the creation of oslc_cm:Defect-type resources?". This would require knowing "support creation", which would leverage the header "AcceptPost", triple of <?container, rdf:type, ldp:Container> and possibly a triple in the content of <?container, oslc:resourceType, oslc_cm:Defect>.

The "AcceptPost" header would need to be converted into a triple by the indexer.

OPTIONS

Not currently used to be anything much more different than HEAD without the overhead to compute and supply Entity tag and lastModified.

Single Document

There has been some desire to have a single "document" that describes a given OSLC/LDP server instance's capabilities. Doing this has some drawbacks in that clients become dependent on this higher-level specialized document, instead of just looking for the capabilities of interest (either by headers or certain triples in content).

Container

Building up some examples, let's start with the basics:

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   ldp:hasMemberRelation ldp:member;
   ldp:membershipResource <http://example.org/app/proj1>;
   dcterms:title "Project 1";
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

Ignoring URL structure, as it should be treated as opaque strings. Though one can see that there is only the non-member data of rdf:type being ldp:DirectContainer (and supporting triples) and a simple dcterms:title for the container. This container can be treated as a creation factory, a client can use HTTP HEAD or OPTIONS to learn if POST is supported (ie it the container supports create). We'll introduce later how a client can introspect about query capability.

Dialogs

Now, let's say you need to associate selection and creation dialogs. This could be done by adding a couple non-member predicates, so that now we have:

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <http://open-services.net/ns/core#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   dcterms:title "Project 1";
   oslc:selectionDialog <picker>;
   oslc:creationDialog <creator>;
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

Query

One of the driving V2 cases was to have a way to filter the members of the container by using some simple query syntax that meets a number of use cases and cost to implement isn't as high as deploying some other solutions (like full SPARQL support). One way to do this is to just add another non-membership triple, such as oslc:querySyntax (creating new term here):

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <http://open-services.net/ns/core#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   dcterms:title "Project 1";
   oslc:selectionDialog <picker>;
   oslc:creationDialog <creator>;
   oslc:queryBase <>; # Points to self
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

There is no reason to support another resource so we set the oslc:querySyntax object to be some identifier of the query syntax supported. Some other alternatives could be:

  1. Reusing oslc:queryBase in some way that its existence indicates OSLC query syntax is supported. Not ideal since OSLC says that other query syntaxes may be supported.

    (possibly add multi-value to support various features: oslc.select, oslc.searchTerms, ...).

  2. Use other tricks that describe the URL patterns accepted by the container: POWDER+OPTIONS, special OPTIONS syntax, etc.

  3. Include some HTTP header parameter: Link: rel="oslcQuery"

  4. Perhaps just the existence of a oslc:queryShape predicate

Other scenarios to consider (fix?) is that in V2 there is no way to know what profile/subset of the OSLC query syntax is supported. This is attempted today by saying the domain defines the subset, the queryCapability is linked to a domain. In reality, domains allow flexibility and implementations include capability in phases. It would be good if a server to advertise how much of the query capability it supports.

Domain / Types supported

In V2, things were organized by oslc:Service which was chained by a unique oslc:domain. In addition to this, there were resource types, shapes and usages associated with various creation, query and dialog capability. All these things, while made to work, provided for a web of relationships and concepts that made it had to navigate and use. To fix some of this, one approach is just to say things are done based on the type of resources they support. Let's build up our example saying it can support 3 different types of resources: oslc_cm:ChangeRequest, oslc_rm:Requirement and ex:Story.

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <http://open-services.net/ns/core#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   dcterms:title "Project 1";
   oslc:selectionDialog <picker>;
   oslc:creationDialog <creator>;
   oslc:queryBase <>; # Points to self
   oslc:resourceType
      <http://open-services.net/ns/cm#ChangeRequest>,
      <http://open-services.net/ns/rm#Requirement>,
      <http://example.org/ns#Story>;
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

Let's look at a couple scenarios and see how it plays out with this:

  1. Which dialog do I use for Requirements?

  2. Can a create ex:Story resources on this container? (ie are these types supported for creation? or also for query?)

  3. Can I query for oslc_cm:ChangeRequests?

  4. @@@TODO

Shapes

Let's look at the motivating case for shapes a again. Shapes help fill a gap in the Linked Data world where servers need to express the constraints they have on their data. Shapes are used for specific scenarios: creation, read/update and query/select.

Introducing a new predicate (oslc:creationShape) which points to the shape(s). If the client wants to know which shape to use for which resource, it can fetch the shape (which it would need to anyway) and determine which resource type it oslc:describes.

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <http://open-services.net/ns/core#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   dcterms:title "Project 1";
   oslc:selectionDialog <picker>;
   oslc:creationDialog <creator>;
   oslc:queryBase <>; # Points to self
   oslc:resourceShape <queryShape>; # Could be rel="describedby" as well
   oslc:creationShape
      <createCRShape>, <createReqShape>, <createStoryShape>;
   oslc:resourceType
      <http://open-services.net/ns/cm#ChangeRequest>,
      <http://open-services.net/ns/rm#Requirement>,
      <http://example.org/ns#Story>;
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

Publisher

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   dcterms:title "Project 1";
   dcterms:publisher <http://example.org/app/publisher>;
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

<http://example.org/app/publisher>
   a oslc:Publisher;
   dcterms:title "Example provider".

OAuth

@@@ TODO Do we need anything?

Provider & Catalog

@@@ TODO These may just be glossary terms and not resource types?

Extensions - TRS/ChangeLog

Simply add the end point as non-member data to the container as:

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix trs: <http://jazz.net/ns/trs#> .

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   dcterms:title "Project 1";
   trs:trackedResourceSet <https://example.org/app/trs> ;
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

Extensions - SPARQL endpoint

Simply add the end point as non-member data to the container as:

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix sd: <http://www.w3.org/ns/sparql-service-description#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   dcterms:title "Project 1";
   sd:endpoint <http://example.org/app/sparql>;
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

Multi-type Containers

It may be seen as a nice feature to have a single container which you can a variety of resource types: Bugs, Stories, Requirements, Test Cases. Though this could lead to possible complexities when a client is simply looking for a place to create bugs. A pattern to improve this would be just to create separate single-purpose containers, relating them together if needed.

Related Groupings of Containers

Often there may need to be a group of related containers to support some function. In v2, we called these domains and wrapped them in an oslc:Service. This "worked" and at the same time didn't work in a number of cases. Some providers made the scope quite wide or narrow as to the scope of resources find in a given service.

One pattern is to put these grouping of containers into a another organizing resource that provides scope, such as a "project" or a "product". Another pattern is to define relationships between these containers. For example, as long as the client has a primary container to start from, they can locate that and then navigate to the other supporting or dependent containers.

Full Example

This examples includes all concepts from the previous sections

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <http://open-services.net/ns/core#>.
@prefix sd: <http://www.w3.org/ns/sparql-service-description#>.
@prefix trs: <http://jazz.net/ns/trs#> .
@prefix ex:  <http://example.org/ns#>.

<http://example.org/app/proj1>
   a ldp:DirectContainer;
   ldp:memberResource <http://example.org/app/proj1>;
   ldp:membershipPredict ldp:member;
   dcterms:title "Project 1";
   dcterms:publisher <http://example.org/app/publisher>;
   oslc:selectionDialog <picker>;
   oslc:creationDialog <creator>;
   oslc:queryBase <.>; # Points to self
   oslc:resourceShape <queryShape>; # Could be rel="describedby" as well
   oslc:creationShape
      <createCRShape>, <createReqShape>, <createStoryShape>;
   oslc:resourceType
      <http://open-services.net/ns/cm#ChangeRequest>,
      <http://open-services.net/ns/rm#Requirement>,
      <http://example.org/ns#Story>;
   sd:endpoint <http://example.org/app/sparql>;
   trs:trackedResourceSet <https://example.org/app/trs> ;
   ldp:member
      <http://example.org/app/proj1/bugs/1>,
      <http://example.org/app/proj1/bugs/2>,
      <http://example.org/app/proj1/bugs/3>.

<http://example.org/app/publisher>
   a oslc:Publisher;
   dcterms:title "Example provider".

Co-existance and backwords compat with V2

There are a large number of existing OSLC 2.0 clients and servers, and still some OSLC 1.0 clients and servers. Some of these clients and servers may be built in an API or using an SDK such as eclipe Lyo. Many others are built on the raw protocols using REST and direct RDF/XML resource parsing. In addition, OSLC 2.0 clients and servers may depend on capabilities that are not (yet) included in OSLC 3.0 such as:

  • Query

  • Paging

  • Resource Shapes

  • Tracked Resource Set

  • Actions (deferred from OSLC3.0 Core in TC vote 2015-04-16)

  • Automation (possibly, there is a TC, but it has no chair)

In other areas where OSLC 2.0 and 3.0 are functionally equivalent, they are implemented quite differently. e.g., Discovery in 2.0 is based on GETting service provider catalog resources while in 3.0 it is based on OPTION headers. Resource Preview is implemented quite differently.

The value propositions for upgrading to OSLC 3.0 are:

  • Integration is based on an open standard, and not controlled by a single vendor

  • OSLC 3.0 is based on the new W3C Linked Data Platform standard which provides a solid foundation for reading and writing linked data resources

  • The specifications are simpler, more consistent and will potentially be more attractive to and easier to consume by new integrations

  • There are some new capabilities including Attachments, Error formats, Inverse link labels, traceability and impact types.

  • improving domain vocabularies for data consistency and removing data gaps

Some existing clients and servers may view the required effort and potential risks of re-implementing their integration code on three new standards (OSLC Domain, OSLC Core, and LDP) is not consistent with the above value propositions, and may choose to stay with OSLC 2.0 until new OSLC 3.0 clients and servers are available to establish a more compelling business need. The various OSLC vendors, client and server components are likely evolve and migrate to OSLC 3.0 at unpredictable and uncoordinated times.All these observations imply a need for OSLC 2.0 and 3.0 interoperability. That is, OSLC is intended to provide a foundation for (lifecycle) application interoperability. Having different versions of OSLC break interoperability would create challenges for achieving this goal. Since we cannot predict when and/or if clients and servers will upgrade, if we want to maintain interoperability, we need a strategy to support OSLC 2.0 and 3.0 interoperability.

OSLC 2.0 and 3.0 interoperability would be maximized if an OSLC 2.0 compliant client could transparently acces an OSLC 3.0 server, and an OSLC 3.0 client could transparently access an OSLC 2.0 server. There are two fundamental approaches to OSLC version compatibility:

  1. Implement existing OSLC 2.0 and 3.0 client APIs and server SDKs on both OSLC 2.0 and 3.0

  2. Develop an OSLC 2.0/3.0 protocol converter that could be used as a proxy or front end to OSLC 2.0 and 3.0 servers

There are pros and cons of for each of these approaches. The API/SDK approach isn't useful for clients and servers that are not built on those APIs. The protocol converter could add overhead and technical debt to servers. However, regardless of the approach taken, we need to analyze the differences between OSLC 2.0 and 3.0 to determine if any approach is feasible. The results of this analysis may need to be factored into the development of the OSLC Core 3.0 specifications in order to ensure interoperability is possible with the adopted specifications.

In order to facilitate this analysis, we can take a capability-based view of OSLC, analyze how each capability is supported by the 2.0 and 3.0 specifications, and use that information to develop the specification for protocol conversion needed to support full interoperability. We can then analyze the gaps discovered and determine if there are changes that should be made to the 3.0 specifications to close critical interoperability gaps.

Capability OSLC 2.0 OSLC 3.0 Notes
Authentication May support OAuth or Basic or other mechanisms Not part of OSLC 3.0, deferred to future specifications or: HTTPS + BASIS MUST, OAuth2, OpenID Connect SHOULD OAuth 1.0a is used by IBM products and is often a big barrier to integration because of the complex handshake.OAuth 1.0a is deprecated. OAuth 2.0 / OIDC may be an approach to addressing this issue.
Create resources POST to creation factory POST to LDP Container Discovery is completely different
Read resources GET Resource-URI GET Resource-URI No change
Update resources PUT Resource-URI PUT Resource-URI No change
Partial update of resources Not supported in OSLC 2.0 core, but is in some of the Domains Relies on LDP PATCH which is incomplete (editors draft)
Delete resources DELETE Resource-URI DELETE Resource-URI No change
Query resources (select and project) OSLC Query syntax (oslc.where, oslc.select) Not part of OSLC 3.0 Core May be possible to implement OSLC 2.0 Query on OSLC 3.0, needs investigation.
Resource Paging oslc.startIndex and oslc.pageSize query parameters Not part of OSLC 3.0, relies on LDP paging which is incomplete (candidate recommendation)
Discover affordances Service provider catalogs and documents LDP Containers and Link headers Discovery is completely different, and the available information is different. Detailed analysis is required to determine if OSLC 2.0 and 3.0 discovery are functionally equivalent
Manage explicit resource lifecycle state (with events and actions) Actions 2.0 Actions is underspecified in Core, has no editor, and may need work.There are also not many consumers except Automation and maybe CM The OSLC Core 3.0 TC has deferred this capability from OSLC 3.0. Server implementations could continue to utilize the OSLC 2.0 Actions specification until this can be more completely analyzed and implemented.
Attach resources to other resources Not part of OSLC 2.0 Covered in Resource Attachments This would not be available to an OSLC 2.0 client accessing a 3.0 server, and the clients wouldn’t know to ask for it. A 3.0 client would not discover the capability from an existing OSLC 2.0 server.Attachments has no compatibility issues.
Display an HTML preview of a resource Request application/oslc-compact+xml Media Type to discover preview. Compact resource is XML Use HTTP Link response header or Prefer request header to discover preview. Compact resource is JSON or Turtle OSLC 3.0 dynamic resizing preview was changed to be consistent with dialogs
Display a delegated HTML dialog for resource viewing, update or creation Discover dialog using service description document Discover dialog using Link response header or Prefer request header. Discovery “prefill” shape using Link header Dialogs function the same after discovery
Create a relationship between resources Update resource with link using PUT Update resource with link using PUT No change although inverse link predicates are deprecated (e.g., Requirement validatedByTestCase and TestCase validates Requirement)
Register interest in changes to a set of resources Monitor Tracked Resource Set ChangeLog Not part of OSLC 3.0 Core The OSLC 2.0 TRS specification may be close and could possibly be implemented in an OSLC 3.0 server.
Provide error responses HTTP status codes and OSLC Error resource HTTP status codes and OSLC Error resource. Error responses on creation or update MUST have a Link header with relation <. See [](http://www.w3.org/TR/ldp/#ldpr-gen-pubclireqs
Supported media types RDF/XML MUST (a specific format)JSON MUST? (isn’t JSON-LD) Turtle MUSTJSON-LD MUST OSLC 3.0 servers should be able to easily translate Turtle to/from RDF/XML or use standard libraries that can produce and consume any RDF syntax.
Specify resource schema Supports Resource Shapes in OSLC 2.0 Not part of OSLC 3.0, relies on W3C RDF Data Shapes which is incomplete (editors draft) This will be a major compatibility issue.

The primary issues that need to be explored are:

  • Discovery compatibility

  • Ability to implement existing OSLC 2.0 capabilities (Actions, Automation, Query, Tracked Resource Set) on an OSLC Core 3.0 server

  • Resource Shapes in support of POST and PUT constraints

New functionality in v3 that backwards-compatible clients need to know won't be in v2 servers

  • "window.opener" functionality in delegated dialogs. If you don't know if a dialog is v2 or v3 then you can't rely on the window.opener support, so you can't open it in a new window - you have to use the "iframe" approach.
Clone this wiki locally