Skip to content

Commit cd9cd74

Browse files
committed
moved to new env
1 parent 835cc55 commit cd9cd74

13 files changed

+281
-1131
lines changed

elmclient/_config.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
##
2+
## © Copyright 2021- IBM Inc. All rights reserved
3+
# SPDX-License-Identifier: MIT
4+
##
5+
6+
import datetime
7+
import logging
8+
import re
9+
import sys
10+
11+
import anytree
12+
import dateutil.parser
13+
import dateutil.tz
14+
import lxml.etree as ET
15+
import requests
16+
import tqdm
17+
import pytz
18+
19+
from . import _app
20+
from . import _project
21+
from . import _typesystem
22+
from . import oslcqueryapi
23+
from . import rdfxml
24+
from . import server
25+
from . import utils
26+
27+
#################################################################################################
28+
29+
logger = logging.getLogger(__name__)
30+
31+
#################################################################################################
32+
33+
BASELINE = 1
34+
STREAM = 2
35+
CHANGESET = 3
36+
37+
class _Config():
38+
configtype = None
39+
def __init__(self, *ags, **kwargs ):
40+
print( f"Config init {self=}" )
41+
pass
42+
def is_stream(self):
43+
return self.configtype == STREAM
44+
def is_baseline(self):
45+
return self.configtype == BASELINE
46+
def is_changeset(self):
47+
return self.configtype == CHANGESET
48+
49+
class _Stream(_Config):
50+
configtype = STREAM
51+
from_baseline = None
52+
baselines = []
53+
changesets = []
54+
def __init__( self, *args, **kwargs ):
55+
super().__init__( *args, **kwargs )
56+
57+
def create_baseline(self):
58+
pass
59+
def create_changeset(self):
60+
pass
61+
pass
62+
63+
class _Baseline(_Config):
64+
configtype = BASELINE
65+
instream = None
66+
streams = []
67+
68+
def __init__( self, *args, **kwargs ):
69+
super().__init__( *args, **kwargs )
70+
def create_stream(self):
71+
pass
72+
73+
class _Changeset(_Config):
74+
configtype = CHANGESET
75+
instream=None
76+
def __init__( self, *args, **kwargs ):
77+
super().__init__( *args, **kwargs )
78+
79+
def deliver(self):
80+
pass
81+
def discard(self):
82+
pass
83+
84+

