Skip to content

Use Cases & Requirements: Discovery

Andrew Berezovskyi edited this page Nov 1, 2018 · 3 revisions

(Please note, this page is likely out-of-sync with the parent Discovery page).

This page is to work through some resource discovery & capability discovery scenarios, and show how they could be implemented in OSLC v2 and OSLC v3, to validate how much of the v2 functionality/resource types we need in v3.

This page is split into two halves: how clients think about discovery, and how servers think about discovery. The scenarios used in each section are different (or not all scenarios are used in both sections) as there is more variation in servers. Apologies that the numbering restarts for the second section.

Some ideas for scenarios to look at:

  • Change Management

  • Automation

    • Configuring an integration between a client and a server

    • A human creating a request & tracking result

    • An automated process creating a request & tracking result

    • Use of template dialogs ("deferred-execution creation dialog)

How clients think about discovery

Automation

Note: at any point in these scenarios authentication might be requested by the server and provided by the client (which may involve prompting the human user, if present, or may involve an unattended process providing credentials it was previously provided with, or failing & exiting if it does not have any to provide. These are left out-of-scope of these scenario descriptions.)

I've used the terms "automation plan", "automation request" and "automation result" in the descriptions of the user's experience of the scenario, as they are concepts that the user will see (although they are likely to have a domain-specific name in the tools in use). However, the user is unlikely to have any knowledge of how these terms are used in the RDF. I will attempt to capitalise & camel-case thenames when talking about the RDF classes, and use lower case with spaces when talking about the concept as the user sees it.

1. Scenario: A human creating a request and tracking the result.

Note that the first 2 stages of this scenario can be combined with stage 3 of the "unattended" scenario below.

User experience/steps In OSLC v2 (or backwards-compatible v3) With pure LDPCs
1.1. Stage 1: configuring the integration (once only)
1.1.1: In the UI of the client app, the user enters the appropriate URL for the server. 1.1.1: The client app asks the user to enter a ServiceProviderCatalog (SPC) or ServiceProvider (SP) URI. (Or, for Jazz-compatible servers, the root services URI). The user is not familiar with these terms. They look in the server UI, which they might already have open, and find no mention of it. The user searches the server's documentation and finds it (if the client & server use the same terms for it). The user enters the URI that they found into the client. The client performs a GET request on that URI (and may have to perform authentication or OAuth actions as needed).
1.1.2: The user is prompted to select the partition (e.g. project, team, tenant, etc) of those on the server to use. 1.1.2: If it was provided with a SPC (or root services document), the client app lists the SPs that it found inside it. (If there were nested SPCs, it either performed a full-depth traversal in order to provide a flat list of all SPs, or preferably includes those nested SPCs in the list presented to the user to allow the user to traverse the tree, but more likely [based on my implementation experience] it ignored them). ¶ The user chooses an SP based on its name and/or (if the client app displayed it) its description. ¶ If the client app was provided with an SP (or if the SPC only contains one SP) then it may skip this step and silently select it, or it may tell the user the name of the SP that it will be using. ¶ The client app perfoms a GET request on that SP, unless it was already inlined in the previous result.
1.1.3: If the client & server both support multiple types of integrations, then the user may be prompted to select which one(s) should be used (e.g. if the client can be a CM client and an Automation client, and that partition on the server has both CM and Automation capabilities/resources, then the user may only want to configure an integration for one of those domains, or for both). 1.1.3: The client app looks at the Service resources inside that SP. If the client app only supports one domain it looks for a Service that indicates that domain, in order to verify that it can work with this SP. If the client app supports multiple domains, then it looks for all Services that indicate any of those domains, and lets the user choose one (or more) of the domains that are supported both by the client app and the SP. ¶ The user chooses one (or more) domain. The client app stores the URIs to the SP and/or Service.
1.1.4: The user may be prompted to select which partition on the client this integration is to be used by. 1.1.4 Client app implementation-specific, using the data returned in 1.1.3 (no further HTTP requests required).
1.2. Stage 2: configuring the automation (manual task)
1.2.1: In the UI of the client app, the user opts to use some automation from a remote server (e.g. before the client runs a test, they want it to request a deployment from a remote deployment server). 1.2.1: Client app implementation-specific, not using any server data.
1.2.2: The user is prompted to select which integration to use. 1.2.2: The client app displays a client implementation-specific dialog showing the list of implementations configured via the steps in 1.1.
1.2.3: The user is prompted to select which automation plan they wish to be invoked. 1.2.3: The client app uses the server's Service resource (either cached in step 1.1.3, or re-requests the URI for it which was discovered in step 1.1.3) to get the oslc:selectionDialog whose oslc:resourceType property has oslc_auto:AutomationPlan among its values, and gets that oslc:SelectionDialog resource's oslc:dialog URI. the client displays an iframe containing that URI to the user (handling resizing as needed). The user selects an automation plan and clicks the submit button - both in the server's delegated UI. The client receives the URI for the selected automation plan via the means defined by the delegated UI spec (window name or postMessage).
1.2.4: The user is prompted to enter any parameters that are required or allowed by that plan. 1.2.4: The client app uses the server's Service resource (the same one as in step 1.2.3) to get the oslc:creationDialog whose oslc:resourceType property has oslc_auto:AutomationRequest among its values, and gets its oslc:dialog URI. It posts a pre-fill to that dialog containing the triple <> oslc_auto:executesAutomationPlan <the URI of the automation plan>, and receives back the URI for the prefilled dialog. The client displays an iframe containing that URI to the user (handling resizing as needed). The user enters whatever parameters are needed, as requested by the server's delegated UI. ¶ (Alternative, simpler flow for steps 1.2.3 and 1.2.4: the client could just display the Automation Request creation dialog without having used the selection dialog or pre-fill, in the expectation that the server will allow the user to select the automation plan in that dialog. But the longer method used here demonstrates more OSLC features.)
1.3. Stage 3: executing the automation (manual task)
1.3.1: The user indicates that they wish to start the automation (e.g. they submit the parameters form). 1.3.1: The user clicks the server's automation request creation dialog delegated UI's submit button (displayed in step 1.2.4). The client receives the URI for the newly-created AutomationRequest resource via the means defined by the delegated UI spec (window name or postMessage).
1.3.2: The user is presented with the status of the automation as it progresses. 1.3.2: The client polls the AutomationRequest URI received in step 1.3.1 to track that resource's oslc_auto:state property, and updates the user on any changes. It also looks at the Service from step 1.1.3, and finds an oslc:queryCapability link to a Query Capability whose oslc:resourceType property has oslc_auto:AutomationResult among its values, and gets that Query Capability's oslc:queryBase URI. The client constructs a query against that base URI to find a resource which has the triple ? oslc_auto:producedByAutomationRequest <URI from step 1.3.1>. This resource may take some time to be created, so the client polls that query until the query returns a match (or a client-specific wait timeout has been reached). Once that resource (an AutmoationResult) has been found the client tracks that resource's oslc_auto:state property for the state of execution (at which point it may stop tracking the AutomationRequest's equivalent property) and also tracks the AutomationResult resource's oslc_auto:verdict property for the final result of the automation - and reports any changes of either of those properties to the user.
1.3.3: The user is notified when the automation completes. 1.3.3: When the oslc_auto:verdict property of the AutomationResult resource that the client is polling changes to a completed verdict, the cient indicates to the user that the automation is complete. This may automatically trigger more execution by the client (e.g. running some automated tests now that the automated deployment has completed).

