Events
The Helix IPLM Events platform publishes the events that occur in the platform. These events can be subscribed to, and are processed by a dedicated event consumer. These event consumers can format, aggregate, and distribute the published events to support a variety of automation applications.
Events overview
Helix IPLM event and messaging system is a flexible way of generating real-time notifications about events related to Helix IPLM objects. In addition, the event system is designed to be easily integrated with third-party tools that can consume real-time information from Helix IPLM. The event system has been designed using the industry-standard Redis Pub/Sub mechanism. A fully functional Redis instance is included in the Helix IPLM package.
Event format
Each event emitted by Helix IPLM event system follows a pre-defined format, and includes a set of available data fields.
Common fields included for all events
Field | Description |
---|---|
Event ID | A unique message identifier |
Event Type | Type of event. Short and human readable |
Timestamp | Synced and high res |
Duration ms | Time to execute the associated operation |
Client IP Address | IP of customer system |
Component | Name of application that initiated a request. "CLI", "LICENSING", "PUBLIC", "SECURITY", "WEB" |
User id, Username | Identifier for user executing the operation (Null for anonymous user) |
Object id,Object name | ID of object associated with request. Only applicable for individual object events. Not applicable for “list” events for example. |
Status code, Errors |
Result of operation, excluding payload |
In addition to this list, some specific event types include contextual fields.
Available event types
The following is the list of available channels and event types.
Channel | Event type | Contextual fields |
---|---|---|
Alias events | ||
alias:pi_edit_alias:<aliasUUID> | pi_edit_alias | N/A |
alias:pi_list_alias:<aliasUUID> | pi_list_alias | N/A |
alias:pi_list_aliases: | pi_list_aliases | N/A |
alias:pi_lock_alias:<aliasUUID> | pi_lock_alias | N/A |
alias:pi_unlock_alias:<aliasUUID> | pi_unlock_alias | N/A |
Group events | ||
group:pi_add_group:<groupUUID> | pi_add_group | N/A |
group:pi_attach_group_to_group:<groupUUID> | pi_attach_group_to_group | childGroupID, childGroupName |
group:pi_attach_user_to_group:<groupUUID> | pi_attach_user_to_group | childUserID, childUserName |
group:pi_detach_group_from_group:<groupUUID> | pi_detach_group_from_group | childGroupID, childGroupName |
group:pi_detach_user_from_group:<groupUUID> | pi_detach_user_from_group | childUserID, childUserName |
group:pi_disable_group:<groupUUID> | pi_disable_group | N/A |
group:pi_edit_group:<groupUUID> | pi_edit_group | N/A |
group:pi_enable_group:<groupUUID> | pi_enable_group | N/A |
group:pi_grant_license_features_to_group:<groupUUID> | pi_grant_license_features_to_group | features |
group:pi_list_group:<groupUUID> | pi_list_group | N/A |
group:pi_list_groups: | pi_list_groups | N/A |
group:pi_obliterate_group:<groupUUID> | pi_obliterate_group | N/A |
IP events | ||
ip:pi_add_line:<ipUUID> | pi_add_line | sourceIPV, line ID, line Name |
ip:pi_attach_label_to_ip:<ipUUID> | pi_attach_label_to_ip | label ID, label Name |
ip:pi_attach_property_set_to_ip:<ipUUID> | pi_attach_property_set_to_ip | propertySet ID, propertySet Name |
ip:pi_delete_ip_attribute:<ipUUID> | pi_delete_ip_attribute | attributeID, attributeName |
ip.delete_line | pi_delete_line | line ID, line Name |
ip:pi_detach_label_from_ip:<ipUUID> | pi_detach_label_from_ip | label ID, label Name |
ip:pi_detach_property_set_from_ip:<ipUUID> | pi_detach_property_set_from_ip | propertySet ID, propertySet Name |
ip:pi_edit_ip:<ipUUID> | pi_edit_ip | N/A |
ip:pi_get_ip_attribute:<ipUUID> | pi_get_ip_attribute | attributeID, attributeName |
ip:pi_list_ip_perms:<ipUUID> | pi_list_ip_perms | N/A |
ip:pi_list_ip:<ipUUID> | pi_list_ip | N/A |
ip:pi_list_ips_perms: | pi_list_ips_perms | N/A |
ip:pi_list_ips: | pi_list_ips | N/A |
ip:pi_set_ip_attribute:<ipUUID> | pi_set_ip_attribute | attributeID, attributeName |
ip:pi_set_ip_perms:<ipUUID> | pi_set_ip_perms | N/A |
ip:pi_set_ip_property:<ipUUID> | pi_set_ip_property | propertyID, propertyName |
IPV events | ||
ipv:pi_add_alias_to_ipv:<ipvUUID> | pi_add_alias_to_ipv | alias ID, aliasName |
ipv:pi_delete_alias_from_ipv:<ipvUUID> | pi_delete_alias_from_ipv | alias ID, aliasName |
ipv:pi_set_ipv_attribute:<ipvUUID> | pi_set_ipv_attribute | attributeID, attributeName |
ipv:pi_set_ipv_property:<ipvUUID> | pi_set_ipv_property | propertyID, propertyName |
Label events | ||
label:pi_add_label:<labelUUID> | pi_add_label | N/A |
label:pi_delete_label:<labelUUID> | pi_delete_label | safe_mode (boolean) |
label:pi_edit_label:<labelUUID> | pi_edit_label | N/A |
label:pi_list_label:<labelUUID> | pi_list_label | N/A |
label:pi_list_labels: | pi_list_labels | N/A |
Library events | ||
library:pi_add_ip:<libraryUUID> | pi_add_ip | sourceIPV, ip ID, ip Name |
library:pi_add_library:<libraryUUID> | pi_add_library | N/A |
library:pi_attach_label_to_library:<libraryUUID> | pi_attach_label_to_library | label ID, label Name |
library:pi_attach_property_set_to_library:<libraryUUID> | pi_attach_property_set_to_library | propertySet ID, propertySet Name |
library:pi_delete_ip | pi_delete_ip | ipName |
library:pi_delete_library_attribute | pi_delete_library_attribute | attributeID, attributeName |
library:pi_delete_library | pi_delete_library | LibraryName |
library:pi_detach_label_from_library:<libraryUUID> | pi_detach_label_from_library | label ID, label Name |
library:pi_detach_property_set_from_library:<libraryUUID> | pi_detach_property_set_from_library | propertySet ID, propertySet Name |
library:pi_edit_library:<libraryUUID> | pi_edit_library | N/A |
library:pi_get_library_attribute:<libraryUUID> | pi_get_library_attribute | attributeID, attributeName |
library:pi_list_libraries_perms: | pi_list_libraries_perms | N/A |
library:pi_list_libraries: | pi_list_libraries | N/A |
library:pi_list_library_perms:<libraryUUID> | pi_list_library_perms | N/A |
library:pi_list_library:<libraryUUID> | pi_list_library | N/A |
library:pi_obliterate_ip: | pi_obliterate_ip | IpID,IPName |
library:pi_set_library_attribute:<libraryUUID> | pi_set_library_attribute | attributeID, attributeName |
library:pi_set_library_perms:<libraryUUID> | pi_set_library_perms | N/A |
Licensing events | ||
licensing:pi_acquire_license: | pi_acquire_license | N/A |
licensing:pi_attach_license: | pi_attach_license | license type |
licensing:pi_detach_license: | pi_detach_license | license type |
licensing:pi_load_license: | pi_load_license | license file ID |
licensing:pi_usage_license: | pi_usage_license | N/A |
Line events | ||
line:pi_add_ipv:<lineUUID> | pi_add_ipv | ipv ID, ipv Name |
line:pi_delete_line_attribute:<lineUUID> | pi_delete_line_attribute | attributeID, attributeName |
line:pi_edit_line:<lineUUID> | pi_edit_line | N/A |
line:pi_get_line_attribute:<lineUUID> | pi_get_line_attribute | attributeID, attributeName |
line:pi_list_line_perms:<lineUUID> | pi_list_line_perms | N/A |
line:pi_list_line:<lineUUID> | pi_list_line | N/A |
line:pi_list_lines_perms: | pi_list_lines_perms | N/A |
line:pi_list_lines: | pi_list_lines | N/A |
line:pi_release_ip:<lineUUID> | pi_release_ip | workspaceID, workspacePath, ipv ID, ipv Name |
line:pi_remove_files_from_line:<lineUUID> | pi_remove_files_from_line | dry_run (boolean) |
line:pi_set_line_attribute:<lineUUID> | pi_set_line_attribute | attributeID, attributeName |
line:pi_set_line_perms:<lineUUID> | pi_set_line_perms | N/A |
Property events | ||
property_definition:pi_add_property_definition:<property_definitionUUID> | pi_add_property_definition | N/A |
property_definition:pi_delete_property_definition:<property_definitionUUID> | pi_delete_property_definition | safe_mode(boolean) |
property_definition:pi_edit_property_definition:<property_definitionUUID> | pi_edit_property_definition | N/A |
property_definition:pi_list_property_definition:<property_definitionUUID> | pi_list_property_definition | N/A |
property_definition:pi_list_property_definitions: | pi_list_property_definitions | N/A |
property_set:pi_add_property_set:<property_setUUID> | pi_add_property_set | N/A |
property_set:pi_attach_property_definition_to_property_set:<property_setUUID> | pi_attach_property_definition_to_property_set | property ID, property Name |
property_set:pi_delete_property_set:<property_setUUID> | pi_delete_property_set | N/A |
property_set:pi_detach_property_definition_from_property_set:<property_setUUID> | pi_detach_property_definition_from_property_set | property ID, property Name |
property_set:pi_edit_property_set:<property_setUUID> | pi_edit_property_set | N/A |
property_set:pi_list_property_set:<property_setUUID> | pi_list_property_set | N/A |
property_set:pi_list_property_sets: | pi_list_property_sets | N/A |
Query events | ||
query:pi_set_query_attribute:<queryUUID> | pi_set_query_attribute | attributeID, attributeName |
System events | ||
system:pi_ext_sync_groups_and_users: | pi_ext_sync_groups_and_users | N/A |
system:pi_login: | pi_login | N/A |
system:pi_logout: | pi_logout | N/A |
Undefined events | ||
undefined:pi_delete_undefined_attribute: | pi_delete_undefined_attribute | N/A |
undefined:pi_get_undefined_attribute: | pi_get_undefined_attribute | N/A |
undefined:pi_set_undefined_attribute: | pi_set_undefined_attribute | N/A |
User events | ||
user:pi_add_user:<userUUID> | pi_add_user | N/A |
user:pi_chpwd_user:<userUUID> | pi_chpwd_user | N/A |
user:pi_delete_user:<userUUID> | pi_delete_user | N/A |
user:pi_disable_user:<userUUID> | pi_disable_user | N/A |
user:pi_edit_user:<userUUID> | pi_edit_user | N/A |
user:pi_enable_user:<userUUID> | pi_enable_user | N/A |
user:pi_grant_license_features_to_user:<userUUID> | pi_grant_license_features_to_user | features |
user:pi_list_user:<userUUID> | pi_list_user | N/A |
user:pi_list_users:<userUUID> | pi_list_users | N/A |
Workspace events | ||
workspace:pi_load_ip:<workspaceUUID> | pi_load_ip | ipv ID, ipv Name |
Custom-defined object events
Channel | EventType | Contextual Fields |
---|---|---|
custom_object_type:pi_add_custom_object:<custom_object_type_UUID> | pi_add_custom_object | customObjectId, customObjectName, sourceCustomObjectVersionName, sourceCustomObjectVersionId |
custom_object_type:pi_add_custom_object_type:<custom_object_type_UUID> | pi_add_custom_object_type |
|
custom_object_type:pi_delete_custom_object_type:<custom_object_type_UUID> | pi_delete_custom_object_type |
|
custom_object_type:pi_delete_custom_object:<custom_object_type_UUID> | pi_delete_custom_object | customObjectId, customObjectName |
custom_object_type:pi_set_custom_object_type_perms:<custom_object_type_UUID> | pi_set_custom_object_type_perms |
|
custom_object_type:pi_edit_custom_object_type:<custom_object_type_UUID> | pi_edit_custom_object_type |
|
custom_object_type:pi_list_custom_object_types: | pi_list_custom_object_types |
|
custom_object_type:pi_list_custom_object_type:<custom_object_type_UUID> | pi_list_custom_object_type |
|
custom_object_type:pi_list_custom_object_type_perms:<custom_object_type_UUID> | pi_list_custom_object_type_perms |
|
custom_object:pi_add_custom_object_version:<custom_object_UUID> | pi_add_custom_object_version | customObjectVersionId, customObjectVersionName |
custom_object:pi_attach_property_set_to_custom_object:<custom_object_UUID> | pi_attach_property_set_to_custom_object | propertySetId, propertySetName |
custom_object:pi_delete_custom_object_version:<custom_object_UUID> | pi_delete_custom_object_version | customObjectVersionId, customObjectVersionName |
custom_object:pi_detach_property_set_from_custom_object:<custom_object_UUID> | pi_detach_property_set_from_custom_object | propertySetId, propertySetName |
custom_object:pi_set_custom_object_perms:<custom_object_UUID> | pi_set_custom_object_perms |
|
custom_object:pi_edit_custom_object:<custom_object_UUID> | pi_edit_custom_object |
|
custom_object:pi_list_custom_objects: | pi_list_custom_objects |
|
custom_object:pi_list_custom_object:<custom_object_UUID> | pi_list_custom_object |
|
custom_object:pi_list_custom_object_perms:<custom_object_UUID> | pi_list_custom_object_perms |
|
custom_object:pi_set_custom_object_property:<custom_object_UUID> | pi_set_custom_object_property | propertyId, propertyName |
custom_object_version:pi_set_custom_object_version_property:<custom_object_UUID> | pi_set_custom_object_version_property | propertyId, propertyName |
custom_object_version:pi_list_custom_object_version:<custom_object_version_UUID> | pi_list_custom_object_version |
|
custom_object_version:pi_list_custom_object_versions: | pi_list_custom_object_versions |
Note: In cases when multiple objects are updated as part of a single transaction, a failed transaction produces a single event. A successful transaction produces a multiple events, one per affected object.
A failed attempt to:
- create an IPLV (POST iplvs, POST iplvs/<id>/copy-to-new-ip) , will fire a pi_add_ip event.
- edit an IPLV (PUT iplvs/<id>), will fire a pi_edit_ipv event (to be added in the next phase of events implementation).
{ "event_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "event_type": "string", "timestamp": 1536341270801, "duration_ms": 20, "client_ip_address": "xxx.xxx.xxx.xxx", "component": "CLI", "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "user_name": "bob", "object_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "object_name": "drinks.vodka@1.TRUNK", "status_code": 400, "errors": [ { "message": "NoPermissionError" }, { "message": "ValidationIllegalFieldError" } ] }
Subscriptions and email notification
Helix IPLM's Subscription and email notification service permits users to manage event subscriptions and receive event notifications by email. The Email Notification service connects to your preferred SMTP server to send the notifications. The email service is not enabled by default. The example Email Notification service is provided by the piextras package using the events_handler
email plugin.
Manage event subscriptions
Event subscriptions are managed using 'pi subscription edit' commands:
'pi subscription edit' command opens a subscriptions template. The template contains subscription configurations, one per line.
pi subscription edit [-h] [--user user] [--group group] [--template TEMPLATE]
- User and Group are optional parameters. Default (no parameters) subscribes only for currently logged in user.
- System Administrator can modify subscription for other users and groups.
- Individual (non-administrative) users can only modify their own subscriptions.
[Libraries] drinks = pi_add_ip # Get a notification when a new IP is added to library drinks [IPs] * = all # Get a notification for all events on all IPs drinks. = all #All IPs in drinks library. Should follow 'pi ip list' patterns.
[Lines]
# add multiple wildcard targets
* = pi_adv_ipv
pi_edit_line
pi_release_ip
pi_remove_files_from_line
Users can subscribe to any object or topic, regardless of permission. For objects that user does not have at least ‘read’ permission, the user will not receive any notifications for that object.
Subscription Rule Examples
Event Type | Examples |
---|---|
Alias | drinks.* = pi_edit_alias (All aliases in "drinks" library) drinks.vodka@*.martini = pi_lock_alias (All aliases on Line "martini") |
Group | group1 = pi_disable_group |
IP | drinks.vodka = pi_add_line ("vodka" IP) |
IPV | drinks.vodka@1.* (IP versions 1 on all Lines in "drinks.vodka") drinks.vodka@* (All IPVs in "drinks.vodka") |
Label | label_name* = pi_delete_label |
Library | drinks = pi_add_ip (all IPs in "drinks" library) |
Licensing | * = pi_acquire_license |
Line | drinks.* = pi_edit_line (All Lines in "drinks" library) drinks.vodka@.* = pi_add_ipv (All Lines in "vodka" IP) drinks.@.martini = pi_release_ip (Lines named "martini" in Library "drinks") .@*.martini = pi_release_ip (All Lines named "martini" ) |
Property_definition | my_property_def = pi_add_property_definition |
Property_set | my_property_set = pi_add_property_set |
Query | my_query = pi_set_query_attribute |
System | * = pi_login |
Undefined | * = all |
User | my_username = pi_enable_user |
Workspace | my_workspace = pi_load_ip |
List subscriptions
pi subscription ls
lists user's current subscriptions, including group subscriptions. Output generates two sets of subscriptions under "Individual" and "Group" headers. If a user is subscribed via sub-group, the subscribed group name is displayed.
pi subscription list, ls [-h] [--user user] [--group group]
SUBSCRIPTION | OBJECT CATEGORY | SUBSCRIBED BY | GROUP NAME * = pi_add_library| Library | Individual | - * = pi_add_library| Library | Group | Group1 * = all | IP | Individual | - drinks. = all | Library | Group | Group2
Email notifications
To receive email notifications, configure an event consumer as shown below in Developing a custom event consumer.
Subscriptions API
A subscription API is available for retrieving a list of users for a given event type. For usage and additional details, refer to Public API documentation included with Helix IPLM installation.
Developing a custom event consumer
The piextras package includes a sample Event Consumer, events_handler
.
The events_handler
is a framework for Redis event consumer plugins and is provided by the piextras package. The piextras package contains example code that you can use out-of-the-box or as a guide for custom development.
The event_handler
provides two example plugins with source code located in .../piextras/event_handler/plugins
:
-
json_plugin.py
- example to write the event payload to a JSON file -
email_plugin.py
- example email generation based on user subscriptions
The events_handler
plugin framework passes user subscriptions to the plugin.
For more information, refer to the README files in the events_handler
and plugins
folders in piextras
package.
Configuration options
System Administrators have global control over the Events system, using 'pi-admin' tool.
pi-admin settings edit
[SYSTEM] # Helix IPLM events. Possible choices: # none Disable events (default) # all Enable all Helix IPLM events # write_only Enables events that result in a Write operation # and disables all other events EVENTS.enable = all
Running the commands above, will trigger the event:
piadmin_configure_events
Current limitations
- The status code of the events
pi_attach_license_event
andpi_detach_license_event
will reflect the status code of the main operation if the main operation fails. - Attaching and detaching licenses are triggered by operations that require licenses (main operation). If the main operation fails, the status code for the pi_attach_license_event and pi_detach_license_event will also report failure even though the license was successfully attached/detached.
- Undefined Attribute Events are fired when the server does not have enough information to distinguish which object the attribute is attached to. Undefined Attribute Events belong to Undefined Event Context.
- Since events are generated by the server, client-side validations which short-circuits execution do not trigger events. Therefore, attempts to edit IP/Line/IPV from CLI which fail due to validation errors do not trigger edit events.
Helix IPLM server configuration
Some additional PiServer configuration is required to use events. More details on configuring events are at Events Administration.