Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion docs/Inspector.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Commands:
list-classes List known classes and objects for each class
show-object-tree Show relationship tree
show-objects-of-class Show properties of objects belonging to a class
show-resources Show the status of a resource and its contained ones
show-sessions Show sessions information
show-smartapp-mods Shows the modules generated by a smart application
verify-detstreams Verify detector streams in the database
Expand Down Expand Up @@ -75,6 +76,9 @@ Options:
-l, --level INTEGER Recursion level in the object tree
-f, --focus TEXT Path within the object relationships to
focus on
-s, --session TEXT Session containing object to display
+e, --show-enabled / -e, --hide-enabled
Show enabled state of resources
-h, --help Show this message and exit.
```

Expand Down Expand Up @@ -105,6 +109,40 @@ Options:
|`daqconf_inspector ./ehn1-daqconfigs/sessions/np02-session.data.xml show-objects-of-class Segment`|
|![list-classes example](./img/inspector_show-objects-of-class.png)|



### `show-resources`

Show Resource tree starting from the specified Resource

First display s the state of the `Resource` itself and if it is a
`ResourceSet` it follows down the tree of `contained_reources` down to
the level specified (default is to go all the way).

```
Usage: daqconf_inspector CONFIG_FILE show-resources [OPTIONS] SESSION_ID
RESOURCE_ID

Options:
-l, --level INTEGER Recursion level in the object tree
-h, --help Show this message and exit.
```

**Legend**

| Icon | Meaning|
|---|---|
| ✅ | Resource enabled |
| ❎ | Resource set enabled but contains some disabled Resources |
| ❌ | Resource directly disabled (included in the Session disable list) |
| ⭕️ | Resource indirectly disabled by algorithm |

|**Example**|
|---|
|`daqconf_inspector /ehn1-daqconfigs/sessions/hd-coldbox-session.data.xml show-resources hd-coldbox-session hd-coldbox-segment`|
|![show-resources example](./img/inspector_show-resources.png)|


### `show-session`

Show details of each session available in the configuration database
Expand All @@ -117,13 +155,14 @@ For each session found in the the database, `show-session` displays:
The icon in front of segments and appliations indicate the enable/disable.

Optionally, it displays the path of the the database file where the object
is define
is defined

**Legend**

| Icon | Meaning|
|---|---|
| ✅ | Resource enabled |
| ❎ | Resource set enabled but contains some disabled Resources |
| ❌ | Resource directly disabled (included in the Session disable list) |
| ⭕️ | Resource indirectly disabled by algorithm |
| 🔵 | Not a resource |
Expand All @@ -139,6 +178,7 @@ Usage: daqconf_inspector CONFIG_FILE show-sessions [OPTIONS]

Options:
-p, --show-file_paths
-l, --list
-h, --help Show this message and exit.
```

Expand All @@ -164,10 +204,24 @@ Note: specifiying the object name is required .
| Icon | Meaning|
|---|---|
| ✅ | Resource enabled |
| ❎ | Resource set enabled but contains some disabled Resources |
| ❌ | Resource directly disabled (included in the Session disable list) |
| ⭕️ | Resource indirectly disabled by algorithm |
| 🔵 | Not a resource |

```
Usage: daqconf_inspector CONFIG_FILE show-smartapp-mods [OPTIONS] SESSION_ID
APP_ID

Options:
+a, --show-attributes / -a, --hide-attributes
Show/Hide attributes
-l, --level INTEGER Recursion level in the object tree
-f, --focus TEXT Path within the object relationships to
focus on
-h, --help Show this message and exit.
```

|**Example**|
|---|
|`daqconf_inspector ehn1-daqconfigs/sessions/np02-session.data.xml show-smartapp-mods np02-session crp4-wiec -f hermes-ctrl-crp4-wiec-np02-wib-1006 -l 2`|
Expand All @@ -180,6 +234,16 @@ Shows the DetectorToDAQ connections in the database

The receiver id and summary sender informations for each connection are shown in a compact table.

