Skip to content

Commit 9608fb0

Browse files
committed
Add examples/dn_simple_deleteartifact.py, re-ran oslcquery regression
1 parent addd09c commit 9608fb0

29 files changed

+2817
-2680
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.14.0
2+
current_version = 0.15.0
33
commit = True
44
tag = True
55

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
SPDX-License-Identifier: MIT
1010

11-
version="0.14.0"
11+
version="0.15.0"
1212

1313

1414
Introduction

elmclient/__meta__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
app = 'elmoslcquery'
1111
description = 'Commandline OSLC query for ELM'
12-
version = '0.14.0'
12+
version = '0.15.0'
1313
license = 'MIT'
1414
author_name = 'Ian Barnard'
1515
author_mail = 'ian.barnard@uk.ibm.com'

elmclient/examples/dn_simple_createartifact.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
##################################################################################
6767
if __name__=="__main__":
6868
if len(sys.argv) != 4:
69-
raise Exception( 'You must provide a string (surrounded by " if including spaces)' )
69+
raise Exception( 'You must provide: The artifact type, the artifact text, and the folder path to create the artifact in - each surrounded by " if including spaces' )
7070

7171
# create our "server" which is how we connect to DOORS Next
7272
# first enable the proxy so if a proxy is running it can monitor the communication with server (this is ignored if proxy isn't running)
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
##
2+
## © Copyright 2023- IBM Inc. All rights reserved
3+
# SPDX-License-Identifier: MIT
4+
##
5+
6+
# example of updating a core artifact
7+
8+
# provide on the commandline the id of an artifact in the project/component/configuration to delete
9+
# this code finds the core artifact and all its bindings, delees each binding individually then deletes the core artifact
10+
# will delete whole modules with deleting the bindings in it
11+
12+
import logging
13+
import os.path
14+
import sys
15+
import time
16+
17+
import lxml.etree as ET
18+
19+
import elmclient.server as elmserver
20+
import elmclient.utils as utils
21+
import elmclient.rdfxml as rdfxml
22+
23+
# setup logging - see levels in utils.py
24+
#loglevel = "INFO,INFO"
25+
loglevel = "TRACE,OFF"
26+
levels = [utils.loglevels.get(l,-1) for l in loglevel.split(",",1)]
27+
if len(levels)<2:
28+
# assert console logging level OFF if not provided
29+
levels.append(None)
30+
if -1 in levels:
31+
raise Exception( f'Logging level {loglevel} not valid - should be comma-separated one or two values from DEBUG, INFO, WARNING, ERROR, CRITICAL, OFF' )
32+
utils.setup_logging( filelevel=levels[0], consolelevel=levels[1] )
33+
34+
logger = logging.getLogger(__name__)
35+
36+
utils.log_commandline( os.path.basename(sys.argv[0]) )
37+
38+
jazzhost = 'https://jazz.ibm.com:9443'
39+
40+
username = 'ibm'
41+
password = 'ibm'
42+
43+
jtscontext = 'jts'
44+
rmcontext = 'rm'
45+
46+
# the project+compontent+config that will be updated
47+
proj = "rm_optout_p2"
48+
comp = proj
49+
conf = f"{comp} Initial Stream"
50+
51+
# caching control
52+
# 0=fully cached (but code below specifies queries aren't cached) - if you need to clear the cache, delet efolder .web_cache
53+
# 1=clear cache initially then continue with cache enabled
54+
# 2=clear cache and disable caching
55+
caching = 2
56+
57+
##################################################################################
58+
if __name__=="__main__":
59+
if len(sys.argv) != 2:
60+
raise Exception( 'You must provide an identifier for the artifact to delete' )
61+
62+
# create our "server" which is how we connect to DOORS Next
63+
# first enable the proxy so if a proxy is running it can monitor the communication with server (this is ignored if proxy isn't running)
64+
elmserver.setupproxy(jazzhost,proxyport=8888)
65+
theserver = elmserver.JazzTeamServer(jazzhost, username, password, verifysslcerts=False, jtsappstring=f"jts:{jtscontext}", appstring='rm', cachingcontrol=caching)
66+
67+
# create the RM application interface
68+
dnapp = theserver.find_app( f"rm:{rmcontext}", ok_to_create=True )
69+
70+
# open the project
71+
p = dnapp.find_project(proj)
72+
73+
# find the component
74+
c = p.find_local_component(comp)
75+
comp_u = c.project_uri
76+
print( f"{comp_u=}" )
77+
78+
# select the configuration
79+
config_u = c.get_local_config(conf)
80+
print( f"{config_u=}" )
81+
c.set_local_config(config_u)
82+
83+
# find the artifact - using OSLC Query
84+
85+
# get the query capability base URL for requirements
86+
qcbase = c.get_query_capability_uri("oslc_rm:Requirement")
87+
88+
# query for a title and for format=module
89+
artifacts = c.execute_oslc_query(
90+
qcbase,
91+
whereterms=[['dcterms:identifier','=',f'"{sys.argv[1]}"']],
92+
select=['*'],
93+
prefixes={rdfxml.RDF_DEFAULT_PREFIX["dcterms"]:'dcterms'} # note this is reversed - url to prefix
94+
)
95+
96+
# print( f"{artifacts=}" )
97+
98+
if len(artifacts)==0:
99+
raise Exception( f"No artifact with identifier '{sys.argv[1]}' found in project {proj} component {comp} configuration {conf}" )
100+
elif len(artifacts)>2:
101+
for k,v in artifacts.items():
102+
print( f'{k} ID {v.get("dcterms:identifier","???")} Title {v.get("dcterms:title","")}' )
103+
raise Exception( "More than one artifcact with that id in project {proj} component {comp} configuraition {conf}" )
104+
105+
# find the core artifact - it has a value for rm_nav:parent
106+
theartifact_u = None
107+
bindings=[]
108+
for artifact in artifacts.keys():
109+
# print( f"Testing parent on {artifact=}" )
110+
if artifacts[artifact].get("rm_nav:parent") is not None:
111+
if theartifact_u:
112+
barf
113+
theartifact_u = artifact
114+
else:
115+
bindings.append(artifact)
116+
117+
if bindings:
118+
# delete the bindings one by one
119+
for binding_u in bindings:
120+
print( f"Deleting binding {binding_u}" )
121+
# now get the artifact content and its etag
122+
theartifact_x, etag = c.execute_get_rdf_xml( binding_u, return_etag=True, intent="Retrieve the artifact" )
123+
print( f"{ET.tostring(theartifact_x)=}\n" )
124+
125+
# get the text - this is always xhtml in a div below jazz_rm:primaryText
126+
thetext = rdfxml.xml_find_element( theartifact_x, ".//jazz_rm:primaryText/xhtml:div" )
127+
print( f"Binding {sys.argv[1]} text='{thetext}'" )
128+
129+
# DELETE to remove the binding
130+
response = c.execute_delete( binding_u, headers={'If-Match':etag}, intent="Update the artifact" )
131+
print( f"{response.status_code}" )
132+
location = response.headers.get('Location')
133+
if response.status_code != 200:
134+
raise Exception( "Binding DELETE failed!" )
135+
else:
136+
print( f"Binding delete succeeded!" )
137+
138+
else:
139+
print( f"No bindings!" )
140+
141+
if not theartifact_u:
142+
raise Exception( "Artifact with rm_nav:parent (i.e. the core artifact) not found!" )
143+
144+
print( f"Found core artifact {theartifact_u=}" )
145+
146+
# now get the artifact content and its etag
147+
theartifact_x, etag = c.execute_get_rdf_xml( theartifact_u, return_etag=True, intent="Retrieve the artifact" )
148+
print( f"{ET.tostring(theartifact_x)=}\n" )
149+
150+
# find the text - this is always xhtml in a div below jazz_rm:primaryText
151+
thetext = rdfxml.xml_find_element( theartifact_x, ".//jazz_rm:primaryText/xhtml:div" )
152+
print( f"Artifact {sys.argv[1]} text='{thetext}'" )
153+
154+
# DELETE it to remove the core artifact
155+
response = c.execute_delete( theartifact_u, headers={'If-Match':etag}, intent="Update the artifact" )
156+
print( f"{response.status_code}" )
157+
location = response.headers.get('Location')
158+
if response.status_code != 200:
159+
raise Exception( "DELETE failed!" )
160+
161+

elmclient/examples/dn_simple_updateartifact.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -53,30 +53,6 @@
5353
# 2=clear cache and disable caching
5454
caching = 2
5555

56-
##################################################################################
57-
def iterwalk1(root, events=None, tags=None):
58-
"""Recuirsive version - Incrementally walks XML structure (like iterparse but for an existing ElementTree structure)
59-
Returns an iterator providing (event, elem) pairs.
60-
Events are start and end
61-
events is a list of events to emit - defaults to ["start","end"]
62-
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
63-
"""
64-
tags = [] if tags is None else tags if type(tags) == list else [tags]
65-
events = events or ["start","end"]
66-
67-
def recursiveiterator(el,suppressyield=False):
68-
if not suppressyield and ( not tags or el.tag in tags ) and "start" in events:
69-
yield ("start",el)
70-
for child in list(el):
71-
yield from recursiveiterator(child)
72-
if not suppressyield and ( not tags or el.tag in tags ) and "end" in events:
73-
yield ("end",el)
74-
75-
def iterator():
76-
yield from recursiveiterator( root, suppressyield=True )
77-
78-
return iterator
79-
8056
##################################################################################
8157
if __name__=="__main__":
8258
if len(sys.argv) != 3:

0 commit comments

Comments
 (0)