elmclient/_project.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ def __init__(self, name, project_uri, app, is_optin=False, singlemode=False,defa
5555
# the services.xml will be retrieved later when needed, because the config to retrieve it in isn't currently known there's no point retrieving it now
5656
return
5757

58+
def listmembers( self ):
59+
pass
60+
5861
def load_types(self):
5962
self._load_types()
6063

elmclient/_queryparser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ def dottedname(self,s):
317317

318318
def identifier(self, s):
319319
logger.info( f"Identifier {s=}" )
320+
print( f"Identifier {s=}" )
320321
if len(s) == 1:
321322
if type(s[0])==str:
322323
result = s[0]

elmclient/_rm.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import pytz
1818

1919
from . import _app
20+
from . import _config
2021
from . import _project
2122
from . import _typesystem
2223
from . import oslcqueryapi
@@ -39,6 +40,20 @@ def __init__(self, name=None, folderuri=None, parent=None):
3940

4041
#################################################################################################
4142

43+
if False:
44+
@utils.mixinomatic
45+
class _RM_PA_stream( _config._Stream,_RMProject ):
46+
pass
47+
48+
@utils.mixinomatic
49+
class _RM_PA_baseline( _config._Baseline,_RMProject ):
50+
pass
51+
52+
@utils.mixinomatic
53+
class _RM_PA_changeset( _config._Changeset,_RMProject):
54+
pass
55+
56+
@utils.mixinomatic
4257
class _RMProject(_project._Project):
4358
# A project
4459
# NOTE there is a derived class RMComponent used for RM components - it doesn't offer any
@@ -47,7 +62,7 @@ class _RMProject(_project._Project):
4762
# For full optin there are as many components as real components; for <=6.0.3 Cfgm-enabled and for >=7.0
4863
# CfgM-disabled (called single mode), there's only ever a single component
4964
def __init__(self, name, project_uri, app, is_optin=False, singlemode=False,defaultinit=True):
50-
super().__init__(name, project_uri, app, is_optin,singlemode,defaultinit=defaultinit)
65+
# super().__init__(name, project_uri, app, is_optin,singlemode,defaultinit=defaultinit)
5166
# self.oslcquery = oslcqueryapi._OSLCOperations(self.app.server,self)
5267
self._components = None # keyed on component uri
5368
self._configurations = None # keyed on the config name
@@ -290,7 +305,7 @@ def load_components_and_configurations(self,force=False):
290305

291306
for component_el in rdfxml.xml_find_elements(crx, './/ldp:contains'):
292307
compu = component_el.get("{%s}resource" % rdfxml.RDF_DEFAULT_PREFIX["rdf"])
293-
compx = self.execute_get_rdf_xml(compu, intent="Retrieve component definition to find configurations")
308+
compx = self.execute_get_rdf_xml(compu, intent="Retrieve component definition to find all configurations", action="Retrieve each configuration")
294309
comptitle = rdfxml.xmlrdf_get_resource_text(compx, './/dcterms:title')
295310

296311
self._components[compu] = {'name': comptitle, 'configurations': {}}
@@ -676,7 +691,7 @@ def get_default_stream_name( self ):
676691
class _RMComponent(_RMProject):
677692
def __init__(self, name, project_uri, app, is_optin=False, singlemode=False,defaultinit=True, project=None):
678693
if not project:
679-
raise Exception( "You mist provide a project instance when creating a component" )
694+
raise Exception( "You must provide a project instance when creating a component" )
680695
super().__init__(name, project_uri, app, is_optin,singlemode,defaultinit=defaultinit)
681696
self.component_project = project
682697
self.services_uri = project.services_uri # needed for reqif which wants to put the services.xml URI into created XML for new definitions
@@ -693,7 +708,7 @@ class _RMApp(_app._App, _typesystem.No_Type_System_Mixin):
693708
supports_components = True
694709
supports_reportable_rest = True
695710
reportablerestbase='publish'
696-
reportable_rest_status = "Supported by applicaiton and implemented here"
711+
reportable_rest_status = "Supported by application and implemented here"
697712
artifact_formats = [ # For RR
698713
'collections'
699714
,'comments'
@@ -717,7 +732,7 @@ class _RMApp(_app._App, _typesystem.No_Type_System_Mixin):
717732

718733
def __init__(self, server, contextroot, jts=None):
719734
super().__init__(server, contextroot, jts=jts)
720-
self.rootservices_xml = self.execute_get_xml(self.reluri('rootservices'), intent="Retrieve RM application rootservices" )
735+
self.rootservices_xml = self.execute_get_xml(self.reluri('rootservices'), intent="Retrieve RM application rootservices", action="Locate project areas URL using tag jp06:projectAreas" )
721736
self.serviceproviders = 'oslc_rm_10:rmServiceProviders'
722737
self.version = rdfxml.xmlrdf_get_resource_text(self.rootservices_xml,'.//oslc_rm_10:version')
723738
self.majorversion = rdfxml.xmlrdf_get_resource_text(self.rootservices_xml,'.//oslc_rm_10:majorVersion')

elmclient/examples/REQIF_IO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ To erase obfuscated credentials use option -2 then the credentials filename:
277277
reqif_io -2 .mycreds
278278
```
279279

280-
TO BE CLEAR: **NOTE the credentials file is only obfuscated unless you use the runtime prompt option -4, i.e. it's pretty easy to decode once you have the python source code**
280+
TO BE CLEAR: **NOTE the credentials file is only obfuscated: unless you use the runtime prompt option -4 to encrypt it, it's pretty easy to decode once you have the python source code**
281281

282282

283283
Future work

elmclient/examples/dn_simple_typesystemimport.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
# example of using the type system import API
77
# also see https://jazz.net/wiki/bin/view/Main/DNGTypeImport
88

9-
# the names for projects/configs involved are hard-coded for simplicity
9+
# the names for project/component/configs involved are hard-coded for simplicity
1010

11-
# IMPORTANT NOTE this hardcodes the url for creating a type import session.
12-
# This should really be done by discovery looking in the component's config-specific services.xml for a CreationFactory for resourceType http://www.ibm.com/xmlns/rdm/types/TypeImportSession
1311

1412
import csv
1513
import logging
@@ -101,6 +99,9 @@
10199

102100
if tgt_config_u is None or src_config_u is None:
103101
raise Exception( "Source or target config not found!" )
102+
103+
# find the CreationFactory URI for type-delivery session
104+
typeimport_u = tgt_c.get_factory_uri( resource_type="http://www.ibm.com/xmlns/rdm/types/TypeImportSession" )
104105

105106
# create the RDF body with the source and target configurations
106107
content = f"""<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:types="http://www.ibm.com/xmlns/rdm/types/">
@@ -111,7 +112,7 @@
111112
</rdf:RDF>"""
112113

113114
# initiate the delivery session - if successful will return 202 with a task tracker location
114-
response = tgt_c.execute_post_rdf_xml( reluri="type-import-sessions", data=content, cacheable=False, intent="Initiate typesystem import" )
115+
response = tgt_c.execute_post_rdf_xml( reluri=typeimport_u, data=content, cacheable=False, intent="Initiate typesystem import",action='start following task tracker' )
115116
logger.debug( f" {response.status_code=} {response=}" )
116117

117118
# get the location

elmclient/examples/log2seq.py

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,44 @@
2222

2323
import jinja2
2424

25+
#
26+
# Example of syntax (from https://bramp.github.io/js-sequence-diagrams/):
27+
#
28+
# Title: Here is a title
29+
# A->B: Normal line
30+
# B-->C: Dashed line
31+
# C->>D: Open arrow
32+
# D-->>A: Dashed open arrow
33+
# # Example of a comment.
34+
# Note left of A: Note to the\n left of A
35+
# Note right of A: Note to the\n right of A
36+
# Note over A: Note over A
37+
# Note over A,B: Note over both A and B
38+
#
39+
2540
JINJA_TEMPLATE = """
2641
<!doctype html>
2742
<html>
2843
<head>
2944
<link rel="stylesheet" type="text/css" href=""https://bramp.github.io/js-sequence-diagrams/css/sequence-diagram-min.css" media="screen" />
45+
<style>
46+
.signal text {
47+
fill: #000000;
48+
}
49+
.signal text:hover {
50+
fill: #aaaaaa
51+
}
52+
.note rect, .note path {
53+
fill: #ffff80;
54+
}
55+
.title rect, .title path{
56+
fill: #ff80ff;
57+
}
58+
.actor rect, .actor path {
59+
fill: #80ffff
60+
}
61+
62+
</style>
3063
</head>
3164
<body onload='showseq();'>
3265
<p>Sequence diagram from emlclient log {{ logfilename }} - wait a few seconds for the diagram to appear...</p>
@@ -145,27 +178,34 @@ def addheaders(events,msgheaders,headerstoshow,direction):
145178
events.append( f"Note {direction}: {text}" )
146179
return
147180

148-
# parse a message from the logfile into a reqat/response tuple
181+
# parse a message from the logfile into a request/response tuple
149182
def decodemessage(msg):
150183
request = {'intent':None,'method': None, 'url': None, 'headers':[], 'body':None}
151-
response = {'status': None,'headers':[], 'body':None}
152-
parts = re.search( r"^(?:INTENT: (.*?)\n\n)?(GET|PUT|POST|HEAD|DELETE|POST) +(\S+)\n( .*?)\n\n(?::+?=\n(.*?)\n-+?=\n)?.*?\n\nResponse: (\d+)\n( .*?)\n\n(?::+?@\n(.*?)\n-+?@\n)?",msg, flags=re.DOTALL+re.MULTILINE )
184+
response = {'status': None,'headers':[], 'body':None, 'action':None }
185+
parts = re.search( r"\n*(?:INTENT: ([^\n]*?)\n+)?(?:(?:(GET|PUT|POST|HEAD|DELETE|POST) +(\S+)\n((?: +.*?\n)+)\n*)(?::+?=\n(.*?)\n-+?=\n)?.*?\n+Response: (\d+?)\n( .*?)\n\n(?::+?@\n(.*?)\n-+?@\n+)?)?(?:ACTION: (.*?)\n)?",msg, flags=re.DOTALL )
186+
if parts.group(0) == '':
187+
burp
188+
# for l,g in enumerate(parts.groups()):
189+
# print( f"{l=} {g=}" )
153190
request['intent'] = parts.group(1)
154191
request['method'] = parts.group(2)
155192
request['url'] = parts.group(3)
156-
for hdrline in parts.group(4).split( "\n" ):
157-
hsplit = hdrline.strip().split(": ",1)
158-
hsplit.append("")
159-
hdr, value = hsplit[0],hsplit[1]
160-
request['headers'].append( (hdr,value) )
193+
if parts.group(4) is not None:
194+
for hdrline in parts.group(4).split( "\n" ):
195+
hsplit = hdrline.strip().split(": ",1)
196+
hsplit.append("")
197+
hdr, value = hsplit[0],hsplit[1]
198+
request['headers'].append( (hdr,value) )
161199
request['body'] = parts.group(5).strip() if parts.group(5) else None
162200
response['status'] = parts.group(6)
163-
for hdrline in parts.group(7).split( "\n" ):
164-
hsplit = hdrline.strip().split(": ",1)
165-
hsplit.append("")
166-
hdr, value = hsplit[0],hsplit[1]
167-
response['headers'].append( (hdr,value) )
201+
if parts.group(7) is not None:
202+
for hdrline in parts.group(7).split( "\n" ):
203+
hsplit = hdrline.strip().split(": ",1)
204+
hsplit.append("")
205+
hdr, value = hsplit[0],hsplit[1]
206+
response['headers'].append( (hdr,value) )
168207
response['body'] = parts.group(8).strip() if parts.group(8) else None
208+
response['action'] = parts.group(9)
169209
return (request,response)
170210

171211
def findheader(hdrname,requestorresponse,notfoundreturn=None):
@@ -257,44 +297,51 @@ def main():
257297

258298
for i,msg in enumerate(msgs):
259299
request,response = decodemessage(msg)
260-
# if INTENT: then add a note for it
261-
300+
# print( f"{request=}" )
301+
# print( f"{response=}" )
262302
line = i
263-
264-
reqparts = urllib.parse.urlparse(request['url'])
265303

266-
path = reqparts.path
267-
if reqparts.query:
268-
path += "?"+reqparts.query
304+
if request['method']:
269305

270-
if request['intent']:
271-
events.append( f"Note left of me: INTENT: {request['intent']}" )
306+
reqparts = urllib.parse.urlparse(request['url'])
272307

273-
events.append( f"me->{host}: {request['method']} {sanitise(path,wrap=True)}" )
274-
275-
addheaders(events,request['headers'],reqshowheaders,"left of me" )
276-
277-
if request['body']:
278-
if contentshouldbeshown(request):
279-
reqbody = sanitise(request['body'], wrap=True)
280-
else:
281-
reqbody = sanitise(request['body'], wrap=False, maxlines=5)
282-
283-
if reqbody:
284-
events.append( f"Note left of me: {reqbody}" )
308+
path = reqparts.path
309+
if reqparts.query:
310+
path += "?"+reqparts.query
311+
312+
# if INTENT: then add a note for it
313+
if request['intent']:
314+
events.append( f"Note left of me: INTENT: {request['intent']}" )
285315

286-
events.append( f"{host}-->me: {response['status']}" )
287-
288-
addheaders(events,response['headers'],respshowheaders,f"right of {host}" )
289-
290-
if response['body']:
291-
if contentshouldbeshown(response):
292-
respbody = sanitise(response['body'], wrap=False)
293-
else:
294-
respbody = sanitise(response['body'], wrap=False, maxlines=5)
295-
# respbody = "Content type not shown..."
296-
297-
events.append( f"Note right of {host}: {respbody}" )
316+
events.append( f"me->{host}: {request['method']} {sanitise(path,wrap=True)}" )
317+
318+
addheaders(events,request['headers'],reqshowheaders,"left of me" )
319+
320+
if request['body']:
321+
if contentshouldbeshown(request):
322+
reqbody = sanitise(request['body'], wrap=True)
323+
else:
324+
reqbody = sanitise(request['body'], wrap=False, maxlines=5)
325+
326+
if reqbody:
327+
events.append( f"Note left of me: {reqbody}" )
328+
329+
events.append( f"{host}-->me: {response['status']}" )
330+
331+
addheaders(events,response['headers'],respshowheaders,f"right of {host}" )
332+
333+
if response['body']:
334+
if contentshouldbeshown(response):
335+
respbody = sanitise(response['body'], wrap=False)
336+
else:
337+
respbody = sanitise(response['body'], wrap=False, maxlines=5)
338+
# respbody = "Content type not shown..."
339+
340+
events.append( f"Note right of {host}: {respbody}" )
341+
342+
# if ACTION: then add a note for it
343+
if response['action']:
344+
events.append( f"Note over me: {response['action']}" )
298345

299346
j2_template = jinja2.Template(JINJA_TEMPLATE)
300347
data = {

0 commit comments

Comments
 (0)