```
Usage: daqconf_inspector CONFIG_FILE show-d2d-connections [OPTIONS]
[CONNECTION_NAME]

Options:
-l, --list
-s, --only-summary
-h, --help Show this message and exit.
```

|**Example**|
|---|
|`daqconf_inspector ehn1-daqconfigs/sessions/np02-session.data.xml show-d2d-connections`|
Expand Down
Binary file added docs/img/inspector_show-resources.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
128 changes: 88 additions & 40 deletions scripts/daqconf_inspector
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def enabled_to_emoji(enabled: Union[int, None]) -> str:
match enabled:
case 1:
return ':white_check_mark:'
case 2:
return ':negative_squared_cross_mark:'
case 0:
return ':heavy_large_circle:'
case -1:
Expand Down Expand Up @@ -87,6 +89,12 @@ class DalRichRenderer:

enabled = not confmodel_dal.component_disabled(self._confdb._obj, session.id, obj.id)
if enabled:
resources = confmodel_dal.resourceset_contains(self._confdb._obj, obj.id)
for res in resources:
rdal = self._confdb.get_dal(class_name="Resource", uid=res)
if self.is_enabled(session, rdal) != 1:
enabled = 2
break
return enabled

enabled -= (obj in session.disabled)
Expand Down Expand Up @@ -135,7 +143,7 @@ class DalRichRenderer:
def make_obj_tree(self, dal_obj, show_attrs=True, path=[], level=None, session=None):
"""Helper function to generate object trees"""

en_status = enabled_to_emoji(self.is_enabled(session, dal_obj))+' ' if not session is None else ""
en_status = enabled_to_emoji(self.is_enabled(session, dal_obj))+' ' if session else ""

tree = Tree(f"{en_status}[green]{dal_obj.id}[/green][magenta]@{dal_obj.className()}[/magenta]")
if level == 0:
Expand All @@ -156,7 +164,7 @@ class DalRichRenderer:
if path:
rel_sel, obj_sel = path[0]
if rel_sel not in rels:
raise click.BadArgumentUsage(f"Object '{rel_sel}' does not exist in {dal_obj.id}")
raise click.BadArgumentUsage(f"Relationship '{rel_sel}' does not exist in {dal_obj.id}")

if show_attrs:
for a in attrs:
Expand Down Expand Up @@ -185,6 +193,26 @@ class DalRichRenderer:
continue
r_tree.add(self.make_obj_tree(val, show_attrs, path[1:], level, session))
return tree



def make_resource_tree(self, dal_obj, level=None, session=None):
"""Helper function to generate object trees"""
import confmodel_dal

en_status = enabled_to_emoji(self.is_enabled(session, dal_obj))+' ' if not session is None else ""

tree = Tree(f"{en_status}[green]{dal_obj.id}[/green][magenta]@{dal_obj.className()}[/magenta]")
if level == 0:
return tree

if level is not None:
level -= 1
resources = confmodel_dal.resourceset_contains(self._confdb._obj, dal_obj.id)
for res in resources:
rdal = self._confdb.get_dal(class_name="Resource", uid=res)
tree.add(self.make_resource_tree(rdal, level, session))
return tree



Expand Down Expand Up @@ -239,14 +267,15 @@ def show_sessions(obj, show_file_paths, list_sessions, session_name):
- The high-level session view, including segments, controllers and applications as
hierarchical tree.
ID and Class are shown for applications and controllers, along with their host and services (open ports)
The icon in front of segments and appliations indicate the enable/disable.
The icon in front of segments and applications indicate the enable/disable.

Optionally, it displays the path of the the database file where the object is define
Optionally, it displays the path of the the database file where the object is defined