Please DO NOT edit this table, as Martin generates it from a local copy that is easier to edit. If you have any suggested changes, please list here after the table.

2. Scenario: An unattended automated process creating a request & tracking a result.

Note that stage 3 of this scenario could follow stages 1 and 2 of the scenario above, to allow a human to configure an automated task via a UI, but then have it run (potentially multiple times) unattended.

TODO

How servers think about discovery

I started thinking about how you would take an SPC, containing SPCs and SPs, which contains Services, which contains resources, and make that into a tree of LDPCs. That is by no means simple. (I haven't included my thinking on that in this wiki page). I'm now going to try the other way around - start with LDPCs, and see how you would describe them with OSLC vocab.

The numbered points in this section are for two reasons: firstly to help refer to the points during discussions, and secondly to separate individual points out in the hope that none get missed during the discussions. So whenever you see a section that has been given a number, consider whether you agree with that or not, separately from the points around it. (Some of the point numbers are inline in brackets to avoid breaking a sentence across multiple bullets).

Basis

This walk through & these examples are based on the option of the spec saying:

  • if a server is providing discovery then it MUST use the OSLC v2 vocab for discovery (in addition to the Link headers - although they have been omitted from the examples)

  • if a server is providing discovery then it MUST provide an SPC

  • servers MAY also make those discovery resources LDPCs

Introduction to Examples

There are examples woven through these thoughts showing a couple of scenarios. Scenario A is to take the most basic form of server (a single LDP Basic Container) and see how we can keep it as simple as possible - as one resource. Scenario B has more complexity to it, and demonstrates each level of OSLC discovery being an LDPC. There is further complexity that could be added to scenario B (e.g. more service providers), but I'm sure you can scale this up in your minds. There is also a simpler example possible where the Service resource maps one-to-one to an LDPC of domain resources, rather than in Scenario B where the Service has multiple LDPCs.

For now I have omitted delegated UI dialogs, although I do think they are an important part of this, but just haven't got round to them.

  • Scenario A
    Server contains one LDPC, with one resource type.

  • Scenario B
    OSLC Automation - with separate LDPCs for Automation Plans, Automation Requests & Automation Results.

In these examples, I've assumed that a "LocalResource" and an "Inline" "Resource" (as specified by the resource shape tables in the v2 spec) allow hash URIs, not just blank nodes as suggested by the spec & vocab. I need to raise a separate ticket to clarify what the case is there.

Also remember that in Turtle "<>" refers to the current request URI.

Walk through

1. How should a server partition its resources?

  • 1.1. Firstly, you start with one or more resource types, across one or more LDPCs.

  • 1.2. The partitioning between LDPCs is up to the server. (1.2.1:) An LDPC can contain one or more types, (1.2.2:) and each type can be split across one or more containers - (1.2.3:) which may or may not have distinct sets of members/contained resources.

  • 1.3. (However, individual domains might explicitly or implicitly require certain organisation, (1.3.1:) e.g. on an OSLC Automation server, for each container of Automation Plan resources there should not be multiple distinct LDPCs for Automation Request resources for those plans. (1.3.2:) i.e. if there's an arrangement that the discovery resources can't describe, then the server is not free in that respect.)

Example A1: Scenario A example 1: An LDPC

This is the intitial example LDPC that the examples for scenario A will build on.

GET /discovery HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.

<>
   a ldp:BasicContainer;
   dcterms:title "Container of all this server's resources (which are all of one type)";
   ldp:contains </r1>, </r2>, </r3>.

Example B1: Scenario A example 1: An LDPC for OSLC Automation

This is the intitial example LDPC that the examples for scenario B will build on.

GET /autoPlans/ HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.

<>
   a ldp:BasicContainer;
   dcterms:title "Tasks available for execution";
   ldp:contains </autoPlans/1>, </autoPlans/2>, </autoPlans/3>.

Very similar for /autoRequests/ and /autoResults/.

2. How should a server advertise that resources of those types can be created?

  • 2.1. Firstly, by the normal LDP means.

    • 2.1.1. However, OSLC v2 allows not just the discovery of the creation capability once a client has the URI for that collection (i.e. for that Service or ServiceProvider), but also the discovery of that collection from an SPC.

    • 2.1.2. Also, we want to keep things backwards-compatible.

  • 2.2. To describe creation of resources, an OSLC Server needs an oslc:CreationFactory resource (only needed for v2 clients).

  • 2.3. That CreationFactory resource must be inlined in an oslc:Service resource (this inlining is required by OSLC v2).

  • 2.4. And it must have an oslc:creation property that points to the URI of the LDPC in which the resource will be created (as POSTing to an LDPC's URI is the way to create resources in that LDPC).

  • -

  • 2.5. If the Service has multiple Creation Factories for a given resource type (i.e. multiple LDPCs for that type), then each factory should be distinguished (2.5.1:) using its dcterms:title (2.5.2:) and, ideally, a vendor-specific URI for oslc:usage.

  • 2.6. Also, considering programatic (unattended) clients that don't understand the vendor-specific oslc:usage URI (which will be most of them), the factory that the server intends be used by such clients should additionally have an oslc:usage value of oslc:default.

  • -

  • 2.7. If a container doesn't support creation, then I'm not sure how we should link to it. That is in the scope of OSLCCORE-26, so I will not discuss it here.

Example A2a: Scenario A example 2a: Adding a Creation Factory

This builds on example A1 above.

GET /discovery HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <...>.

<>
   a ldp:BasicContainer, oslc:CreationFactory;
   dcterms:title "Container of all this server's resources (which are all of one type)";
   ldp:contains </r1>, </r2>, </r3>;
   oslc:creation <>; # Itself
   oslc:resourceType <http://example.com/resource-type>. # Optional

Example A2b: Scenario A example 2b: Adding a Service

This builds on example A2a immediately above.

GET /discovery HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <...>.

<>
   a ldp:BasicContainer, oslc:CreationFactory, oslc:Service;
   dcterms:title "Container of all this server's resources (which are all of one type)";
   ldp:contains </r1>, </r2>, </r3>;
   oslc:domain <http://example.com/custom-oslc-domain>;
   oslc:creationFactory <>;
   oslc:creation <>.

Example B2a: Scenario B example 2a: Adding a Creation Factory

This builds on example B1 above.

GET /autoPlans/ HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <...>.
@prefix oslc_auto: <...>.

<>
   a ldp:BasicContainer;
   dcterms:title "Tasks available for execution";
   ldp:contains </autoPlans/1>, </autoPlans/2>, </autoPlans/3>.

_:factory
   a oslc:CreationFactory;
   oslc:creation <>; # The request URI
   oslc:resourceType oslc_auto:AutomationPlan.

Example B2b: Scenario B example 2b: Adding a Service

This builds on example B2a immediately above.

GET /automation/ HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix oslc: <...>.

<>
   a oslc:Service;
   oslc:domain <http://open-services.net/ns/auto#>;
   dcterms:title "Task automation";
   oslc:creationFactory [
      oslc:creation </autoPlans/>;
      oslc:resourceType oslc:AutomationPlan.
   ]; # Note: OSLC Automation doesn't require creation of plans
   oslc:creationFactory [
      oslc:creation </autoRequests/>;
      oslc:resourceType oslc:AutomationRequest.
   ];
   oslc:creationFactory [
      oslc:creation </autoResults/>;
      oslc:resourceType oslc:AutomationResult.
   ]. # Note: OSLC Automation doesn't require creation of results

GET /autoPlans/ HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.

<>
   a ldp:BasicContainer;
   dcterms:title "Tasks available for execution";
   ldp:contains </autoPlans/1>, </autoPlans/2>, </autoPlans/3>.

3. How should a server decide how many Service resources to have?

  • 3.1. To start with, each Service should only serve a single OSLC domain. (The "occurs" restriction of oslc:domain on oslc:Service in v2 is exactly-once).

  • 3.2. For resource types that are vendor-specific or part of an extension: (3.2.1:) if they fit into an existing OSLC domain then they can be part of that domain's Service, (3.2.2:) otherwise the vendor or extension designer should define their own domain URI.

  • 3.3. After that, it depends on how the server decides how many Service Providers it should have - see below.

  • 3.4. (And I see no reason for a Service Provider to have multiple Service resources for a single domain... but I suppose they can if they have good reason to. Again, an oslc:usage value of oslc:default is very useful here for clients not expecting multiple Services per domain in a Service Provider).

4. How does a client find the resources that are owned by a Service?

  • 4.1. We have both OSLC v2 query capabilities and normal LDP GETs available to us.

    • 4.1.1 But for LDP GETs, you need to know the URIs of the LDPCs - see 2.7 above.
  • 4.2. We are working unde rthe option of the spec saying that discovery resources MAY be LDPCs (see "basis" section above). Therefore, if the server wants to, it can have the Service resource be an LDPC container itself. In which case it would contain the LDPCs that it links to.

  • 4.3. This could either be as a Direct Container using the oslc:creationFactory predicate (which has the problems from OSLCCORE-26 for read-only containers)

  • 4.4. or it could be a Basic Container using the ldp:contains predicate (which would solve OSLCCORE-26) - the "basis" section above leaves this choice open for servers to decide.

  • 4.5. If the Service contains multiple LDPCs (multiple Creation Factories) then being an LDPC (containing other LDPCs) would be particularly good if the server supported creation of new containers within the Service, but I expect that is very rare.

  • 4.6. For discovery of containers I (playing the role of a server implementor) am split - (4.6.1:) as there seems to be a containment relationship here it makes sense to represent it using LDP, but I can't see the benefit for the client... (4.6.2:) well, no, the benefit for the client is being able to use ldp:contains to find all containers in that Service (that is, in that domain in that SP) whether or not they can create resources in them. (4.6.3:) So I would lean towards making Services be LDPCs - either of LDPCs, or if they only need a single container then being that container itself. But that is OSLCCORE-26 again.

Example B4: Scenario B example for section 4: Making a Service an LDPC

This builds on example B2b above.

If the server implementor wanted to make the Service an LDPC itself (this time considering the case where the server doesn't support creation of Plans or Results), it might look like this. (Note that this is the case where the Service has multiple LDPCs. In simpler cases if there is only one LDPC, then the Service could perhaps be that LDPC containing the domain resources directly, as in example A2b).

GET /automation/ HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix oslc: <...>.

<>
   a oslc:Service, ldp:BasicContainer;
   oslc:domain <http://open-services.net/ns/auto#>;
   dcterms:title "Task automation";
   oslc:creationFactory [
      oslc:creation </autoRequests/>;
      oslc:resourceType oslc:AutomationRequest.
   ];
   ldp:contains </autoPlans/>, </autoRequests/>, </autoResults/>. # Useful for querying, discovering dialogs, etc, etc.

5. For a client to discover a Service (and therefore discover the LDPC), that Service must be linked to from a Service Provider.

  • 5.1. The Service Provider links to Services using the oslc:service predicate.

  • 5.2. How many Service Providers should the server have?

    • 5.2.1. I suggets one per "partition".

    • 5.2.2. Where "partition" is anything that makese sense to the server but (5.2.2.1:) is not an OSLC domain itself. (5.2.2.2: if the server's only partitions are OSLC domains, then I would suggest having a single SP with multiple Services, but there's no reason why they can't have multiple SPs, each having a single Service resource with a different domain for each SP's service - the only down side is that under the most basic client implementation this makes it the user's responsibility to choose the SP for the appropriate domain, whereas the clients will be programmed to automatically select the appropriate Service for the domain they are looking for within a SP already selected by the user - see step 1.1.3 under "How clients think about discovery -> Automation -> Scenario 1" above.)

  • 5.3 That SP can be an LDPC, containing its Services. (I ought to expand this to ask "How does a client find the Services that are provided by a Service Provider?")

Example A5: Scenario A example for section 5: Adding a Service Provider

This builds on example A2b above.

GET /discovery HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <...>.

<>
   a ldp:BasicContainer, oslc:CreationFactory, oslc:Service, oslc:ServiceProvider;
   dcterms:title "Container of all this server's resources (which are all of one type)";
   ldp:contains </r1>, </r2>, </r3>;
   oslc:service <>;
   oslc:domain <http://example.com/custom-oslc-domain>;
   oslc:creationFactory <>;
   oslc:creation <>.

Example B5: Scenario B example for section 5: Adding a Service Provider

This builds on example B2b or B4 above.

In this case I am assuming only one Service Provider for the whole server, and multiple services within in (e.g. one for Change Management one for Automation):

GET / HTTP/1.1
Host: example.com
Accept: text/turtle

200 OK
Content-Type: text/turtle

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix oslc: <...>.

<>
   a oslc:ServiceProvider;
   dcterms:title "My server";
   oslc:service </automation/>, </changeManagement/>.

Example B5.3: Scenario B example for section 5.3: A Service Provider as an LDPC

This builds on example B5 immediately above.

And the SP can also be an LDPC of Services:

GET / HTTP/1.1
Host: example.com
Accept: text/turtle

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix oslc: <...>.

<>
   a oslc:ServiceProvider, ldp:BasicContainer;
   dcterms:title "My server";
   oslc:service </automation/>, </changeManagement/>;
   ldp:contains </automation/>, </changeManagement/>.

6. A client discovers a Service Provider from a Service Provider Catalog

  • 6.1 In most cases I would expect a server to have a single SPC.

  • 6.2 If the server requires a hierarchy, they can achieve this using SPCs (as SPCs can contain other SPCs).

  • 6.3 For servers that only have a single SP, this level can seem like one level too many of discovery. But it does provide some benefits:

    • 6.3.1 It is the only level that allows for hierarchy

    • 6.3.2 It is the only level that can (via the other levels) allow discovery of everything - multiple SPCs, all partitions (SPs), OSLC domains (services), collections (via services) and resource types (via collections/services).

  • 6.4 While I would suggest that clients allow their users to enter either an SPC or an SP URI (6.4.1:) I would suggest that servers should not rely on that, and so should always provide an SPC.

  • 6.5 That SPC can also be an LDPC of its SPs. (I ought to expand this to ask "How does a client find the Service Providers that are linked to from a Service Provider Catalog?")

Example A6: Scenario A example for section 6: Adding a Service Provider Catalog

This builds on example A5 above.

GET /discovery HTTP/1.1
Host: example.com

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix oslc: <...>.

<>
   a ldp:BasicContainer, oslc:CreationFactory, oslc:Service, oslc:ServiceProvider, oslc:ServiceProviderCatalog;
   dcterms:title "Container of all this server's resources (which are all of one type)";
   ldp:contains </r1>, </r2>, </r3>;
   oslc:serviceProvider <>;
   oslc:service <>;
   oslc:domain <http://example.com/custom-oslc-domain>;
   oslc:creationFactory <>;
   oslc:creation <>.

Example A6: Scenario A example for section 6: Adding a Service Provider Catalog

This builds on example B5 or B5.3 above.

GET /catalog HTTP/1.1
Host: example.com
Accept: text/turtle

200 OK
Content-Type: text/turtle

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix oslc: <...>.

<>
   a oslc:ServiceProviderCatalog;
   dcterms:title "My server's Service Provider Catalog";
   oslc:serviceProvider </>.

Example B6.5: Scenario B example for section 5.3 A Service Provider Catalog as an LDPC

This builds on example B6 immediately above.

And the SPC can also be an LDPC of SPs:

GET / HTTP/1.1
Host: example.com
Accept: text/turtle

200 OK
Content-Type: text/turtle
Link: http://www.w3.org/ns/ldp#BasicContainer; rel="type",
      <http://www.w3.org/ns/ldp#Resource>; rel="type"

@prefix dcterms: <http://purl.org/dc/terms/>.
@prefix oslc: <...>.

<>
   a oslc:ServiceProviderCatalog, ldp:BasicContainer;
   dcterms:title "My server";
   oslc:serviceProvider </>;
   ldp:contains </>.

Conclusion

  • If we want to allow for the approach shown inthe examples for scenario A (allowing all discovery information in a single resource

    • i.e. allowing the server to collapse any number of the layers of discovery together) then we cannot require that servers make SPCs or SPs into LSPCs, as then they can't collapse them into their existing/lowest-level LDPC. However, I doubt many people will be interested in that. For one thing, I expect the existing libraries (Eclipse Lyo) don't make it easy to do.
  • I haven't yet walked through how a client would access this discovery, and whether using LDPCs would help them. However, while it could unify the selection of an SP from an SPC with the selection of an individual domain resource (e.g. a change request reosurce, or an Automation Plan) from a Service, I believe that selection of a Service from an SP will always be different as in the vast majority of cases it should be possible without interaction from the user - the client should know what domain it is looking for and that should be enough. (Or if interaction from the user is required, it should be to select which OSLC domain to use, without having to display the Service resources themselves to the user). I believe this is reflected in the fact that Services are required to eb inlined in the representations of their Service Providers.

  • I believe the most complexity in Scenario B came from the fact that a scenario had multiple LDPCs. If in v3 we limited Service resources to a single LDPC, that might simplify things. However, v2 requires that Service resources be "Local Resources" inside their SPs, so requiring that the Service and the LDPC be the same resource is unlikely to be a good idea.

  • If we're looking for OSLC resource discovery to appear simple for those who already understand something about LDP, this might be one approach: we should see the SP and Service resources as a single "layer" of discovery (as Services are "Local Resources" inside SPs). This is the key resources in OSLC discovery, and represents a "partition" of data on the server. (If this doesn't make sense for the server, then the server should only have a single SP for the entire server.) SPCs are an LDPC of SPs (and other SPCs). They also have to include both the oslc:serviceProvider and oslc:serviceProviderCatalog predicates, in addition to the LDP containment predicate. Service resources inside an SP describe the LDPCs that are available in that partition. Those LDPCs are the third and final "layer" of discovery.

Jim Amsden comments:

There may be a simpler approach. Consider SPC, SP and Service are all separate resources and are all also of type ldp:Container. The only special case is that a SP, an LSPC that contains Services, would be required to return its ldp:contains elements inline, not a just URI references. Then clients can do V2 discovery by doing a GET on those resources, without ever knowing anything about them being ldp:Containers.

Similarly, a V3 client can use OPTIONS, HEAD, or GET on the LDPCs, get the link headers to discover:

  1. The SPs in an SPC (through the ldp:contains property of the SPC LDPC)

  2. The Services provide by an SP (through the ldp:contains property of the SP LDPC) whether inlined or not

  3. The capabilities of that service through the Accept-Post header, oslc:resoureType Link header, oslc:constrainedBy Link header, oslc:creationDialog Link header, oslc:selectionDialog Link header, etc. The special case in this situation is the Service LDPC is also the "creation factory", the URI you POST to to create resources allow by the oslc:resourceType Link header. That is, the oslc:creationFactory property of a Service would be the URI for the service itself. The same is would likely be true of the oslc:queryBase if query is applied to any LDPC to do selection and projection on its ldp:contains resources. This is at the heart of merging OSLC2 and OSLC3 discovery through LDP.

  4. Any additional discovery properties that are currently defined by V2 and commonly used by V2 clients are still available in V3 as proerties of the LDPC resource itself and would be returned from a GET on that resource.

  5. The Prefer header can be used to manage the content of an LDPC returned on a GET.

The difference between the SP and Link header approaches to discovery is then just one of convenience and client preference for processing entity request bodies from a GET vs. examining Link headers from OPTIONS/HEAD.

The following sections explore this approach, and indentifies and addresses potential issues.

1. Configuring the Client for Integration

The client application uses OSLC Discovery capabilities to determine what services are available on what domains from one or more servers, and uses that information to configure how these services are exposed to its users.The client is required to know the server’s starting point for discovery. This is typically one or more URIs that servers provide that partition their capabilities and resources in some way. These “Discovery URIs” are LDPCs that may also be: * ServiceProviderCatalog

  • an LDPC that provides additional server properties and organizes ServiceProviders and possibly other ServiceProvider catalogs.

    • ServiceProvider

      • an LDPC, possibly in a ServiceProviderCatalog LDPC that provides an inlined representation of one or more services
    • Service - an LDPC that specifies detailed information about what resources and capabilities the service supports.

1.1 Client Discovers Capabilities

The client has a number of options for discovering capabilities depending on its needs. It can either GET resources that describe the capabilities up front and use them to configure the UI on startup, or the client can incrementally discover capabilities based on what the user attempts to do, i.e., lazily construct the UI to support the user as needed.Servers may respond to OPTIONS “*” with Link headers that provide the LDPCs that support OSLC discovery.

1.1 Discovering the capabilities of a particular LDPC

OSLC is build on LDP and assume servers provide support for LDPCs. If the client is given a URI for an LDPC, they can use that to directly discover the capabilities the server provides on that LDPC.The client sends and OPTIONS or HEAD request with the LDPC as the request URI. The server response includes Link headers that describe what resources can be created in that LDPC, how to access creation and selection delegated UI dialogs, etc.The LDPC may be a Service which provides additional properties the client can GET to discover additional capabilities and information about capabilities including the supported domain, intended usage, and queryBase URI for making queries on resources, etc. The Service LDPC itself may or may not support POST to create resources, instead providing the oslc:creationFactory URI to an LDPC that does support resource creation. This allows servers to separate discovery resources from resources that organize managed content.

1.2 Discovering the capabilities of a collection of LDPCs

Clients that do up-front configuration may wish to discover a set of services in a single HTTP request. To do this the client would do a GET on a ServiceProvider LDPC. The entity response body is an LDP-R resource that has the properties of the ServiceProvider, and local resources for each of the Service resources offered by that service provider. The oslc:service property of the ServiceProvider resource has oslc:representation value oslc:Iline meaning the resource representation of the ServiceProvider will include inlined representations of the ldp:contains Services and their properties. Similarly, all the properties of a Service resource are also inlined. This allow the client to discover all the services provided by a service provider in a single GET request.Servers that support dynamic extensions may utilize OSLC discovery on the ServiceProvider itself to support user selection of desired services, or for creating new services.

1.3 Discovering the organization of provided services

Servers may choose to separate, partition or otherwise organize their capabilities and managed resources into different LDPCs, and these LDPCs may be ServiceProviderCatalog resources in order to provide additional information such as the publisher of the capabilities, the supported domains, server security configuration information and a list of contained service providers.A ServiceProviderCatalog LDPC may itself also provide discoverable OSLC capabilities though the Accept-Post and Link headers or through reference in some Service oslc:creationFactory. Servers may use this capability to support resource previews of service providers, user selection from available service providers, or for server extension through creation of new service providers.GET <ServiceProviderCatalog>

Potential Issues

1. Inhibits Separating OSLC2 and OSLC3 discovery for different server implementationsIt commingles Service Provider and LDPC types making it more difficult for OSLC3 servers who only want to support OSLC3 clients to only use the simpler, more dynamic LDPC discovery.Resolution: an LDPC is a resource and can have properties. The ServiceProviderCatalog, ServiceProvider and Service resources simply define additional properties. So this is essentially no difference for OSLC2 or OSLC3 clients or servers, and simply introduces three new LDPC subtypes.2. Increased complexityIt potentially increases the complexity of OSLC discovery by encouraging overlapping implementations of the same discovery capability. The intent of compatibility was to enable the continued use of existing OSLC2 clients, but to still encourage future clients and servers to utilize the simpler LDPC-based discovery. Keeping these separate may help facilitate the achievement of that objective.Resolution: If the ServiceProviderCatalog, ServiceProvider are a kind of LDPC, then the approaches to discovery are essentially merged and there is no additional complexity added to OSLC3. Clients and servers are already expected to use LDPC-based discovery, and handle RDF resources with defined properties. That is, OSLC3 discovery information is available from OPTIONS or HEAD methods and Link headers, but it is also available on the properties of an LDPC in the response to a GET method. So merging the OSLC2 discover resources with OSLC3 LDPCs doesn’t add anything new to OSLC3 other than some additional properties which may be required anyway to support the use cases.3. Overloads GET for OSLC2 ClientsThis potentially overloads the meaning of GET on an LDPC. What does the server return, the Service Provider resource, or the LDPC properties and content? There is no content-type or prefer header to distinguish these, and we probably don't want to introduce one.Resolution: GET on an LDPC would always return the content of the LDPC as an RDF resource. This would simply include the ServiceProviderCatalog and ServiceProvider properties, and would work for OSLC2 or OSLC3 clients. The only issue is OSLC2 clients might get the contents of the LDPC as well as the OSLC2 discovery properties which could have performance implications. OSLC3 clients can use the Prefer header to control what contents are returned.Recommendation: LDPCs Link headers can specify rel='type' with values: ldp:Container and/or ldp:BasicContainer, and oslc:ServiceProviderCatalog, oslc:ServiceProvider or oslc:ServiceThe are no arbitrary LDPC’s they are specific LDPCs that we define. OSLC defines the resource shapes that defines the content of a ServiceProvider as a specific kind of LDPC. So this is not.4. Inlining Service resources in a ServiceProvider resourceThis is related to the previous issue. If a Service is an LDPC, then it is directly addressable. However, the oslc:services property of a ServiceProvider is required to be inlined. If a ServiceProvider is also an LDPC, then LDP defines how the members are returned on a GET or added with POST/PUT and this could conflict with the OSLC2.0 resource shapes constraint that the members be inlined.Resolution: The specification for the ServiceProvider resource constraints using Resource Shapes can define how the members should be represented and this could be seen as a standard means of overriding the default LDPC members.

Clone this wiki locally