See discovery spec: http://tools.oasis-open.org/version-control/browse/wsvn/oslc-core/specs/discovery.html

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).

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:

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.

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:

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:

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 <http://www.w3.org/ns/ldp#constrainedBy>. See http://www.w3.org/TR/ldp/#ldpr-gen-pubclireqs||<style="padding: 10px; margin: 0px; width: 25%; border: 1px solid #dbdbdb;" |1>

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:

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

Discovery (last edited 2015-05-04 18:05:08 by jamsden)