\b
Legend
------
✅ : Resource enabled
❎ : Resource set enabled but contains some disabled Resources
❌ : Resource directly disabled (listed in the Session disable list)
⭕️ : Resource indirectly disabled by algorithm
🔵 : Not a resource
Expand Down Expand Up @@ -492,21 +521,23 @@ def show_objects_of_class(obj, klass, vtable):
@click.option('+a/-a','--show-attributes/--hide-attributes', "show_attrs", default=True, help="Show/Hide attributes")
@click.option('-l','--level', "level", type=int, default=None, help="Recursion level in the object tree")
@click.option('-f','--focus', "focus_path", default=None, help="Path within the object relationships to focus on")
@click.option('-s','--session', "session_name", default=None, help="Session containing object to display")
@click.option('+e/-e','--show-enabled/--hide-enabled', "show_enabled", default=False, help="Show enabled state of resources")
@click.pass_obj
def show_object_tree(obj, uid, show_attrs, focus_path, level):
def show_object_tree(obj, uid, show_attrs, focus_path, level, session_name, show_enabled):
"""
Show the relationship tree of the OKS object with identifier UID.

UID is the unique object identifier in the database, composed by object name and class name.
The UID format argument is <object name>@<class>.

Starting from the selected object, attributes and objects refererd by relationships are shown recursively as hierarchical tree.
Starting from the selected object, attributes and objects referred by relationships are shown recursively as hierarchical tree.
By default the command recursively crawls through relationship without limits. The recursion level can be limited with the corresponding optional parameter (see below).
In case focussing on a relationship branch is helpful, the focus path option (see below for details) allows to specify the branch to focus on, starting trom the top object.
In case focussing on a relationship branch is helpful, the focus path option (see below for details) allows to specify the branch to focus on, starting from the top object.
If a focus path is specified, the recursion level is applied starting from the last element of the focus path.
The focus path syntax combines relationhsip and object names, using `.` separators, and `[]` to select a single item in multi-value relatiosnips.
The focus path syntax combines relationship and object names, using `.` separators, and `[]` to select a single item in multi-value relationships.
The structure of the focus path specifier is `<relationship>[<optional object name>].<relationship>[<optional object name>]`.
Note: specifiying the object name is required
Note: specifying the object name is required

\b
`show-object-tree` subcommand example:
Expand All @@ -523,7 +554,7 @@ def show_object_tree(obj, uid, show_attrs, focus_path, level):


if klass not in cfg.classes():
print(f'[red]Class {klass} unknow to configuration[/red]')
print(f'[red]Class {klass} unknown to configuration[/red]')
print(f'Known classes: {sorted(cfg.classes())}')
raise SystemExit(-1)

Expand All @@ -534,7 +565,7 @@ def show_object_tree(obj, uid, show_attrs, focus_path, level):
for p in focus_path:
m = re_index.match(p)
if m is None:
raise RuntimeError("Incorrect systax of path specifier p")
raise RuntimeError("Incorrect syntax of path specifier p")
rel,_,name = m.groups()
path.append((rel, name))

Expand All @@ -543,7 +574,26 @@ def show_object_tree(obj, uid, show_attrs, focus_path, level):
except RuntimeError as e:
raise click.BadArgumentUsage(f"Object '{id}' does not exist")

tree = drr.make_obj_tree(do, show_attrs, path, level)
session = False
if show_enabled:
if session_name:
session = cfg.get_dal("Session", session_name)
if not session:
raise click.BadArgumentUsage(f"Session '{session_name}' does not exist")
elif do.isDalType('Resource'):
import confmodel_dal
session_list = cfg.get_dals("Session")
for sess in session_list:
parents = confmodel_dal.component_get_parents(cfg._obj, sess.id, id)
if parents:
if session is None:
session = sess
else:
# object in more than one Session
print(f"[red]{id}@{klass} is used in more than one session, cannot determine enabled status[/red]")
raise SystemExit(-1)

tree = drr.make_obj_tree(do, show_attrs, path, level, session)
print(tree)


Expand Down Expand Up @@ -660,8 +710,8 @@ def verify_detstreams(obj):
"""
Performs basic validation of detector datastreams in a database.

