RM OSLC - created links don't seem to persist
hi all
I'm developing my first RM OSLC app which at some point will create a link between two requirements.
The code I started with is from the OSLC workshop RM example 03. This is in a GC context, I should add.
I just don't see the links in the GUI, or if I inquire programmatically, although they appear to be present right after creation.And no error is thrown. (This is RM 6.0.6.1)
Here's some code:
I seem to have missed something.
private void updateRequirement(OslcClient oslcClient, String sourceURL, String targetURL) throws Exception {
Thread.sleep(3000); //wait for indexing
//Get the document we just created
ClientResponse sourceResponse = oslcClient.getResource(sourceURL, OSLCConstants.CT_RDF);
if (sourceResponse.getStatusCode() != 200) {
sourceResponse.consumeContent();
throw new HttpResponseException(sourceResponse.getStatusCode(),
sourceResponse.getMessage());
}
Requirement sourceReq = sourceResponse.getEntity(Requirement.class);
List<String> etagValues = sourceResponse.getHeaders().get("etag");
Link links[] = sourceReq.getSatisfies();
for (Link link : links) {
log.println("S LINK: " + link);
}
//Get the document we just created
ClientResponse targetResponse = oslcClient.getResource(targetURL, OSLCConstants.CT_RDF);
if (targetResponse.getStatusCode() != 200) {
targetResponse.consumeContent();
throw new HttpResponseException(targetResponse.getStatusCode(),
targetResponse.getMessage());
}
Requirement targetReq = targetResponse.getEntity(Requirement.class);
List<String> tetagValues = targetResponse.getHeaders().get("etag");
Link satisfies = new Link(targetReq.getAbout());
sourceReq.setSatisfies(new Link[] { satisfies });
sourceResponse = etagValues != null ?
oslcClient.updateResource(sourceURL, sourceReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF,
etagValues.get(etagValues.size() - 1)) :
oslcClient.updateResource(sourceURL, sourceReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF);
sourceResponse.consumeContent();
if (sourceResponse.getStatusCode() != 200) {
sourceResponse.consumeContent();
throw new HttpResponseException(sourceResponse.getStatusCode(),
sourceResponse.getMessage());
}
targetResponse = tetagValues != null ?
oslcClient.updateResource(targetURL, targetReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF,
tetagValues.get(tetagValues.size() - 1)) :
oslcClient.updateResource(targetURL, targetReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF);
targetResponse.consumeContent();
if (targetResponse.getStatusCode() != 200) {
targetResponse.consumeContent();
throw new HttpResponseException(targetResponse.getStatusCode(),
targetResponse.getMessage());
}
Link alinks[] = sourceReq.getSatisfies();
for (Link link : alinks) {
log.println("LINK: " + link);
}
log.println("Linked");
//If we get here then our PUT succeeded and the requirement should have our link now
}
Thread.sleep(3000); //wait for indexing
//Get the document we just created
ClientResponse sourceResponse = oslcClient.getResource(sourceURL, OSLCConstants.CT_RDF);
if (sourceResponse.getStatusCode() != 200) {
sourceResponse.consumeContent();
throw new HttpResponseException(sourceResponse.getStatusCode(),
sourceResponse.getMessage());
}
Requirement sourceReq = sourceResponse.getEntity(Requirement.class);
List<String> etagValues = sourceResponse.getHeaders().get("etag");
Link links[] = sourceReq.getSatisfies();
for (Link link : links) {
log.println("S LINK: " + link);
}
//Get the document we just created
ClientResponse targetResponse = oslcClient.getResource(targetURL, OSLCConstants.CT_RDF);
if (targetResponse.getStatusCode() != 200) {
targetResponse.consumeContent();
throw new HttpResponseException(targetResponse.getStatusCode(),
targetResponse.getMessage());
}
Requirement targetReq = targetResponse.getEntity(Requirement.class);
List<String> tetagValues = targetResponse.getHeaders().get("etag");
Link satisfies = new Link(targetReq.getAbout());
sourceReq.setSatisfies(new Link[] { satisfies });
sourceResponse = etagValues != null ?
oslcClient.updateResource(sourceURL, sourceReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF,
etagValues.get(etagValues.size() - 1)) :
oslcClient.updateResource(sourceURL, sourceReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF);
sourceResponse.consumeContent();
if (sourceResponse.getStatusCode() != 200) {
sourceResponse.consumeContent();
throw new HttpResponseException(sourceResponse.getStatusCode(),
sourceResponse.getMessage());
}
targetResponse = tetagValues != null ?
oslcClient.updateResource(targetURL, targetReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF,
tetagValues.get(tetagValues.size() - 1)) :
oslcClient.updateResource(targetURL, targetReq, OSLCConstants.CT_RDF,
OSLCConstants.CT_RDF);
targetResponse.consumeContent();
if (targetResponse.getStatusCode() != 200) {
targetResponse.consumeContent();
throw new HttpResponseException(targetResponse.getStatusCode(),
targetResponse.getMessage());
}
Link alinks[] = sourceReq.getSatisfies();
for (Link link : alinks) {
log.println("LINK: " + link);
}
log.println("Linked");
//If we get here then our PUT succeeded and the requirement should have our link now
}
3 answers
Code seems to work if I use a "Specifies" or "Elaborates" link to another requirement.
It would appear that the problem is that the "Satisfies" link type isn't supported by OSLC, at least through the lyo app. When I look at a Satisfies link that I established via the RM gui, I see:
<ds:Link type="Link">
<rrm:title>Satisfies</rrm:title>
<ds:linkType>
https://myserver/rm/types/_HJ2MLNobEemsbO6NwH1NuA
</ds:linkType>
<ds:isParentLink>false</ds:isParentLink>
<ds:isChildLink>false</ds:isChildLink>
<rrm:relation>
https://myserver/rm/resources/MB_ace34e61a36346599ddc93be08259e86
</rrm:relation>
<rrm:alternative>
https://myserver/rm/resources/MB_ace34e61a36346599ddc93be08259e86
</rrm:alternative>
<rrm:identifier>328</rrm:identifier>
<ds:content>
<rrm:title>Actor 1</rrm:title>
<rrm:identifier>328</rrm:identifier>
<rrm:description/>
<rrm:format>Text</rrm:format>
<ds:artifactFormat>Actor</ds:artifactFormat>
</ds:content>
</ds:Link>
<rrm:title>Satisfies</rrm:title>
<ds:linkType>
https://myserver/rm/types/_HJ2MLNobEemsbO6NwH1NuA
</ds:linkType>
<ds:isParentLink>false</ds:isParentLink>
<ds:isChildLink>false</ds:isChildLink>
<rrm:relation>
https://myserver/rm/resources/MB_ace34e61a36346599ddc93be08259e86
</rrm:relation>
<rrm:alternative>
https://myserver/rm/resources/MB_ace34e61a36346599ddc93be08259e86
</rrm:alternative>
<rrm:identifier>328</rrm:identifier>
<ds:content>
<rrm:title>Actor 1</rrm:title>
<rrm:identifier>328</rrm:identifier>
<rrm:description/>
<rrm:format>Text</rrm:format>
<ds:artifactFormat>Actor</ds:artifactFormat>
</ds:content>
</ds:Link>
compare to the Specifies relationship:
<ds:Specifies type="Specifies">
<rrm:title>Specifies</rrm:title>
<ds:linkType>
https://myserver/rm/types/_TuEXEdoaEemsbO6NwH1NuA
</ds:linkType>
<rrm:relation>
https://myserver/rm/resources/MB_d33e8df4600f41a9a59b8c3ae658f9f2
</rrm:relation>
<rrm:alternative>
https://myserver/rm/resources/MB_d33e8df4600f41a9a59b8c3ae658f9f2
</rrm:alternative>
<rrm:identifier>331</rrm:identifier>
<ds:content>
<rrm:title>Do wacka do</rrm:title>
<rrm:identifier>331</rrm:identifier>
<rrm:description/>
<rrm:format>Text</rrm:format>
<ds:artifactFormat>Use Case Requirement</ds:artifactFormat>
</ds:content>
</ds:Specifies>
<rrm:title>Specifies</rrm:title>
<ds:linkType>
https://myserver/rm/types/_TuEXEdoaEemsbO6NwH1NuA
</ds:linkType>
<rrm:relation>
https://myserver/rm/resources/MB_d33e8df4600f41a9a59b8c3ae658f9f2
</rrm:relation>
<rrm:alternative>
https://myserver/rm/resources/MB_d33e8df4600f41a9a59b8c3ae658f9f2
</rrm:alternative>
<rrm:identifier>331</rrm:identifier>
<ds:content>
<rrm:title>Do wacka do</rrm:title>
<rrm:identifier>331</rrm:identifier>
<rrm:description/>
<rrm:format>Text</rrm:format>
<ds:artifactFormat>Use Case Requirement</ds:artifactFormat>
</ds:content>
</ds:Specifies>
So - bottom line, can someone confirm whether the Satisfies link can be created using OSLC?
OK, So, here's what you need to do - instead of creating a link, work through the extendedProperties:
replace
Link satisfies = new Link(targetReq.getAbout());
sourceReq.setSatisfies(new Link[] { satisfies });
sourceReq.setSatisfies(new Link[] { satisfies });
with:
Map<QName,Object> pmap = sourceReq.getExtendedProperties();
// this is the Satisfies link type
QName key = new QName("https://myserver/rm/types/", "_HJ2MLNobEemsbO6NwH1NuA", "rm_property");
pmap.put(key, targetReq);
sourceReq.setExtendedProperties(pmap);
// this is the Satisfies link type
QName key = new QName("https://myserver/rm/types/", "_HJ2MLNobEemsbO6NwH1NuA", "rm_property");
pmap.put(key, targetReq);
sourceReq.setExtendedProperties(pmap);
(thanks Scott!)
Steve, please be aware that Eclipse Lyo is probably a better infrastructure. The Examples you started with are so old, that they precede the newer frameworks that can make life easier. https://rsjazz.wordpress.com/2019/03/07/type-system-manager-part-2/ and the related articles show how to get started with the older 2.4 version. See https://github.com/OSLC/lyo-samples/tree/master/oslc4j-client-samples/src/main/java/org/eclipse/lyo/oslc4j/client/samples . Especially https://github.com/OSLC/lyo-samples/blob/master/oslc4j-client-samples/src/main/java/org/eclipse/lyo/oslc4j/client/samples/RMSample.java