[OSLC] How to query the hierarchy of requirements within a module
Hi,
I've installed a test project in DOORS Next (don#t remember how it was called, something with an "Automatic Meter Reader").
When I clilck on the module "AMR Hazards and Risks" I see a nice outline of the contained (?) artifacts (requirements?).
I'm able to query all requirements via OSLC. I can also detect what requirements are actually modules and what these modules contain (actually "use").
But how can I detect via OSLC in what order and hierarchy the requirements appear in their module?
Accepted answer
Hi Davyd,
Your last paragraph made my day. You were right in that my initial GET request was incorrect. The reason is that Ian's description at https://jazz.net/forum/questions/272284/example-working-code-for-adding-requirements-to-a-module-via-oslc is not exactly correct: He suggests to use the header "DOORS-RP-Request-Type", but apparently that's wrong. The first dash between "DOORS" and "RP" must be removed, as in your comment above, and then it works.
Thanks for all your help!
But I must say that I find it extremely irritating that external access to DNG data (like import/export/sync) requires so much voluntary forum help, so much spec reading, so much web hunting for example code (which is often completely outdated and disfunctional). From my perspective https://www.omg.org/news/meetings/tc/ca-15/special-events/oslc-presentations/ruehlin.pdf brings it to the point.
AFAIK, Jazz is implemented in Java, so why doesn't IBM, at least for the most fundamental data concepts (such as Folder, Requirement, RequirementCollection, Module, ModuleBinding), provide a concise and functional Java library that allows to do the common CRUD operations? Possibly Eclipse Lyo could serve as a base for such a high-level library. I mean, now that I at least know all the protocol details to work with the RM module structures, I still need to figure out how to read and manipulate the RDF bodies of requests and responses, deal with ETags and thelike. I assume that's all totally easy for you because you're the ones who made it, and thereby have built up a lot of knowledge about RDF, OSLC, Lyo, and DNG (and therefore know where to use dashes in headers, and where not). For a single developer in a tiny company that wants to integrate a modeling tool with multiple requirement management systems (such as DNG, CodeBeamer, JIRA, Polarion, etc.) this is really not a very pleasant undertaking. I'm really hoping you take my comments as constructive criticism, because I think with very little effort from your side you could make the Java tool integration a bombastic experience ;-)
Comments
showing 5 of 6
show 1 more comments
3 other answers
Hi Eike
You can access the module structure using the DNG Module API (not OSLC) see here https://jazz.net/wiki/bin/view/Main/DNGModuleApiOverview
When accessing this you'll be switching from the OSLC API where you always use header OSLC-Core-Version: 2.0, so
- Don't use header OSLC-Core-Version
- Use the header:DOORSRP-Request-Type: public 2.0 - capitalized exactly as I've put here
- Provide the configuration using header vvc.configuration - only accepts a local configuration
There's an example (in Python) of using the module API in my OSS client code on github.com here - it's not exactly polished, but includes example code to calculate section number from the structure.
It's also possible to get the module structure using the DNG Reportable REST API (not OSLC) which doesn't use/need headers; you can put all the parameters in the URL and also you can access it using a logged-in browser which can be very convenient to test the URL.
For example the following query will return the content of the module, with each value showing the section number of the artifact:
https://SERVER:PORT/rm/publish/modules?moduleUri=MD_COUvD0B5Eeuh3Iiax2L3Ow&oslc_config.context=https%3A%2F%2FSERVER%3APORT%2Frm%2Fcm%2Fstream%2F_B7GQsEB5Eeuh3Iiax2L3Ow
HTH
Ian
Hi Ian,
Thank you very much for your reply. In the meantime I had already found the "/rm/publish/modules?" approach (mentiones in some other post here). With that I came up with some code:
private static void processModuleDescription(Map<String, IRMRequirement> requirements, DocumentBuilder builder, RMModule module, ClientResponse response)
{
try (InputStream input = response.getEntity(InputStream.class))
{
Document document = builder.parse(input);
Element root = document.getDocumentElement();
NodeList contextBindings = root.getElementsByTagName("rrm:contextBinding");
for (int i = 0, length = contextBindings.getLength(); i < length; i++)
{
Node contextBinding = contextBindings.item(i);
Map<String, String> properties = getXMLProperties(contextBinding);
String section = properties.get("rrm:section");
int depth = Integer.parseInt(properties.get("rrm:depth"));
int bookOrder = Integer.parseInt(properties.get("rrm:bookOrder"));
boolean heading = Boolean.parseBoolean(properties.get("rrm:isHeading"));
String identifier = properties.get("rrm:identifier");
RMRequirement requirement = (RMRequirement)requirements.get(identifier);
RMModuleRequirement parentRequirement = getParentRequirement(module, section, depth);
RMModuleRequirement moduleRequirement = new RMModuleRequirement(requirement, module, parentRequirement, section, depth, bookOrder, heading);
if (parentRequirement == null)
{
module.addSubRequirement(moduleRequirement);
}
else
{
parentRequirement.addSubRequirement(moduleRequirement);
}
}
}
catch (IOException | SAXException ex)
{
throw WrappedException.wrap(ex);
}
}
private static RMModuleRequirement getParentRequirement(RMModule module, String section, int depth)
{
RMModuleRequirement parent = null;
StringTokenizer tokenizer = new StringTokenizer(section, ".");
for (int i = 0, parents = depth - 1; i < parents; i++)
{
int segment = Integer.parseInt(tokenizer.nextToken()) - 1;
IRMModuleRequirement[] subRequirements = parent == null ? module.getSubRequirements() : parent.getSubRequirements();
parent = (RMModuleRequirement)subRequirements[segment];
}
return parent;
}
But I'll definitely read the DNGModuleApiOverview document and have a look at your Github code, too.
Thank you very much again!
Cheers
/Eike
It turns out that the "/rm/publish/modules" approach does not work for us because we'll need to update the module structure later.
I'd really like to play with the mechanisms explained in https://jazz.net/wiki/bin/view/Main/DNGModuleApiOverview , so I'm trying to follow https://jazz.net/forum/questions/272284/example-working-code-for-adding-requirements-to-a-module-via-oslc .
But I seem to struggle on the "NOTE" in step 5, i.e., my response contains lots of <oslc_rm:uses ...> tags. Here are the request details from my Rest client:
{ "method": "GET", "transformRequest": [ null ], "transformResponse": [ null ], "jsonpCallbackParam": "callback", "url": "https://192.168.99.3:9443/rm/resources/MD_rmNNhnbjEeyVS6HRXK_XDw", "headers": { "Accept": "application/rdf+xml", "DOORS-RP-Request-Type": "public 2.0" }, "data": "", "timeout": {} }
What am I missing?