It checks the collection of all detastreans in the database for uiniqueness.
It also checks that all geo_ids references by detecor streams are unique.
It checks the collection of all datastreams in the database for uniqueness.
It also checks that all geo_ids references by detector streams are unique.
"""
from rich.highlighter import ReprHighlighter
rh = ReprHighlighter()
Expand Down Expand Up @@ -738,7 +788,7 @@ def verify_smart_apps(obj):
Implemented tests:
- `services`: The exposed service consistency between application interface and network rules is checked.
the services referenced in network rules are compared with the list in the `exposes_service` attribute.
The tedt fails if any of the network rules services is not present in `exposes_service`.
The test fails if any of the network rules services is not present in `exposes_service`.
"""

from dataclasses import dataclass
Expand Down Expand Up @@ -807,18 +857,19 @@ def verify_smart_apps(obj):
def show_smartapp_mods(obj, session_id, app_id, show_attrs, level, focus_path):
"""
For the selected smart application and session, execute the generate modules method and displays the results in a hierarchical tree.
Resource objexts are displaied with their status.
Resource objects are displayed with their status.

In case focussing on a relationship branch is helpful, the focus path option (see below for details) allows to specify the branch to focus on, starting trom the top object.
In case focussing on a relationship branch is helpful, the focus path option (see below for details) allows to specify the branch to focus on, starting from the top object.
If a focus path is specified, the recursion level is applied starting from the last element of the focus path.
The focus path syntax combines relationhsip and object names, using `.` separators, and `[]` to select a single item in multi-value relatiosnips.
The structure of the focus path specifier is `<relationship>[<optional object name>].<relationship>[<optional object name>]`.
Note: specifiying the object name is required .
The focus path syntax combines relationship and object names, using `.` separators, and `[]` to select a single item in multi-value relationships.
The structure of the focus path specifier is `<module name>.<relationship>[<optional object name>]`.
Note: specifying the module name is required .

\b
Legend
------
✅ : Resource enabled
❎ : Resource set enabled but contains some disabled Resources
❌ : Resource directly disabled (listed in the Session disable list)
⭕️ : Resource indirectly disabled by algorithm
🔵 : Not a resource
Expand Down Expand Up @@ -879,34 +930,31 @@ def show_smartapp_mods(obj, session_id, app_id, show_attrs, level, focus_path):
@cli.command(short_help="Show the status of a resource and its contained ones")
@click.argument('session_id')
@click.argument('resource_id')
@click.option('+a/-a','--show-attributes/--hide-attributes', "show_attrs", default=True, help="Show/Hide attributes")
@click.option('-l','--level', "level", type=int, default=None, help="Recursion level in the object tree")
@click.option('-f','--focus', "focus_path", default=None, help="Path within the object relationships to focus on")
@click.pass_obj
def show_resources(obj, session_id, resource_id, show_attrs, level, focus_path):
import re
def show_resources(obj, session_id, resource_id, level):
"""
Show Resource tree starting from the specified Resource

\b
Legend
------
✅ : Resource enabled
❎ : Resource set enabled but contains some disabled Resources
❌ : Resource directly disabled (listed in the Session disable list)
⭕️ : Resource indirectly disabled by algorithm

"""

from rich.highlighter import ReprHighlighter
rh = ReprHighlighter()
cfg = obj.cfg
drr = DalRichRenderer(cfg)

focus_path = focus_path.split('.') if focus_path is not None else []
re_index = re.compile('([\w-]*)(\[([\w-]*)\])?')
path = []
for p in focus_path:
m = re_index.match(p)
if m is None:
raise RuntimeError("Incorrect systax of path specifier p")
rel,_,name = m.groups()
path.append((rel, name))

s = cfg.get_dal('Session', session_id)
session = cfg.get_dal('Session', session_id)

r = cfg.get_dal('Resource', resource_id)
resource = cfg.get_dal('Resource', resource_id)

t = drr.make_obj_tree(r, show_attrs, path, level, s)
print(t)
tree = drr.make_resource_tree(resource, level, session)
print(tree)


if __name__== "__main__":
Expand Down