Now that we have a basic understanding of the RootServices document, and how to access protected APIs. Let’s go thru the process of discovery, in order to identify what is needed for OSLC APIs. I’ll be covering the basics behind the OSLC Resource Shape. Understanding resource shapes is key for identifying what properties are required when creating new components and artifacts with ELM APIs.
Sample Project
I’ve setup a sample project area on the server called “JKE Banking” utilizing the admin screen.
I will be using this Project-Area for many of the examples in this series, I recommend setting it up on your development server so that you can follow along.
I’m going to start by looking at a key item for all ELM applications – the Project Area. To find the services related to Project Areas, we need to look at the OSLC Services Catalog on our server. As we are working with a DOORSNext server (AKA rm), we can find search for the API in our RootServices document, by searching for <oslc_rm:rmServiceProviders>.
<oslc_rm:rmServiceProviders rdf:resource="https://elm-t1-rm.fyre.ibm.com:9443/rm/oslc_rm/catalog" />
The rdf:resource is the API we will be calling.
In both of the prior blog entries on Authentication, we ended up getting a list of all the Project Areas on our server. Here’s what that API looks like in Python, utilizing http client:
import http.client
conn = http.client.HTTPSConnection("elmwb.com", undefined)
payload = ''
headers = {
'OSLC-Core-Version': '2.0',
'Accept': ‘applications/rdf+xml’,
‘Authorization’: ’Bearer 6fT3oSX0mysHiaUJH9sXAdCfIXhrG59rNESdLEaQ'
}
conn.request("GET", "/rm/oslc_rm/catalog", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
API Documentation – OSLC Catalog
Get: https://server:port/rm/oslc_rm/catalog
Authorization: Bearer Token
Request Headers:
“OSLC-Core-Version”:”2.0”
“Accept”:”applications/json” or “text/turtle” or “applications/rdf+xml”
Response Body:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/"
xmlns:jazzDisc="http://jazz.net/ns/discovery#"
xmlns:oslc=“http://open-services.net/ns/core#">
<oslc:ServiceProviderCatalog rdf:about="https://elmwb.com:9443/rm/oslc_rm/catalog">
<dcterms:title rdf:parseType="Literal">RMCatalog</dcterms:title>
<dcterms:publisher rdf:resource="https://elmwb.com:9443/rm/application-about" />
<oslc:domain rdf:resource="http://open-services.net/ns/rm#" />
<oslc:serviceProvider>
<oslc:ServiceProvider rdf:about="https://elmwb.com:9443/rm/oslc_rm/_LgdUMIkaEey3TMAARolZjw/services.xml">
<dcterms:title rdf:parseType="Literal">JKE Banking (Requirements Management)</dcterms:title>
<jazzDisc:messageReceiver rdf:resource="https://elmwb.com:9443/rm/web/com/ibm/rdm/web/copyReceiver/CopyHandler.html"/>
<jp:consumerRegistry rdf:resource="https://elmwb.com:9443/rm/process/project-areas/_LgdUMIkaEey3TMAARolZjw/links"/>
<oslc:details rdf:resource="https://elmwb.com:9443/rm/process/project-areas/_LgdUMIkaEey3TMAARolZjw"/>
</oslc:ServiceProvider>
</oslc:serviceProvider>
</oslc:ServiceProviderCatalog>
</rdf:RDF>
I’ve simplified the response body to only provide information about our “JKE Banking (Requirements Management)” example project. This catalog will provide us with the <oslc:details>, note this is within a <oslc:serviceProvider>, which is our next API we will execute.
API Documentation – OSLC Project Area Details
Get: https://server:port/rm/process/project-areas/<Project Area UUID>
Authorization: Bearer Token
Request Headers:
“OSLC-Core-Version”:”2.0”
“Accept”:”applications/json” or “text/turtle” or “applications/rdf+xml”
Response Body:
Response Body:
@prefix acc: <http://open-services.net/ns/core/acc#> .
@prefix process: <http://jazz.net/ns/process#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix jfs_process: <http://jazz.net/xmlns/prod/jazz/process/1.0/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix process_shapes: <http://jazz.net/ns/process/shapes/> .
@prefix oslc: <http://open-services.net/ns/core#> .
<https://elmwb.com:9443/rm/process/project-areas/_LgdUMIkaEey3TMAARolZjw>
a process:ProjectArea ;
process:isAccessPublic
"false"^^xsd:boolean ;
process:isAccessVisibleToAccessList
"false"^^xsd:boolean ;
process:isAccessVisibleToMembers
"true"^^xsd:boolean ;
process:summary "JKE Banking (Requirements Management)"^^rdf:XMLLiteral ;
oslc:archived "false"^^xsd:boolean ;
oslc:instanceShape process_shapes:ProjectArea ;
oslc:serviceProvider
<https://elmwb.com:9443/rm/oslc_rm/_LgdUMIkaEey3TMAARolZjw/services.xml> ;
acc:accessContext <https://elmwb.com:9443/rm/acclist#_LgdUMIkaEey3TMAARolZjw> ;
dcterms:description "The purpose of this project is to specify and manage the requirements of the JKE Business Recovery Matters project."^^rdf:XMLLiteral ;
dcterms:modified "2022-02-08T20:04:05.000Z"^^xsd:dateTime ;
dcterms:title "JKE Banking (Requirements Management)"^^rdf:XMLLiteral .
<https://elmwb.com:9443/rm/application-about>
a oslc:Publisher ;
oslc:icon <https://elmwb.com:9443/rm/web/com.ibm.rdm.web/pages/images/RDNG_16.png> ;
oslc:label "Requirements Management" ;
dcterms:identifier "http://jazz.net/application/rm" ;
dcterms:title "Requirements Management"^^rdf:XMLLiteral .
<https://elmwb.com:9443/rm/oslc_rm/_LgdUMIkaEey3TMAARolZjw/services.xml>
a oslc:ServiceProvider ;
jfs_process:globalConfigurationAware
"no"^^rdf:XMLLiteral ;
oslc:details <https://elmwb.com:9443/rm/process/project-areas/_LgdUMIkaEey3TMAARolZjw> ;
oslc:publisher <https://elmwb.com:9443/rm/application-about> ;
oslc:service
[ a oslc:Service ;
oslc:domain <http://open-services.net/ns/rm#>
] .
Now we are getting somewhere. The above “text/turtle” response provides us with the “oslc:instanceShape”, this is the description of a “Project Area”. We can now define what is required in order to create a new project area. If you haven’t read up on Turtle (https://www.w3.org/TR/turtle/), the above highlighted value tell you that you can go to http://jazz.net/ns/process/shapes/ProjectArea to see it’s resource shape.
Currently on the referred page, we see to definition files, one is a RDF/XML file and the other is a Turtle.
Reading the resource shape
Let’s review the turtle, as its format is more human readable. I won’t go thru the entire file, but will focus on a few entries to help your understanding of an OSLC resource shape. I purposely chose the Project Area resource shape, as it is a standard resource shape regardless of the ELM server instance. Please note, there is no public API to create a project area.
Comments and Prefixes
# Arthur Ryman
# 2015-02-25 - Created.
# 2015-03-01 - Improve title. Mark collection resources as hidden. Added instanceShape, accessControl, and accessContext.
# 2015-03-02 - Updated based on review comments from Kevin Cornell and Rafik Jaouani.
@prefix acc: <http://open-services.net/ns/core/acc#> .
@prefix acp: <http://jazz.net/ns/acp#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix oslc: <http://open-services.net/ns/core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix process: <http://jazz.net/ns/process#> .
@prefix shapes: <http://jazz.net/ns/process/shapes/> .
The above lines provide with the various name spaces (or prefixes), this values are used to replace the content in the following lines, e.g. replace acc with the value https://open-services.net/ns/core/acc# so that you can get a fully qualified link to additional information.
@base <http://jazz.net/ns/process/shapes/ProjectArea> .
<>
a oslc:ResourceShape ;
dcterms:title "Jazz Foundation Project Area."^^rdf:XMLLiteral ;
dcterms:description "This shape describes project area resources hosted by the Jazz Foundation Process component."^^rdf:XMLLiteral;
oslc:describes process:ProjectArea ;
oslc:property
<#accessContext> ,
<#accessControl> ,
<#admins> ,
<#archived> ,
<#description> ,
<#history> ,
<#instanceShape> ,
<#isAccessPublic> ,
<#isAccessVisibleToAccessList> ,
<#isAccessVisibleToMembers> ,
<#isInitialized> ,
<#links> ,
<#members> ,
<#modified> ,
<#projectAdmins> ,
<#readAccessList> ,
<#roles> ,
<#summary>,
<#teamAreas> ,
<#timelines> ,
<#title> .
These lines provide you with the various properties of the resource shape. We see that we have a “Jazz Foundation Project Area” with 21 properties, beginning with #accessContext and ending with #title. The remainder of the turtle will describe each of the properties in more detail.
I will review two of the properties “#description” and “#history”.
#description
This is an optional value based on the oslc:occurs being oslc:Zero-or-one. We can see that XMLLiteral is defined at http://open-services.net/ns/core#valueType as a URI that indicates a value type, in our case XMLLiteral.
<#description>
a oslc:Property ;
oslc:propertyDefinition dcterms:description ;
dcterms:description "The description of the project area."^^rdf:XMLLiteral ;
oslc:name "description" ;
oslc:occurs oslc:Zero-or-one ;
oslc:valueType rdf:XMLLiteral .
#history
This is a mandatory value based on the oslc:occurs being oslc:Exactly-one; however, it is also oslc:readOnly true, meaning that if not provided at create time, then it will not be writable via API. We can see that it is defined at http://open-services.net/ns/core#valueType as a RDF description, in our case oslc:Resource.
<#history>
a oslc:Property ;
oslc:propertyDefinition process:history ;
dcterms:description "The link to the history of the project area."^^rdf:XMLLiteral ;
oslc:name "history" ;
oslc:occurs oslc:Exactly-one ;
oslc:representation oslc:Reference ;
oslc:readOnly true ;
oslc:valueType oslc:Resource ;
oslc:hidden true ;
oslc:range process:History .
A more detailed review of each of the values in the resource shape can be found at the following link.
What is required in the API call?
Now that we understand how to read the resource shape, let’s do an exercise to define what the body of a NON-EXISTENT create Project Area API could look like. After going thru the entire resource shape, you will find 15 values which are listed as “Exactly-One”, these are required for the creation of a new Project Area; however, not all of them are required when calling the API. There are 5 values of “Zero-or-One”, these are optional values, and one value of “Zero-or-Many”, which is an optional list of values. For most APIs, utilizing the definitions of the properties with “Exactly-One” should provide you with what you need to create a new instance of that Resource.
If you go back to your server and look at the Project Area Definition, we should be able to map to our properties:
We can take the list of properties and see the following categories, which could help us in defining the Body of an API call.
Property | oslc:occurs | oslc:readonly | oslc:hidden | Comments |
#accessContext | Zero-or-many | TRUE | TRUE | |
#accessControl | Zero-or-one | TRUE | TRUE | Deprecated |
#admins | Exactly-one | TRUE | TRUE | |
#archived | Exactly-one | Defaults to False | ||
#description | Zero-or-one | Optional | ||
#history | Exactly-one | TRUE | TRUE | |
#instanceShape | Zero-or-one | TRUE | TRUE | |
#isAccessPublic | Exactly-one | Defaults to False | ||
#isAccessVisibleToAccessList | Exactly-one | Defaults to True | ||
#isAccessVisbleToMembers | Exactly-one | Defaults to True | ||
#isInitialized | Zero-or-one | TRUE | Defaults to True | |
#links | Exactly-one | TRUE | TRUE | |
#members | Exactly-one | TRUE | TRUE | |
#modified | Exactly-one | Defaults to create time | ||
#projectAdmins | Exactly-one | TRUE | TRUE | Deprecated, replaced by #admins |
#readAccessList | Exactly-one | TRUE | TRUE | |
#roles | Exactly-one | TRUE | TRUE | |
#summary | Zero-or-one | Optional | ||
#teamAreas | Exactly-one | TRUE | TRUE | |
#timelines | Exactly-one | TRUE | TRUE | |
#title | Exactly-one | Mandatory |
Given the above table analysis, it would appear that the body of the Create API should contain the following values:
- A mandatory flag to indicate if the project area is archived
- An optional description
- A mandatory flag if it is accessible to the public
- A mandatory flag if the access is visible to the access list
- A mandatory flag if the access is visible to members of the project area
- A mandatory time stamp for the modified time
- An optional summary
- A mandatory Title
One thing to consider, the oslc:hidden tag is defined as “A hint that indicates that property MAY be hidden when presented in a user interface.” Given this, it is likely that you do not need to provide values to a hidden property in an API call, as it is likely to be a computed property.
In my next article I will take a look at a public API and see if we can perform the same analysis to identify the content of the API payload.