diff --git a/core/schema/src/main/liquibase/35.0.0/changelog.xml b/core/schema/src/main/liquibase/35.0.0/changelog.xml new file mode 100644 index 000000000000..2f9f5983a73e --- /dev/null +++ b/core/schema/src/main/liquibase/35.0.0/changelog.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT COUNT(*) FROM eventconf_sources + + + + + + + + SELECT COUNT(*) FROM eventconf_events + + + + + + \ No newline at end of file diff --git a/core/schema/src/main/liquibase/changelog.xml b/core/schema/src/main/liquibase/changelog.xml index 1415f27ce35a..dc5faa409220 100644 --- a/core/schema/src/main/liquibase/changelog.xml +++ b/core/schema/src/main/liquibase/changelog.xml @@ -102,6 +102,7 @@ + diff --git a/core/schema/src/main/resources/sql/eventconf_events.sql b/core/schema/src/main/resources/sql/eventconf_events.sql new file mode 100644 index 000000000000..7e8b6675de95 --- /dev/null +++ b/core/schema/src/main/resources/sql/eventconf_events.sql @@ -0,0 +1,2763 @@ +-- +-- Licensed to The OpenNMS Group, Inc (TOG) under one or more +-- contributor license agreements. See the LICENSE.md file +-- distributed with this work for additional information +-- regarding copyright ownership. +-- +-- TOG licenses this file to You under the GNU Affero General +-- Public License Version 3 (the "License") or (at your option) +-- any later version. You may not use this file except in +-- compliance with the License. You may obtain a copy of the +-- License at: +-- +-- https://www.gnu.org/licenses/agpl-3.0.txt +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +-- either express or implied. See the License for the specific +-- language governing permissions and limitations under the +-- License. +-- + +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (49, 10, 'uei.opennms.org/threshold/absoluteChangeExceeded', 'OpenNMS-defined threshold event: absoluteChangeExceeded', 'Absolute change threshold for the following metric exceeded: %parm[all]%', true, ' + uei.opennms.org/threshold/absoluteChangeExceeded + OpenNMS-defined threshold event: absoluteChangeExceeded + Absolute change threshold for the following metric exceeded: %parm[all]% + + Absolute change exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (50, 11, 'uei.opennms.org/internal/discoveryConfigChange', 'OpenNMS-defined internal event: discovery configuration changed', 'This event is sent by the WebUI or the user when discovery configuration has changed and should be reloaded', true, ' + uei.opennms.org/internal/discoveryConfigChange + OpenNMS-defined internal event: discovery configuration changed + This event is sent by the WebUI or the user when discovery configuration has changed and should be reloaded + + The discovery configuration has been changed and should be reloaded + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (51, 11, 'uei.opennms.org/internal/discovery/hardwareInventoryFailed', 'OpenNMS-defined internal event: reload specified daemon configuration failed', '

The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed with the following reason: %parm[reason]%.

', true, ' + uei.opennms.org/internal/discovery/hardwareInventoryFailed + OpenNMS-defined internal event: reload specified daemon configuration failed + <p>The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed with the following reason: %parm[reason]%.</p> + + <p>The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.</p> + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (52, 11, 'uei.opennms.org/internal/discovery/hardwareInventorySuccessful', 'OpenNMS-defined internal event: hardware discovery successful', '

The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has been completed successfuly.

', true, ' + uei.opennms.org/internal/discovery/hardwareInventorySuccessful + OpenNMS-defined internal event: hardware discovery successful + <p>The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has been completed successfuly.</p> + + <p>The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has been completed successfuly.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (53, 11, 'uei.opennms.org/internal/discovery/newSuspect', 'OpenNMS-defined internal event: discovery newSuspect', '

Interface %interface% has been discovered in location %parm[location]% and is + being queued for a services scan.

', true, ' + uei.opennms.org/internal/discovery/newSuspect + OpenNMS-defined internal event: discovery newSuspect + <p>Interface %interface% has been discovered in location %parm[location]% and is + being queued for a services scan.</p> + + A new interface (%interface%) has been discovered in location %parm[location]% and is + being queued for a services scan. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (54, 12, 'uei.opennms.org/internal/interfaceManaged', 'OpenNMS-defined internal event: interfaceManaged', '

The interface %interface% is being + remanaged.

This interface will now + participate in service polling.

', true, ' + uei.opennms.org/internal/interfaceManaged + OpenNMS-defined internal event: interfaceManaged + <p>The interface %interface% is being + remanaged.</p> <p>This interface will now + participate in service polling.</p> + + The interface %interface% is being remanaged. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (55, 12, 'uei.opennms.org/internal/interfaceUnmanaged', 'OpenNMS-defined internal event: interfaceUnmanaged', '

The interface %interface% is being forcibly + unmanaged.

This interface and all + associated services will NOT be polled + until the interface is remanaged.

', true, ' + uei.opennms.org/internal/interfaceUnmanaged + OpenNMS-defined internal event: interfaceUnmanaged + <p>The interface %interface% is being forcibly + unmanaged.</p> <p>This interface and all + associated services will <b>NOT</b> be polled + until the interface is remanaged.</p> + + The interface %interface% is being forcibly unmanaged. + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (56, 12, 'uei.opennms.org/internal/notificationWithoutUsers', 'OpenNMS-defined internal event: notificationWithoutUsers', '

A destination path in a notification has not been + assigned any users.

', true, ' + uei.opennms.org/internal/notificationWithoutUsers + OpenNMS-defined internal event: notificationWithoutUsers + <p>A destination path in a notification has not been + assigned any users.</p> + + A destination path in a notification has not been assigned + any users. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (66, 12, 'uei.opennms.org/internal/authentication/failure', 'OpenNMS-defined internal event: an authentication failure has occurred in WebUI', 'This event is sent by the WebUI when an authentication failure occurs.', true, ' + uei.opennms.org/internal/authentication/failure + OpenNMS-defined internal event: an authentication failure has occurred in WebUI + This event is sent by the WebUI when an authentication failure occurs. + + OpenNMS user ''%parm[user]%'' (may be blank) has failed to login + from %parm[ip]%. The failure event is %parm[exceptionName]% with + the message ''%parm[exceptionMessage]%''. + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (67, 12, 'uei.opennms.org/internal/authentication/loggedOut', 'OpenNMS-defined internal event: a user logged out of the web UI', 'This event is sent by the WebUI when a user logs out of the WebUI.', true, ' + uei.opennms.org/internal/authentication/loggedOut + OpenNMS-defined internal event: a user logged out of the web UI + This event is sent by the WebUI when a user logs out of the WebUI. + + OpenNMS user ''%parm[user]%'' logged out of the WebUI. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (68, 12, 'uei.opennms.org/internal/authentication/sessionRemoved', 'OpenNMS-defined internal event: a user''s session was removed from the WebUI', 'This event is sent by the WebUI when a user''s session is removed for any + reason other than a user-initiated logout. This generally means that + the session timed out due to inactivity.', true, ' + uei.opennms.org/internal/authentication/sessionRemoved + OpenNMS-defined internal event: a user''s session was removed from the WebUI + This event is sent by the WebUI when a user''s session is removed for any + reason other than a user-initiated logout. This generally means that + the session timed out due to inactivity. + + OpenNMS user ''%parm[user]%'' has been logged out of the WebUI, most likely + due to a session timeout. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (69, 12, 'uei.opennms.org/internal/kscReportUpdated', 'OpenNMS-defined internal event: KSC report updated', '

The KSC Report ''%parm[reportTitle]%'' has been updated (remaining graphs: %parm[graphCount]%).

+

Some graphs defined on the report have been removed, due to an invalid resource or chart.

+

A resource is not valid on any of the following situations: the nodeId (or nodeSource) doesn''t + exist, the resource type + is not valid or doesn''t exist on the node, the resource name is not valid or doesn''t exist on the node.

+

Check the logs for more details.

', true, ' + uei.opennms.org/internal/kscReportUpdated + OpenNMS-defined internal event: KSC report updated + <p>The KSC Report ''%parm[reportTitle]%'' has been updated (remaining graphs: %parm[graphCount]%).</p> + <p>Some graphs defined on the report have been removed, due to an invalid resource or chart.</p> + <p>A resource is not valid on any of the following situations: the nodeId (or nodeSource) doesn''t + exist, the resource type + is not valid or doesn''t exist on the node, the resource name is not valid or doesn''t exist on the node.</p> + <p>Check the logs for more details.</p> + The KSC Report %parm[reportTitle]% has been updated. + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (70, 12, 'uei.opennms.org/services/passiveServiceStatus', 'OpenNMS-defined service event: passiveServiceStatus', '

Status information for service %parm[passiveServiceName]% has been updated.
+ Passive Service Name: %parm[passiveServiceName]%
+ IP Interface: %parm[passiveIpAddr]%
+ Service Status: %parm[passiveStatus]%
+ Reason: %parm[passiveReasonCode]%

', true, ' + uei.opennms.org/services/passiveServiceStatus + OpenNMS-defined service event: passiveServiceStatus + <p>Status information for service %parm[passiveServiceName]% has been updated. <br/> + Passive Service Name: %parm[passiveServiceName]%<br/> + IP Interface: %parm[passiveIpAddr]%<br/> + Service Status: %parm[passiveStatus]%<br/> + Reason: %parm[passiveReasonCode]%</p> + <p>Status information for service %parm[passiveServiceName]% has been updated.</p> + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (71, 12, 'uei.opennms.org/asset/maintenance/expirationWarning', 'Maintenance contract will expire in less then %parm[#4]% days', '

Maintenance contract of %nodelabel% will expire in less then %parm[#4]% days.

', true, ' + uei.opennms.org/asset/maintenance/expirationWarning + Maintenance contract will expire in less then %parm[#4]% days + <p>Maintenance contract of %nodelabel% will expire in less then %parm[#4]% days.</p> + <p>Maintenance contract %parm[#3]% of %nodelabel% will expire at %parm[#2]%.</p> + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (72, 12, 'uei.opennms.org/internal/monitoringSystemAdded', 'Monitoring system Added', 'A new monitoring system has been added', true, ' + uei.opennms.org/internal/monitoringSystemAdded + Monitoring system Added + A new monitoring system has been added + A new monitoring system of type ''%parm[monitoringSystemType]%'' has been added with ID + ''%parm[monitoringSystemId]%'' at location ''%parm[monitoringSystemLocation]%''. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (73, 12, 'uei.opennms.org/internal/monitoringSystemLocationChanged', 'Monitoring system Location Changed', 'Monitoring system location changed', true, ' + uei.opennms.org/internal/monitoringSystemLocationChanged + Monitoring system Location Changed + Monitoring system location changed + Monitoring system of type ''%parm[monitoringSystemType]%'' with ID + ''%parm[monitoringSystemId]%'' has changed its location from ''%parm[monitoringSystemPreviousLocation]%'' to + ''%parm[monitoringSystemLocation]%''. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (74, 12, 'uei.opennms.org/internal/monitoringSystemDeleted', 'Monitoring system Deleted', 'Monitoring system Deleted', true, ' + uei.opennms.org/internal/monitoringSystemDeleted + Monitoring system Deleted + Monitoring system Deleted + Monitoring system of type ''%parm[monitoringSystemType]%'' with ID + ''%parm[monitoringSystemId]%'' at location ''%parm[monitoringSystemLocation]%'' has been deleted. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (1, 1, 'uei.opennms.org/generic/traps/SNMP_Cold_Start', 'OpenNMS-defined trap event: SNMP_Cold_Start', '

A coldStart trap signifies that the sending protocol entity is reinitializing itself such that the + agent''s configuration or the protocol entity implementation may be altered.

', true, ' + + + generic + 0 + + + uei.opennms.org/generic/traps/SNMP_Cold_Start + OpenNMS-defined trap event: SNMP_Cold_Start + <p>A coldStart trap signifies that the sending protocol entity is reinitializing itself such that the + agent''s configuration or the protocol entity implementation may be altered.</p> + Agent Up with Possible Changes (coldStart Trap) + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (2, 1, 'uei.opennms.org/generic/traps/SNMP_Warm_Start', 'OpenNMS-defined trap event: SNMP_Warm_Start', '

A warmStart trap signifies that the sending protocol entity is reinitializing itself such that + neither the agent configuration nor the + protocol entity implementation is altered.

', true, ' + + + generic + 1 + + + uei.opennms.org/generic/traps/SNMP_Warm_Start + OpenNMS-defined trap event: SNMP_Warm_Start + <p>A warmStart trap signifies that the sending protocol entity is reinitializing itself such that + neither the agent configuration nor the + protocol entity implementation is altered.</p> + Agent Up with No Changes (warmStart Trap) + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (3, 1, 'uei.opennms.org/generic/traps/SNMP_Link_Down', 'OpenNMS-defined trap event: SNMP_Link_Down', '

A linkDown trap signifies that the sending protocol entity recognizes a failure in one of the + communication link represented in the agent''s + configuration. The data passed with the event are 1) The name and value of the ifIndex instance for the + affected interface. The name of the + interface can be retrieved via an snmpget of .1.3.6.1.2.1.2.2.1.2.INST, where INST is the instance returned + with the trap.

', true, ' + + + generic + 2 + + + uei.opennms.org/generic/traps/SNMP_Link_Down + OpenNMS-defined trap event: SNMP_Link_Down + <p>A linkDown trap signifies that the sending protocol entity recognizes a failure in one of the + communication link represented in the agent''s + configuration. The data passed with the event are 1) The name and value of the ifIndex instance for the + affected interface. The name of the + interface can be retrieved via an snmpget of .1.3.6.1.2.1.2.2.1.2.INST, where INST is the instance returned + with the trap.</p> + Agent Interface Down (linkDown Trap) + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (4, 1, 'uei.opennms.org/translator/traps/SNMP_Link_Down', 'Translator Enriched LinkDown Event', '

A linkDown trap signifies that the sending protocol entity recognizes a failure in one of the + communication link represented in the agent''s configuration.

+

Instance: %parm[#1]%

+

IfDescr: %parm[ifDescr]%

+

IfName: %parm[ifName]%

+

IfAlias: %parm[ifAlias]%

', true, ' + uei.opennms.org/translator/traps/SNMP_Link_Down + Translator Enriched LinkDown Event + <p>A linkDown trap signifies that the sending protocol entity recognizes a failure in one of the + communication link represented in the agent''s configuration. </p> + <p>Instance: %parm[#1]% </p> + <p>IfDescr: %parm[ifDescr]% </p> + <p>IfName: %parm[ifName]% </p> + <p>IfAlias: %parm[ifAlias]% </p> + Agent Interface Down (linkDown Trap) + + Minor + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (5, 1, 'uei.opennms.org/generic/traps/SNMP_Link_Up', 'OpenNMS-defined trap event: SNMP_Link_Up', '

A linkUp trap signifies that the sending protocol entity recognizes that one of the communication + links represented in the agent''s + configuration has come up. The data passed with the event are 1) The name and value of the ifIndex instance + for the affected interface. The name of + the interface can be retrieved via an snmpget of .1.3.6.1.2.1.2.2.1.2.INST, where INST is the instance + returned with the trap.

', true, ' + + + generic + 3 + + + uei.opennms.org/generic/traps/SNMP_Link_Up + OpenNMS-defined trap event: SNMP_Link_Up + <p>A linkUp trap signifies that the sending protocol entity recognizes that one of the communication + links represented in the agent''s + configuration has come up. The data passed with the event are 1) The name and value of the ifIndex instance + for the affected interface. The name of + the interface can be retrieved via an snmpget of .1.3.6.1.2.1.2.2.1.2.INST, where INST is the instance + returned with the trap.</p> + Agent Interface Up (linkUp Trap) + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (6, 1, 'uei.opennms.org/translator/traps/SNMP_Link_Up', 'Translator Enriched LinkUp Event', '

A linkUp trap signifies that the sending protocol entity recognizes that one of the communication + links represented in the agent''s configuration has come up.

+

Instance: %parm[#1]%

+

IfDescr: %parm[ifDescr]%

+

IfName: %parm[ifName]%

+

IfAlias: %parm[ifAlias]%

', true, ' + uei.opennms.org/translator/traps/SNMP_Link_Up + Translator Enriched LinkUp Event + <p>A linkUp trap signifies that the sending protocol entity recognizes that one of the communication + links represented in the agent''s configuration has come up. </p> + <p>Instance: %parm[#1]% </p> + <p>IfDescr: %parm[ifDescr]% </p> + <p>IfName: %parm[ifName]% </p> + <p>IfAlias: %parm[ifAlias]% </p> + Agent Interface Up (linkUp Trap) + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (7, 1, 'uei.opennms.org/generic/traps/SNMP_Authen_Failure', 'OpenNMS-defined trap event: SNMP_Authen_Failure', '

An authentication failure trap signifies that the sending protocol entity is the addressee of a + protocol message that is not properly + authenticated.

', true, ' + + + generic + 4 + + + uei.opennms.org/generic/traps/SNMP_Authen_Failure + OpenNMS-defined trap event: SNMP_Authen_Failure + <p>An authentication failure trap signifies that the sending protocol entity is the addressee of a + protocol message that is not properly + authenticated.</p> + Incorrect Community Name (authenticationFailure Trap) + + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (32, 8, 'uei.opennms.org/internal/reloadSnmpPollerConfig', 'OpenNMS-defined internal event: reloadSnmpPollerConfig', '

The administrator has changed the SnmpPoller + configuration. SnmpPoller will load the new configuration.

', true, ' + uei.opennms.org/internal/reloadSnmpPollerConfig + OpenNMS-defined internal event: reloadSnmpPollerConfig + <p>The administrator has changed the SnmpPoller + configuration. SnmpPoller will load the new configuration.</p> + + <p>The SnmpPoller configuration files have changed.</p> + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (8, 1, 'uei.opennms.org/generic/traps/SNMP_EGP_Down', 'OpenNMS-defined trap event: SNMP_EGP_Down', '

An egpNeighborLoss trap signifies that an EGP neighbor for whom the sending protocol entity was an + EGP peer has been marked down and the + peer relationship no longer obtains. The data passed with the event are The name and value of the ifIndex + egpNeighAddr for the affected + neighbor.

', true, ' + + + generic + 5 + + + uei.opennms.org/generic/traps/SNMP_EGP_Down + OpenNMS-defined trap event: SNMP_EGP_Down + <p>An egpNeighborLoss trap signifies that an EGP neighbor for whom the sending protocol entity was an + EGP peer has been marked down and the + peer relationship no longer obtains. The data passed with the event are The name and value of the ifIndex + egpNeighAddr for the affected + neighbor.</p> + EGP Neighbor Down (egpNeighborLoss Trap) + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (9, 2, 'uei.opennms.org/ackd/acknowledge', 'OpenNMS-defined Acknowledgment request', 'A message received requesting an Acknowledgable be acknowledged. +

Acknowledgement Request:%parm[refId]% of type:%parm[ackType]% was received with the + action:%parm[ackAction]% was received for User: %parm[ackUser]%

+ Typically received from an external source or as a choice of an AckReader implementation.', true, ' + uei.opennms.org/ackd/acknowledge + OpenNMS-defined Acknowledgment request + A message received requesting an Acknowledgable be acknowledged. + <p>Acknowledgement Request:%parm[refId]% of type:%parm[ackType]% was received with the + action:%parm[ackAction]% was received for User: %parm[ackUser]%</p> + Typically received from an external source or as a choice of an AckReader implementation. + + <p>Acknowledgement Request:%parm[refId]% of type:%parm[ackType]% was received with the + action:%parm[ackAction]% was received for User: %parm[ackUser]%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (10, 3, 'uei.opennms.org/alarms/trigger', 'Alarm: Generic Trigger', 'A problem has been triggered.', true, ' + uei.opennms.org/alarms/trigger + Alarm: Generic Trigger + A problem has been triggered. + A problem has been triggered on %parm[node]%/%parm[ip]%/%parm[service]%. + Warning + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (11, 3, 'uei.opennms.org/alarms/clear', 'Alarm: Generic Clear', 'A problem has been cleared.', true, ' + uei.opennms.org/alarms/clear + Alarm: Generic Clear + A problem has been cleared. + A problem has been cleared on %parm[node]%/%parm[ip]%/%parm[service]%. + Cleared + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (12, 3, 'uei.opennms.org/alarms/situation', 'Alarm: Situation', '%parm[situationDescr]%', true, ' + uei.opennms.org/alarms/situation + Alarm: Situation + %parm[situationDescr]% + %parm[situationLogMsg]% + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (13, 4, 'uei.opennms.org/bmp/peerDown', 'BMP: Peer Down', '

BGP session to Peer %parm[address]% at AS%parm[as]% lost (Router ID: %parm[id]%). + Reason: %parm[type]%. Error: %parm[error]%.

', true, ' + uei.opennms.org/bmp/peerDown + BMP: Peer Down + <p>BGP session to Peer %parm[address]% at AS%parm[as]% lost (Router ID: %parm[id]%). + Reason: %parm[type]%. Error: %parm[error]%.</p> + Router has lost the BGP session to Peer %parm[address]% at AS%parm[as]% (Router ID: %parm[id]%). + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (14, 4, 'uei.opennms.org/bmp/peerUp', 'BMP: Peer Up', '

BGP session to Peer %parm[address]% at AS%parm[as]% established (Router ID: %parm[id]%).

', true, ' + uei.opennms.org/bmp/peerUp + BMP: Peer Up + <p>BGP session to Peer %parm[address]% at AS%parm[as]% established (Router ID: %parm[id]%).</p> + Router has established the BGP session to Peer %parm[address]% at AS%parm[as]% (Router ID: %parm[id]%). + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (15, 5, 'uei.opennms.org/bsm/serviceOperationalStatusChanged', 'Business Service Monitoring: Service Operational Status Changed', '

The operational status for business service ''%parm[businessServiceName]%'', with + id=%parm[businessServiceId]%, changed from %parm[prevSeverityLabel]% to %parm[newSeverityLabel]%. + args(%parm[##]%): %parm[all]%

', true, ' + uei.opennms.org/bsm/serviceOperationalStatusChanged + Business Service Monitoring: Service Operational Status Changed + <p>The operational status for business service ''%parm[businessServiceName]%'', with + id=%parm[businessServiceId]%, changed from %parm[prevSeverityLabel]% to %parm[newSeverityLabel]%. + args(%parm[##]%): %parm[all]%</p> + The operational status for business service ''%parm[businessServiceName]%'' changed + from %parm[prevSeverityLabel]% to %parm[newSeverityLabel]%. + + Indeterminate +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (16, 5, 'uei.opennms.org/bsm/serviceProblem', 'Business Service Monitoring: Service Problem', '

There are currently one or more problems affecting business service ''%parm[businessServiceName]%''. Root cause: %parm[rootCause]%. + args(%parm[##]%): %parm[all]%

', true, ' + uei.opennms.org/bsm/serviceProblem + Business Service Monitoring: Service Problem + <p>There are currently one or more problems affecting business service ''%parm[businessServiceName]%''. Root cause: %parm[rootCause]%. + args(%parm[##]%): %parm[all]%</p> + One or more problems are affecting business service ''%parm[businessServiceName]%''. + + Indeterminate + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (17, 5, 'uei.opennms.org/bsm/serviceProblemResolved', 'Business Service Monitoring: Service Problem Resolved', '

The problem affecting business service ''%parm[businessServiceName]%'' has been resolved. + args(%parm[##]%): %parm[all]%

', true, ' + uei.opennms.org/bsm/serviceProblemResolved + Business Service Monitoring: Service Problem Resolved + <p>The problem affecting business service ''%parm[businessServiceName]%'' has been resolved. + args(%parm[##]%): %parm[all]%</p> + The problems affecting business service ''%parm[businessServiceName]%'' have been + resolved. + + Indeterminate + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (18, 5, 'uei.opennms.org/bsm/graphInvalidated', 'Business Service Monitoring: Graph invalidated', '

Business Service ''%parm[businessServiceName]%'' with ID ''%parm[businessServiceId]%'' is affected by the deletion of %parm[cause]%. + A reload of the BSM daemon is scheduled. Make sure the Business Service still works properly. + Please verify it''s definition.

', true, ' + uei.opennms.org/bsm/graphInvalidated + Business Service Monitoring: Graph invalidated + <p>Business Service ''%parm[businessServiceName]%'' with ID ''%parm[businessServiceId]%'' is affected by the deletion of %parm[cause]%. + A reload of the BSM daemon is scheduled. Make sure the Business Service still works properly. + Please verify it''s <a href="admin/bsm/adminpage.jsp">definition</a>.</p> + Business service ''%parm[businessServiceName]%'' with ID ''%parm[businessServiceId]%'' is affected by the deletion of %parm[cause]%. + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (19, 5, 'uei.opennms.org/internal/serviceDeleted', 'Business Service Monitoring: Service deleted', '

The business service ''%parm[businessServiceName]%'' has been deleted. + args(%parm[##]%): %parm[all]%

', true, ' + uei.opennms.org/internal/serviceDeleted + Business Service Monitoring: Service deleted + <p>The business service ''%parm[businessServiceName]%'' has been deleted. + args(%parm[##]%): %parm[all]%</p> + The business service ''%parm[businessServiceName]%'' has been deleted. + + Indeterminate + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (20, 6, 'uei.opennms.org/internal/capsd/discPause', 'OpenNMS-defined internal event: capsd discPause', '

The services scanning engine has asked discovery to + pause due to a backlog of interfaces yet to be scanned. +

', true, ' + uei.opennms.org/internal/capsd/discPause + OpenNMS-defined internal event: capsd discPause + <p>The services scanning engine has asked discovery to + pause due to a backlog of interfaces yet to be scanned. + </p> + + Capsd has asked Discovery to pause momentarily. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (21, 6, 'uei.opennms.org/internal/capsd/discResume', 'OpenNMS-defined internal event: capsd discResume', '

Capsd is approving discovery to resume adding nodes + to the Capsd queue.

', true, ' + uei.opennms.org/internal/capsd/discResume + OpenNMS-defined internal event: capsd discResume + <p>Capsd is approving discovery to resume adding nodes + to the Capsd queue.</p> + + Capsd is ready for Discovery to resume scheduling nodes. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (22, 6, 'uei.opennms.org/internal/capsd/forceRescan', 'OpenNMS-defined internal event: capsd forceRescan', '

A services scan has been forced.

+

The administrator has forced a services scan on + this node to update the list of supported + services.

', true, ' + uei.opennms.org/internal/capsd/forceRescan + OpenNMS-defined internal event: capsd forceRescan + <p>A services scan has been forced.</p> + <p>The administrator has forced a services scan on + this node to update the list of supported + services.</p> + + <p>A services scan has been forced on this + node.</p> + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (23, 6, 'uei.opennms.org/internal/capsd/rescanCompleted', 'OpenNMS-defined internal event: capsd rescanCompleted', '

A services scan has been completed.

+

The list of services on this node has been + updated.

', true, ' + uei.opennms.org/internal/capsd/rescanCompleted + OpenNMS-defined internal event: capsd rescanCompleted + <p>A services scan has been completed.</p> + <p>The list of services on this node has been + updated.</p> + + <p>A services scan has been completed on this + node.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (24, 6, 'uei.opennms.org/internal/capsd/addNode', 'OpenNMS-defined internal event: capsd addNode', '

This event is an external command to add a node + to the database. The required paramater is the IP + address for the main interface: %interface%, and + the optional parameter of a node label: %nodelabel%.

', true, ' + uei.opennms.org/internal/capsd/addNode + OpenNMS-defined internal event: capsd addNode + <p>This event is an external command to add a node + to the database. The required paramater is the IP + address for the main interface: %interface%, and + the optional parameter of a node label: %nodelabel%.</p> + + <p>A request has been made to add a node with interface: + %interface% and node label: %nodelabel%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (25, 6, 'uei.opennms.org/internal/capsd/deleteNode', 'OpenNMS-defined internal event: capsd deleteNode', '

This event is an external command to delete a node + from the database. The required paramater is the IP + address for one interface: %interface%.

', true, ' + uei.opennms.org/internal/capsd/deleteNode + OpenNMS-defined internal event: capsd deleteNode + <p>This event is an external command to delete a node + from the database. The required paramater is the IP + address for one interface: %interface%.</p> + + <p>A request has been made to delete a node with interface: + %interface%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (26, 6, 'uei.opennms.org/internal/capsd/deleteInterface', 'OpenNMS-defined internal event: capsd deleteInterface', '

This event is an external command to delete an interface + from the database. The required paramater is the IP + address for the interface: %interface%, or the nodeid %nodeid% + and ifIndex %ifindex%.

', true, ' + uei.opennms.org/internal/capsd/deleteInterface + OpenNMS-defined internal event: capsd deleteInterface + <p>This event is an external command to delete an interface + from the database. The required paramater is the IP + address for the interface: %interface%, or the nodeid %nodeid% + and ifIndex %ifindex%.</p> + + <p>A request has been made to delete an interface: + %interface% on node %nodeid% with ifIndex %ifindex%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (27, 6, 'uei.opennms.org/internal/capsd/changeService', 'OpenNMS-defined internal event: capsd changeService', '

This event will add or remove a service from an interface. + The paramters include the interface, %interface%, the service, + %service%, and any required qualifiers, %parm[#2]%. The action + taken will be: %parm[#1]%.

', true, ' + uei.opennms.org/internal/capsd/changeService + OpenNMS-defined internal event: capsd changeService + <p>This event will add or remove a service from an interface. + The paramters include the interface, %interface%, the service, + %service%, and any required qualifiers, %parm[#2]%. The action + taken will be: %parm[#1]%.</p> + + <p>A request has been made to %parm[#1]% the %service% service + on interface: %interface%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (28, 7, 'uei.opennms.org/nodes/dataCollectionFailed', 'OpenNMS-defined node event: dataCollectionFailed', '

%service% data collection on interface %interface% failed because of the following condition: ''%parm[reason]%''.

', true, ' + uei.opennms.org/nodes/dataCollectionFailed + OpenNMS-defined node event: dataCollectionFailed + <p>%service% data collection on interface %interface% failed because of the following condition: ''%parm[reason]%''.</p> + %service% data collection on interface %interface% failed. + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (29, 7, 'uei.opennms.org/nodes/dataCollectionSucceeded', 'OpenNMS-defined node event: dataCollectionSucceeded', '

%service% data collection on interface %interface% previously failed and has been restored.

', true, ' + uei.opennms.org/nodes/dataCollectionSucceeded + OpenNMS-defined node event: dataCollectionSucceeded + <p>%service% data collection on interface %interface% previously failed and has been restored.</p> + %service% data collection on interface %interface% previously failed and has been restored. + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (30, 8, 'uei.opennms.org/internal/reloadScriptConfig', 'OpenNMS-defined internal event: reloadScriptConfig', '

The administrator has changed the ScriptD configuration. + ScriptD will load the new configuration.

', true, ' + uei.opennms.org/internal/reloadScriptConfig + OpenNMS-defined internal event: reloadScriptConfig + <p>The administrator has changed the ScriptD configuration. + ScriptD will load the new configuration.</p> + + <p>The ScriptD configuration files have changed.</p> + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (31, 8, 'uei.opennms.org/internal/reloadVacuumdConfig', 'OpenNMS-defined internal event: reloadVacuumdConfig', '

The administrator has changed the Vacuumd + configuration. Vacuumd will load the new configuration.

', true, ' + uei.opennms.org/internal/reloadVacuumdConfig + OpenNMS-defined internal event: reloadVacuumdConfig + <p>The administrator has changed the Vacuumd + configuration. Vacuumd will load the new configuration.</p> + + <p>The Vacuumd configuration files have changed.</p> + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (33, 8, 'uei.opennms.org/internal/reloadDaemonConfig', 'OpenNMS-defined internal event: reload specified daemon configuration', '

The administrator has changed the daemon: %parm[daemonName]% + configuration files and requests the configuration to be re-marshaled and applied.

', true, ' + uei.opennms.org/internal/reloadDaemonConfig + OpenNMS-defined internal event: reload specified daemon configuration + <p>The administrator has changed the daemon: %parm[daemonName]% + configuration files and requests the configuration to be re-marshaled and applied.</p> + + <p>The daemon: %parm[daemonName]% configuration files has changed.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (34, 8, 'uei.opennms.org/internal/reloadDaemonConfigFailed', 'OpenNMS-defined internal event: reload specified daemon configuration failed', '

The administrator has changed the daemon: %parm[daemonName]% + configuration files and the request for the configuration to be re-marshaled and applied + has failed because of the following condition %parm[reason]%.

', true, ' + uei.opennms.org/internal/reloadDaemonConfigFailed + OpenNMS-defined internal event: reload specified daemon configuration failed + <p>The administrator has changed the daemon: %parm[daemonName]% + configuration files and the request for the configuration to be re-marshaled and applied + has failed because of the following condition %parm[reason]%.</p> + + <p>The daemon: %parm[daemonName]% configuration changes have failed to be + applied.</p> + + Major + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (35, 8, 'uei.opennms.org/internal/reloadDaemonConfigSuccessful', 'OpenNMS-defined internal event: reload specified daemon configuration successful', '

The administrator has changed the daemon: %parm[daemonName]% + configuration files and the request for the configuration to be re-marshaled and applied + has succeeded.

', true, ' + uei.opennms.org/internal/reloadDaemonConfigSuccessful + OpenNMS-defined internal event: reload specified daemon configuration successful + <p>The administrator has changed the daemon: %parm[daemonName]% + configuration files and the request for the configuration to be re-marshaled and applied + has succeeded.</p> + + <p>The daemon: %parm[daemonName]% configuration changes have successfully been + applied.</p> + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (36, 8, 'uei.opennms.org/internal/thresholdConfigChange', 'OpenNMS-defined internal event: threshold configuration changed', 'This event is sent by the WebUI or the user when threshold configuration has changed and should be reloaded', true, ' + uei.opennms.org/internal/thresholdConfigChange + OpenNMS-defined internal event: threshold configuration changed + This event is sent by the WebUI or the user when threshold configuration has changed and should be reloaded + + The thresholds configuration has been changed and should be reloaded + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (37, 8, 'uei.opennms.org/internal/eventsConfigChange', 'OpenNMS-defined internal event: event configuration changed', 'This event is sent by the WebUI or the user when event configuration has changed and should be reloaded', true, ' + uei.opennms.org/internal/eventsConfigChange + OpenNMS-defined internal event: event configuration changed + This event is sent by the WebUI or the user when event configuration has changed and should be reloaded + + The events configuration has been changed and should be reloaded + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (38, 8, 'uei.opennms.org/internal/reloadPollerConfig', 'OpenNMS-defined internal event: reloadPollerConfig', '

The administrator has changed the poller + configuration files. The pollers and related services will + now restart to detect the changes.

', true, ' + uei.opennms.org/internal/reloadPollerConfig + OpenNMS-defined internal event: reloadPollerConfig + <p>The administrator has changed the poller + configuration files. The pollers and related services will + now restart to detect the changes.</p> + + <p>The poller configuration files have + changed.</p> + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (39, 8, 'uei.opennms.org/internal/syslogdConfigChange', 'OpenNMS-defined internal event: Syslogd configuration changed', 'This event is sent by the WebUI or the user when the Syslogd configuration has changed and should be + reloaded', true, ' + uei.opennms.org/internal/syslogdConfigChange + OpenNMS-defined internal event: Syslogd configuration changed + This event is sent by the WebUI or the user when the Syslogd configuration has changed and should be + reloaded + + The Syslogd configuration has been changed and should be reloaded + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (40, 8, 'uei.opennms.org/internal/configureSNMP', 'OpenNMS-defined internal event: configureSNMP', '

SNMP definition for IP address + %parm[firstIPAddress]%-%parm[lastIPAddress]% has been + updated with community string + "%parm[communityString]%"

', true, ' + uei.opennms.org/internal/configureSNMP + OpenNMS-defined internal event: configureSNMP + <p>SNMP definition for IP address + %parm[firstIPAddress]%-%parm[lastIPAddress]% has been + updated with community string + "%parm[communityString]%"</p> + + <p>SNMP community string + "%parm[communityString]%" has been defined + for IP %parm[firstIPAddress]%-%parm[lastIPAddress]%.</p> + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (41, 8, 'uei.opennms.org/internal/translator/entityConfigChanged', 'OpenNMS defined event: A trap based event was received indicating a configuration change on a + device and has been translated to this generic event', 'This is a translated entity configuration change event.

+ +

Source: %parm[configSource]%

+

User: %parm[configUser]%

', true, ' + uei.opennms.org/internal/translator/entityConfigChanged + OpenNMS defined event: A trap based event was received indicating a configuration change on a + device and has been translated to this generic event + This is a translated entity configuration change event.<p> + + <p>Source: %parm[configSource]% </p> + <p>User: %parm[configUser]% </p> + + <p>"%parm[configUser]%" changed entity %nodelabel%_%interface% from source: %parm[configSource]% </a></p> + + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (42, 9, 'uei.opennms.org/correlation/serviceFlapping', 'OpenNMS-defined correlator event: A service has been detected to be in a flapping state', 'This event is sent when a correlation rule has detected that a service is flapping.', true, ' + uei.opennms.org/correlation/serviceFlapping + OpenNMS-defined correlator event: A service has been detected to be in a flapping state + This event is sent when a correlation rule has detected that a service is flapping. + + The service: %service% has been correlated to indicate a flapping state. + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (43, 9, 'uei.opennms.org/internal/droolsEngineException', 'OpenNMS-defined Drools Engine Encountered Exception', 'Drools engine encountered an exception while running rules', true, ' + uei.opennms.org/internal/droolsEngineException + OpenNMS-defined Drools Engine Encountered Exception + Drools engine encountered an exception while running rules + + Drools engine rule %parm[enginename]% has encountered an exception : %parm[stacktrace]%. + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (44, 10, 'uei.opennms.org/threshold/highThresholdExceeded', 'OpenNMS-defined threshold event: highThresholdExceeded', 'A high threshold for the following metric exceeded: %parm[all]%', true, ' + uei.opennms.org/threshold/highThresholdExceeded + OpenNMS-defined threshold event: highThresholdExceeded + A high threshold for the following metric exceeded: %parm[all]% + + High threshold exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% + + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (45, 10, 'uei.opennms.org/threshold/lowThresholdExceeded', 'OpenNMS-defined threshold event: lowThresholdExceeded', 'Low threshold for the following metric exceeded: %parm[all]%', true, ' + uei.opennms.org/threshold/lowThresholdExceeded + OpenNMS-defined threshold event: lowThresholdExceeded + Low threshold for the following metric exceeded: %parm[all]% + + Low threshold exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% + + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (46, 10, 'uei.opennms.org/threshold/highThresholdRearmed', 'OpenNMS-defined threshold event: highThresholdRearmed', 'High threshold has been rearmed for the following metric: %parm[all]%', true, ' + uei.opennms.org/threshold/highThresholdRearmed + OpenNMS-defined threshold event: highThresholdRearmed + High threshold has been rearmed for the following metric: %parm[all]% + + High threshold rearmed for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (47, 10, 'uei.opennms.org/threshold/lowThresholdRearmed', 'OpenNMS-defined threshold event: lowThresholdRearmed', 'Low threshold has been rearmed for the following metric: %parm[all]%', true, ' + uei.opennms.org/threshold/lowThresholdRearmed + OpenNMS-defined threshold event: lowThresholdRearmed + Low threshold has been rearmed for the following metric: %parm[all]% + + Low threshold rearmed for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (48, 10, 'uei.opennms.org/threshold/relativeChangeExceeded', 'OpenNMS-defined threshold event: relativeChangeExceeded', 'Relative change threshold for the following metric exceeded: %parm[all]%', true, ' + uei.opennms.org/threshold/relativeChangeExceeded + OpenNMS-defined threshold event: relativeChangeExceeded + Relative change threshold for the following metric exceeded: %parm[all]% + + Relative change change exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (57, 12, 'uei.opennms.org/internal/notificationsTurnedOff', 'OpenNMS-defined internal event: notificationsTurnedOff', '

Notifications have been disabled.

+

The administrator has disabled notifications on + OpenNMS. No pages or emails will be sent until notifications + are reenabled.

+

+ Responsible user: %parm[remoteUser]% + at %parm[remoteHost]% (%parm[remoteAddr]%) +

', true, ' + uei.opennms.org/internal/notificationsTurnedOff + OpenNMS-defined internal event: notificationsTurnedOff + <p>Notifications have been disabled.</p> + <p>The administrator has disabled notifications on + OpenNMS. No pages or emails will be sent until notifications + are reenabled.</p> + <p> + Responsible user: <em>%parm[remoteUser]%</em> + at <em>%parm[remoteHost]% (%parm[remoteAddr]%)</em> + </p> + + <p>Notifications have been disabled.</p> + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (58, 12, 'uei.opennms.org/internal/notificationsTurnedOn', 'OpenNMS-defined internal event: notificationsTurnedOn', '

Notifications have been enabled.

+

The administrator has enabled notifications on + OpenNMS. Pages and/or emails will be sent based upon receipt + of important events.

+

+ Responsible user: %parm[remoteUser]% + at %parm[remoteHost]% (%parm[remoteAddr]%) +

', true, ' + uei.opennms.org/internal/notificationsTurnedOn + OpenNMS-defined internal event: notificationsTurnedOn + <p>Notifications have been enabled.</p> + <p>The administrator has enabled notifications on + OpenNMS. Pages and/or emails will be sent based upon receipt + of important events.</p> + <p> + Responsible user: <em>%parm[remoteUser]%</em> + at <em>%parm[remoteHost]% (%parm[remoteAddr]%)</em> + </p> + + <p>Notifications have been enabled.</p> + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (59, 12, 'uei.opennms.org/internal/restartSCM', 'OpenNMS-defined internal event: restartSCM', '

SCM has been asked to restart.

', true, ' + uei.opennms.org/internal/restartSCM + OpenNMS-defined internal event: restartSCM + <p>SCM has been asked to restart.</p> + + SCM has been asked to restart. + + Indeterminate +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (60, 12, 'uei.opennms.org/internal/rtc/subscribe', 'OpenNMS-defined internal event: rtc subscribe', '

This event is generated to RTC by any process that + wishes to receive POSTs of RTC data.

', true, ' + uei.opennms.org/internal/rtc/subscribe + OpenNMS-defined internal event: rtc subscribe + <p>This event is generated to RTC by any process that + wishes to receive POSTs of RTC data.</p> + + A subscription to RTC for the %parm[viewname]% for + %parm[url]% has been generated. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (61, 12, 'uei.opennms.org/internal/rtc/unsubscribe', 'OpenNMS-defined internal event: rtc unsubscribe', '

This event is generated to RTC by any subscribed + process that wishes to discontinue receipt of POSTs of RTC + data.

', true, ' + uei.opennms.org/internal/rtc/unsubscribe + OpenNMS-defined internal event: rtc unsubscribe + <p>This event is generated to RTC by any subscribed + process that wishes to discontinue receipt of POSTs of RTC + data.</p> + + Unsubscribe request received from %parm[url]%. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (62, 12, 'uei.opennms.org/internal/serviceManaged', 'OpenNMS-defined internal event: serviceManaged', '

The service %service% on interface %interface% is + being remanaged.

', true, ' + uei.opennms.org/internal/serviceManaged + OpenNMS-defined internal event: serviceManaged + <p>The service %service% on interface %interface% is + being remanaged.</p> + + The service %service% on interface %interface% is being + remanaged. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (63, 12, 'uei.opennms.org/internal/schedOutagesChanged', 'OpenNMS-defined internal event: scehduled outage configuration changed', 'This event is sent by the WebUI or the user when scheduled outage configuration has changed and should be + reloaded', true, ' + uei.opennms.org/internal/schedOutagesChanged + OpenNMS-defined internal event: scehduled outage configuration changed + This event is sent by the WebUI or the user when scheduled outage configuration has changed and should be + reloaded + + The scheduled outage configuration has been changed and should be reloaded + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (64, 12, 'uei.opennms.org/internal/promoteQueueData', 'OpenNMS-defined event: A request has been made promote data from the RRD Queue', 'This event is generated to invoke the promotion data of the Queueing RRD Strategy.', true, ' + uei.opennms.org/internal/promoteQueueData + OpenNMS-defined event: A request has been made promote data from the RRD Queue + This event is generated to invoke the promotion data of the Queueing RRD Strategy. + + A request has been generated to promote data from the queue for the file(s): %parm[filesToPromote]%. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (65, 12, 'uei.opennms.org/internal/authentication/successfulLogin', 'OpenNMS-defined internal event: a user has successfully authentication to the WebUI', 'This event is sent by the WebUI when a user has successfully authenticated', true, ' + uei.opennms.org/internal/authentication/successfulLogin + OpenNMS-defined internal event: a user has successfully authentication to the WebUI + This event is sent by the WebUI when a user has successfully authenticated + + OpenNMS user %parm[user]% has logged in from %parm[ip]%. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (75, 12, 'uei.opennms.org/internal/telemetry/clockSkewDetected', 'Clock Skew detected', 'Clock skew (%parm[delta]% ms) detected for flow exporter (maxClockSkew = %parm[maxClockSkew]% secs)', true, ' + uei.opennms.org/internal/telemetry/clockSkewDetected + Clock Skew detected + Clock skew (%parm[delta]% ms) detected for flow exporter (maxClockSkew = %parm[maxClockSkew]% secs) + Clock skew for exporter with interface ''%interface%'' in location ''%parm[monitoringSystemLocation]%'' detected by ''%parm[monitoringSystemId]%''. + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (76, 12, 'uei.opennms.org/translator/telemetry/clockSkewDetected', 'Clock Skew detected', 'Clock skew (%parm[delta]% ms) detected for flow exporter (maxClockSkew = %parm[maxClockSkew]% secs)', true, ' + uei.opennms.org/translator/telemetry/clockSkewDetected + Clock Skew detected + Clock skew (%parm[delta]% ms) detected for flow exporter (maxClockSkew = %parm[maxClockSkew]% secs) + Clock skew for exporter with interface ''%interface%'' in location ''%parm[monitoringSystemLocation]%'' detected by ''%parm[monitoringSystemId]%''. + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (77, 12, 'uei.opennms.org/internal/applicationDeleted', 'OpenNMS-defined application event: applicationDeleted', 'Application ''%parm[applicationName]%'' with ID ''%parm[applicationId]%'' has been deleted.', true, ' + uei.opennms.org/internal/applicationDeleted + OpenNMS-defined application event: applicationDeleted + Application ''%parm[applicationName]%'' with ID ''%parm[applicationId]%'' has been deleted. + Application ''%parm[applicationName]%'' has been deleted. + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (78, 12, 'uei.opennms.org/internal/applicationChanged', 'OpenNMS-defined node event: applicationChanged', 'The application ''%parm[applicationName]%'' with ID ''%parm[applicationId]%'' has been changed.', true, ' + uei.opennms.org/internal/applicationChanged + OpenNMS-defined node event: applicationChanged + The application ''%parm[applicationName]%'' with ID ''%parm[applicationId]%'' has been changed. + Application ''%parm[applicationName]%'' configuration has been changed. + Warning + Make sure ''%parm[applicationName]%'' application''s definition still reflects the requirements. Please verify it''s <a href="admin/applications.htm?applicationid=%parm[applicationId]%&edit=services">definition</a>. +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (79, 12, 'uei.opennms.org/internal/applicationCreated', 'OpenNMS-defined node event: applicationCreated', 'The application ''%parm[applicationName]%'' with ID ''%parm[applicationId]%'' has been created.', true, ' + uei.opennms.org/internal/applicationCreated + OpenNMS-defined node event: applicationCreated + The application ''%parm[applicationName]%'' with ID ''%parm[applicationId]%'' has been created. + Application ''%parm[applicationName]%'' has been created. + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (80, 12, 'uei.opennms.org/internal/telemetry/illegalFlowDetected', 'Illegal flow detected', 'A flow was dropped due to the following reason: ''%parm[cause]%''', true, ' + uei.opennms.org/internal/telemetry/illegalFlowDetected + Illegal flow detected + A flow was dropped due to the following reason: ''%parm[cause]%'' + A flow (protocol ''%parm[protocol]%'') from exporter ''%interface%'' in location ''%parm[monitoringSystemLocation]%'' was detected and dropped by ''%parm[monitoringSystemId]%'' due to the following reason: ''%parm[cause]%''. + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (81, 13, 'uei.opennms.org/internal/topology/linkDown', 'OpenNMS-defined topology event: linkDown', '

node: %nodeid% with ifindex: %ifindex% is down

', true, ' + uei.opennms.org/internal/topology/linkDown + OpenNMS-defined topology event: linkDown + <p>node: %nodeid% with ifindex: %ifindex% is down </p> + + node: %nodeid% with ifindex: %ifindex% is down + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (82, 13, 'uei.opennms.org/internal/topology/linkUp', 'OpenNMS-defined topology event: linkUp', '

node: %nodeid% with ifindex: %ifindex% is up

', true, ' + uei.opennms.org/internal/topology/linkUp + OpenNMS-defined topology event: linkUp + <p>node: %nodeid% with ifindex: %ifindex% is up </p> + + node: %nodeid% with ifindex: %ifindex% is up + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (83, 14, 'uei.opennms.org/traps/eventTrap', 'OPENNMS-MIB defined trap event: eventTrap', '

This is the definition of the generic OpenNMS trap sent from the + scriptd process. Key variables are uei (which tells what type + of OpenNMS event this was), interface (the IP address of the interface + that caused the event) and severity.

+ + + + + + + + + + + + + + + + + + +
+ + dbid + %parm[#1]%;

+ + distPoller + %parm[#2]%;

+ + create-time + %parm[#3]%;

+ + master-station + %parm[#4]%;

+ + uei + %parm[#5]%;

+ + source + %parm[#6]%;

+ + nodeid + %parm[#7]%;

+ + time + %parm[#8]%;

+ + host + %parm[#9]%;

+ + interface + %parm[#10]%;

+ + snmphost + %parm[#11]%;

+ + service + %parm[#12]%;

+ + descr + %parm[#13]%;

+ + logmsg + %parm[#14]%;

+ + severity + %parm[#15]%;

+ + pathoutage + %parm[#16]%;

+ + operinst + %parm[#17]%;

+ + ifresolve + %parm[#18]%;

+ + nodelabel + %parm[#19]%;

', true, ' + + + id + .1.3.6.1.4.1.5813.1 + + + generic + 6 + + + specific + 1 + + + uei.opennms.org/traps/eventTrap + OPENNMS-MIB defined trap event: eventTrap + <p>This is the definition of the generic OpenNMS trap sent from the + scriptd process. Key variables are uei (which tells what type + of OpenNMS event this was), interface (the IP address of the interface + that caused the event) and severity.</p><table> + <tr><td><b> + + dbid</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + distPoller</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + create-time</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + master-station</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + uei</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr> + <tr><td><b> + + source</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + nodeid</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + time</b></td><td> + %parm[#8]%;</td><td><p></p></td></tr> + <tr><td><b> + + host</b></td><td> + %parm[#9]%;</td><td><p></p></td></tr> + <tr><td><b> + + interface</b></td><td> + %parm[#10]%;</td><td><p></p></td></tr> + <tr><td><b> + + snmphost</b></td><td> + %parm[#11]%;</td><td><p></p></td></tr> + <tr><td><b> + + service</b></td><td> + %parm[#12]%;</td><td><p></p></td></tr> + <tr><td><b> + + descr</b></td><td> + %parm[#13]%;</td><td><p></p></td></tr> + <tr><td><b> + + logmsg</b></td><td> + %parm[#14]%;</td><td><p></p></td></tr> + <tr><td><b> + + severity</b></td><td> + %parm[#15]%;</td><td><p></p></td></tr> + <tr><td><b> + + pathoutage</b></td><td> + %parm[#16]%;</td><td><p></p></td></tr> + <tr><td><b> + + operinst</b></td><td> + %parm[#17]%;</td><td><p></p></td></tr> + <tr><td><b> + + ifresolve</b></td><td> + %parm[#18]%;</td><td><p></p></td></tr> + <tr><td><b> + + nodelabel</b></td><td> + %parm[#19]%;</td><td><p></p></td></tr></table> + + <p>An OpenNMS Event has been received as an SNMP Trap + with UEI: %parm[#5]%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (84, 14, 'uei.opennms.org/traps/tl1AutonomousMessageTrap', 'OPENNMS-MIB defined trap event: tl1AutonomousMessageTrap', '

This trap is used to convey the contents of a TL1 autonomous message + received from a TL1 NE or a north-bound TL1 EMS. Managers receiving + this trap may need to perform additional analysis of its varbinds in + order to realize value from this trap.

+ + + + + + + + + + + + +
+ + nodeid + %parm[#1]%;

+ + time + %parm[#2]%;

+ + host + %parm[#3]%;

+ + interface + %parm[#4]%;

+ + service + %parm[#5]%;

+ + severity + %parm[#6]%;

+ + tl1amRawMessage + %parm[#7]%;

+ + tl1amAlarmCode + %parm[#8]%;

+ + tl1amAutonomousTag + %parm[#9]%;

+ + tl1amVerb + %parm[#10]%;

+ + tl1amAutoBlock + %parm[#11]%;

+ + tl1amAID + %parm[#12]%;

+ + tl1amAdditionalParams + %parm[#13]%;

', true, ' + + + id + .1.3.6.1.4.1.5813.1 + + + generic + 6 + + + specific + 2 + + + uei.opennms.org/traps/tl1AutonomousMessageTrap + OPENNMS-MIB defined trap event: tl1AutonomousMessageTrap + <p>This trap is used to convey the contents of a TL1 autonomous message + received from a TL1 NE or a north-bound TL1 EMS. Managers receiving + this trap may need to perform additional analysis of its varbinds in + order to realize value from this trap.</p><table> + <tr><td><b> + + nodeid</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + time</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + host</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + interface</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + service</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr> + <tr><td><b> + + severity</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + tl1amRawMessage</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + tl1amAlarmCode</b></td><td> + %parm[#8]%;</td><td><p></p></td></tr> + <tr><td><b> + + tl1amAutonomousTag</b></td><td> + %parm[#9]%;</td><td><p></p></td></tr> + <tr><td><b> + + tl1amVerb</b></td><td> + %parm[#10]%;</td><td><p></p></td></tr> + <tr><td><b> + + tl1amAutoBlock</b></td><td> + %parm[#11]%;</td><td><p></p></td></tr> + <tr><td><b> + + tl1amAID</b></td><td> + %parm[#12]%;</td><td><p></p></td></tr> + <tr><td><b> + + tl1amAdditionalParams</b></td><td> + %parm[#13]%;</td><td><p></p></td></tr></table> + <p> + tl1AutonomousMessageTrap trap received + nodeid=%parm[#1]% + time=%parm[#2]% + host=%parm[#3]% + interface=%parm[#4]% + service=%parm[#5]% + severity=%parm[#6]% + tl1amRawMessage=%parm[#7]% + tl1amAlarmCode=%parm[#8]% + tl1amAutonomousTag=%parm[#9]% + tl1amVerb=%parm[#10]% + tl1amAutoBlock=%parm[#11]% + tl1amAID=%parm[#12]% + tl1amAdditionalParams=%parm[#13]%</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (85, 14, 'uei.opennms.org/traps/alarmTrap', 'OPENNMS-MIB defined trap event: alarmTrap', '

The OpenNMS alarm SNMP Trap

+ + + + + + + + + + + + + + + + + + + + +
+ + dbid + %parm[#1]%;

+ + distPoller + %parm[#2]%;

+ + create-time + %parm[#3]%;

+ + master-station + %parm[#4]%;

+ + uei + %parm[#5]%;

+ + source + %parm[#6]%;

+ + nodeid + %parm[#7]%;

+ + time + %parm[#8]%;

+ + host + %parm[#9]%;

+ + interface + %parm[#10]%;

+ + snmphost + %parm[#11]%;

+ + service + %parm[#12]%;

+ + descr + %parm[#13]%;

+ + logmsg + %parm[#14]%;

+ + severity + %parm[#15]%;

+ + pathoutage + %parm[#16]%;

+ + operinst + %parm[#17]%;

+ + ifresolve + %parm[#18]%;

+ + nodelabel + %parm[#19]%;

+ + alarmId + %parm[#20]%;

+ + synchronizing + %parm[#21]%;

', true, ' + + + id + .1.3.6.1.4.1.5813.1 + + + generic + 6 + + + specific + 3 + + + uei.opennms.org/traps/alarmTrap + OPENNMS-MIB defined trap event: alarmTrap + <p>The OpenNMS alarm SNMP Trap</p><table> + <tr><td><b> + + dbid</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + distPoller</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + create-time</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + master-station</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + uei</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr> + <tr><td><b> + + source</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + nodeid</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + time</b></td><td> + %parm[#8]%;</td><td><p></p></td></tr> + <tr><td><b> + + host</b></td><td> + %parm[#9]%;</td><td><p></p></td></tr> + <tr><td><b> + + interface</b></td><td> + %parm[#10]%;</td><td><p></p></td></tr> + <tr><td><b> + + snmphost</b></td><td> + %parm[#11]%;</td><td><p></p></td></tr> + <tr><td><b> + + service</b></td><td> + %parm[#12]%;</td><td><p></p></td></tr> + <tr><td><b> + + descr</b></td><td> + %parm[#13]%;</td><td><p></p></td></tr> + <tr><td><b> + + logmsg</b></td><td> + %parm[#14]%;</td><td><p></p></td></tr> + <tr><td><b> + + severity</b></td><td> + %parm[#15]%;</td><td><p></p></td></tr> + <tr><td><b> + + pathoutage</b></td><td> + %parm[#16]%;</td><td><p></p></td></tr> + <tr><td><b> + + operinst</b></td><td> + %parm[#17]%;</td><td><p></p></td></tr> + <tr><td><b> + + ifresolve</b></td><td> + %parm[#18]%;</td><td><p></p></td></tr> + <tr><td><b> + + nodelabel</b></td><td> + %parm[#19]%;</td><td><p></p></td></tr> + <tr><td><b> + + alarmId</b></td><td> + %parm[#20]%;</td><td><p></p></td></tr> + <tr><td><b> + + synchronizing</b></td><td> + %parm[#21]%;</td><td><p></p></td></tr></table> + + <p>An OpenNMS Event has been received as an SNMP Trap + with UEI: %parm[#5]%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (86, 14, 'uei.opennms.org/traps/heartbeatTrap', 'OPENNMS-MIB defined trap event: heartbeatTrap', '

Trap sent periodically by OpenNMS to keep alive external SNMP Manager

', true, ' + + + id + .1.3.6.1.4.1.5813.1 + + + generic + 6 + + + specific + 4 + + + uei.opennms.org/traps/heartbeatTrap + OPENNMS-MIB defined trap event: heartbeatTrap + <p>Trap sent periodically by OpenNMS to keep alive external SNMP Manager</p><table></table> + <p> + heartbeatTrap trap received</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (87, 14, 'uei.opennms.org/traps/startSyncTrap', 'OPENNMS-MIB defined trap event: startSyncTrap', '

OpenNMS Synchronization Process is starting

', true, ' + + + id + .1.3.6.1.4.1.5813.1 + + + generic + 6 + + + specific + 5 + + + uei.opennms.org/traps/startSyncTrap + OPENNMS-MIB defined trap event: startSyncTrap + <p>OpenNMS Synchronization Process is starting</p><table></table> + <p> + startSyncTrap trap received</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (88, 14, 'uei.opennms.org/traps/endSyncTrap', 'OPENNMS-MIB defined trap event: endSyncTrap', '

OpenNMS Synchronization Process is successfully ended

', true, ' + + + id + .1.3.6.1.4.1.5813.1 + + + generic + 6 + + + specific + 6 + + + uei.opennms.org/traps/endSyncTrap + OPENNMS-MIB defined trap event: endSyncTrap + <p>OpenNMS Synchronization Process is successfully ended</p><table></table> + <p> + endSyncTrap trap received</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (89, 14, 'uei.opennms.org/traps/syncRequestTrap', 'OPENNMS-MIB defined trap event: syncRequestTrap', '

OpenNMS synchronization request

', true, ' + + + id + .1.3.6.1.4.1.5813.1 + + + generic + 6 + + + specific + 7 + + + uei.opennms.org/traps/syncRequestTrap + OPENNMS-MIB defined trap event: syncRequestTrap + <p>OpenNMS synchronization request</p><table></table> + <p> + syncRequestTrap trap received</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (90, 15, 'uei.opennms.org/internal/poller/outageCreated', 'OpenNMS-defined node event: outageCreated', '

A %service% outage was created on interface + %interface% because of the following condition: %parm[eventReason]%.

', true, ' + uei.opennms.org/internal/poller/outageCreated + OpenNMS-defined node event: outageCreated + <p>A %service% outage was created on interface + %interface% because of the following condition: %parm[eventReason]%.</p> + + %service% outage identified on interface %interface%. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (91, 15, 'uei.opennms.org/internal/poller/outageResolved', 'OpenNMS-defined node event: outageResolved', '

The %service% service outage on interface %interface% + has been restored.

', true, ' + uei.opennms.org/internal/poller/outageResolved + OpenNMS-defined node event: outageResolved + <p>The %service% service outage on interface %interface% + has been restored.</p> + + The %service% outage on interface %interface% has been + resolved. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (92, 15, 'uei.opennms.org/internal/poller/suspendPollingService', 'OpenNMS-defined poller event: suspendPollingService', '

A forced rescan has identified the %service% service + on interface %interface% as no longer part of any poller package, + or the service has been unmanaged. +

Polling will be discontinued.

', true, ' + uei.opennms.org/internal/poller/suspendPollingService + OpenNMS-defined poller event: suspendPollingService + <p>A forced rescan has identified the %service% service + on interface %interface% as no longer part of any poller package, + or the service has been unmanaged. + </p> Polling will be discontinued.</p> + + Polling will be discontinued for %service% service on interface + %interface%. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (93, 15, 'uei.opennms.org/internal/poller/resumePollingService', 'OpenNMS-defined poller event: resumePollingService', '

A forced rescan has identified the %service% service + on interface %interface% as covered by a poller package, and + managed. +

Polling will begin in accordance with the package and + any applicable outage calendar.

', true, ' + uei.opennms.org/internal/poller/resumePollingService + OpenNMS-defined poller event: resumePollingService + <p>A forced rescan has identified the %service% service + on interface %interface% as covered by a poller package, and + managed. + </p> Polling will begin in accordance with the package and + any applicable outage calendar.</p> + + Polling will begin/resume for %service% service on interface + %interface%. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (94, 15, 'uei.opennms.org/nodes/serviceUnmanaged', 'OpenNMS-defined internal event: serviceUnmanaged', '

The service %service% on interface %interface% is + being forcibly unmanaged.

', true, ' + uei.opennms.org/nodes/serviceUnmanaged + OpenNMS-defined internal event: serviceUnmanaged + <p>The service %service% on interface %interface% is + being forcibly unmanaged.</p> + + The service %service% on interface %interface% is being + forcibly unmanaged. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (95, 15, 'uei.opennms.org/nodes/deleteService', 'OpenNMS-defined node event: deleteService', '

Due to excessive downtime, the %service% service on + interface %interface% has been scheduled for + deletion.

When a service has been down + for one week, it is determined to have been removed and will + be deleted. If the service is later rediscovered, it will be + re-added and associated with the appropriate + interface.

If this is the only service + associated with an interface, the interface will be + scheduled for deletion as well, with the generation of the + deleteInterface event.

', true, ' + uei.opennms.org/nodes/deleteService + OpenNMS-defined node event: deleteService + <p>Due to excessive downtime, the %service% service on + interface %interface% has been scheduled for + deletion.</p> <p>When a service has been down + for one week, it is determined to have been removed and will + be deleted. If the service is later rediscovered, it will be + re-added and associated with the appropriate + interface.</p> <p>If this is the only service + associated with an interface, the interface will be + scheduled for deletion as well, with the generation of the + deleteInterface event.</p> + + The %service% service on interface %interface% has been + scheduled for deletion. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (96, 15, 'uei.opennms.org/nodes/duplicateNodeDeleted', 'OpenNMS-defined node event: duplicateNodeDeleted', '

Node :%nodeid% labled: %nodelabel%; was determined to be a + duplicate node and is has been deleted.

', true, ' + uei.opennms.org/nodes/duplicateNodeDeleted + OpenNMS-defined node event: duplicateNodeDeleted + <p>Node :%nodeid% labled: %nodelabel%; was determined to be a + duplicate node and is has been deleted.</p> + + <p>Node #<a + href="element/node.jsp?node=%nodeid%">%nodeid%</a> + was determined to be a duplicate node and is being flagged + for deletion.</p> + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (97, 15, 'uei.opennms.org/nodes/interfaceDeleted', 'OpenNMS-defined node event: interfaceDeleted', '

Interface %interface% deleted from node # + %nodeid% with ifIndex %ifindex%.

This event is + generated following an extended outage for a service, in + which that service is the only service associated with an + interface. If the service is later rediscovered, a new + interface will be added and the service will be associated + with that new interface.

', true, ' + uei.opennms.org/nodes/interfaceDeleted + OpenNMS-defined node event: interfaceDeleted + <p>Interface %interface% deleted from node #<a + href="element/node.jsp?node=%nodeid%"> + %nodeid%</a> with ifIndex %ifindex%.</p> <p>This event is + generated following an extended outage for a service, in + which that service is the only service associated with an + interface. If the service is later rediscovered, a new + interface will be added and the service will be associated + with that new interface.</p> + + Interface %interface% deleted from node #<a + href="element/node.jsp?node=%nodeid%">%nodeid%</a> + with ifIndex %ifindex%. + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (98, 15, 'uei.opennms.org/nodes/interfaceDown', 'OpenNMS-defined node event: interfaceDown', '

All services are down on interface %interface% +

This event is generated when node outage + processing determines that the critical service or all + services on the interface are now down

+ New outage records have been created and service level + availability calculations will be impacted until this outage + is resolved.

', true, ' + uei.opennms.org/nodes/interfaceDown + OpenNMS-defined node event: interfaceDown + <p>All services are down on interface %interface% + </p> <p>This event is generated when node outage + processing determines that the critical service or all + services on the interface are now down </p> <p> + New outage records have been created and service level + availability calculations will be impacted until this outage + is resolved.</p> + + Interface %interface% is down. + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (99, 15, 'uei.opennms.org/nodes/snmp/interfaceOperDown', 'OpenNMS-defined node event: snmp interface Oper Status Down', '

The operational status of interface is down +

This event is generated when an snmp poll on interface find the operational status down. +

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceOperDown + OpenNMS-defined node event: snmp interface Oper Status Down + <p>The operational status of interface is down + </p> <p>This event is generated when an snmp poll on interface find the operational status down. + </p> + <p>Params %parm[all]% </p> + Operational status Down on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Minor + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (100, 15, 'uei.opennms.org/nodes/snmp/interfaceOperTesting', 'OpenNMS-defined node event: snmp interface Oper Status Testing', '

The operational status of interface is testing +

This event is generated when an snmp poll on interface find the operational status testing. +

The testing state indicates that some tests must be performed on the interface. Once completed + the state may change to up, dormant, or down, as appropriate.

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceOperTesting + OpenNMS-defined node event: snmp interface Oper Status Testing + <p>The operational status of interface is testing + </p> <p>This event is generated when an snmp poll on interface find the operational status testing. + </p><p>The testing state indicates that some tests must be performed on the interface. Once completed + the state may change to up, dormant, or down, as appropriate.</p> + <p>Params %parm[all]% </p> + Operational status Testing on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Warning + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (101, 15, 'uei.opennms.org/nodes/snmp/interfaceOperUnknown', 'OpenNMS-defined node event: snmp interface Oper Status Unknown', '

The operational status of interface is unknown +

This event is generated when an snmp poll on interface find the operational status unknown. +

The unknown state indicates that the state of the interface can not be + ascertained.

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceOperUnknown + OpenNMS-defined node event: snmp interface Oper Status Unknown + <p>The operational status of interface is unknown + </p> <p>This event is generated when an snmp poll on interface find the operational status unknown. + </p> <p>The unknown state indicates that the state of the interface can not be + ascertained.</p> + <p>Params %parm[all]% </p> + Operational status Unknown on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Minor + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (102, 15, 'uei.opennms.org/nodes/snmp/interfaceOperDormant', 'OpenNMS-defined node event: snmp interface Oper Status Dormant', '

The operational status of interface is dormant +

This event is generated when an snmp poll on interface find the operational status dormant. +

The dormant state indicates that the relevant interface is not actually in a condition + to pass packets but is in a pending state, waiting for some external event.

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceOperDormant + OpenNMS-defined node event: snmp interface Oper Status Dormant + <p>The operational status of interface is dormant + </p> <p>This event is generated when an snmp poll on interface find the operational status dormant. + </p><p>The dormant state indicates that the relevant interface is not actually in a condition + to pass packets but is in a pending state, waiting for some external event.</p> + <p>Params %parm[all]% </p> + Operational status Dormant on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Warning + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (103, 15, 'uei.opennms.org/nodes/snmp/interfaceOperNotPresent', 'OpenNMS-defined node event: snmp interface Oper Status Not Present', '

The operational status of interface is not present +

This event is generated when an snmp poll on interface find the operational status not present. +

The not present state indicates that the interface is down specifically because + some component, typically a hardware component, is not present in the managed system.

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceOperNotPresent + OpenNMS-defined node event: snmp interface Oper Status Not Present + <p>The operational status of interface is not present + </p> <p>This event is generated when an snmp poll on interface find the operational status not present. + </p> <p>The not present state indicates that the interface is down specifically because + some component, typically a hardware component, is not present in the managed system.</p> + <p>Params %parm[all]% </p> + Operational status Not Present on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Minor + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (104, 15, 'uei.opennms.org/nodes/snmp/interfaceOperLowerLayerDown', 'OpenNMS-defined node event: snmp interface Oper Status Lower Layer Down', '

The operational status of interface is lower layer down +

This event is generated when an snmp poll on interface find the operational status lower layer down. +

The lower layer down state indicates that this interface runs on top of one or + more other interfaces and that this interface is down specifically because one or more of these + lower-layer interfaces are down.

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceOperLowerLayerDown + OpenNMS-defined node event: snmp interface Oper Status Lower Layer Down + <p>The operational status of interface is lower layer down + </p> <p>This event is generated when an snmp poll on interface find the operational status lower layer down. + </p> <p>The lower layer down state indicates that this interface runs on top of one or + more other interfaces and that this interface is down specifically because one or more of these + lower-layer interfaces are down.</p> + <p>Params %parm[all]% </p> + Operational status Lower Layer Down on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Minor + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (105, 15, 'uei.opennms.org/nodes/snmp/interfaceAdminDown', 'OpenNMS-defined node event: snmp interface Admin Status Down', '

The administration status of interface is down +

This event is generated when an snmp poll on interface find the administration status + down. +

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceAdminDown + OpenNMS-defined node event: snmp interface Admin Status Down + <p>The administration status of interface is down + </p> <p>This event is generated when an snmp poll on interface find the administration status + down. + </p> + <p>Params %parm[all]% </p> + Administration status Down on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (106, 15, 'uei.opennms.org/nodes/interfaceReparented', 'OpenNMS-defined node event: interfaceReparented', '

Interface %interface% has been reparented under + node %parm[newNodeID]% from node + %parm[oldNodeID]%.

Usually this happens + after a services scan discovers that a node with multiple + interfaces is now running an SNMP agent and is therefore + able to reparent the node''s interfaces under a single node + identifier.

This is typically not a + reason for concern, but you should be aware that the node + association of this interface has changed.

', true, ' + uei.opennms.org/nodes/interfaceReparented + OpenNMS-defined node event: interfaceReparented + <p>Interface %interface% has been reparented under + node %parm[newNodeID]% from node + %parm[oldNodeID]%.</p> <p>Usually this happens + after a services scan discovers that a node with multiple + interfaces is now running an SNMP agent and is therefore + able to reparent the node''s interfaces under a single node + identifier.</p> <p>This is typically not a + reason for concern, but you should be aware that the node + association of this interface has changed.</p> + + %interface% has been reparented under node %parm[newNodeID]% + from node %parm[oldNodeID]%. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (107, 15, 'uei.opennms.org/nodes/interfaceUp', 'OpenNMS-defined node event: interfaceUp', '

The interface %interface% which was previously down + is now up.

This event is generated when + node outage processing determines that the critical service + or all services on the interface are restored.

+

This event will cause any active outages associated + with this interface to be cleared.

', true, ' + uei.opennms.org/nodes/interfaceUp + OpenNMS-defined node event: interfaceUp + <p>The interface %interface% which was previously down + is now up.</p> <p>This event is generated when + node outage processing determines that the critical service + or all services on the interface are restored. </p> + <p>This event will cause any active outages associated + with this interface to be cleared.</p> + + Interface %interface% is up. + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (108, 15, 'uei.opennms.org/nodes/snmp/interfaceOperUp', 'OpenNMS-defined node event: snmp interface Oper Status Up', '

The operational status of interface is up +

This event is generated when an snmp poll on interface find the operational status up. +

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceOperUp + OpenNMS-defined node event: snmp interface Oper Status Up + <p>The operational status of interface is up + </p> <p>This event is generated when an snmp poll on interface find the operational status up. + </p> + <p>Params %parm[all]% </p> + Operational status Up on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (109, 15, 'uei.opennms.org/nodes/snmp/interfaceAdminUp', 'OpenNMS-defined node event: snmp interface Admin Status Up', '

The administration status of interface is down +

This event is generated when an snmp poll on interface find the administration status + up. +

+

Params %parm[all]%

', true, ' + uei.opennms.org/nodes/snmp/interfaceAdminUp + OpenNMS-defined node event: snmp interface Admin Status Up + <p>The administration status of interface is down + </p> <p>This event is generated when an snmp poll on interface find the administration status + up. + </p> + <p>Params %parm[all]% </p> + Administration status Up on interface ifname:%parm[snmpifname]% + ifindex:%parm[snmpifindex]% ifdescr:%parm[snmpifdescr]% + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (110, 15, 'uei.opennms.org/nodes/nodeAdded', 'OpenNMS-defined node event: nodeAdded', 'The node "%parm[nodelabel]%" was added and is now being monitored.', true, ' + uei.opennms.org/nodes/nodeAdded + OpenNMS-defined node event: nodeAdded + The node "%parm[nodelabel]%" was added and is now being monitored. + A new node "%parm[nodelabel]%" was added. + Warning + This event is for information only. Please make sure that the newly added device <a href="element/node.jsp?node=%nodeid%">"%parm[nodelabel]%"</a> is monitored as desired. +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (111, 15, 'uei.opennms.org/nodes/nodeUpdated', 'OpenNMS-defined node event: nodeUpdated', '

A currently provisioned node (%parm[nodelabel]%) was updated by + OpenNMS.

', true, ' + uei.opennms.org/nodes/nodeUpdated + OpenNMS-defined node event: nodeUpdated + <p>A currently provisioned node (%parm[nodelabel]%) was updated by + OpenNMS.</p> + + A provisioned node (%parm[nodelabel]%) was updated by OpenNMS. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (112, 15, 'uei.opennms.org/nodes/nodeLocationChanged', 'OpenNMS-defined node event: nodeLocationChanged', '

A currently provisioned node (%parm[nodelabel]%) changed its + location from (%parm[nodePrevLocation]%) to (%parm[nodeCurrentLocation]%).

', true, ' + uei.opennms.org/nodes/nodeLocationChanged + OpenNMS-defined node event: nodeLocationChanged + <p>A currently provisioned node (%parm[nodelabel]%) changed its + location from (%parm[nodePrevLocation]%) to (%parm[nodeCurrentLocation]%).</p> + + A provisioned node (%parm[nodelabel]%) changed its location to (%parm[nodeCurrentLocation]%). + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (113, 15, 'uei.opennms.org/nodes/nodeCategoryMembershipChanged', 'OpenNMS-defined node event: nodeCategoryMembershipChanged', '

Node (%parm[nodelabel]%) has changed its Category + membership and deleted (%parm[categoriesDeleted]%) and added (%parm[categoriesAdded]%).

', true, ' + uei.opennms.org/nodes/nodeCategoryMembershipChanged + OpenNMS-defined node event: nodeCategoryMembershipChanged + <p>Node (%parm[nodelabel]%) has changed its Category + membership and deleted (%parm[categoriesDeleted]%) and added (%parm[categoriesAdded]%).</p> + + Node category membership has changed for node (%parm[nodelabel]%). + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (114, 15, 'uei.opennms.org/nodes/nodeDeleted', 'OpenNMS-defined node event: nodeDeleted', '

%parm[nodelabel]% (%parm[foreignSource]%:%parm[foreignId]%) in location %parm[location]% was deleted from requisition %parm[foreignSource]%.

+

This can have multiple reasons. +

    +
  • It was removed from the corresponding requisition %parm[foreignSource]%. This can be done manually using the web UI or using provisiond import schedules.
  • +
  • It was manually deleted using the "Delete nodes" entry in the Admin menu.
  • +
  • It was removed using the ReST API
  • +
+ Operator Instructions:
+ Please verify if the deletion was planned.

', true, ' + uei.opennms.org/nodes/nodeDeleted + OpenNMS-defined node event: nodeDeleted + <p>%parm[nodelabel]% (%parm[foreignSource]%:%parm[foreignId]%) in location %parm[location]% was deleted from requisition %parm[foreignSource]%.</p> + <p>This can have multiple reasons. + <ul> + <li>It was removed from the corresponding requisition %parm[foreignSource]%. This can be done manually using the web UI or using provisiond import schedules.</li> + <li>It was manually deleted using the "Delete nodes" entry in the Admin menu.</li> + <li>It was removed using the ReST API</li> + </ul> + Operator Instructions:<br/> + Please verify if the deletion was planned.</p> + + Node %parm[nodelabel]% (%nodeid%) was deleted. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (115, 15, 'uei.opennms.org/nodes/nodeDown', 'OpenNMS-defined node event: nodeDown', '

All interfaces on node %parm[nodelabel]% are + down because of the following condition: %parm[eventReason]%.

+ This event is generated when node outage processing determines + that all interfaces on the node are down.

+ New outage records have been created and service level + availability calculations will be impacted until this outage + is resolved.

', true, ' + uei.opennms.org/nodes/nodeDown + OpenNMS-defined node event: nodeDown + <p>All interfaces on node %parm[nodelabel]% are + down because of the following condition: %parm[eventReason]%.</p> <p> + This event is generated when node outage processing determines + that all interfaces on the node are down.</p> <p> + New outage records have been created and service level + availability calculations will be impacted until this outage + is resolved.</p> + + Node %parm[nodelabel]% is down. + + Major + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (116, 15, 'uei.opennms.org/nodes/pathOutage', 'OpenNMS-defined node event: pathOutage', '

The state of node %parm[nodelabel]% is unknown + because the critical path to the node is down.

+

This event is generated when node outage processing + determines that the critical path IP address/service for + this node is not responding..

', true, ' + uei.opennms.org/nodes/pathOutage + OpenNMS-defined node event: pathOutage + <p>The state of node %parm[nodelabel]% is unknown + because the critical path to the node is down.</p> + <p>This event is generated when node outage processing + determines that the critical path IP address/service for + this node is not responding..</p> + + %parm[nodelabel]% path outage. Critical path = + %parm[criticalPathIp]% %parm[criticalPathServiceName]% + + Major + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (117, 15, 'uei.opennms.org/nodes/nodeGainedInterface', 'OpenNMS-defined node event: nodeGainedInterface', '

Interface %interface% has been associated with Node + #%nodeid%.

', true, ' + uei.opennms.org/nodes/nodeGainedInterface + OpenNMS-defined node event: nodeGainedInterface + <p>Interface %interface% has been associated with Node + #<a + href="element/node.jsp?node=%nodeid%">%nodeid%</a>.</p> + + Interface %interface% has been associated with Node #<a + href="element/node.jsp?node=%nodeid%">%nodeid%</a>. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (118, 15, 'uei.opennms.org/nodes/nodeGainedService', 'OpenNMS-defined node event: nodeGainedService', '

A service scan has identified the %service% service + on interface %interface%.

If this + interface (%interface%) is within the list of ranges and + specific addresses to be managed by OpenNMS, this service + will be scheduled for regular availability checks.

', true, ' + uei.opennms.org/nodes/nodeGainedService + OpenNMS-defined node event: nodeGainedService + <p>A service scan has identified the %service% service + on interface %interface%.</p> <p>If this + interface (%interface%) is within the list of ranges and + specific addresses to be managed by OpenNMS, this service + will be scheduled for regular availability checks.</p> + + The %service% service has been discovered on interface + %interface%. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (119, 15, 'uei.opennms.org/nodes/nodeInfoChanged', 'OpenNMS-defined node event: nodeInfoChanged', '

Node information has changed for node + #%nodeid%.

', true, ' + uei.opennms.org/nodes/nodeInfoChanged + OpenNMS-defined node event: nodeInfoChanged + <p>Node information has changed for node + #%nodeid%.</p> + + <p>Node information has changed for <a + href="element/node.jsp?node=%nodeid%">%nodeid%</a>.</p> + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (120, 15, 'uei.opennms.org/nodes/nodeLabelChanged', 'OpenNMS-defined node event: nodeLabelChanged', '

Node #%nodeid%''s + label was changed from "%parm[oldNodeLabel]%" to + "%parm[newNodeLabel]%".

', true, ' + uei.opennms.org/nodes/nodeLabelChanged + OpenNMS-defined node event: nodeLabelChanged + <p>Node #<a + href="element/node.jsp?node=%nodeid%">%nodeid%</a>''s + label was changed from "%parm[oldNodeLabel]%" to + "%parm[newNodeLabel]%".</p> + + Node #<a + href="element/node.jsp?node=%nodeid%">%nodeid%</a>''s + label was changed from "%parm[oldNodeLabel]%" to + "%parm[newNodeLabel]%". + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (121, 15, 'uei.opennms.org/nodes/nodeLostService', 'OpenNMS-defined node event: nodeLostService', '

A %service% outage was identified on interface + %interface% because of the following condition: %parm[eventReason]%.

+ A new Outage record has been created and service level + availability calculations will be impacted until this outage is + resolved.

', true, ' + uei.opennms.org/nodes/nodeLostService + OpenNMS-defined node event: nodeLostService + <p>A %service% outage was identified on interface + %interface% because of the following condition: %parm[eventReason]%.</p> <p> + A new Outage record has been created and service level + availability calculations will be impacted until this outage is + resolved.</p> + + %service% outage identified on interface %interface%. + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (122, 15, 'uei.opennms.org/nodes/nodeRegainedService', 'OpenNMS-defined node event: nodeRegainedService', '

The %service% service on interface %interface% was + previously down and has been restored.

+

This event is generated when a service which had + previously failed polling attempts is again responding to + polls by OpenNMS.

This event will cause + any active outages associated with this service/interface + combination to be cleared.

', true, ' + uei.opennms.org/nodes/nodeRegainedService + OpenNMS-defined node event: nodeRegainedService + <p>The %service% service on interface %interface% was + previously down and has been restored.</p> + <p>This event is generated when a service which had + previously failed polling attempts is again responding to + polls by OpenNMS. </p> <p>This event will cause + any active outages associated with this service/interface + combination to be cleared.</p> + + The %service% outage on interface %interface% has been + cleared. Service is restored. + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (123, 15, 'uei.opennms.org/nodes/nodeUp', 'OpenNMS-defined node event: nodeUp', '

Node %parm[nodelabel]% which was previously down is + now up.

This event is generated when node + outage processing determines that all interfaces on the node + are up.

This event will cause any active + outages associated with this node to be cleared.

', true, ' + uei.opennms.org/nodes/nodeUp + OpenNMS-defined node event: nodeUp + <p>Node %parm[nodelabel]% which was previously down is + now up.</p> <p>This event is generated when node + outage processing determines that all interfaces on the node + are up.</p> <p>This event will cause any active + outages associated with this node to be cleared.</p> + + Node %parm[nodelabel]% is up. + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (124, 15, 'uei.opennms.org/nodes/primarySnmpInterfaceChanged', 'OpenNMS-defined node event: primarySnmpInterfaceChanged', '

This event indicates that the interface selected + for SNMP data collection for this node has changed. This is + usually due to a network or address reconfiguration + impacting this device.

', true, ' + uei.opennms.org/nodes/primarySnmpInterfaceChanged + OpenNMS-defined node event: primarySnmpInterfaceChanged + <p>This event indicates that the interface selected + for SNMP data collection for this node has changed. This is + usually due to a network or address reconfiguration + impacting this device.</p> + + Primary SNMP interface for node <a + href="element/node.jsp?node=%nodeid%">%nodeid%</a> + has changed from %parm[oldPrimarySnmpAddress]% to + %parm[newPrimarySnmpAddress]%. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (125, 15, 'uei.opennms.org/nodes/reinitializePrimarySnmpInterface', 'OpenNMS-defined node event: reinitializePrimarySnmpInterface', '

A change in configuration on this node has been + detected and the SNMP data collection mechanism is being + triggered to refresh its required profile of the remote + node.

', true, ' + uei.opennms.org/nodes/reinitializePrimarySnmpInterface + OpenNMS-defined node event: reinitializePrimarySnmpInterface + <p>A change in configuration on this node has been + detected and the SNMP data collection mechanism is being + triggered to refresh its required profile of the remote + node.</p> + + SNMP information on %interface% is being refreshed for data + collection purposes. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (126, 15, 'uei.opennms.org/nodes/serviceResponsive', 'OpenNMS-defined node event: serviceResponsive', '

The %service% service which was previously unresponsive + is now responding normally on interface %interface%.

', true, ' + uei.opennms.org/nodes/serviceResponsive + OpenNMS-defined node event: serviceResponsive + <p>The %service% service which was previously unresponsive + is now responding normally on interface %interface%.</p> + + %service% is responding normally on interface %interface%. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (127, 15, 'uei.opennms.org/nodes/serviceDeleted', 'OpenNMS-defined node event: serviceDeleted', '

Service %service% was deleted from interface + %interface%, associated with Node ID# %nodeid%.

+

When a service is deleted from an interface, it is + due to extended downtime model configured in pollerd + configuration.

If a previously deleted service + becomes active again on an interface, it will be re-added to + the OpenNMS database as a new occurrence of that service and + will be disassociated with any historic outages.

', true, ' + uei.opennms.org/nodes/serviceDeleted + OpenNMS-defined node event: serviceDeleted + <p>Service %service% was deleted from interface + %interface%, associated with Node ID# %nodeid%.</p> + <p>When a service is deleted from an interface, it is + due to extended downtime model configured in pollerd + configuration.</p> <p>If a previously deleted service + becomes active again on an interface, it will be re-added to + the OpenNMS database as a new occurrence of that service and + will be disassociated with any historic outages.</p> + + The %service% service was deleted from interface + %interface%. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (128, 15, 'uei.opennms.org/nodes/serviceUnresponsive', 'OpenNMS-defined node event: serviceUnresponsive', '

The %service% service is up but was unresponsive + during the last poll on interface %interface%.

', true, ' + uei.opennms.org/nodes/serviceUnresponsive + OpenNMS-defined node event: serviceUnresponsive + <p>The %service% service is up but was unresponsive + during the last poll on interface %interface%.</p> + + %service% is up but unresponsive on interface %interface%. + + Minor +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (129, 15, 'uei.opennms.org/nodes/assetInfoChanged', 'OpenNMS-defined node event: assetInfoChanged', '

The Asset info for node %nodeid% (%nodelabel%) + has been changed via the webUI.

', true, ' + uei.opennms.org/nodes/assetInfoChanged + OpenNMS-defined node event: assetInfoChanged + <p>The Asset info for node %nodeid% (%nodelabel%) + has been changed via the webUI.</p> + + <p>The Asset info for node %nodeid% (%nodelabel%) + has been changed via the webUI.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (130, 15, 'uei.opennms.org/deviceconfig/configBackupStarted', 'OpenNMS-defined node event: configBackupStarted', '

Config backup started on %service% + during the last poll on interface %interface%.

', true, ' + uei.opennms.org/deviceconfig/configBackupStarted + OpenNMS-defined node event: configBackupStarted + <p>Config backup started on %service% + during the last poll on interface %interface%.</p> + + %service% config backup started on interface %interface%. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (131, 15, 'uei.opennms.org/deviceconfig/configBackupFailed', 'OpenNMS-defined node event: configBackupFailed', '

Failed to backup config associated with %service% + during the last poll on interface %interface% because of + the following condition: %parm[eventReason]%.

', true, ' + uei.opennms.org/deviceconfig/configBackupFailed + OpenNMS-defined node event: configBackupFailed + <p>Failed to backup config associated with %service% + during the last poll on interface %interface% because of + the following condition: %parm[eventReason]%.</p> + + %service% config backup failed on interface %interface%. + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (132, 15, 'uei.opennms.org/deviceconfig/configBackupSucceeded', 'OpenNMS-defined node event: configBackupSucceeded', '

Config backup succeeded on %service% + during the last poll on interface %interface%.

', true, ' + uei.opennms.org/deviceconfig/configBackupSucceeded + OpenNMS-defined node event: configBackupSucceeded + <p>Config backup succeeded on %service% + during the last poll on interface %interface%.</p> + + %service% config backup succeeded on interface %interface%. + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (133, 16, 'uei.opennms.org/provisioner/provisioningAdapterFailed', 'OpenNMS-defined Provisioning Adapter Failed message', 'A provisioning adapter failed for host %host% with the following condition: %parm[reason]%.

', true, ' + uei.opennms.org/provisioner/provisioningAdapterFailed + OpenNMS-defined Provisioning Adapter Failed message + A provisioning adapter failed for host %host% with the following condition: %parm[reason]%.<p> + + <p>A provisioning adapter failed for host.</p> + + Major + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (134, 16, 'uei.opennms.org/internal/provisiond/scheduledNodeScanStarted', 'OpenNMS-defined Provisiond Event: scheduledNodeScanStarted', 'A message from the Provisiond NodeScan lifecycle that a scheduled NodeScan has started: +

The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + started scheduled Node Scan.

', true, ' + uei.opennms.org/internal/provisiond/scheduledNodeScanStarted + OpenNMS-defined Provisiond Event: scheduledNodeScanStarted + A message from the Provisiond NodeScan lifecycle that a scheduled NodeScan has started: + <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + started scheduled Node Scan. </p> + + <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + started scheduled scan.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (135, 16, 'uei.opennms.org/internal/provisiond/nodeScanCompleted', 'OpenNMS-defined Provisiond Event: nodeScanCompleted', 'A message from the Provisiond NodeScan lifecycle that a NodeScan has completed: +

The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + completed.

+ Typically the result of a request of an import request or a scheduled/user forced rescan.', true, ' + uei.opennms.org/internal/provisiond/nodeScanCompleted + OpenNMS-defined Provisiond Event: nodeScanCompleted + A message from the Provisiond NodeScan lifecycle that a NodeScan has completed: + <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + completed.</p> + Typically the result of a request of an import request or a scheduled/user forced rescan. + + <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + completed.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (136, 16, 'uei.opennms.org/internal/provisiond/nodeScanAborted', 'OpenNMS-defined Provisiond Event: nodeScanAborted', 'A message from the Provisiond NodeScan lifecycle that a NodeScan has Aborted: +

The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + aborted for the following reason: %parm[reason]%

', true, ' + uei.opennms.org/internal/provisiond/nodeScanAborted + OpenNMS-defined Provisiond Event: nodeScanAborted + A message from the Provisiond NodeScan lifecycle that a NodeScan has Aborted: + <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + aborted for the following reason: %parm[reason]% </p> + + <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has + aborted.</p> + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (137, 16, 'uei.opennms.org/internal/importer/reloadImport', 'OpenNMS-defined internal event: importer reloadImport', '

This event will cause the importer to run the model-import process. + The parameters include foreignSource, url, and deleteThreshold that override + configuration properties as well as XML and default values.

', true, ' + uei.opennms.org/internal/importer/reloadImport + OpenNMS-defined internal event: importer reloadImport + <p>This event will cause the importer to run the model-import process. + The parameters include foreignSource, url, and deleteThreshold that override + configuration properties as well as XML and default values.</p> + + <p>A request had been made to run the model-import process with the + parms: %parm[all]%.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (138, 16, 'uei.opennms.org/internal/importer/importStarted', 'OpenNMS-defined internal event: importer process has started', '

This event indicates the model-importer process has started

', true, ' + uei.opennms.org/internal/importer/importStarted + OpenNMS-defined internal event: importer process has started + <p>This event indicates the model-importer process has started</p> + + <p>This event indicates the model-importer process has started from resource: %parm[importResource]% + </p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (139, 16, 'uei.opennms.org/internal/importer/importSuccessful', 'OpenNMS-defined internal event: importer process successfully completed', '

This event indicates the model-importer process has completed successfully. There + is 1 parameter called importStats: %parm[importStats]%

', true, ' + uei.opennms.org/internal/importer/importSuccessful + OpenNMS-defined internal event: importer process successfully completed + <p>This event indicates the model-importer process has completed successfully. There + is 1 parameter called importStats: %parm[importStats]%</p> + + <p>This event indicates the model-importer process has completed successfully from resource: + %parm[importResource]%</p> + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (140, 16, 'uei.opennms.org/internal/importer/importFailed', 'OpenNMS-defined internal event: importer process failed.', '

This event indicates the model-importer process has failed. There is 1 parameter + called failureMessage: %parm[failureMessage]%

', true, ' + uei.opennms.org/internal/importer/importFailed + OpenNMS-defined internal event: importer process failed. + <p>This event indicates the model-importer process has failed. There is 1 parameter + called failureMessage: %parm[failureMessage]%</p> + + <p>This event indicates the model-importer process has failed from resource: %parm[importResource]%</p> + + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (141, 17, 'uei.opennms.org/circuitBreaker/stateChange', 'OpenNMS-defined event: Circuit breaker has changed state', 'A cirtcuit breaker named %parm[name]% on %dpname% has changed state from %parm[fromState]% to %parm[toState]%.', true, ' + + + parm[toState] + ~OPEN|HALF_OPEN|FORCED_OPEN + + + uei.opennms.org/circuitBreaker/stateChange + OpenNMS-defined event: Circuit breaker has changed state + A cirtcuit breaker named %parm[name]% on %dpname% has changed state from %parm[fromState]% to %parm[toState]%. + Circuit breaker %parm[name]% on %dpname% changed state to %parm[toState]% + Warning + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (142, 17, 'uei.opennms.org/circuitBreaker/stateChange', 'OpenNMS-defined event: Circuit breaker has changed state', 'A cirtcuit breaker named %parm[name]% on %dpname% has changed state from %parm[fromState]% to %parm[toState]%.', true, ' + + + parm[toState] + ~CLOSED|DISABLED + + + uei.opennms.org/circuitBreaker/stateChange + OpenNMS-defined event: Circuit breaker has changed state + A cirtcuit breaker named %parm[name]% on %dpname% has changed state from %parm[fromState]% to %parm[toState]%. + Circuit breaker %parm[name]% on %dpname% changed state to: %parm[toState]% + Normal + + + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (143, 18, 'uei.opennms.org/perspective/nodes/nodeLostService', 'OpenNMS-defined perspective poller event: A perspective poller detected a node lost service', '

A %service% outage was identified on interface %interface% from location: %parm[perspective]%.

', true, ' + uei.opennms.org/perspective/nodes/nodeLostService + OpenNMS-defined perspective poller event: A perspective poller detected a node lost service + <p>A %service% outage was identified on interface %interface% from location: %parm[perspective]%.</p> + + %service% outage identified on interface %interface% from location %parm[perspective]% with reason code: %parm[eventReason]%. + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (144, 18, 'uei.opennms.org/perspective/nodes/nodeRegainedService', 'OpenNMS-defined perspective poller event: A perspective poller detected a node regained service', '

The %service% service on interface %interface% was previously down from %parm[perspective]%.

+

This event is generated when a service which had previously failed polling attempts is again responding to polls by OpenNMS.

', true, ' + uei.opennms.org/perspective/nodes/nodeRegainedService + OpenNMS-defined perspective poller event: A perspective poller detected a node regained service + <p>The %service% service on interface %interface% was previously down from %parm[perspective]%.</p> + <p>This event is generated when a service which had previously failed polling attempts is again responding to polls by OpenNMS. </p> + + %service% outage identified on interface %interface% from location %parm[perspective]% has cleared. + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (145, 19, 'uei.opennms.org/reportd/reportRunFailed', 'OpenNMS-defined Reportd Event: reportRunFailed', 'A message from the Reportd reporting service that a report has failed to run: +

The report with name %parm[reportName]% failed to run for the following reason: %parm[reason]%

', true, ' + uei.opennms.org/reportd/reportRunFailed + OpenNMS-defined Reportd Event: reportRunFailed + A message from the Reportd reporting service that a report has failed to run: + <p>The report with name %parm[reportName]% failed to run for the following reason: %parm[reason]% </p> + + <p>The report with name %parm[reportName]% failed to run.</p> + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (146, 19, 'uei.opennms.org/reportd/reportDeliveryFailed', 'OpenNMS-defined Reportd Event: reportDeliveryFailed', 'A message from the Reportd delivery service that a report could not be delivered: +

The report with name %parm[reportName]% could not be delivered for the following reason: + %parm[reason]%

', true, ' + uei.opennms.org/reportd/reportDeliveryFailed + OpenNMS-defined Reportd Event: reportDeliveryFailed + A message from the Reportd delivery service that a report could not be delivered: + <p>The report with name %parm[reportName]% could not be delivered for the following reason: + %parm[reason]% </p> + + <p>The report with name %parm[reportName]% could not be delivered.</p> + + Minor + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (147, 20, 'DISCARD-MATCHING-MESSAGES', 'OpenNMS-defined DISCARD-MATCHING-MESSAGES', 'DISCARD-MATCHING-MESSAGES is used in the syslogd to generate events that + have no matching events. This event is not persisted by default.', true, ' + DISCARD-MATCHING-MESSAGES + OpenNMS-defined DISCARD-MATCHING-MESSAGES + DISCARD-MATCHING-MESSAGES is used in the syslogd to generate events that + have no matching events. This event is not persisted by default. + + <p>DISCARD-MATCHING-MESSAGES.</p> + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (148, 21, 'uei.opennms.org/troubleTicket/create', 'OpenNMS-defined trouble ticket event: A request has been made to create a trouble ticket', 'This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for creating a new trouble ticket.', true, ' + uei.opennms.org/troubleTicket/create + OpenNMS-defined trouble ticket event: A request has been made to create a trouble ticket + This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for creating a new trouble ticket. + + A request has been generated to create a trouble ticket. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (149, 21, 'uei.opennms.org/troubleTicket/update', 'OpenNMS-defined trouble ticket event: A request has been made to update a trouble ticket', 'This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for updating an existing trouble ticket.', true, ' + uei.opennms.org/troubleTicket/update + OpenNMS-defined trouble ticket event: A request has been made to update a trouble ticket + This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for updating an existing trouble ticket. + + A request has been generated to update a trouble ticket. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (150, 21, 'uei.opennms.org/troubleTicket/close', 'OpenNMS-defined trouble ticket event: A request has been made to close a trouble ticket', 'This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for closing an existing trouble ticket.', true, ' + uei.opennms.org/troubleTicket/close + OpenNMS-defined trouble ticket event: A request has been made to close a trouble ticket + This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for closing an existing trouble ticket. + + A request has been generated to close a trouble ticket. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (151, 21, 'uei.opennms.org/troubleTicket/cancel', 'OpenNMS-defined trouble ticket event: A request has been made to cancel a trouble ticket', 'This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for canceling an existing trouble ticket.', true, ' + uei.opennms.org/troubleTicket/cancel + OpenNMS-defined trouble ticket event: A request has been made to cancel a trouble ticket + This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS + for canceling an existing trouble ticket. + + A request has been generated to cancel a trouble ticket. + + Normal +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (152, 21, 'uei.opennms.org/troubleTicket/communicationError', 'OpenNMS-defined trouble ticket event: A communication error occurred', 'This event is generated when OpenNMS is unable to retrive, save or update a ticket + via the Trouble Ticket API. Communications failed with reason: %parm[reason]%.', true, ' + uei.opennms.org/troubleTicket/communicationError + OpenNMS-defined trouble ticket event: A communication error occurred + This event is generated when OpenNMS is unable to retrive, save or update a ticket + via the Trouble Ticket API. Communications failed with reason: %parm[reason]%. + + A communication error occurred between OpenNMS and the Trouble Ticket system. + + Warning +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (153, 22, 'uei.opennms.org/api/tl1d/message/autonomous', 'OpenNMS-defined Autonomous TL1 message', 'This is a TL1 autonomous message delivered for host: %host%.

+ +

Message: %parm[raw-message]%

+

Alarm Code: %parm[alarm-code]%

+

ATAG: %parm[atag]%

+

Verb: %parm[verb]%

+

Auto Block: %parm[autoblock]%

', true, ' + uei.opennms.org/api/tl1d/message/autonomous + OpenNMS-defined Autonomous TL1 message + This is a TL1 autonomous message delivered for host: %host%.<p> + + <p>Message: %parm[raw-message]% </p> + <p>Alarm Code: %parm[alarm-code]% </p> + <p>ATAG: %parm[atag]% </p> + <p>Verb: %parm[verb]% </p> + <p>Auto Block: %parm[autoblock]% </p> + + <p> %host%:%parm[verb]%:%parm[autoblock]% </p> + + Warning + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (154, 23, 'MATCH-ANY-UEI', 'OpenNMS-defined event: MATCH-ANY-UEI', '

This UEI will never be generated, but exists + so that notifications can match any UEI for a + particular filter rule. Useful to see all events for + a particular node via notifications. +

', true, ' + MATCH-ANY-UEI + OpenNMS-defined event: MATCH-ANY-UEI + <p>This UEI will never be generated, but exists + so that notifications can match any UEI for a + particular filter rule. Useful to see all events for + a particular node via notifications. + </p> + + MATCH-ANY-UEI event. + + Indeterminate +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (155, 23, 'uei.opennms.org/default/trap', 'OpenNMS-defined default event: trap', '

An SNMP Trap (%snmp%) with no matching configuration was received from interface %interface%.

+

The trap included the + following variable bindings:

%parm[all]%

', true, ' + uei.opennms.org/default/trap + OpenNMS-defined default event: trap + <p>An SNMP Trap (%snmp%) with no matching configuration was received from interface %interface%.</p> + <p>The trap included the + following variable bindings:</p> <p>%parm[all]%</p> + An SNMP Trap with no matching configuration was received from interface + %interface%. + + Indeterminate + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (156, 23, 'uei.opennms.org/default/event', 'OpenNMS-defined default event: event', '

An event with no matching configuration was received from interface %interface%. This event + included the following parameters: + %parm[all]%

', true, ' + uei.opennms.org/default/event + OpenNMS-defined default event: event + <p>An event with no matching configuration was received from interface %interface%. This event + included the following parameters: + %parm[all]%</p> + An event with no matching configuration was received from interface %interface%. + + Indeterminate + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); +INSERT INTO eventconf_events(id, source_id, uei, event_label, description, enabled, xml_content, created_time, last_modified, modified_by) VALUES (157, 23, 'uei.opennms.org/generic/traps/EnterpriseDefault', 'OpenNMS-defined trap event: EnterpriseDefault', '

This is the default event format used when an enterprise specific event (trap) is received for + which no format has been configured + (i.e. no event definition exists).

The total number of arguments received with the trap: + %parm[##]%.

+

They were:

%parm[all]%

+

Here is a "mask" element definition that matches this + event, for use in event configuration files:
+

+ <mask>
+   <maskelement>
+     <mename>id</mename>
+     <mevalue>%id%</mevalue>
+   </maskelement>
+   <maskelement>
+     <mename>generic</mename>
+     <mevalue>%generic%</mevalue>
+   </maskelement>
+   <maskelement>
+     <mename>specific</mename>
+     <mevalue>%specific%</mevalue>
+   </maskelement>
+ </mask> +
+

', true, ' + + + generic + 6 + + + uei.opennms.org/generic/traps/EnterpriseDefault + OpenNMS-defined trap event: EnterpriseDefault + <p>This is the default event format used when an enterprise specific event (trap) is received for + which no format has been configured + (i.e. no event definition exists).</p> <p>The total number of arguments received with the trap: + %parm[##]%.</p> + <p>They were:<p> <p>%parm[all]%<p> + <p>Here is a "mask" element definition that matches this + event, for use in event configuration files:<br/> + <blockquote> + &lt;mask&gt;<br/> + &nbsp;&nbsp;&lt;maskelement&gt;<br/> + &nbsp;&nbsp;&nbsp;&nbsp;&lt;mename&gt;id&lt;/mename&gt;<br/> + &nbsp;&nbsp;&nbsp;&nbsp;&lt;mevalue&gt;%id%&lt;/mevalue&gt;<br/> + &nbsp;&nbsp;&lt;/maskelement&gt;<br/> + &nbsp;&nbsp;&lt;maskelement&gt;<br/> + &nbsp;&nbsp;&nbsp;&nbsp;&lt;mename&gt;generic&lt;/mename&gt;<br/> + &nbsp;&nbsp;&nbsp;&nbsp;&lt;mevalue&gt;%generic%&lt;/mevalue&gt;<br/> + &nbsp;&nbsp;&lt;/maskelement&gt;<br/> + &nbsp;&nbsp;&lt;maskelement&gt;<br/> + &nbsp;&nbsp;&nbsp;&nbsp;&lt;mename&gt;specific&lt;/mename&gt;<br/> + &nbsp;&nbsp;&nbsp;&nbsp;&lt;mevalue&gt;%specific%&lt;/mevalue&gt;<br/> + &nbsp;&nbsp;&lt;/maskelement&gt;<br/> + &lt;/mask&gt; + </blockquote> + <p> + + Received unformatted enterprise event (enterprise:%id% generic:%generic% specific:%specific%). %parm[##]% + args: %parm[all]% + + Normal + +', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'system-migration'); + +ALTER SEQUENCE eventconf_events_id_seq RESTART WITH 158; diff --git a/core/schema/src/main/resources/sql/eventconf_sources.sql b/core/schema/src/main/resources/sql/eventconf_sources.sql new file mode 100644 index 000000000000..2b11a7fe029e --- /dev/null +++ b/core/schema/src/main/resources/sql/eventconf_sources.sql @@ -0,0 +1,47 @@ +-- +-- Licensed to The OpenNMS Group, Inc (TOG) under one or more +-- contributor license agreements. See the LICENSE.md file +-- distributed with this work for additional information +-- regarding copyright ownership. +-- +-- TOG licenses this file to You under the GNU Affero General +-- Public License Version 3 (the "License") or (at your option) +-- any later version. You may not use this file except in +-- compliance with the License. You may obtain a copy of the +-- License at: +-- +-- https://www.gnu.org/licenses/agpl-3.0.txt +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +-- either express or implied. See the License for the specific +-- language governing permissions and limitations under the +-- License. +-- + +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (1, 'opennms.snmp.trap.translator.events', '', 'opennms', 23, true, 8, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (2, 'opennms.ackd.events', '', 'opennms', 22, true, 1, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (3, 'opennms.alarm.events', '', 'opennms', 21, true, 3, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (4, 'opennms.bmp.events', '', 'opennms', 20, true, 2, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (5, 'opennms.bsm.events', '', 'opennms', 19, true, 5, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (6, 'opennms.capsd.events', '', 'opennms', 18, true, 8, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (7, 'opennms.collectd.events', '', 'opennms', 17, true, 2, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (8, 'opennms.config.events', '', 'opennms', 16, true, 12, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (9, 'opennms.correlation.events', '', 'opennms', 15, true, 2, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (10, 'opennms.default.threshold.events', '', 'opennms', 14, true, 6, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (11, 'opennms.discovery.events', '', 'opennms', 13, true, 4, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (12, 'opennms.internal.events', '', 'opennms', 12, true, 27, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (13, 'opennms.linkd.events', '', 'opennms', 11, true, 2, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (14, 'opennms.mib.events', '', 'opennms', 10, true, 7, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (15, 'opennms.pollerd.events', '', 'opennms', 9, true, 43, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (16, 'opennms.provisioning.events', '', 'opennms', 8, true, 8, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (17, 'opennms.minion.events', '', 'opennms', 7, true, 2, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (18, 'opennms.perspective.poller.events', '', 'opennms', 6, true, 2, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (19, 'opennms.reportd.events', '', 'opennms', 5, true, 2, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (20, 'opennms.syslogd.events', '', 'opennms', 4, true, 1, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (21, 'opennms.ticketd.events', '', 'opennms', 3, true, 5, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (22, 'opennms.tl1d.events', '', 'opennms', 2, true, 1, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); +INSERT INTO eventconf_sources(id, name, description, vendor, file_order, enabled, event_count, created_time, last_modified, uploaded_by) VALUES (23, 'opennms.catch-all.events', '', 'opennms', 1, true, 4, CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , 'system-migration'); + +ALTER SEQUENCE eventconf_sources_id_seq RESTART WITH 24; diff --git a/features/bsm/daemon/pom.xml b/features/bsm/daemon/pom.xml index acebde1449ca..1d43abbb523c 100644 --- a/features/bsm/daemon/pom.xml +++ b/features/bsm/daemon/pom.xml @@ -143,5 +143,12 @@ + + org.opennms + opennms-config + ${project.version} + test-jar + test + diff --git a/features/bsm/daemon/src/test/java/org/opennms/netmgt/bsm/daemon/BsmdIT.java b/features/bsm/daemon/src/test/java/org/opennms/netmgt/bsm/daemon/BsmdIT.java index 0c0ac65c6ac8..c134a2ddcccd 100644 --- a/features/bsm/daemon/src/test/java/org/opennms/netmgt/bsm/daemon/BsmdIT.java +++ b/features/bsm/daemon/src/test/java/org/opennms/netmgt/bsm/daemon/BsmdIT.java @@ -59,6 +59,7 @@ import org.opennms.netmgt.bsm.service.model.BusinessService; import org.opennms.netmgt.bsm.service.model.Status; import org.opennms.netmgt.config.DefaultEventConfDao; +import org.opennms.netmgt.config.EventConfTestUtil; import org.opennms.netmgt.dao.DatabasePopulator; import org.opennms.netmgt.dao.api.AlarmDao; import org.opennms.netmgt.dao.api.ApplicationDao; @@ -72,6 +73,7 @@ import org.opennms.netmgt.model.OnmsMonitoredService; import org.opennms.netmgt.model.OnmsSeverity; import org.opennms.netmgt.model.events.EventBuilder; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.xml.event.Event; import org.opennms.test.JUnitConfigurationEnvironment; import org.springframework.beans.factory.annotation.Autowired; @@ -501,8 +503,8 @@ public void verifyStartupWithoutRequiredEventData() throws Exception { public void verifyStartupWithoutAlarmData() throws Exception { // Load custom events DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new ClassPathResource("/eventconf.xml")); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new ClassPathResource("/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); // Remove Alarm Data REQUIRED_EVENT_UEIS.forEach(eventUei -> eventConfDao.getEvents(eventUei).get(0).setAlarmData(null)); @@ -524,8 +526,8 @@ public void verifyStartupWithoutAlarmData() throws Exception { public void verifyStartupWithChangedReductionKey() throws Exception { // Load custom events DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new ClassPathResource("/eventconf.xml")); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new ClassPathResource("/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); // change reduction key REQUIRED_EVENT_UEIS.forEach(uei -> eventConfDao.getEvents(uei).get(0).getAlarmData().setReductionKey("custom")); diff --git a/features/discovery/pom.xml b/features/discovery/pom.xml index a799591acd96..b428df852b9f 100644 --- a/features/discovery/pom.xml +++ b/features/discovery/pom.xml @@ -125,5 +125,12 @@ org.opennms.features.events.daemon test + + org.opennms + opennms-config + ${project.version} + test-jar + test + diff --git a/features/discovery/src/test/java/org/opennms/netmgt/discovery/NewSuspectLocationTest.java b/features/discovery/src/test/java/org/opennms/netmgt/discovery/NewSuspectLocationTest.java index ab9bbee696e8..68d67d1eac51 100644 --- a/features/discovery/src/test/java/org/opennms/netmgt/discovery/NewSuspectLocationTest.java +++ b/features/discovery/src/test/java/org/opennms/netmgt/discovery/NewSuspectLocationTest.java @@ -29,14 +29,18 @@ import org.junit.Test; import org.opennms.core.test.ConfigurationTestUtils; import org.opennms.netmgt.config.DefaultEventConfDao; +import org.opennms.netmgt.config.EventConfTestUtil; import org.opennms.netmgt.eventd.EventExpander; import org.opennms.netmgt.eventd.EventUtilDaoImpl; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.xml.event.Event; import org.springframework.core.io.FileSystemResource; import com.codahale.metrics.MetricRegistry; +import java.util.List; + public class NewSuspectLocationTest { private final String NEW_SUSPECT_UEI = "uei.opennms.org/internal/discovery/newSuspect"; private final String CUSTOM_LOCATION = "Ponyville"; @@ -47,8 +51,8 @@ public class NewSuspectLocationTest { @Before public void setUp() throws Exception { m_eventConfDao = new DefaultEventConfDao(); - m_eventConfDao.setConfigResource(new FileSystemResource(ConfigurationTestUtils.getFileForConfigFile("eventconf.xml"))); - m_eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new org.springframework.core.io.ClassPathResource("etc/eventconf.xml")); + m_eventConfDao.loadEventsFromDB(eventConfEventList); m_eventExpander = new EventExpander(new MetricRegistry()); m_eventExpander.setEventConfDao(m_eventConfDao); diff --git a/features/discovery/src/test/resources/etc/eventconf.xml b/features/discovery/src/test/resources/etc/eventconf.xml new file mode 100644 index 000000000000..c86000456a24 --- /dev/null +++ b/features/discovery/src/test/resources/etc/eventconf.xml @@ -0,0 +1,15 @@ + + + + + logmsg + operaction + autoaction + tticket + script + + + + events/opennms.discovery.events.xml + + diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.discovery.events.xml b/features/discovery/src/test/resources/etc/events/opennms.discovery.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/opennms.discovery.events.xml rename to features/discovery/src/test/resources/etc/events/opennms.discovery.events.xml diff --git a/features/events/collector/pom.xml b/features/events/collector/pom.xml index 2a47389f9dca..840419008ba5 100644 --- a/features/events/collector/pom.xml +++ b/features/events/collector/pom.xml @@ -97,5 +97,12 @@ opennms-services test + + org.opennms + opennms-config + ${project.version} + test-jar + test + diff --git a/features/events/collector/src/test/java/org/opennms/netmgt/collection/EventMetricsCollectorIT.java b/features/events/collector/src/test/java/org/opennms/netmgt/collection/EventMetricsCollectorIT.java index 667d0a5523c5..92fe30d4b6b7 100644 --- a/features/events/collector/src/test/java/org/opennms/netmgt/collection/EventMetricsCollectorIT.java +++ b/features/events/collector/src/test/java/org/opennms/netmgt/collection/EventMetricsCollectorIT.java @@ -26,18 +26,15 @@ import org.mockito.Mockito; import org.opennms.core.test.OpenNMSJUnit4ClassRunner; import org.opennms.netmgt.collection.api.CollectionAgentFactory; -import org.opennms.netmgt.collection.api.PersistenceSelectorStrategy; import org.opennms.netmgt.collection.api.Persister; import org.opennms.netmgt.collection.api.PersisterFactory; import org.opennms.netmgt.collection.api.ResourceType; import org.opennms.netmgt.collection.api.ResourceTypeMapper; import org.opennms.netmgt.collection.api.ServiceParameters; -import org.opennms.netmgt.collection.api.StrategyDefinition; import org.opennms.netmgt.collection.support.IndexStorageStrategy; import org.opennms.netmgt.collection.support.PersistAllSelectorStrategy; -import org.opennms.netmgt.collection.support.builder.GenericTypeResource; -import org.opennms.netmgt.collection.support.builder.NodeLevelResource; import org.opennms.netmgt.config.DefaultEventConfDao; +import org.opennms.netmgt.config.EventConfTestUtil; import org.opennms.netmgt.dao.api.IpInterfaceDao; import org.opennms.netmgt.dao.api.SnmpInterfaceDao; import org.opennms.netmgt.events.api.EventSubscriptionService; @@ -47,7 +44,7 @@ import org.opennms.netmgt.events.api.model.ImmutableParm; import org.opennms.netmgt.events.api.model.ImmutableValue; import org.opennms.netmgt.mock.MockPersister; -import org.opennms.netmgt.mock.MockResourceType; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.OnmsIpInterface; import org.opennms.netmgt.model.OnmsNode; import org.opennms.netmgt.rrd.RrdRepository; @@ -62,7 +59,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.function.Function; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; @@ -95,8 +91,8 @@ public class EventMetricsCollectorIT { private EventMetricsCollector getCollector(Persister persister) throws IOException { // load testing eventconf DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new FileSystemResource("src/test/resources/events/collection.events.xml")); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource("src/test/resources/events/collection.events.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); // fake interface info OnmsNode node = new OnmsNode(); diff --git a/features/events/traps/pom.xml b/features/events/traps/pom.xml index 3bd016df8c05..aac27c5fadac 100644 --- a/features/events/traps/pom.xml +++ b/features/events/traps/pom.xml @@ -186,5 +186,12 @@ ${project.version} test + + org.opennms + opennms-config + ${project.version} + test-jar + test + diff --git a/features/events/traps/src/test/java/org/opennms/netmgt/trapd/JoeSnmpTrapHandlerIT.java b/features/events/traps/src/test/java/org/opennms/netmgt/trapd/JoeSnmpTrapHandlerIT.java index 63f181c211b7..82281931f226 100644 --- a/features/events/traps/src/test/java/org/opennms/netmgt/trapd/JoeSnmpTrapHandlerIT.java +++ b/features/events/traps/src/test/java/org/opennms/netmgt/trapd/JoeSnmpTrapHandlerIT.java @@ -22,7 +22,15 @@ package org.opennms.netmgt.trapd; +import org.junit.Before; import org.junit.BeforeClass; +import org.opennms.netmgt.config.EventConfTestUtil; +import org.opennms.netmgt.config.api.EventConfDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; + +import java.util.List; /** * {@link TrapHandlerITCase} which uses the snmp strategy {@link org.opennms.netmgt.snmp.joesnmp.JoeSnmpStrategy}. @@ -31,9 +39,21 @@ */ public class JoeSnmpTrapHandlerIT extends TrapHandlerITCase { + @Autowired + private EventConfDao eventConfDao; + @BeforeClass public static void setUpBeforeClass() throws Exception { System.setProperty("org.opennms.snmp.strategyClass", "org.opennms.netmgt.snmp.joesnmp.JoeSnmpStrategy"); } + @Before + public void setUp() throws Exception { + List events = EventConfTestUtil.parseResourcesAsEventConfEvents( + new FileSystemResource("src/test/resources/org/opennms/netmgt/trapd/eventconf.xml")); + // Load into DB + eventConfDao.loadEventsFromDB(events); + super.setUp(); + } + } diff --git a/features/events/traps/src/test/java/org/opennms/netmgt/trapd/Snmp4JTrapHandlerIT.java b/features/events/traps/src/test/java/org/opennms/netmgt/trapd/Snmp4JTrapHandlerIT.java index e310721eef8f..e045bad42f00 100644 --- a/features/events/traps/src/test/java/org/opennms/netmgt/trapd/Snmp4JTrapHandlerIT.java +++ b/features/events/traps/src/test/java/org/opennms/netmgt/trapd/Snmp4JTrapHandlerIT.java @@ -22,16 +22,23 @@ package org.opennms.netmgt.trapd; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.opennms.netmgt.config.EventConfTestUtil; +import org.opennms.netmgt.config.api.EventConfDao; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.snmp.SnmpConfiguration; import org.opennms.netmgt.snmp.SnmpInstId; import org.opennms.netmgt.snmp.SnmpObjId; import org.opennms.netmgt.snmp.SnmpV3TrapBuilder; import org.opennms.netmgt.snmp.SnmpValue; import org.opennms.netmgt.snmp.snmp4j.Snmp4JStrategy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; import java.util.LinkedHashMap; +import java.util.List; import static org.junit.Assert.assertEquals; import static org.opennms.core.utils.InetAddressUtils.str; @@ -43,11 +50,23 @@ */ public class Snmp4JTrapHandlerIT extends TrapHandlerITCase { + @Autowired + private EventConfDao eventConfDao; + @BeforeClass public static void setUpBeforeClass() throws Exception { System.setProperty("org.opennms.snmp.strategyClass", "org.opennms.netmgt.snmp.snmp4j.Snmp4JStrategy"); } + @Before + public void setUp() throws Exception { + List events = EventConfTestUtil.parseResourcesAsEventConfEvents( + new FileSystemResource("src/test/resources/org/opennms/netmgt/trapd/eventconf.xml")); + // Load into DB + eventConfDao.loadEventsFromDB(events); + super.setUp(); + } + @Override public void sendTrap(final String version, final String enterprise, final int generic, final int specific) throws Exception { if ("v3".equals(version)) { diff --git a/features/events/traps/src/test/java/org/opennms/netmgt/trapd/TrapdIT.java b/features/events/traps/src/test/java/org/opennms/netmgt/trapd/TrapdIT.java index d534334bec33..567fc72b7360 100644 --- a/features/events/traps/src/test/java/org/opennms/netmgt/trapd/TrapdIT.java +++ b/features/events/traps/src/test/java/org/opennms/netmgt/trapd/TrapdIT.java @@ -26,14 +26,13 @@ import static org.junit.Assert.assertTrue; import java.net.InetAddress; -import java.util.Arrays; +import java.net.UnknownHostException; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.TreeMap; -import java.util.stream.Collectors; import org.hamcrest.Matchers; import org.junit.After; @@ -46,10 +45,13 @@ import org.opennms.core.utils.InetAddressUtils; import org.opennms.features.scv.api.Credentials; import org.opennms.features.scv.api.SecureCredentialsVault; +import org.opennms.netmgt.config.EventConfTestUtil; import org.opennms.netmgt.config.TrapdConfigFactory; +import org.opennms.netmgt.config.api.EventConfDao; import org.opennms.netmgt.config.trapd.Snmpv3User; import org.opennms.netmgt.dao.mock.MockEventIpcManager; import org.opennms.netmgt.events.api.EventConstants; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.scriptd.helper.EventForwarder; import org.opennms.netmgt.scriptd.helper.SnmpTrapHelper; @@ -64,6 +66,7 @@ import org.opennms.test.JUnitConfigurationEnvironment; import org.snmp4j.security.SecurityLevel; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; import org.springframework.test.context.ContextConfiguration; @RunWith(OpenNMSJUnit4ClassRunner.class) @@ -124,14 +127,24 @@ public void deleteCredentials(String alias) { @Autowired MockEventIpcManager m_mockEventIpcManager; - private final InetAddress localAddr = InetAddressUtils.getLocalHostAddress(); + @Autowired + private EventConfDao eventConfDao; + + private final InetAddress localAddr = InetAddressUtils.getLocalLoopbackAddress().get(); private final String localhost = InetAddressUtils.toIpAddrString(localAddr); @Before - public void setUp() { + public void setUp() throws Exception { + + List events = EventConfTestUtil.parseResourcesAsEventConfEvents( + new FileSystemResource("src/test/resources/org/opennms/netmgt/trapd/eventconf.xml")); + // Load into DB + eventConfDao.loadEventsFromDB(events); + m_mockEventIpcManager.setSynchronous(true); m_trapd.setSecureCredentialsVault(new MockSecureCredentialsVault()); m_trapd.onStart(); + } @After diff --git a/features/events/traps/src/test/resources/org/opennms/netmgt/trapd/applicationContext-trapDaemonTest.xml b/features/events/traps/src/test/resources/org/opennms/netmgt/trapd/applicationContext-trapDaemonTest.xml index 11cf9bf793d8..48b6e017c185 100644 --- a/features/events/traps/src/test/resources/org/opennms/netmgt/trapd/applicationContext-trapDaemonTest.xml +++ b/features/events/traps/src/test/resources/org/opennms/netmgt/trapd/applicationContext-trapDaemonTest.xml @@ -5,8 +5,25 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> - - classpath:/org/opennms/netmgt/trapd/eventconf.xml + + + + + + + + + + + + + + + + + + + diff --git a/features/vaadin-snmp-events-and-metrics/pom.xml b/features/vaadin-snmp-events-and-metrics/pom.xml index 2713f7711c85..7b194207dba3 100644 --- a/features/vaadin-snmp-events-and-metrics/pom.xml +++ b/features/vaadin-snmp-events-and-metrics/pom.xml @@ -124,7 +124,13 @@ org.opennms.core.test-api.lib test - + + org.opennms + opennms-config + ${project.version} + test-jar + test + diff --git a/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/config/EventAdminApplication.java b/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/config/EventAdminApplication.java index 6973642bed5f..b49ab7817e0c 100644 --- a/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/config/EventAdminApplication.java +++ b/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/config/EventAdminApplication.java @@ -22,19 +22,14 @@ package org.opennms.features.vaadin.config; import java.io.File; -import java.io.FileWriter; -import java.util.Iterator; import org.opennms.core.utils.ConfigFileConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.vaadin.dialogs.ConfirmDialog; import org.opennms.core.xml.JaxbUtils; import org.opennms.features.vaadin.events.EventPanel; import org.opennms.netmgt.config.api.EventConfDao; -import org.opennms.netmgt.events.api.EventConstants; import org.opennms.netmgt.events.api.EventProxy; -import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.xml.eventconf.Events; import com.vaadin.annotations.Theme; @@ -43,14 +38,12 @@ import com.vaadin.v7.data.util.FilesystemContainer; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; import com.vaadin.v7.ui.ComboBox; import com.vaadin.v7.ui.HorizontalLayout; import com.vaadin.v7.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.UI; import com.vaadin.v7.ui.VerticalLayout; -import com.vaadin.ui.Button.ClickEvent; /** * The Class Event Administration Application. @@ -135,78 +128,6 @@ public void valueChange(ValueChangeEvent event) { } }); - final Button add = new Button("Add New Events File"); - toolbar.addComponent(add); - add.addClickListener(new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - PromptWindow w = new PromptWindow("New Events Configuration", "Events File Name") { - @Override - public void textFieldChanged(String fieldValue) { - final File file = new File(eventsDir, normalizeFilename(fieldValue)); - LOG.info("Adding new events file {}", file); - final Events events = new Events(); - addEventPanel(layout, file, events); - } - }; - addWindow(w); - } - }); - - final Button remove = new Button("Remove Selected Events File"); - toolbar.addComponent(remove); - remove.addClickListener(new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - if (eventSource.getValue() == null) { - Notification.show("Please select an event configuration file."); - return; - } - final File file = (File) eventSource.getValue(); - ConfirmDialog.show(getUI(), - "Are you sure?", - "Do you really want to remove the file " + file.getName() + "?\nThis cannot be undone and OpenNMS won't be able to handle the events configured on this file.", - "Yes", - "No", - new ConfirmDialog.Listener() { - public void onClose(ConfirmDialog dialog) { - if (dialog.isConfirmed()) { - LOG.info("deleting file {}", file); - if (file.delete()) { - try { - // Updating eventconf.xml - boolean modified = false; - File configFile = ConfigFileConstants.getFile(ConfigFileConstants.EVENT_CONF_FILE_NAME); - Events config = JaxbUtils.unmarshal(Events.class, configFile); - for (Iterator it = config.getEventFiles().iterator(); it.hasNext();) { - String fileName = it.next(); - if (file.getAbsolutePath().contains(fileName)) { - it.remove(); - modified = true; - } - } - if (modified) { - JaxbUtils.marshal(config, new FileWriter(configFile)); - EventBuilder eb = new EventBuilder(EventConstants.EVENTSCONFIG_CHANGED_EVENT_UEI, "WebUI"); - eventProxy.send(eb.getEvent()); - } - // Updating UI Components - eventSource.select(null); - if (layout.getComponentCount() > 1) - layout.removeComponent(layout.getComponent(1)); - } catch (Exception e) { - LOG.error("an error ocurred while saving the event configuration: {}", e.getMessage(), e); - Notification.show("Can't save event configuration. " + e.getMessage(), Notification.Type.ERROR_MESSAGE); - } - } else { - Notification.show("Cannot delete file " + file, Notification.Type.WARNING_MESSAGE); - } - } - } - }); - } - }); - layout.addComponent(toolbar); layout.addComponent(new Label("")); layout.setComponentAlignment(toolbar, Alignment.MIDDLE_RIGHT); diff --git a/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/events/EventPanel.java b/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/events/EventPanel.java index 9f5b783adbce..0738ab738cf4 100644 --- a/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/events/EventPanel.java +++ b/features/vaadin-snmp-events-and-metrics/src/main/java/org/opennms/features/vaadin/events/EventPanel.java @@ -21,16 +21,33 @@ */ package org.opennms.features.vaadin.events; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; - -import org.opennms.core.utils.ConfigFileConstants; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinService; +import com.vaadin.server.VaadinServletRequest; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.codehaus.jackson.map.ObjectMapper; import org.opennms.core.xml.JaxbUtils; import org.opennms.features.vaadin.api.Logger; -import org.opennms.features.vaadin.config.EditorToolbar; import org.opennms.netmgt.config.api.EventConfDao; import org.opennms.netmgt.events.api.EventConstants; import org.opennms.netmgt.events.api.EventProxy; @@ -42,7 +59,6 @@ import com.vaadin.v7.data.Property; import com.vaadin.v7.data.Property.ValueChangeEvent; -import com.vaadin.v7.data.fieldgroup.FieldGroup.CommitException; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; @@ -51,10 +67,13 @@ import com.vaadin.ui.Panel; import com.vaadin.v7.ui.VerticalLayout; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; + /** * The Class Event Panel. - * - * @author Alejandro Galue + * + * @author Alejandro Galue */ @SuppressWarnings("serial") public abstract class EventPanel extends Panel { @@ -80,6 +99,10 @@ public abstract class EventPanel extends Panel { /** The base event object. */ final Events baseEventsObject = new Events(); + private static final String EVENT_CONFIG_UPLOAD_URL = "/api/v2/eventconf/upload"; + + private static final String EVENT_CONFIG_UPLOADED_SOURCE_NAMES_URL = "/api/v2/eventconf/sources/names"; + /** * Instantiates a new event panel. * @@ -129,49 +152,6 @@ public void buttonClick(Button.ClickEvent event) { final EventForm eventForm = new EventForm(); eventForm.setVisible(false); - final EditorToolbar bottomToolbar = new EditorToolbar() { - @Override - public boolean save() { - org.opennms.netmgt.xml.eventconf.Event event = eventForm.getEvent(); - logger.info("Event " + event.getUei() + " has been " + (isNew ? "created." : "updated.")); - try { - eventForm.commit(); - eventForm.setReadOnly(true); - eventTable.refreshRowCache(); - } catch (CommitException e) { - String msg = "Can't save the changes: " + e.getMessage(); - logger.error(msg); - Notification.show(msg, Notification.Type.ERROR_MESSAGE); - return false; - } - return true; - } - @Override - public boolean delete() { - Object eventId = eventTable.getValue(); - if (eventId != null) { - org.opennms.netmgt.xml.eventconf.Event event = eventTable.getEvent(eventId); - logger.info("Event " + event.getUei() + " has been removed."); - eventTable.select(null); - eventTable.removeItem(eventId); - eventTable.refreshRowCache(); - } - return true; - } - @Override - public boolean edit() { - eventForm.setReadOnly(false); - return true; - } - @Override - public boolean cancel() { - eventForm.discard(); - eventForm.setReadOnly(true); - return true; - } - }; - bottomToolbar.setVisible(false); - eventTable.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { @@ -186,20 +166,8 @@ public void valueChange(ValueChangeEvent event) { } eventForm.setReadOnly(true); eventForm.setVisible(eventId != null); - bottomToolbar.setReadOnly(true); - bottomToolbar.setVisible(eventId != null); } } - }); - - final Button add = new Button("Add Event", new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - eventTable.addEvent(eventForm.createBasicEvent()); - eventForm.setReadOnly(false); - bottomToolbar.setReadOnly(false); - setIsNew(true); - } }); final VerticalLayout mainLayout = new VerticalLayout(); @@ -207,12 +175,8 @@ public void buttonClick(ClickEvent event) { mainLayout.setMargin(true); mainLayout.addComponent(topToolbar); mainLayout.addComponent(eventTable); - mainLayout.addComponent(add); mainLayout.addComponent(eventForm); - mainLayout.addComponent(bottomToolbar); mainLayout.setComponentAlignment(topToolbar, Alignment.MIDDLE_RIGHT); - mainLayout.setComponentAlignment(add, Alignment.MIDDLE_RIGHT); - setContent(mainLayout); } @@ -248,10 +212,12 @@ public void setIsNew(boolean isNew) { * @param logger the logger */ public void processEvents(final Logger logger) { - if (eventFile.exists()) { + String fileName = eventFile.getName().replaceFirst("\\.xml$", ""); + List names = this.getUploadedSourceNames(logger); + if (names.contains(fileName)) { ConfirmDialog.show(getUI(), "Are you sure?", - "Do you really want to override the existig file?\nAll current information will be lost.", + "Do you really want to override all existing events for this event source?\nAll current information will be lost.", "Yes", "No", new ConfirmDialog.Listener() { @@ -319,30 +285,17 @@ private void saveFile(final File file, final Logger logger) { event.setMask(null); } } - // Save the XML of the new events - saveEvents(baseEventsObject, file, logger); - // Add a reference to the new file into eventconf.xml if there are events - String fileName = file.getAbsolutePath().replaceFirst(".*\\" + File.separatorChar + "events\\" + File.separatorChar + "(.*)", "events" + File.separatorChar + "$1"); - final Events rootEvents = eventConfDao.getRootEvents(); - final File rootFile = ConfigFileConstants.getFile(ConfigFileConstants.EVENT_CONF_FILE_NAME); - if (baseEventsObject.getEvents().size() > 0) { - if (!rootEvents.getEventFiles().contains(fileName)) { - logger.info("Adding a reference to " + fileName + " inside eventconf.xml."); - rootEvents.getEventFiles().add(0, fileName); - saveEvents(rootEvents, rootFile, logger); - } + boolean response = uploadFileToApi(baseEventsObject, file, logger); + if (response) { + EventBuilder eb = new EventBuilder(EventConstants.EVENTSCONFIG_CHANGED_EVENT_UEI, "WebUI"); + eventProxy.send(eb.getEvent()); + logger.info("The event's configuration reload operation is being performed."); + success(); } else { - // If a reference to an empty events file exist, it should be removed. - if (rootEvents.getEventFiles().contains(fileName)) { - logger.info("Removing a reference to " + fileName + " inside eventconf.xml because there are no events."); - rootEvents.getEventFiles().remove(fileName); - saveEvents(rootEvents, rootFile, logger); - } + final String message = "Failed to upload event source file."; + logger.error(message); + failure(message); } - EventBuilder eb = new EventBuilder(EventConstants.EVENTSCONFIG_CHANGED_EVENT_UEI, "WebUI"); - eventProxy.send(eb.getEvent()); - logger.info("The event's configuration reload operation is being performed."); - success(); } catch (Exception e) { logger.error(e.getClass() + ": " + (e.getMessage() == null ? "[No Details]" : e.getMessage())); if (e.getMessage() == null) { @@ -369,4 +322,96 @@ private void saveEvents(final Events events, final File eventFile, final Logger JaxbUtils.marshal(events, writer); writer.close(); } + + private boolean uploadFileToApi(final Events events, final File eventFile, final Logger logger) { + logger.info("Saving event source file to database."); + // Marshal the Events object into a byte array + byte[] eventData; + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + JaxbUtils.marshal(events, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)); + eventData = outputStream.toByteArray(); + } catch (IOException e) { + logger.error("Failed to serialize Events object: " + e.getMessage()); + throw new RuntimeException("Error serializing Events object", e); + } + String apiUrl = getApiUrl(EVENT_CONFIG_UPLOAD_URL); + HttpPost uploadRequest = new HttpPost(apiUrl); + uploadRequest.setHeader("Cookie", getCookie(logger)); + HttpEntity multipart = MultipartEntityBuilder.create() + .addBinaryBody("upload", eventData, ContentType.APPLICATION_XML, eventFile.getName()) + .build(); + uploadRequest.setEntity(multipart); + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(uploadRequest)) { + int statusCode = response.getStatusLine().getStatusCode(); + String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + if (statusCode == HttpStatus.SC_OK) { + logger.info("File successfully uploaded via API: " + statusCode); + logger.debug("Response: " + responseBody); + return true; + } else { + logger.error("Upload failed: " + statusCode); + logger.debug("Response: " + responseBody); + return false; + } + } catch (IOException e) { + logger.error("I/O error during file upload: " + e.getMessage()); + throw new RuntimeException("I/O error during file upload", e); + } catch (Exception e) { + logger.error("Unexpected error during file upload: " + e.getMessage()); + throw new RuntimeException("Unexpected error during file upload", e); + } + } + + private String getApiUrl(final String api) { + VaadinServletRequest vaadinServletRequest = (VaadinServletRequest) VaadinService.getCurrentRequest(); + HttpServletRequest httpRequest = vaadinServletRequest.getHttpServletRequest(); + String baseUrl = httpRequest.getRequestURL().toString() + .replace(httpRequest.getRequestURI(), "") + + httpRequest.getContextPath(); + return baseUrl + api; + } + + private String getCookie(final Logger logger) { + VaadinRequest request = VaadinService.getCurrentRequest(); + if (request == null) { + logger.error("No current request found"); + throw new RuntimeException("No current request found"); + } + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie c : cookies) { + if ("JSESSIONID".equalsIgnoreCase(c.getName())) { + return "JSESSIONID=" + c.getValue(); + } + } + } + logger.error("JSESSIONID cookie not found"); + throw new RuntimeException("No JSESSIONID cookie found"); + } + + private List getUploadedSourceNames(final Logger logger) { + String apiUrl = getApiUrl(EVENT_CONFIG_UPLOADED_SOURCE_NAMES_URL); + HttpGet getRequest = new HttpGet(apiUrl); + getRequest.setHeader("Cookie", getCookie(logger)); + try (CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = httpClient.execute(getRequest)) { + int statusCode = response.getStatusLine().getStatusCode(); + String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + if (statusCode == HttpStatus.SC_OK) { + logger.info("Successfully fetched uploaded source names"); + ObjectMapper mapper = new ObjectMapper(); + return Arrays.asList(mapper.readValue(responseBody, String[].class)); + } else { + logger.error("Error getting uploaded source names. HTTP status: " + statusCode); + throw new RuntimeException("Failed to fetch uploaded source names. HTTP " + statusCode); + } + } catch (IOException e) { + logger.error("I/O error fetching uploaded source names: " + e.getMessage()); + throw new RuntimeException("I/O error fetching uploaded source names", e); + } catch (Exception e) { + logger.error("Unexpected error fetching uploaded source names: " + e.getMessage()); + throw new RuntimeException("Unexpected error fetching uploaded source names", e); + } + } } diff --git a/features/vaadin-snmp-events-and-metrics/src/test/java/org/opennms/features/vaadin/events/EventFormTest.java b/features/vaadin-snmp-events-and-metrics/src/test/java/org/opennms/features/vaadin/events/EventFormTest.java index 72dbdc9c0b29..3e58e7489a43 100644 --- a/features/vaadin-snmp-events-and-metrics/src/test/java/org/opennms/features/vaadin/events/EventFormTest.java +++ b/features/vaadin-snmp-events-and-metrics/src/test/java/org/opennms/features/vaadin/events/EventFormTest.java @@ -21,16 +21,16 @@ */ package org.opennms.features.vaadin.events; -import java.io.File; +import java.util.List; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.opennms.core.test.ConfigurationTestUtils; import org.opennms.netmgt.config.DefaultEventConfDao; +import org.opennms.netmgt.config.EventConfTestUtil; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.xml.eventconf.Event; import org.opennms.netmgt.xml.eventconf.LogDestType; -import org.springframework.core.io.FileSystemResource; import com.vaadin.v7.data.fieldgroup.FieldGroup; import com.vaadin.v7.ui.ComboBox; @@ -54,11 +54,10 @@ public class EventFormTest { */ @Before public void setUp() throws Exception { - File config = new File(ConfigurationTestUtils.getDaemonEtcDirectory(), "events/MPLS.events.xml"); - Assert.assertTrue(config.exists()); dao = new DefaultEventConfDao(); - dao.setConfigResource(new FileSystemResource(config)); - dao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents( + new org.springframework.core.io.ClassPathResource("etc/events/MPLS.events.xml")); + dao.loadEventsFromDB(eventConfEventList); } /** diff --git a/opennms-base-assembly/src/main/filtered/etc/events/MPLS.events.xml b/features/vaadin-snmp-events-and-metrics/src/test/resources/etc/events/MPLS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/MPLS.events.xml rename to features/vaadin-snmp-events-and-metrics/src/test/resources/etc/events/MPLS.events.xml diff --git a/integration-tests/config/src/test/java/org/opennms/netmgt/config/WillItUnmarshalIT.java b/integration-tests/config/src/test/java/org/opennms/netmgt/config/WillItUnmarshalIT.java index a8747faeff37..3e9ad9071b42 100644 --- a/integration-tests/config/src/test/java/org/opennms/netmgt/config/WillItUnmarshalIT.java +++ b/integration-tests/config/src/test/java/org/opennms/netmgt/config/WillItUnmarshalIT.java @@ -315,7 +315,7 @@ private static void addFile(final Source source, final String file, final Class< addFile(Source.EXAMPLE, "viewsdisplay.xml", Viewinfo.class, false, null); // Add all event files - for (final File file : FileUtils.listFiles(new File(getDaemonEtcDirectory(), "events"), + for (final File file : FileUtils.listFiles(new File(getDaemonEtcDirectory(), "examples/events"), new String[] { "xml" }, true)) { addFile(Source.ABSOLUTE, file.getPath(), Events.class, false, null); diff --git a/opennms-base-assembly/src/main/filtered/etc/eventconf.xml b/opennms-base-assembly/src/main/filtered/etc/eventconf.xml index 53ae14268f65..4b6f3073d98d 100644 --- a/opennms-base-assembly/src/main/filtered/etc/eventconf.xml +++ b/opennms-base-assembly/src/main/filtered/etc/eventconf.xml @@ -8,260 +8,6 @@ script - - events/opennms.snmp.trap.translator.events.xml - events/opennms.ackd.events.xml - events/opennms.alarm.events.xml - events/opennms.bmp.events.xml - events/opennms.bsm.events.xml - events/opennms.capsd.events.xml - events/opennms.collectd.events.xml - events/opennms.config.events.xml - events/opennms.correlation.events.xml - events/opennms.default.threshold.events.xml - events/opennms.discovery.events.xml - events/opennms.internal.events.xml - events/opennms.linkd.events.xml - events/opennms.mib.events.xml - events/opennms.pollerd.events.xml - events/opennms.provisioning.events.xml - events/opennms.minion.events.xml - events/opennms.perspective.poller.events.xml - events/opennms.reportd.events.xml - events/opennms.syslogd.events.xml - events/opennms.ticketd.events.xml - events/opennms.tl1d.events.xml - events/GraphMLAssetPluginEvents.xml - events/3Com.events.xml - events/AdaptecRaid.events.xml - events/ADIC-v2.events.xml - events/Adtran.events.xml - events/Adtran.Atlas.events.xml - events/Aedilis.events.xml - events/AirDefense.events.xml - events/AIX.events.xml - events/AKCP.events.xml - events/AlcatelLucent.OmniSwitch.events.xml - events/AlcatelLucent.SMSBrick.events.xml - events/Allot.events.xml - events/Allot.NetXplorer.events.xml - events/Allot.SM.events.xml - events/Alteon.events.xml - events/Altiga.events.xml - events/APC.events.xml - events/APC.Best.events.xml - events/APC.Exide.events.xml - events/ApacheHTTPD.syslog.events.xml - events/Aruba.AP.events.xml - events/Aruba.Switch.events.xml - events/Aruba.events.xml - events/Ascend.events.xml - events/ASYNCOS-MAIL-MIB.events.xml - events/Avocent.ACS.events.xml - events/Avocent.ACS5000.events.xml - events/Avocent.AMX5000.events.xml - events/Avocent.AMX5010.events.xml - events/Avocent.AMX5020.events.xml - events/Avocent.AMX5030.events.xml - events/Avocent.CCM.events.xml - events/Avocent.DSR.events.xml - events/Avocent.DSR1021.events.xml - events/Avocent.DSR2010.events.xml - events/Avocent-DSView.events.xml - events/Avocent.Mergepoint.events.xml - events/Avocent.PMTrap.events.xml - events/Audiocodes.events.xml - events/A10.AX.events.xml - events/ATMForum.events.xml - events/BackupExec.events.xml - events/BEA.events.xml - events/BGP4.events.xml - events/BladeNetwork.events.xml - events/Bluecat.events.xml - events/BlueCoat.events.xml - events/Brocade.events.xml - events/Broadcom-BASPTrap.events.xml - events/CA.ArcServe.events.xml - events/Ceragon-FA1500.events.xml - events/Cisco.airespace.xml - events/Cisco.CIDS.events.xml - events/Cisco.5300dchan.events.xml - events/Cisco.mcast.events.xml - events/Cisco.SCE.events.xml - events/Cisco2.events.xml - events/Cisco.events.xml - events/CitrixNetScaler.events.xml - events/Colubris.events.xml - events/ComtechEFData.events.xml - events/Concord.events.xml - events/Covergence.events.xml - events/CPQHPIM.events.xml - events/Clarent.events.xml - events/Clarinet.events.xml - events/Clavister.events.xml - events/Compuware.events.xml - events/Cricket.events.xml - events/CRITAPP.events.xml - events/Crossbeam.events.xml - events/Dell-Asf.events.xml - events/DellArrayManager.events.xml - events/DellEquallogic.events.xml - events/Dell-DRAC2.events.xml - events/Dell-ITassist.events.xml - events/Dell-F10-bgb4-v2.events.xml - events/Dell-F10-chassis.events.xml - events/Dell-F10-copy-config.events.xml - events/Dell-F10-mstp.events.xml - events/Dell-F10-system-component.events.xml - events/DellOpenManage.events.xml - events/DellRacHost.events.xml - events/DellStorageManagement.events.xml - events/DISMAN.events.xml - events/DISMAN-PING.events.xml - events/Dlink.events.xml - events/DMTF.events.xml - events/DPS.events.xml - events/DS1.events.xml - events/EMC.events.xml - events/EMC-Celerra.events.xml - events/EMC-Clariion.events.xml - events/Evertz.7780ASI-IP2.events.xml - events/Evertz.7880IP-ASI-IP.events.xml - events/Evertz.7880IP-ASI-IP-FR.events.xml - events/Evertz.7881DEC-MP2-HD.events.xml - events/Extreme.events.xml - events/F5.events.xml - events/fcmgmt.events.xml - events/Fore.events.xml - events/Fortinet-FortiCore-v52.events.xml - events/Fortinet-FortiGate-v52.events.xml - events/Fortinet-FortiMail.events.xml - events/Fortinet-FortiManager-Analyzer.events.xml - events/Fortinet-FortiRecorder.events.xml - events/Fortinet-FortiVoice.events.xml - events/Fortinet-FortiCore-v4.events.xml - events/Fortinet-FortiGate-v4.events.xml - events/FoundryNetworks.events.xml - events/FoundryNetworks2.events.xml - events/FujitsuSiemens.events.xml - events/GGSN.events.xml - events/Groupwise.events.xml - events/HP.events.xml - events/HWg.Poseidon.events.xml - events/IBM.events.xml - events/IBM-UMS.events.xml - events/IBMRSA2.events.xml - events/IBM.EIF.events.xml - events/IEEE802dot11.events.xml - events/ietf.dlsw.events.xml - events/ietf.docsis.events.xml - events/ietf.events.xml - events/ietf.ptopo.events.xml - events/ietf.sna-dlc.events.xml - events/ietf.tn3270e.events.xml - events/ietf.vrrp.events.xml - events/Infoblox.events.xml - events/Intel.events.xml - events/INTEL-LAN-ADAPTERS-MIB.events.xml - events/InteractiveIntelligence.events.xml - events/IronPort.events.xml - events/ISS.events.xml - events/IPUnity-SES-MIB.events.xml - events/IPV6.events.xml - events/Juniper.mcast.events.xml - events/Juniper.events.xml - events/Juniper.ive.events.xml - events/Juniper.screen.events.xml - events/Junos.events.xml - events/JunosV1.events.xml - events/K5Systems.events.xml - events/Konica.events.xml - events/LLDP.events.xml - events/Liebert.events.xml - events/Liebert.600SM.events.xml - events/Linksys.events.xml - events/LinuxKernel.syslog.events.xml - events/Lucent.events.xml - events/MadgeNetworks.events.xml - events/McAfee.events.xml - events/MGE-UPS.events.xml - events/Microsoft.events.xml - events/MikrotikRouterOS.events.xml - events/Multicast.standard.events.xml - events/MPLS.events.xml - events/MRV.events.xml - events/MSDP.events.xml - events/Mylex.events.xml - events/NetApp.events.xml - events/Netbotz.events.xml - events/Netgear.events.xml - events/NetgearProsafeSmartSwitch.events.xml - events/NetgearProsafeSmartSwitch.syslog.events.xml - events/Netscreen.events.xml - events/NetSNMP.events.xml - events/Nokia.events.xml - events/NORTEL.Contivity.events.xml - events/Novell.events.xml - events/OpenSSH.syslog.events.xml - events/OpenWrt.syslog.events.xml - events/Oracle.events.xml - events/OSPF.events.xml - events/Overland.events.xml - events/Overture.events.xml - events/Procmail.syslog.events.xml - events/POSIX.syslog.events.xml - events/Postfix.syslog.events.xml - events/Packeteer.events.xml - events/Patrol.events.xml - events/PCube.events.xml - events/Pingtel.events.xml - events/Pixelmetrix.events.xml - events/Polycom.events.xml - events/Powerware.events.xml - events/Primecluster.events.xml - events/Quintum.events.xml - events/Raytheon.events.xml - events/RADLAN-MIB.events.xml - events/RAPID-CITY.events.xml - events/Redline.events.xml - events/RFC1382.events.xml - events/RFC1628.events.xml - events/Rightfax.events.xml - events/RiverbedSteelhead.events.xml - events/RMON.events.xml - events/Sensaphone.events.xml - events/Sentry.events.xml - events/Siemens-HiPath3000.events.xml - events/Siemens-HiPath3000-HG1500.events.xml - events/Siemens-HiPath4000.events.xml - events/Siemens-HiPath8000-OpenScapeVoice.events.xml - events/SNA-NAU.events.xml - events/SNMP-REPEATER.events.xml - events/Snort.events.xml - events/SonicWall.events.xml - events/Sonus.events.xml - events/Sudo.syslog.events.xml - events/SunILOM.events.xml - events/Symbol.events.xml - events/Syslogd.events.xml - events/SystemEdge.events.xml - events/SwissQual.events.xml - events/TransPath.events.xml - events/Trendmicro.events.xml - events/TrippLite.events.xml - events/TUT.events.xml - events/UPS-MIB.events.xml - events/Uptime.events.xml - events/Veeam_Backup-Replication.events.xml - events/Veraz.events.xml - events/VMWare.env.events.xml - events/VMWare.vc.events.xml - events/VMWare.vminfo.events.xml - events/VMWare.obsolete.events.xml - events/VMWare.events.xml - events/Waverider.3000.events.xml - events/Websense.events.xml - events/Xerox-V2.events.xml - events/Xerox.events.xml - events/opennms.catch-all.events.xml + + diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.ackd.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.ackd.events.xml deleted file mode 100644 index 797087c61053..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.ackd.events.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - uei.opennms.org/ackd/acknowledge - OpenNMS-defined Acknowledgment request - A message received requesting an Acknowledgable be acknowledged. - <p>Acknowledgement Request:%parm[refId]% of type:%parm[ackType]% was received with the - action:%parm[ackAction]% was received for User: %parm[ackUser]%</p> - Typically received from an external source or as a choice of an AckReader implementation. - - <p>Acknowledgement Request:%parm[refId]% of type:%parm[ackType]% was received with the - action:%parm[ackAction]% was received for User: %parm[ackUser]%.</p> - - Normal - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.bmp.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.bmp.events.xml deleted file mode 100644 index d06d2c538cf0..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.bmp.events.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - uei.opennms.org/bmp/peerDown - BMP: Peer Down - <p>BGP session to Peer %parm[address]% at AS%parm[as]% lost (Router ID: %parm[id]%). - Reason: %parm[type]%. Error: %parm[error]%.</p> - Router has lost the BGP session to Peer %parm[address]% at AS%parm[as]% (Router ID: %parm[id]%). - Minor - - - - - uei.opennms.org/bmp/peerUp - BMP: Peer Up - <p>BGP session to Peer %parm[address]% at AS%parm[as]% established (Router ID: %parm[id]%).</p> - Router has established the BGP session to Peer %parm[address]% at AS%parm[as]% (Router ID: %parm[id]%). - Normal - - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.bsm.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.bsm.events.xml deleted file mode 100644 index ebe5cdc11195..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.bsm.events.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - uei.opennms.org/bsm/serviceOperationalStatusChanged - Business Service Monitoring: Service Operational Status Changed - <p>The operational status for business service '%parm[businessServiceName]%', with - id=%parm[businessServiceId]%, changed from %parm[prevSeverityLabel]% to %parm[newSeverityLabel]%. - args(%parm[##]%): %parm[all]%</p> - The operational status for business service '%parm[businessServiceName]%' changed - from %parm[prevSeverityLabel]% to %parm[newSeverityLabel]%. - - Indeterminate - - - uei.opennms.org/bsm/serviceProblem - Business Service Monitoring: Service Problem - <p>There are currently one or more problems affecting business service '%parm[businessServiceName]%'. Root cause: %parm[rootCause]%. - args(%parm[##]%): %parm[all]%</p> - One or more problems are affecting business service '%parm[businessServiceName]%'. - - Indeterminate - - - - - - uei.opennms.org/bsm/serviceProblemResolved - Business Service Monitoring: Service Problem Resolved - <p>The problem affecting business service '%parm[businessServiceName]%' has been resolved. - args(%parm[##]%): %parm[all]%</p> - The problems affecting business service '%parm[businessServiceName]%' have been - resolved. - - Indeterminate - - - - uei.opennms.org/bsm/graphInvalidated - Business Service Monitoring: Graph invalidated - <p>Business Service '%parm[businessServiceName]%' with ID '%parm[businessServiceId]%' is affected by the deletion of %parm[cause]%. - A reload of the BSM daemon is scheduled. Make sure the Business Service still works properly. - Please verify it's <a href="admin/bsm/adminpage.jsp">definition</a>.</p> - Business service '%parm[businessServiceName]%' with ID '%parm[businessServiceId]%' is affected by the deletion of %parm[cause]%. - Warning - - - - - uei.opennms.org/internal/serviceDeleted - Business Service Monitoring: Service deleted - <p>The business service '%parm[businessServiceName]%' has been deleted. - args(%parm[##]%): %parm[all]%</p> - The business service '%parm[businessServiceName]%' has been deleted. - - Indeterminate - - - - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.capsd.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.capsd.events.xml deleted file mode 100644 index 7b777b5d8909..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.capsd.events.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - uei.opennms.org/internal/capsd/discPause - OpenNMS-defined internal event: capsd discPause - <p>The services scanning engine has asked discovery to - pause due to a backlog of interfaces yet to be scanned. - </p> - - Capsd has asked Discovery to pause momentarily. - - Warning - - - uei.opennms.org/internal/capsd/discResume - OpenNMS-defined internal event: capsd discResume - <p>Capsd is approving discovery to resume adding nodes - to the Capsd queue.</p> - - Capsd is ready for Discovery to resume scheduling nodes. - - Normal - - - uei.opennms.org/internal/capsd/forceRescan - OpenNMS-defined internal event: capsd forceRescan - <p>A services scan has been forced.</p> - <p>The administrator has forced a services scan on - this node to update the list of supported - services.</p> - - <p>A services scan has been forced on this - node.</p> - - Warning - - - uei.opennms.org/internal/capsd/rescanCompleted - OpenNMS-defined internal event: capsd rescanCompleted - <p>A services scan has been completed.</p> - <p>The list of services on this node has been - updated.</p> - - <p>A services scan has been completed on this - node.</p> - - Normal - - - uei.opennms.org/internal/capsd/addNode - OpenNMS-defined internal event: capsd addNode - <p>This event is an external command to add a node - to the database. The required paramater is the IP - address for the main interface: %interface%, and - the optional parameter of a node label: %nodelabel%.</p> - - <p>A request has been made to add a node with interface: - %interface% and node label: %nodelabel%.</p> - - Normal - - - uei.opennms.org/internal/capsd/deleteNode - OpenNMS-defined internal event: capsd deleteNode - <p>This event is an external command to delete a node - from the database. The required paramater is the IP - address for one interface: %interface%.</p> - - <p>A request has been made to delete a node with interface: - %interface%.</p> - - Normal - - - uei.opennms.org/internal/capsd/deleteInterface - OpenNMS-defined internal event: capsd deleteInterface - <p>This event is an external command to delete an interface - from the database. The required paramater is the IP - address for the interface: %interface%, or the nodeid %nodeid% - and ifIndex %ifindex%.</p> - - <p>A request has been made to delete an interface: - %interface% on node %nodeid% with ifIndex %ifindex%.</p> - - Normal - - - uei.opennms.org/internal/capsd/changeService - OpenNMS-defined internal event: capsd changeService - <p>This event will add or remove a service from an interface. - The paramters include the interface, %interface%, the service, - %service%, and any required qualifiers, %parm[#2]%. The action - taken will be: %parm[#1]%.</p> - - <p>A request has been made to %parm[#1]% the %service% service - on interface: %interface%.</p> - - Normal - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.catch-all.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.catch-all.events.xml deleted file mode 100644 index 8dcc324bb50b..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.catch-all.events.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - MATCH-ANY-UEI - OpenNMS-defined event: MATCH-ANY-UEI - <p>This UEI will never be generated, but exists - so that notifications can match any UEI for a - particular filter rule. Useful to see all events for - a particular node via notifications. - </p> - - MATCH-ANY-UEI event. - - Indeterminate - - - uei.opennms.org/default/trap - OpenNMS-defined default event: trap - <p>An SNMP Trap (%snmp%) with no matching configuration was received from interface %interface%.</p> - <p>The trap included the - following variable bindings:</p> <p>%parm[all]%</p> - An SNMP Trap with no matching configuration was received from interface - %interface%. - - Indeterminate - - - - uei.opennms.org/default/event - OpenNMS-defined default event: event - <p>An event with no matching configuration was received from interface %interface%. This event - included the following parameters: - %parm[all]%</p> - An event with no matching configuration was received from interface %interface%. - - Indeterminate - - - - - - generic - 6 - - - uei.opennms.org/generic/traps/EnterpriseDefault - OpenNMS-defined trap event: EnterpriseDefault - <p>This is the default event format used when an enterprise specific event (trap) is received for - which no format has been configured - (i.e. no event definition exists).</p> <p>The total number of arguments received with the trap: - %parm[##]%.</p> - <p>They were:<p> <p>%parm[all]%<p> - <p>Here is a "mask" element definition that matches this - event, for use in event configuration files:<br/> - <blockquote> - &lt;mask&gt;<br/> - &nbsp;&nbsp;&lt;maskelement&gt;<br/> - &nbsp;&nbsp;&nbsp;&nbsp;&lt;mename&gt;id&lt;/mename&gt;<br/> - &nbsp;&nbsp;&nbsp;&nbsp;&lt;mevalue&gt;%id%&lt;/mevalue&gt;<br/> - &nbsp;&nbsp;&lt;/maskelement&gt;<br/> - &nbsp;&nbsp;&lt;maskelement&gt;<br/> - &nbsp;&nbsp;&nbsp;&nbsp;&lt;mename&gt;generic&lt;/mename&gt;<br/> - &nbsp;&nbsp;&nbsp;&nbsp;&lt;mevalue&gt;%generic%&lt;/mevalue&gt;<br/> - &nbsp;&nbsp;&lt;/maskelement&gt;<br/> - &nbsp;&nbsp;&lt;maskelement&gt;<br/> - &nbsp;&nbsp;&nbsp;&nbsp;&lt;mename&gt;specific&lt;/mename&gt;<br/> - &nbsp;&nbsp;&nbsp;&nbsp;&lt;mevalue&gt;%specific%&lt;/mevalue&gt;<br/> - &nbsp;&nbsp;&lt;/maskelement&gt;<br/> - &lt;/mask&gt; - </blockquote> - <p> - - Received unformatted enterprise event (enterprise:%id% generic:%generic% specific:%specific%). %parm[##]% - args: %parm[all]% - - Normal - - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.collectd.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.collectd.events.xml deleted file mode 100644 index cb7779e3a750..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.collectd.events.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - uei.opennms.org/nodes/dataCollectionFailed - OpenNMS-defined node event: dataCollectionFailed - <p>%service% data collection on interface %interface% failed because of the following condition: '%parm[reason]%'.</p> - %service% data collection on interface %interface% failed. - Minor - - - - uei.opennms.org/nodes/dataCollectionSucceeded - OpenNMS-defined node event: dataCollectionSucceeded - <p>%service% data collection on interface %interface% previously failed and has been restored.</p> - %service% data collection on interface %interface% previously failed and has been restored. - Normal - - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.config.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.config.events.xml deleted file mode 100644 index e0ceb09f4dc8..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.config.events.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - uei.opennms.org/internal/reloadScriptConfig - OpenNMS-defined internal event: reloadScriptConfig - <p>The administrator has changed the ScriptD configuration. - ScriptD will load the new configuration.</p> - - <p>The ScriptD configuration files have changed.</p> - - Minor - - - uei.opennms.org/internal/reloadVacuumdConfig - OpenNMS-defined internal event: reloadVacuumdConfig - <p>The administrator has changed the Vacuumd - configuration. Vacuumd will load the new configuration.</p> - - <p>The Vacuumd configuration files have changed.</p> - - Minor - - - uei.opennms.org/internal/reloadSnmpPollerConfig - OpenNMS-defined internal event: reloadSnmpPollerConfig - <p>The administrator has changed the SnmpPoller - configuration. SnmpPoller will load the new configuration.</p> - - <p>The SnmpPoller configuration files have changed.</p> - - Minor - - - uei.opennms.org/internal/reloadDaemonConfig - OpenNMS-defined internal event: reload specified daemon configuration - <p>The administrator has changed the daemon: %parm[daemonName]% - configuration files and requests the configuration to be re-marshaled and applied.</p> - - <p>The daemon: %parm[daemonName]% configuration files has changed.</p> - - Normal - - - uei.opennms.org/internal/reloadDaemonConfigFailed - OpenNMS-defined internal event: reload specified daemon configuration failed - <p>The administrator has changed the daemon: %parm[daemonName]% - configuration files and the request for the configuration to be re-marshaled and applied - has failed because of the following condition %parm[reason]%.</p> - - <p>The daemon: %parm[daemonName]% configuration changes have failed to be - applied.</p> - - Major - - - - uei.opennms.org/internal/reloadDaemonConfigSuccessful - OpenNMS-defined internal event: reload specified daemon configuration successful - <p>The administrator has changed the daemon: %parm[daemonName]% - configuration files and the request for the configuration to be re-marshaled and applied - has succeeded.</p> - - <p>The daemon: %parm[daemonName]% configuration changes have successfully been - applied.</p> - - Normal - - - - uei.opennms.org/internal/thresholdConfigChange - OpenNMS-defined internal event: threshold configuration changed - This event is sent by the WebUI or the user when threshold configuration has changed and should be reloaded - - The thresholds configuration has been changed and should be reloaded - - Normal - - - uei.opennms.org/internal/eventsConfigChange - OpenNMS-defined internal event: event configuration changed - This event is sent by the WebUI or the user when event configuration has changed and should be reloaded - - The events configuration has been changed and should be reloaded - - Normal - - - uei.opennms.org/internal/reloadPollerConfig - OpenNMS-defined internal event: reloadPollerConfig - <p>The administrator has changed the poller - configuration files. The pollers and related services will - now restart to detect the changes.</p> - - <p>The poller configuration files have - changed.</p> - - Warning - - - uei.opennms.org/internal/syslogdConfigChange - OpenNMS-defined internal event: Syslogd configuration changed - This event is sent by the WebUI or the user when the Syslogd configuration has changed and should be - reloaded - - The Syslogd configuration has been changed and should be reloaded - - Normal - - - uei.opennms.org/internal/configureSNMP - OpenNMS-defined internal event: configureSNMP - <p>SNMP definition for IP address - %parm[firstIPAddress]%-%parm[lastIPAddress]% has been - updated with community string - "%parm[communityString]%"</p> - - <p>SNMP community string - "%parm[communityString]%" has been defined - for IP %parm[firstIPAddress]%-%parm[lastIPAddress]%.</p> - - Warning - - - uei.opennms.org/internal/translator/entityConfigChanged - OpenNMS defined event: A trap based event was received indicating a configuration change on a - device and has been translated to this generic event - This is a translated entity configuration change event.<p> - - <p>Source: %parm[configSource]% </p> - <p>User: %parm[configUser]% </p> - - <p>"%parm[configUser]%" changed entity %nodelabel%_%interface% from source: %parm[configSource]% </a></p> - - Warning - - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.correlation.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.correlation.events.xml deleted file mode 100644 index ec0d0ef8aeb0..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.correlation.events.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - uei.opennms.org/correlation/serviceFlapping - OpenNMS-defined correlator event: A service has been detected to be in a flapping state - This event is sent when a correlation rule has detected that a service is flapping. - - The service: %service% has been correlated to indicate a flapping state. - - Minor - - - - uei.opennms.org/internal/droolsEngineException - OpenNMS-defined Drools Engine Encountered Exception - Drools engine encountered an exception while running rules - - Drools engine rule %parm[enginename]% has encountered an exception : %parm[stacktrace]%. - - Normal - - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.default.threshold.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.default.threshold.events.xml deleted file mode 100644 index 1129171ce115..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.default.threshold.events.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - uei.opennms.org/threshold/highThresholdExceeded - OpenNMS-defined threshold event: highThresholdExceeded - A high threshold for the following metric exceeded: %parm[all]% - - High threshold exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% - - Warning - - - - uei.opennms.org/threshold/lowThresholdExceeded - OpenNMS-defined threshold event: lowThresholdExceeded - Low threshold for the following metric exceeded: %parm[all]% - - Low threshold exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% - - Warning - - - - uei.opennms.org/threshold/highThresholdRearmed - OpenNMS-defined threshold event: highThresholdRearmed - High threshold has been rearmed for the following metric: %parm[all]% - - High threshold rearmed for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% - - Normal - - - - uei.opennms.org/threshold/lowThresholdRearmed - OpenNMS-defined threshold event: lowThresholdRearmed - Low threshold has been rearmed for the following metric: %parm[all]% - - Low threshold rearmed for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% - - Normal - - - - uei.opennms.org/threshold/relativeChangeExceeded - OpenNMS-defined threshold event: relativeChangeExceeded - Relative change threshold for the following metric exceeded: %parm[all]% - - Relative change change exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% - - Warning - - - uei.opennms.org/threshold/absoluteChangeExceeded - OpenNMS-defined threshold event: absoluteChangeExceeded - Absolute change threshold for the following metric exceeded: %parm[all]% - - Absolute change exceeded for service %service% metric %parm[expressionLabel]% [%parm[ds]%] on interface %parm[label]%/%interface% - - Warning - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.internal.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.internal.events.xml deleted file mode 100644 index 7ab5c5c5ede5..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.internal.events.xml +++ /dev/null @@ -1,279 +0,0 @@ - - - uei.opennms.org/internal/interfaceManaged - OpenNMS-defined internal event: interfaceManaged - <p>The interface %interface% is being - remanaged.</p> <p>This interface will now - participate in service polling.</p> - - The interface %interface% is being remanaged. - - Warning - - - uei.opennms.org/internal/interfaceUnmanaged - OpenNMS-defined internal event: interfaceUnmanaged - <p>The interface %interface% is being forcibly - unmanaged.</p> <p>This interface and all - associated services will <b>NOT</b> be polled - until the interface is remanaged.</p> - - The interface %interface% is being forcibly unmanaged. - - Minor - - - uei.opennms.org/internal/notificationWithoutUsers - OpenNMS-defined internal event: notificationWithoutUsers - <p>A destination path in a notification has not been - assigned any users.</p> - - A destination path in a notification has not been assigned - any users. - - Warning - - - uei.opennms.org/internal/notificationsTurnedOff - OpenNMS-defined internal event: notificationsTurnedOff - <p>Notifications have been disabled.</p> - <p>The administrator has disabled notifications on - OpenNMS. No pages or emails will be sent until notifications - are reenabled.</p> - <p> - Responsible user: <em>%parm[remoteUser]%</em> - at <em>%parm[remoteHost]% (%parm[remoteAddr]%)</em> - </p> - - <p>Notifications have been disabled.</p> - - Minor - - - uei.opennms.org/internal/notificationsTurnedOn - OpenNMS-defined internal event: notificationsTurnedOn - <p>Notifications have been enabled.</p> - <p>The administrator has enabled notifications on - OpenNMS. Pages and/or emails will be sent based upon receipt - of important events.</p> - <p> - Responsible user: <em>%parm[remoteUser]%</em> - at <em>%parm[remoteHost]% (%parm[remoteAddr]%)</em> - </p> - - <p>Notifications have been enabled.</p> - - Warning - - - - - uei.opennms.org/internal/restartSCM - OpenNMS-defined internal event: restartSCM - <p>SCM has been asked to restart.</p> - - SCM has been asked to restart. - - Indeterminate - - - uei.opennms.org/internal/rtc/subscribe - OpenNMS-defined internal event: rtc subscribe - <p>This event is generated to RTC by any process that - wishes to receive POSTs of RTC data.</p> - - A subscription to RTC for the %parm[viewname]% for - %parm[url]% has been generated. - - Normal - - - uei.opennms.org/internal/rtc/unsubscribe - OpenNMS-defined internal event: rtc unsubscribe - <p>This event is generated to RTC by any subscribed - process that wishes to discontinue receipt of POSTs of RTC - data.</p> - - Unsubscribe request received from %parm[url]%. - - Warning - - - uei.opennms.org/internal/serviceManaged - OpenNMS-defined internal event: serviceManaged - <p>The service %service% on interface %interface% is - being remanaged.</p> - - The service %service% on interface %interface% is being - remanaged. - - Warning - - - uei.opennms.org/internal/schedOutagesChanged - OpenNMS-defined internal event: scehduled outage configuration changed - This event is sent by the WebUI or the user when scheduled outage configuration has changed and should be - reloaded - - The scheduled outage configuration has been changed and should be reloaded - - Normal - - - uei.opennms.org/internal/promoteQueueData - OpenNMS-defined event: A request has been made promote data from the RRD Queue - This event is generated to invoke the promotion data of the Queueing RRD Strategy. - - A request has been generated to promote data from the queue for the file(s): %parm[filesToPromote]%. - - Normal - - - uei.opennms.org/internal/authentication/successfulLogin - OpenNMS-defined internal event: a user has successfully authentication to the WebUI - This event is sent by the WebUI when a user has successfully authenticated - - OpenNMS user %parm[user]% has logged in from %parm[ip]%. - - Normal - - - - uei.opennms.org/internal/authentication/failure - OpenNMS-defined internal event: an authentication failure has occurred in WebUI - This event is sent by the WebUI when an authentication failure occurs. - - OpenNMS user '%parm[user]%' (may be blank) has failed to login - from %parm[ip]%. The failure event is %parm[exceptionName]% with - the message '%parm[exceptionMessage]%'. - - Minor - - - - uei.opennms.org/internal/authentication/loggedOut - OpenNMS-defined internal event: a user logged out of the web UI - This event is sent by the WebUI when a user logs out of the WebUI. - - OpenNMS user '%parm[user]%' logged out of the WebUI. - - Normal - - - - uei.opennms.org/internal/authentication/sessionRemoved - OpenNMS-defined internal event: a user's session was removed from the WebUI - This event is sent by the WebUI when a user's session is removed for any - reason other than a user-initiated logout. This generally means that - the session timed out due to inactivity. - - OpenNMS user '%parm[user]%' has been logged out of the WebUI, most likely - due to a session timeout. - - Normal - - - - uei.opennms.org/internal/kscReportUpdated - OpenNMS-defined internal event: KSC report updated - <p>The KSC Report '%parm[reportTitle]%' has been updated (remaining graphs: %parm[graphCount]%).</p> - <p>Some graphs defined on the report have been removed, due to an invalid resource or chart.</p> - <p>A resource is not valid on any of the following situations: the nodeId (or nodeSource) doesn't - exist, the resource type - is not valid or doesn't exist on the node, the resource name is not valid or doesn't exist on the node.</p> - <p>Check the logs for more details.</p> - The KSC Report %parm[reportTitle]% has been updated. - Warning - - - uei.opennms.org/services/passiveServiceStatus - OpenNMS-defined service event: passiveServiceStatus - <p>Status information for service %parm[passiveServiceName]% has been updated. <br/> - Passive Service Name: %parm[passiveServiceName]%<br/> - IP Interface: %parm[passiveIpAddr]%<br/> - Service Status: %parm[passiveStatus]%<br/> - Reason: %parm[passiveReasonCode]%</p> - <p>Status information for service %parm[passiveServiceName]% has been updated.</p> - Normal - - - uei.opennms.org/asset/maintenance/expirationWarning - Maintenance contract will expire in less then %parm[#4]% days - <p>Maintenance contract of %nodelabel% will expire in less then %parm[#4]% days.</p> - <p>Maintenance contract %parm[#3]% of %nodelabel% will expire at %parm[#2]%.</p> - Warning - - - - uei.opennms.org/internal/monitoringSystemAdded - Monitoring system Added - A new monitoring system has been added - A new monitoring system of type '%parm[monitoringSystemType]%' has been added with ID - '%parm[monitoringSystemId]%' at location '%parm[monitoringSystemLocation]%'. - - Normal - - - uei.opennms.org/internal/monitoringSystemLocationChanged - Monitoring system Location Changed - Monitoring system location changed - Monitoring system of type '%parm[monitoringSystemType]%' with ID - '%parm[monitoringSystemId]%' has changed its location from '%parm[monitoringSystemPreviousLocation]%' to - '%parm[monitoringSystemLocation]%'. - - Normal - - - uei.opennms.org/internal/monitoringSystemDeleted - Monitoring system Deleted - Monitoring system Deleted - Monitoring system of type '%parm[monitoringSystemType]%' with ID - '%parm[monitoringSystemId]%' at location '%parm[monitoringSystemLocation]%' has been deleted. - - Normal - - - uei.opennms.org/internal/telemetry/clockSkewDetected - Clock Skew detected - Clock skew (%parm[delta]% ms) detected for flow exporter (maxClockSkew = %parm[maxClockSkew]% secs) - Clock skew for exporter with interface '%interface%' in location '%parm[monitoringSystemLocation]%' detected by '%parm[monitoringSystemId]%'. - Warning - - - uei.opennms.org/translator/telemetry/clockSkewDetected - Clock Skew detected - Clock skew (%parm[delta]% ms) detected for flow exporter (maxClockSkew = %parm[maxClockSkew]% secs) - Clock skew for exporter with interface '%interface%' in location '%parm[monitoringSystemLocation]%' detected by '%parm[monitoringSystemId]%'. - - Warning - - - uei.opennms.org/internal/applicationDeleted - OpenNMS-defined application event: applicationDeleted - Application '%parm[applicationName]%' with ID '%parm[applicationId]%' has been deleted. - Application '%parm[applicationName]%' has been deleted. - Warning - - - uei.opennms.org/internal/applicationChanged - OpenNMS-defined node event: applicationChanged - The application '%parm[applicationName]%' with ID '%parm[applicationId]%' has been changed. - Application '%parm[applicationName]%' configuration has been changed. - Warning - Make sure '%parm[applicationName]%' application's definition still reflects the requirements. Please verify it's <a href="admin/applications.htm?applicationid=%parm[applicationId]%&edit=services">definition</a>. - - - uei.opennms.org/internal/applicationCreated - OpenNMS-defined node event: applicationCreated - The application '%parm[applicationName]%' with ID '%parm[applicationId]%' has been created. - Application '%parm[applicationName]%' has been created. - Normal - - - uei.opennms.org/internal/telemetry/illegalFlowDetected - Illegal flow detected - A flow was dropped due to the following reason: '%parm[cause]%' - A flow (protocol '%parm[protocol]%') from exporter '%interface%' in location '%parm[monitoringSystemLocation]%' was detected and dropped by '%parm[monitoringSystemId]%' due to the following reason: '%parm[cause]%'. - Warning - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.linkd.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.linkd.events.xml deleted file mode 100644 index 0a7604207276..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.linkd.events.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - uei.opennms.org/internal/topology/linkDown - OpenNMS-defined topology event: linkDown - <p>node: %nodeid% with ifindex: %ifindex% is down </p> - - node: %nodeid% with ifindex: %ifindex% is down - - Minor - - - - uei.opennms.org/internal/topology/linkUp - OpenNMS-defined topology event: linkUp - <p>node: %nodeid% with ifindex: %ifindex% is up </p> - - node: %nodeid% with ifindex: %ifindex% is up - - Normal - - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.mib.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.mib.events.xml deleted file mode 100644 index f8bc0238b833..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.mib.events.xml +++ /dev/null @@ -1,396 +0,0 @@ - - - - - id - .1.3.6.1.4.1.5813.1 - - - generic - 6 - - - specific - 1 - - - uei.opennms.org/traps/eventTrap - OPENNMS-MIB defined trap event: eventTrap - <p>This is the definition of the generic OpenNMS trap sent from the - scriptd process. Key variables are uei (which tells what type - of OpenNMS event this was), interface (the IP address of the interface - that caused the event) and severity.</p><table> - <tr><td><b> - - dbid</b></td><td> - %parm[#1]%;</td><td><p></p></td></tr> - <tr><td><b> - - distPoller</b></td><td> - %parm[#2]%;</td><td><p></p></td></tr> - <tr><td><b> - - create-time</b></td><td> - %parm[#3]%;</td><td><p></p></td></tr> - <tr><td><b> - - master-station</b></td><td> - %parm[#4]%;</td><td><p></p></td></tr> - <tr><td><b> - - uei</b></td><td> - %parm[#5]%;</td><td><p></p></td></tr> - <tr><td><b> - - source</b></td><td> - %parm[#6]%;</td><td><p></p></td></tr> - <tr><td><b> - - nodeid</b></td><td> - %parm[#7]%;</td><td><p></p></td></tr> - <tr><td><b> - - time</b></td><td> - %parm[#8]%;</td><td><p></p></td></tr> - <tr><td><b> - - host</b></td><td> - %parm[#9]%;</td><td><p></p></td></tr> - <tr><td><b> - - interface</b></td><td> - %parm[#10]%;</td><td><p></p></td></tr> - <tr><td><b> - - snmphost</b></td><td> - %parm[#11]%;</td><td><p></p></td></tr> - <tr><td><b> - - service</b></td><td> - %parm[#12]%;</td><td><p></p></td></tr> - <tr><td><b> - - descr</b></td><td> - %parm[#13]%;</td><td><p></p></td></tr> - <tr><td><b> - - logmsg</b></td><td> - %parm[#14]%;</td><td><p></p></td></tr> - <tr><td><b> - - severity</b></td><td> - %parm[#15]%;</td><td><p></p></td></tr> - <tr><td><b> - - pathoutage</b></td><td> - %parm[#16]%;</td><td><p></p></td></tr> - <tr><td><b> - - operinst</b></td><td> - %parm[#17]%;</td><td><p></p></td></tr> - <tr><td><b> - - ifresolve</b></td><td> - %parm[#18]%;</td><td><p></p></td></tr> - <tr><td><b> - - nodelabel</b></td><td> - %parm[#19]%;</td><td><p></p></td></tr></table> - - <p>An OpenNMS Event has been received as an SNMP Trap - with UEI: %parm[#5]%.</p> - - Normal - - - - - id - .1.3.6.1.4.1.5813.1 - - - generic - 6 - - - specific - 2 - - - uei.opennms.org/traps/tl1AutonomousMessageTrap - OPENNMS-MIB defined trap event: tl1AutonomousMessageTrap - <p>This trap is used to convey the contents of a TL1 autonomous message - received from a TL1 NE or a north-bound TL1 EMS. Managers receiving - this trap may need to perform additional analysis of its varbinds in - order to realize value from this trap.</p><table> - <tr><td><b> - - nodeid</b></td><td> - %parm[#1]%;</td><td><p></p></td></tr> - <tr><td><b> - - time</b></td><td> - %parm[#2]%;</td><td><p></p></td></tr> - <tr><td><b> - - host</b></td><td> - %parm[#3]%;</td><td><p></p></td></tr> - <tr><td><b> - - interface</b></td><td> - %parm[#4]%;</td><td><p></p></td></tr> - <tr><td><b> - - service</b></td><td> - %parm[#5]%;</td><td><p></p></td></tr> - <tr><td><b> - - severity</b></td><td> - %parm[#6]%;</td><td><p></p></td></tr> - <tr><td><b> - - tl1amRawMessage</b></td><td> - %parm[#7]%;</td><td><p></p></td></tr> - <tr><td><b> - - tl1amAlarmCode</b></td><td> - %parm[#8]%;</td><td><p></p></td></tr> - <tr><td><b> - - tl1amAutonomousTag</b></td><td> - %parm[#9]%;</td><td><p></p></td></tr> - <tr><td><b> - - tl1amVerb</b></td><td> - %parm[#10]%;</td><td><p></p></td></tr> - <tr><td><b> - - tl1amAutoBlock</b></td><td> - %parm[#11]%;</td><td><p></p></td></tr> - <tr><td><b> - - tl1amAID</b></td><td> - %parm[#12]%;</td><td><p></p></td></tr> - <tr><td><b> - - tl1amAdditionalParams</b></td><td> - %parm[#13]%;</td><td><p></p></td></tr></table> - <p> - tl1AutonomousMessageTrap trap received - nodeid=%parm[#1]% - time=%parm[#2]% - host=%parm[#3]% - interface=%parm[#4]% - service=%parm[#5]% - severity=%parm[#6]% - tl1amRawMessage=%parm[#7]% - tl1amAlarmCode=%parm[#8]% - tl1amAutonomousTag=%parm[#9]% - tl1amVerb=%parm[#10]% - tl1amAutoBlock=%parm[#11]% - tl1amAID=%parm[#12]% - tl1amAdditionalParams=%parm[#13]%</p> - - Normal - - - - - id - .1.3.6.1.4.1.5813.1 - - - generic - 6 - - - specific - 3 - - - uei.opennms.org/traps/alarmTrap - OPENNMS-MIB defined trap event: alarmTrap - <p>The OpenNMS alarm SNMP Trap</p><table> - <tr><td><b> - - dbid</b></td><td> - %parm[#1]%;</td><td><p></p></td></tr> - <tr><td><b> - - distPoller</b></td><td> - %parm[#2]%;</td><td><p></p></td></tr> - <tr><td><b> - - create-time</b></td><td> - %parm[#3]%;</td><td><p></p></td></tr> - <tr><td><b> - - master-station</b></td><td> - %parm[#4]%;</td><td><p></p></td></tr> - <tr><td><b> - - uei</b></td><td> - %parm[#5]%;</td><td><p></p></td></tr> - <tr><td><b> - - source</b></td><td> - %parm[#6]%;</td><td><p></p></td></tr> - <tr><td><b> - - nodeid</b></td><td> - %parm[#7]%;</td><td><p></p></td></tr> - <tr><td><b> - - time</b></td><td> - %parm[#8]%;</td><td><p></p></td></tr> - <tr><td><b> - - host</b></td><td> - %parm[#9]%;</td><td><p></p></td></tr> - <tr><td><b> - - interface</b></td><td> - %parm[#10]%;</td><td><p></p></td></tr> - <tr><td><b> - - snmphost</b></td><td> - %parm[#11]%;</td><td><p></p></td></tr> - <tr><td><b> - - service</b></td><td> - %parm[#12]%;</td><td><p></p></td></tr> - <tr><td><b> - - descr</b></td><td> - %parm[#13]%;</td><td><p></p></td></tr> - <tr><td><b> - - logmsg</b></td><td> - %parm[#14]%;</td><td><p></p></td></tr> - <tr><td><b> - - severity</b></td><td> - %parm[#15]%;</td><td><p></p></td></tr> - <tr><td><b> - - pathoutage</b></td><td> - %parm[#16]%;</td><td><p></p></td></tr> - <tr><td><b> - - operinst</b></td><td> - %parm[#17]%;</td><td><p></p></td></tr> - <tr><td><b> - - ifresolve</b></td><td> - %parm[#18]%;</td><td><p></p></td></tr> - <tr><td><b> - - nodelabel</b></td><td> - %parm[#19]%;</td><td><p></p></td></tr> - <tr><td><b> - - alarmId</b></td><td> - %parm[#20]%;</td><td><p></p></td></tr> - <tr><td><b> - - synchronizing</b></td><td> - %parm[#21]%;</td><td><p></p></td></tr></table> - - <p>An OpenNMS Event has been received as an SNMP Trap - with UEI: %parm[#5]%.</p> - - Normal - - - - - id - .1.3.6.1.4.1.5813.1 - - - generic - 6 - - - specific - 4 - - - uei.opennms.org/traps/heartbeatTrap - OPENNMS-MIB defined trap event: heartbeatTrap - <p>Trap sent periodically by OpenNMS to keep alive external SNMP Manager</p><table></table> - <p> - heartbeatTrap trap received</p> - - Normal - - - - - id - .1.3.6.1.4.1.5813.1 - - - generic - 6 - - - specific - 5 - - - uei.opennms.org/traps/startSyncTrap - OPENNMS-MIB defined trap event: startSyncTrap - <p>OpenNMS Synchronization Process is starting</p><table></table> - <p> - startSyncTrap trap received</p> - - Normal - - - - - id - .1.3.6.1.4.1.5813.1 - - - generic - 6 - - - specific - 6 - - - uei.opennms.org/traps/endSyncTrap - OPENNMS-MIB defined trap event: endSyncTrap - <p>OpenNMS Synchronization Process is successfully ended</p><table></table> - <p> - endSyncTrap trap received</p> - - Normal - - - - - id - .1.3.6.1.4.1.5813.1 - - - generic - 6 - - - specific - 7 - - - uei.opennms.org/traps/syncRequestTrap - OPENNMS-MIB defined trap event: syncRequestTrap - <p>OpenNMS synchronization request</p><table></table> - <p> - syncRequestTrap trap received</p> - - Normal - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.minion.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.minion.events.xml deleted file mode 100644 index 138e15c4f46d..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.minion.events.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - parm[toState] - ~OPEN|HALF_OPEN|FORCED_OPEN - - - uei.opennms.org/circuitBreaker/stateChange - OpenNMS-defined event: Circuit breaker has changed state - A cirtcuit breaker named %parm[name]% on %dpname% has changed state from %parm[fromState]% to %parm[toState]%. - Circuit breaker %parm[name]% on %dpname% changed state to %parm[toState]% - Warning - - - - - - - - parm[toState] - ~CLOSED|DISABLED - - - uei.opennms.org/circuitBreaker/stateChange - OpenNMS-defined event: Circuit breaker has changed state - A cirtcuit breaker named %parm[name]% on %dpname% has changed state from %parm[fromState]% to %parm[toState]%. - Circuit breaker %parm[name]% on %dpname% changed state to: %parm[toState]% - Normal - - - - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.perspective.poller.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.perspective.poller.events.xml deleted file mode 100644 index 4d9449dba78b..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.perspective.poller.events.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - uei.opennms.org/perspective/nodes/nodeLostService - OpenNMS-defined perspective poller event: A perspective poller detected a node lost service - <p>A %service% outage was identified on interface %interface% from location: %parm[perspective]%.</p> - - %service% outage identified on interface %interface% from location %parm[perspective]% with reason code: %parm[eventReason]%. - - Minor - - - - uei.opennms.org/perspective/nodes/nodeRegainedService - OpenNMS-defined perspective poller event: A perspective poller detected a node regained service - <p>The %service% service on interface %interface% was previously down from %parm[perspective]%.</p> - <p>This event is generated when a service which had previously failed polling attempts is again responding to polls by OpenNMS. </p> - - %service% outage identified on interface %interface% from location %parm[perspective]% has cleared. - - Normal - - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.provisioning.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.provisioning.events.xml deleted file mode 100644 index 66aadb1bd3a3..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.provisioning.events.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - uei.opennms.org/provisioner/provisioningAdapterFailed - OpenNMS-defined Provisioning Adapter Failed message - A provisioning adapter failed for host %host% with the following condition: %parm[reason]%.<p> - - <p>A provisioning adapter failed for host.</p> - - Major - - - - uei.opennms.org/internal/provisiond/scheduledNodeScanStarted - OpenNMS-defined Provisiond Event: scheduledNodeScanStarted - A message from the Provisiond NodeScan lifecycle that a scheduled NodeScan has started: - <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has - started scheduled Node Scan. </p> - - - <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has - started scheduled scan.</p> - - Normal - - - uei.opennms.org/internal/provisiond/nodeScanCompleted - OpenNMS-defined Provisiond Event: nodeScanCompleted - A message from the Provisiond NodeScan lifecycle that a NodeScan has completed: - <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has - completed.</p> - Typically the result of a request of an import request or a scheduled/user forced rescan. - - <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has - completed.</p> - - Normal - - - uei.opennms.org/internal/provisiond/nodeScanAborted - OpenNMS-defined Provisiond Event: nodeScanAborted - A message from the Provisiond NodeScan lifecycle that a NodeScan has Aborted: - <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has - aborted for the following reason: %parm[reason]% </p> - - <p>The Node with Id: %nodeid%; ForeignSource: %parm[foreignSource]%; ForeignId:%parm[foreignId]% has - aborted.</p> - - Warning - - - uei.opennms.org/internal/importer/reloadImport - OpenNMS-defined internal event: importer reloadImport - <p>This event will cause the importer to run the model-import process. - The parameters include foreignSource, url, and deleteThreshold that override - configuration properties as well as XML and default values.</p> - - <p>A request had been made to run the model-import process with the - parms: %parm[all]%.</p> - - Normal - - - uei.opennms.org/internal/importer/importStarted - OpenNMS-defined internal event: importer process has started - <p>This event indicates the model-importer process has started</p> - - <p>This event indicates the model-importer process has started from resource: %parm[importResource]% - </p> - - Normal - - - uei.opennms.org/internal/importer/importSuccessful - OpenNMS-defined internal event: importer process successfully completed - <p>This event indicates the model-importer process has completed successfully. There - is 1 parameter called importStats: %parm[importStats]%</p> - - <p>This event indicates the model-importer process has completed successfully from resource: - %parm[importResource]%</p> - - Normal - - - - uei.opennms.org/internal/importer/importFailed - OpenNMS-defined internal event: importer process failed. - <p>This event indicates the model-importer process has failed. There is 1 parameter - called failureMessage: %parm[failureMessage]%</p> - - <p>This event indicates the model-importer process has failed from resource: %parm[importResource]%</p> - - Warning - - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.reportd.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.reportd.events.xml deleted file mode 100644 index 387563a55318..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.reportd.events.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - uei.opennms.org/reportd/reportRunFailed - OpenNMS-defined Reportd Event: reportRunFailed - A message from the Reportd reporting service that a report has failed to run: - <p>The report with name %parm[reportName]% failed to run for the following reason: %parm[reason]% </p> - - <p>The report with name %parm[reportName]% failed to run.</p> - - Minor - - - - uei.opennms.org/reportd/reportDeliveryFailed - OpenNMS-defined Reportd Event: reportDeliveryFailed - A message from the Reportd delivery service that a report could not be delivered: - <p>The report with name %parm[reportName]% could not be delivered for the following reason: - %parm[reason]% </p> - - <p>The report with name %parm[reportName]% could not be delivered.</p> - - Minor - - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.snmp.trap.translator.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.snmp.trap.translator.events.xml deleted file mode 100644 index ab40f90a7ecf..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.snmp.trap.translator.events.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - - - generic - 0 - - - uei.opennms.org/generic/traps/SNMP_Cold_Start - OpenNMS-defined trap event: SNMP_Cold_Start - <p>A coldStart trap signifies that the sending protocol entity is reinitializing itself such that the - agent's configuration or the protocol entity implementation may be altered.</p> - Agent Up with Possible Changes (coldStart Trap) - - Normal - - - - - generic - 1 - - - uei.opennms.org/generic/traps/SNMP_Warm_Start - OpenNMS-defined trap event: SNMP_Warm_Start - <p>A warmStart trap signifies that the sending protocol entity is reinitializing itself such that - neither the agent configuration nor the - protocol entity implementation is altered.</p> - Agent Up with No Changes (warmStart Trap) - - Normal - - - - - generic - 2 - - - uei.opennms.org/generic/traps/SNMP_Link_Down - OpenNMS-defined trap event: SNMP_Link_Down - <p>A linkDown trap signifies that the sending protocol entity recognizes a failure in one of the - communication link represented in the agent's - configuration. The data passed with the event are 1) The name and value of the ifIndex instance for the - affected interface. The name of the - interface can be retrieved via an snmpget of .1.3.6.1.2.1.2.2.1.2.INST, where INST is the instance returned - with the trap.</p> - Agent Interface Down (linkDown Trap) - - Minor - - - - - uei.opennms.org/translator/traps/SNMP_Link_Down - Translator Enriched LinkDown Event - <p>A linkDown trap signifies that the sending protocol entity recognizes a failure in one of the - communication link represented in the agent's configuration. </p> - <p>Instance: %parm[#1]% </p> - <p>IfDescr: %parm[ifDescr]% </p> - <p>IfName: %parm[ifName]% </p> - <p>IfAlias: %parm[ifAlias]% </p> - Agent Interface Down (linkDown Trap) - - Minor - - - - - - - - - generic - 3 - - - uei.opennms.org/generic/traps/SNMP_Link_Up - OpenNMS-defined trap event: SNMP_Link_Up - <p>A linkUp trap signifies that the sending protocol entity recognizes that one of the communication - links represented in the agent's - configuration has come up. The data passed with the event are 1) The name and value of the ifIndex instance - for the affected interface. The name of - the interface can be retrieved via an snmpget of .1.3.6.1.2.1.2.2.1.2.INST, where INST is the instance - returned with the trap.</p> - Agent Interface Up (linkUp Trap) - - Normal - - - - - uei.opennms.org/translator/traps/SNMP_Link_Up - Translator Enriched LinkUp Event - <p>A linkUp trap signifies that the sending protocol entity recognizes that one of the communication - links represented in the agent's configuration has come up. </p> - <p>Instance: %parm[#1]% </p> - <p>IfDescr: %parm[ifDescr]% </p> - <p>IfName: %parm[ifName]% </p> - <p>IfAlias: %parm[ifAlias]% </p> - Agent Interface Up (linkUp Trap) - - Normal - - - - - - - generic - 4 - - - uei.opennms.org/generic/traps/SNMP_Authen_Failure - OpenNMS-defined trap event: SNMP_Authen_Failure - <p>An authentication failure trap signifies that the sending protocol entity is the addressee of a - protocol message that is not properly - authenticated.</p> - Incorrect Community Name (authenticationFailure Trap) - - Warning - - - - - - generic - 5 - - - uei.opennms.org/generic/traps/SNMP_EGP_Down - OpenNMS-defined trap event: SNMP_EGP_Down - <p>An egpNeighborLoss trap signifies that an EGP neighbor for whom the sending protocol entity was an - EGP peer has been marked down and the - peer relationship no longer obtains. The data passed with the event are The name and value of the ifIndex - egpNeighAddr for the affected - neighbor.</p> - EGP Neighbor Down (egpNeighborLoss Trap) - - Warning - - diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.syslogd.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.syslogd.events.xml deleted file mode 100644 index 8742dd38a8eb..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.syslogd.events.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - DISCARD-MATCHING-MESSAGES - OpenNMS-defined DISCARD-MATCHING-MESSAGES - DISCARD-MATCHING-MESSAGES is used in the syslogd to generate events that - have no matching events. This event is not persisted by default. - - <p>DISCARD-MATCHING-MESSAGES.</p> - - Normal - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.ticketd.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.ticketd.events.xml deleted file mode 100644 index 20d15e02ec18..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.ticketd.events.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - uei.opennms.org/troubleTicket/create - OpenNMS-defined trouble ticket event: A request has been made to create a trouble ticket - This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS - for creating a new trouble ticket. - - A request has been generated to create a trouble ticket. - - Normal - - - uei.opennms.org/troubleTicket/update - OpenNMS-defined trouble ticket event: A request has been made to update a trouble ticket - This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS - for updating an existing trouble ticket. - - A request has been generated to update a trouble ticket. - - Normal - - - uei.opennms.org/troubleTicket/close - OpenNMS-defined trouble ticket event: A request has been made to close a trouble ticket - This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS - for closing an existing trouble ticket. - - A request has been generated to close a trouble ticket. - - Normal - - - uei.opennms.org/troubleTicket/cancel - OpenNMS-defined trouble ticket event: A request has been made to cancel a trouble ticket - This event is generated to invoke the asynchronous Trouble Ticket API in OpenNMS - for canceling an existing trouble ticket. - - A request has been generated to cancel a trouble ticket. - - Normal - - - uei.opennms.org/troubleTicket/communicationError - OpenNMS-defined trouble ticket event: A communication error occurred - This event is generated when OpenNMS is unable to retrive, save or update a ticket - via the Trouble Ticket API. Communications failed with reason: %parm[reason]%. - - A communication error occurred between OpenNMS and the Trouble Ticket system. - - Warning - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.tl1d.events.xml b/opennms-base-assembly/src/main/filtered/etc/events/opennms.tl1d.events.xml deleted file mode 100644 index fed7f4ab4534..000000000000 --- a/opennms-base-assembly/src/main/filtered/etc/events/opennms.tl1d.events.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - uei.opennms.org/api/tl1d/message/autonomous - OpenNMS-defined Autonomous TL1 message - This is a TL1 autonomous message delivered for host: %host%.<p> - - <p>Message: %parm[raw-message]% </p> - <p>Alarm Code: %parm[alarm-code]% </p> - <p>ATAG: %parm[atag]% </p> - <p>Verb: %parm[verb]% </p> - <p>Auto Block: %parm[autoblock]% </p> - - <p> %host%:%parm[verb]%:%parm[autoblock]% </p> - - Warning - - - \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/3Com.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/3Com.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/3Com.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/3Com.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/A10.AX.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/A10.AX.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/A10.AX.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/A10.AX.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ADIC-v2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ADIC-v2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ADIC-v2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ADIC-v2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/AIX.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/AIX.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/AIX.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/AIX.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/AKCP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/AKCP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/AKCP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/AKCP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/APC.Best.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/APC.Best.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/APC.Best.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/APC.Best.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/APC.Exide.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/APC.Exide.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/APC.Exide.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/APC.Exide.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/APC.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/APC.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/APC.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/APC.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ASYNCOS-MAIL-MIB.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ASYNCOS-MAIL-MIB.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ASYNCOS-MAIL-MIB.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ASYNCOS-MAIL-MIB.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ATMForum.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ATMForum.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ATMForum.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ATMForum.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/AdaptecRaid.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/AdaptecRaid.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/AdaptecRaid.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/AdaptecRaid.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Adtran.Atlas.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Adtran.Atlas.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Adtran.Atlas.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Adtran.Atlas.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Adtran.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Adtran.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Adtran.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Adtran.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Aedilis.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Aedilis.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Aedilis.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Aedilis.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/AirDefense.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/AirDefense.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/AirDefense.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/AirDefense.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/AlcatelLucent.OmniSwitch.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/AlcatelLucent.OmniSwitch.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/AlcatelLucent.OmniSwitch.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/AlcatelLucent.OmniSwitch.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/AlcatelLucent.SMSBrick.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/AlcatelLucent.SMSBrick.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/AlcatelLucent.SMSBrick.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/AlcatelLucent.SMSBrick.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Allot.NetXplorer.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Allot.NetXplorer.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Allot.NetXplorer.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Allot.NetXplorer.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Allot.SM.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Allot.SM.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Allot.SM.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Allot.SM.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Allot.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Allot.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Allot.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Allot.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Alteon.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Alteon.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Alteon.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Alteon.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Altiga.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Altiga.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Altiga.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Altiga.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ApacheHTTPD.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ApacheHTTPD.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ApacheHTTPD.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ApacheHTTPD.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Aruba.AP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Aruba.AP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Aruba.AP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Aruba.AP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Aruba.Switch.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Aruba.Switch.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Aruba.Switch.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Aruba.Switch.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Aruba.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Aruba.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Aruba.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Aruba.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Ascend.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Ascend.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Ascend.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Ascend.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Audiocodes.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Audiocodes.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Audiocodes.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Audiocodes.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent-DSView.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent-DSView.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent-DSView.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent-DSView.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.ACS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.ACS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.ACS.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.ACS.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.ACS5000.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.ACS5000.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.ACS5000.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.ACS5000.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5000.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5000.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5000.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5000.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5010.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5010.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5010.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5010.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5020.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5020.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5020.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5020.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5030.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5030.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.AMX5030.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.AMX5030.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.CCM.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.CCM.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.CCM.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.CCM.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.DSR.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.DSR.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.DSR.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.DSR.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.DSR1021.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.DSR1021.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.DSR1021.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.DSR1021.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.DSR2010.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.DSR2010.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.DSR2010.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.DSR2010.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.Mergepoint.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.Mergepoint.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.Mergepoint.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.Mergepoint.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Avocent.PMTrap.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.PMTrap.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Avocent.PMTrap.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Avocent.PMTrap.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/BEA.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/BEA.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/BEA.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/BEA.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/BGP4.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/BGP4.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/BGP4.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/BGP4.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/BackupExec.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/BackupExec.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/BackupExec.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/BackupExec.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/BladeNetwork.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/BladeNetwork.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/BladeNetwork.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/BladeNetwork.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/BlueCoat.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/BlueCoat.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/BlueCoat.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/BlueCoat.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Bluecat.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Bluecat.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Bluecat.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Bluecat.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Broadcom-BASPTrap.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Broadcom-BASPTrap.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Broadcom-BASPTrap.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Broadcom-BASPTrap.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Brocade.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Brocade.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Brocade.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Brocade.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/CA.ArcServe.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/CA.ArcServe.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/CA.ArcServe.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/CA.ArcServe.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/CPQHPIM.README.txt b/opennms-base-assembly/src/main/filtered/etc/examples/events/CPQHPIM.README.txt similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/CPQHPIM.README.txt rename to opennms-base-assembly/src/main/filtered/etc/examples/events/CPQHPIM.README.txt diff --git a/opennms-base-assembly/src/main/filtered/etc/events/CPQHPIM.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/CPQHPIM.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/CPQHPIM.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/CPQHPIM.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/CRITAPP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/CRITAPP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/CRITAPP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/CRITAPP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Ceragon-FA1500.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Ceragon-FA1500.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Ceragon-FA1500.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Ceragon-FA1500.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cisco.5300dchan.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.5300dchan.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cisco.5300dchan.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.5300dchan.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cisco.CIDS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.CIDS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cisco.CIDS.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.CIDS.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cisco.SCE.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.SCE.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cisco.SCE.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.SCE.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cisco.airespace.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.airespace.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cisco.airespace.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.airespace.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cisco.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cisco.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cisco.mcast.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.mcast.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cisco.mcast.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco.mcast.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cisco2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cisco2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cisco2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/CitrixNetScaler.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/CitrixNetScaler.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/CitrixNetScaler.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/CitrixNetScaler.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Clarent.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Clarent.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Clarent.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Clarent.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Clarinet.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Clarinet.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Clarinet.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Clarinet.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Clavister.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Clavister.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Clavister.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Clavister.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Colubris.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Colubris.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Colubris.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Colubris.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Compuware.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Compuware.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Compuware.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Compuware.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ComtechEFData.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ComtechEFData.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ComtechEFData.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ComtechEFData.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Concord.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Concord.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Concord.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Concord.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Covergence.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Covergence.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Covergence.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Covergence.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Cricket.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Cricket.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Cricket.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Cricket.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Crossbeam.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Crossbeam.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Crossbeam.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Crossbeam.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DISMAN-PING.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DISMAN-PING.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DISMAN-PING.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DISMAN-PING.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DISMAN.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DISMAN.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DISMAN.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DISMAN.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DMTF.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DMTF.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DMTF.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DMTF.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DPS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DPS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DPS.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DPS.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DS1.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DS1.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DS1.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DS1.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-Asf.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-Asf.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-Asf.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-Asf.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-DRAC2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-DRAC2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-DRAC2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-DRAC2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-bgb4-v2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-bgb4-v2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-bgb4-v2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-bgb4-v2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-chassis.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-chassis.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-chassis.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-chassis.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-copy-config.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-copy-config.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-copy-config.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-copy-config.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-mstp.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-mstp.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-mstp.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-mstp.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-system-component.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-system-component.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-F10-system-component.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-F10-system-component.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dell-ITassist.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-ITassist.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dell-ITassist.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dell-ITassist.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DellArrayManager.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DellArrayManager.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DellArrayManager.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DellArrayManager.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DellEquallogic.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DellEquallogic.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DellEquallogic.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DellEquallogic.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DellOpenManage.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DellOpenManage.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DellOpenManage.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DellOpenManage.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DellRacHost.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DellRacHost.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DellRacHost.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DellRacHost.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/DellStorageManagement.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/DellStorageManagement.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/DellStorageManagement.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/DellStorageManagement.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Dlink.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Dlink.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Dlink.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Dlink.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/EMC-Celerra.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/EMC-Celerra.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/EMC-Celerra.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/EMC-Celerra.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/EMC-Clariion.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/EMC-Clariion.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/EMC-Clariion.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/EMC-Clariion.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/EMC.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/EMC.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/EMC.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/EMC.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Evertz.7780ASI-IP2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7780ASI-IP2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Evertz.7780ASI-IP2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7780ASI-IP2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Evertz.7880IP-ASI-IP-FR.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7880IP-ASI-IP-FR.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Evertz.7880IP-ASI-IP-FR.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7880IP-ASI-IP-FR.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Evertz.7880IP-ASI-IP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7880IP-ASI-IP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Evertz.7880IP-ASI-IP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7880IP-ASI-IP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Evertz.7881DEC-MP2-HD.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7881DEC-MP2-HD.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Evertz.7881DEC-MP2-HD.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Evertz.7881DEC-MP2-HD.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Extreme.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Extreme.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Extreme.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Extreme.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/F5.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/F5.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/F5.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/F5.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fore.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fore.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fore.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fore.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiCore-v4.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiCore-v4.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiCore-v4.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiCore-v4.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiCore-v52.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiCore-v52.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiCore-v52.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiCore-v52.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiGate-v4.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiGate-v4.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiGate-v4.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiGate-v4.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiGate-v52.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiGate-v52.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiGate-v52.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiGate-v52.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiMail.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiMail.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiMail.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiMail.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiManager-Analyzer.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiManager-Analyzer.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiManager-Analyzer.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiManager-Analyzer.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiRecorder.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiRecorder.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiRecorder.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiRecorder.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiVoice.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiVoice.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Fortinet-FortiVoice.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Fortinet-FortiVoice.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/FoundryNetworks.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/FoundryNetworks.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/FoundryNetworks.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/FoundryNetworks.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/FoundryNetworks2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/FoundryNetworks2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/FoundryNetworks2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/FoundryNetworks2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/FujitsuSiemens.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/FujitsuSiemens.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/FujitsuSiemens.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/FujitsuSiemens.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/GGSN.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/GGSN.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/GGSN.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/GGSN.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/GraphMLAssetPluginEvents.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/GraphMLAssetPluginEvents.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/GraphMLAssetPluginEvents.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/GraphMLAssetPluginEvents.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Groupwise.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Groupwise.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Groupwise.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Groupwise.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/HP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/HP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/HP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/HP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/HWg.Poseidon.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/HWg.Poseidon.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/HWg.Poseidon.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/HWg.Poseidon.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IBM-UMS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IBM-UMS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IBM-UMS.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IBM-UMS.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IBM.EIF.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IBM.EIF.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IBM.EIF.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IBM.EIF.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IBM.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IBM.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IBM.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IBM.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IBMRSA2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IBMRSA2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IBMRSA2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IBMRSA2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IEEE802dot11.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IEEE802dot11.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IEEE802dot11.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IEEE802dot11.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/INTEL-LAN-ADAPTERS-MIB.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/INTEL-LAN-ADAPTERS-MIB.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/INTEL-LAN-ADAPTERS-MIB.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/INTEL-LAN-ADAPTERS-MIB.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IPUnity-SES-MIB.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IPUnity-SES-MIB.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IPUnity-SES-MIB.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IPUnity-SES-MIB.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IPV6.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IPV6.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IPV6.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IPV6.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ISS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ISS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ISS.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ISS.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Infoblox.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Infoblox.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Infoblox.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Infoblox.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Intel.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Intel.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Intel.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Intel.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/InteractiveIntelligence.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/InteractiveIntelligence.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/InteractiveIntelligence.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/InteractiveIntelligence.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/IronPort.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/IronPort.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/IronPort.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/IronPort.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Juniper.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Juniper.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Juniper.ive.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.ive.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Juniper.ive.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.ive.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Juniper.mcast.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.mcast.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Juniper.mcast.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.mcast.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Juniper.screen.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.screen.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Juniper.screen.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Juniper.screen.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Junos.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Junos.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Junos.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Junos.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/JunosV1.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/JunosV1.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/JunosV1.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/JunosV1.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/K5Systems.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/K5Systems.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/K5Systems.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/K5Systems.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Konica.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Konica.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Konica.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Konica.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/LLDP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/LLDP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/LLDP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/LLDP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Liebert.600SM.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Liebert.600SM.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Liebert.600SM.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Liebert.600SM.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Liebert.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Liebert.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Liebert.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Liebert.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Linksys.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Linksys.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Linksys.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Linksys.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/LinuxKernel.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/LinuxKernel.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/LinuxKernel.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/LinuxKernel.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Lucent.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Lucent.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Lucent.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Lucent.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/MGE-UPS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/MGE-UPS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/MGE-UPS.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/MGE-UPS.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/examples/events/MPLS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/MPLS.events.xml new file mode 100644 index 000000000000..fd92699ff938 --- /dev/null +++ b/opennms-base-assembly/src/main/filtered/etc/examples/events/MPLS.events.xml @@ -0,0 +1,842 @@ + + + + + id + .1.3.6.1.3.118 + + + generic + 6 + + + specific + 1 + + + uei.opennms.org/mpls/traps/mplsVrfIfUp + MPLS-VPN-MIB defined trap event: mplsVrfIfUp + <p>This notification is generated when: +a. The ifOperStatus of an interface associated with a VRF + changes to the up(1) state. +b. When an interface with ifOperStatus = up(1) is + associated with a VRF.</p><table></table> + <p> + mplsVrfIfUp trap received</p> + + Normal + + + + + + id + .1.3.6.1.3.118 + + + generic + 6 + + + specific + 2 + + + uei.opennms.org/mpls/traps/mplsVrfIfDown + MPLS-VPN-MIB defined trap event: mplsVrfIfDown + <p>This notification is generated when: +a. The ifOperStatus of an interface associated with a VRF + changes to the down(1) state. +b. When an interface with ifOperStatus = up(1) state is + disassociated with a VRF.</p><table></table> + <p> + mplsVrfIfDown trap received</p> + + Minor + + + + + + id + .1.3.6.1.3.118 + + + generic + 6 + + + specific + 3 + + + uei.opennms.org/mpls/traps/mplsNumVrfRouteMidThreshExceeded + MPLS-VPN-MIB defined trap event: mplsNumVrfRouteMidThreshExceeded + <p>This notification is generated when the number of routes +contained by the specified VRF exceeds the value indicated by +mplsVrfMidRouteThreshold.</p><table></table> + <p> + mplsNumVrfRouteMidThreshExceeded trap received</p> + + Warning + + + + + + id + .1.3.6.1.3.118 + + + generic + 6 + + + specific + 4 + + + uei.opennms.org/mpls/traps/mplsNumVrfRouteMaxThreshExceeded + MPLS-VPN-MIB defined trap event: mplsNumVrfRouteMaxThreshExceeded + <p>This notification is generated when the number of routes +contained by the specified VRF reaches or attempts to exceed +the maximum allowed value as indicated by +mplsVrfMaxRouteThreshold.</p><table></table> + <p> + mplsNumVrfRouteMaxThreshExceeded trap received</p> + + Minor + + + + + + id + .1.3.6.1.3.118 + + + generic + 6 + + + specific + 5 + + + uei.opennms.org/mpls/traps/mplsNumVrfSecIllegalLabelThreshExceeded + MPLS-VPN-MIB defined trap event: mplsNumVrfSecIllegalLabelThreshExceeded + <p>This notification is generated when the number of illegal +label violations on a VRF as indicated by +mplsVpnVrfSecIllegalLabelViolations has exceeded +mplsVpnVrfSecIllegalLabelRcvThresh. The threshold is not +included in the varbind here because the value of +mplsVpnVrfSecIllegalLabelViolations should be one greater than +the threshold at the time this notification is issued.</p><table></table> + <p> + mplsNumVrfSecIllegalLabelThreshExceeded trap received</p> + + Warning + + + + + + id + .1.3.6.1.2.1.10.166.11 + + + generic + 6 + + + specific + 1 + + + uei.opennms.org/ietf/mplsL3vpnStdMib/traps/mplsL3VpnVrfUp + MPLS-L3VPN-STD-MIB defined trap event: mplsL3VpnVrfUp + <p>This notification is generated when: +a. No interface is associated with this VRF, and the first + (and only first) interface associated with it has its + ifOperStatus change to up(1). + +b. One interface is associated with this VRF, and + the ifOperStatus of this interface changes to up(1). + +c. Multiple interfaces are associated with this VRF, and the + ifOperStatus of all interfaces is down(2), and the first + of those interfaces has its ifOperStatus change to up(1).</p><table> + <tr><td><b> + + mplsL3VpnIfConfRowStatus</b></td><td> + %parm[#1]%;</td><td><p> + active(1) + notInService(2) + notReady(3) + createAndGo(4) + createAndWait(5) + destroy(6) + </p></td></tr> + <tr><td><b> + + mplsL3VpnVrfOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + </p></td></tr></table> + <p> + mplsL3VpnVrfUp trap received + mplsL3VpnIfConfRowStatus=%parm[#1]% + mplsL3VpnVrfOperStatus=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.2.1.10.166.11 + + + generic + 6 + + + specific + 2 + + + uei.opennms.org/ietf/mplsL3vpnStdMib/traps/mplsL3VpnVrfDown + MPLS-L3VPN-STD-MIB defined trap event: mplsL3VpnVrfDown + <p>This notification is generated when: +a. One interface is associated with this VRF, and + the ifOperStatus of this interface changes from up(1) + to down(2). + +b. Multiple interfaces are associated with this VRF, and + the ifOperStatus of all except one of these interfaces is + equal to up(1), and the ifOperStatus of that interface + changes from up(1) to down(2). + +c. The last interface with ifOperStatus equal to up(1) + is disassociated from a VRF.</p><table> + <tr><td><b> + + mplsL3VpnIfConfRowStatus</b></td><td> + %parm[#1]%;</td><td><p> + active(1) + notInService(2) + notReady(3) + createAndGo(4) + createAndWait(5) + destroy(6) + </p></td></tr> + <tr><td><b> + + mplsL3VpnVrfOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + </p></td></tr></table> + <p> + mplsL3VpnVrfDown trap received + mplsL3VpnIfConfRowStatus=%parm[#1]% + mplsL3VpnVrfOperStatus=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.2.1.10.166.11 + + + generic + 6 + + + specific + 3 + + + uei.opennms.org/ietf/mplsL3vpnStdMib/traps/mplsL3VpnVrfRouteMidThreshExceeded + MPLS-L3VPN-STD-MIB defined trap event: mplsL3VpnVrfRouteMidThreshExceeded + <p>This notification is generated when the number of routes +contained by the specified VRF exceeds the value indicated by +mplsL3VpnVrfMidRouteThreshold. A single notification MUST be +generated when this threshold is exceeded, and no other +notifications of this type should be issued until the value +of mplsL3VpnVrfPerfCurrNumRoutes has fallen below that of +mplsL3VpnVrfConfMidRteThresh.</p><table> + <tr><td><b> + + mplsL3VpnVrfPerfCurrNumRoutes</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + mplsL3VpnVrfConfMidRteThresh</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + mplsL3VpnVrfRouteMidThreshExceeded trap received + mplsL3VpnVrfPerfCurrNumRoutes=%parm[#1]% + mplsL3VpnVrfConfMidRteThresh=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.2.1.10.166.11 + + + generic + 6 + + + specific + 4 + + + uei.opennms.org/ietf/mplsL3vpnStdMib/traps/mplsL3VpnVrfNumVrfRouteMaxThreshExceeded + MPLS-L3VPN-STD-MIB defined trap event: mplsL3VpnVrfNumVrfRouteMaxThreshExceeded + <p>This notification is generated when the number of routes +contained by the specified VRF exceeds or attempts to exceed +the maximum allowed value as indicated by +mplsL3VpnVrfMaxRouteThreshold. In cases where +mplsL3VpnVrfConfHighRteThresh is set to the same value +as mplsL3VpnVrfConfMaxRoutes, mplsL3VpnVrfConfHighRteThresh +need not be exceeded; rather, just reached for this notification +to be issued. + +Note that mplsL3VpnVrfConfRteMxThrshTime denotes the interval +at which the this notification will be reissued after the +maximum value has been exceeded (or reached if +mplsL3VpnVrfConfMaxRoutes and mplsL3VpnVrfConfHighRteThresh are +equal) and the initial notification has been issued. This value +is intended to prevent continuous generation of notifications by +an agent in the event that routes are continually added to a VRF +after it has reached its maximum value. The default value is 0 +minutes. If this value is set to 0, the agent should only issue +a single notification at the time that the maximum threshold has +been reached, and should not issue any more notifications until +the value of routes has fallen below the configured threshold +value.</p><table> + <tr><td><b> + + mplsL3VpnVrfPerfCurrNumRoutes</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + mplsL3VpnVrfConfHighRteThresh</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + mplsL3VpnVrfNumVrfRouteMaxThreshExceeded trap received + mplsL3VpnVrfPerfCurrNumRoutes=%parm[#1]% + mplsL3VpnVrfConfHighRteThresh=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.2.1.10.166.11 + + + generic + 6 + + + specific + 5 + + + uei.opennms.org/ietf/mplsL3vpnStdMib/traps/mplsL3VpnNumVrfSecIllglLblThrshExcd + MPLS-L3VPN-STD-MIB defined trap event: mplsL3VpnNumVrfSecIllglLblThrshExcd + <p>This notification is generated when the number of illegal +label violations on a VRF as indicated by + +mplsL3VpnVrfSecIllegalLblVltns has exceeded +mplsL3VpnIllLblRcvThrsh. The threshold is not +included in the varbind here because the value of +mplsL3VpnVrfSecIllegalLblVltns should be one greater than +the threshold at the time this notification is issued.</p><table> + <tr><td><b> + + mplsL3VpnVrfSecIllegalLblVltns</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + mplsL3VpnNumVrfSecIllglLblThrshExcd trap received + mplsL3VpnVrfSecIllegalLblVltns=%parm[#1]%</p> + + Warning + + + + + + id + .1.3.6.1.2.1.10.166.11 + + + generic + 6 + + + specific + 6 + + + uei.opennms.org/ietf/mplsL3vpnStdMib/traps/mplsL3VpnNumVrfRouteMaxThreshCleared + MPLS-L3VPN-STD-MIB defined trap event: mplsL3VpnNumVrfRouteMaxThreshCleared + <p>This notification is generated only after the number of routes +contained by the specified VRF exceeds or attempts to exceed +the maximum allowed value as indicated by +mplsVrfMaxRouteThreshold, and then falls below this value. The +emission of this notification informs the operator that the +error condition has been cleared without the operator having to +query the device. + +Note that mplsL3VpnVrfConfRteMxThrshTime denotes the interval at +which the mplsNumVrfRouteMaxThreshExceeded notification will +be reissued after the maximum value has been exceeded (or +reached if mplsL3VpnVrfConfMaxRoutes and +mplsL3VpnVrfConfHighRteThresh are equal) and the initial +notification has been issued. Therefore, +the generation of this notification should also be emitted with +this same frequency (assuming that the error condition is +cleared). Specifically, if the error condition is reached and +cleared several times during the period of time specified in +mplsL3VpnVrfConfRteMxThrshTime, only a single notification will +be issued to indicate the first instance of the error condition +as well as the first time the error condition is cleared. +This behavior is intended to prevent continuous generation of +notifications by an agent in the event that routes are +continually added and removed to/from a VRF after it has +reached its maximum value. The default value is 0. If this +value is set to 0, the agent should issue a notification +whenever the maximum threshold has been cleared.</p><table> + <tr><td><b> + + mplsL3VpnVrfPerfCurrNumRoutes</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + mplsL3VpnVrfConfHighRteThresh</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + mplsL3VpnNumVrfRouteMaxThreshCleared trap received + mplsL3VpnVrfPerfCurrNumRoutes=%parm[#1]% + mplsL3VpnVrfConfHighRteThresh=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.2.1.10.166.2 + + + generic + 6 + + + specific + 1 + + + uei.opennms.org/ietf/mplsLsrStdMib/traps/mplsXCUp + MPLS-LSR-STD-MIB defined trap event: mplsXCUp + <p>This notification is generated when the +mplsXCOperStatus object for one or more contiguous +entries in mplsXCTable are about to enter the up(1) +state from some other state. The included values of +mplsXCOperStatus MUST both be set equal to this +new state (i.e: up(1)). The two instances of +mplsXCOperStatus in this notification indicate the range +of indexes that are affected. Note that all the indexes +of the two ends of the range can be derived from the +instance identifiers of these two objects. For +cases where a contiguous range of cross-connects +have transitioned into the up(1) state at roughly +the same time, the device SHOULD issue a single +notification for each range of contiguous indexes in +an effort to minimize the emission of a large number +of notifications. If a notification has to be +issued for just a single cross-connect entry, then +the instance identifier (and values) of the two +mplsXCOperStatus objects MUST be the identical.</p><table> + <tr><td><b> + + mplsXCOperStatus</b></td><td> + %parm[#1]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr> + <tr><td><b> + + mplsXCOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr></table> + <p> + mplsXCUp trap received + mplsXCOperStatus=%parm[#1]% + mplsXCOperStatus=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.2.1.10.166.2 + + + generic + 6 + + + specific + 2 + + + uei.opennms.org/ietf/mplsLsrStdMib/traps/mplsXCDown + MPLS-LSR-STD-MIB defined trap event: mplsXCDown + <p>This notification is generated when the +mplsXCOperStatus object for one or more contiguous +entries in mplsXCTable are about to enter the +down(2) state from some other state. The included values +of mplsXCOperStatus MUST both be set equal to this +down(2) state. The two instances of mplsXCOperStatus +in this notification indicate the range of indexes +that are affected. Note that all the indexes of the +two ends of the range can be derived from the +instance identifiers of these two objects. For +cases where a contiguous range of cross-connects +have transitioned into the down(2) state at roughly +the same time, the device SHOULD issue a single +notification for each range of contiguous indexes in +an effort to minimize the emission of a large number +of notifications. If a notification has to be +issued for just a single cross-connect entry, then +the instance identifier (and values) of the two +mplsXCOperStatus objects MUST be identical.</p><table> + <tr><td><b> + + mplsXCOperStatus</b></td><td> + %parm[#1]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr> + <tr><td><b> + + mplsXCOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr></table> + <p> + mplsXCDown trap received + mplsXCOperStatus=%parm[#1]% + mplsXCOperStatus=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.2.1.10.166.3 + + + generic + 6 + + + specific + 1 + + + uei.opennms.org/ietf/mplsTeStdMib/traps/mplsTunnelUp + MPLS-TE-STD-MIB defined trap event: mplsTunnelUp + <p>This notification is generated when a +mplsTunnelOperStatus object for one of the +configured tunnels is about to leave the down state +and transition into some other state (but not into +the notPresent state). This other state is +indicated by the included value of +mplsTunnelOperStatus.</p><table> + <tr><td><b> + + mplsTunnelAdminStatus</b></td><td> + %parm[#1]%;</td><td><p> + up(1) + down(2) + testing(3) + </p></td></tr> + <tr><td><b> + + mplsTunnelOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr></table> + <p> + mplsTunnelUp trap received + mplsTunnelAdminStatus=%parm[#1]% + mplsTunnelOperStatus=%parm[#2]%</p> + + Normal + + parm[#1] + + + + + + parm[#2] + + + + + + + + + + + + + id + .1.3.6.1.2.1.10.166.3 + + + generic + 6 + + + specific + 2 + + + uei.opennms.org/ietf/mplsTeStdMib/traps/mplsTunnelDown + MPLS-TE-STD-MIB defined trap event: mplsTunnelDown + <p>This notification is generated when a +mplsTunnelOperStatus object for one of the +configured tunnels is about to enter the down state +from some other state (but not from the notPresent +state). This other state is indicated by the +included value of mplsTunnelOperStatus.</p><table> + <tr><td><b> + + mplsTunnelAdminStatus</b></td><td> + %parm[#1]%;</td><td><p> + up(1) + down(2) + testing(3) + </p></td></tr> + <tr><td><b> + + mplsTunnelOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr></table> + <p> + mplsTunnelDown trap received + mplsTunnelAdminStatus=%parm[#1]% + mplsTunnelOperStatus=%parm[#2]%</p> + + Minor + + parm[#1] + + + + + + parm[#2] + + + + + + + + + + + + + id + .1.3.6.1.2.1.10.166.3 + + + generic + 6 + + + specific + 3 + + + uei.opennms.org/ietf/mplsTeStdMib/traps/mplsTunnelRerouted + MPLS-TE-STD-MIB defined trap event: mplsTunnelRerouted + <p>This notification is generated when a tunnel is +rerouted. If the mplsTunnelARHopTable is used, then +this tunnel instance's entry in the +mplsTunnelARHopTable MAY contain the new path for +this tunnel some time after this trap is issued by +the agent.</p><table> + <tr><td><b> + + mplsTunnelAdminStatus</b></td><td> + %parm[#1]%;</td><td><p> + up(1) + down(2) + testing(3) + </p></td></tr> + <tr><td><b> + + mplsTunnelOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr></table> + <p> + mplsTunnelRerouted trap received + mplsTunnelAdminStatus=%parm[#1]% + mplsTunnelOperStatus=%parm[#2]%</p> + + Warning + + parm[#1] + + + + + + parm[#2] + + + + + + + + + + + + + id + .1.3.6.1.2.1.10.166.3 + + + generic + 6 + + + specific + 4 + + + uei.opennms.org/ietf/mplsTeStdMib/traps/mplsTunnelReoptimized + MPLS-TE-STD-MIB defined trap event: mplsTunnelReoptimized + <p>This notification is generated when a tunnel is +reoptimized. If the mplsTunnelARHopTable is used, +then this tunnel instance's entry in the +mplsTunnelARHopTable MAY contain the new path for +this tunnel some time after this trap is issued by +the agent.</p><table> + <tr><td><b> + + mplsTunnelAdminStatus</b></td><td> + %parm[#1]%;</td><td><p> + up(1) + down(2) + testing(3) + </p></td></tr> + <tr><td><b> + + mplsTunnelOperStatus</b></td><td> + %parm[#2]%;</td><td><p> + up(1) + down(2) + testing(3) + unknown(4) + dormant(5) + notPresent(6) + lowerLayerDown(7) + </p></td></tr></table> + <p> + mplsTunnelReoptimized trap received + mplsTunnelAdminStatus=%parm[#1]% + mplsTunnelOperStatus=%parm[#2]%</p> + + Warning + + parm[#1] + + + + + + parm[#2] + + + + + + + + + + \ No newline at end of file diff --git a/opennms-base-assembly/src/main/filtered/etc/events/MRV.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/MRV.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/MRV.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/MRV.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/MSDP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/MSDP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/MSDP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/MSDP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/MadgeNetworks.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/MadgeNetworks.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/MadgeNetworks.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/MadgeNetworks.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/McAfee.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/McAfee.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/McAfee.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/McAfee.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Microsoft.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Microsoft.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Microsoft.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Microsoft.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/MikrotikRouterOS.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/MikrotikRouterOS.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/MikrotikRouterOS.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/MikrotikRouterOS.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Multicast.standard.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Multicast.standard.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Multicast.standard.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Multicast.standard.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Mylex.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Mylex.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Mylex.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Mylex.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/NORTEL.Contivity.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/NORTEL.Contivity.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/NORTEL.Contivity.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/NORTEL.Contivity.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/NetApp.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/NetApp.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/NetApp.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/NetApp.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/NetSNMP.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/NetSNMP.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/NetSNMP.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/NetSNMP.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Netbotz.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Netbotz.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Netbotz.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Netbotz.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Netgear.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Netgear.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Netgear.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Netgear.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/NetgearProsafeSmartSwitch.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/NetgearProsafeSmartSwitch.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/NetgearProsafeSmartSwitch.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/NetgearProsafeSmartSwitch.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/NetgearProsafeSmartSwitch.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/NetgearProsafeSmartSwitch.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/NetgearProsafeSmartSwitch.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/NetgearProsafeSmartSwitch.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Netscreen.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Netscreen.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Netscreen.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Netscreen.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Nokia.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Nokia.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Nokia.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Nokia.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Novell.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Novell.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Novell.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Novell.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/OSPF.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/OSPF.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/OSPF.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/OSPF.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/OpenSSH.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/OpenSSH.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/OpenSSH.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/OpenSSH.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/OpenWrt.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/OpenWrt.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/OpenWrt.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/OpenWrt.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Oracle.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Oracle.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Oracle.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Oracle.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Overland.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Overland.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Overland.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Overland.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Overture.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Overture.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Overture.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Overture.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/PCube.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/PCube.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/PCube.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/PCube.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/POSIX.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/POSIX.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/POSIX.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/POSIX.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Packeteer.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Packeteer.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Packeteer.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Packeteer.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Patrol.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Patrol.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Patrol.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Patrol.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Pingtel.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Pingtel.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Pingtel.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Pingtel.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Pixelmetrix.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Pixelmetrix.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Pixelmetrix.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Pixelmetrix.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Polycom.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Polycom.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Polycom.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Polycom.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Postfix.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Postfix.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Postfix.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Postfix.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Powerware.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Powerware.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Powerware.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Powerware.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Primecluster.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Primecluster.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Primecluster.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Primecluster.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Procmail.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Procmail.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Procmail.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Procmail.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Quintum.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Quintum.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Quintum.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Quintum.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/RADLAN-MIB.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/RADLAN-MIB.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/RADLAN-MIB.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/RADLAN-MIB.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/RAPID-CITY.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/RAPID-CITY.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/RAPID-CITY.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/RAPID-CITY.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/RFC1382.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/RFC1382.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/RFC1382.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/RFC1382.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/RFC1628.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/RFC1628.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/RFC1628.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/RFC1628.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/RMON.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/RMON.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/RMON.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/RMON.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Raytheon.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Raytheon.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Raytheon.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Raytheon.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Redline.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Redline.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Redline.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Redline.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Rightfax.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Rightfax.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Rightfax.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Rightfax.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/RiverbedSteelhead.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/RiverbedSteelhead.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/RiverbedSteelhead.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/RiverbedSteelhead.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/SNA-NAU.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/SNA-NAU.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/SNA-NAU.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/SNA-NAU.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/SNMP-REPEATER.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/SNMP-REPEATER.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/SNMP-REPEATER.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/SNMP-REPEATER.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Sensaphone.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Sensaphone.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Sensaphone.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Sensaphone.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Sentry.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Sentry.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Sentry.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Sentry.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath3000-HG1500.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath3000-HG1500.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath3000-HG1500.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath3000-HG1500.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath3000.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath3000.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath3000.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath3000.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath4000.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath4000.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath4000.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath4000.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath8000-OpenScapeVoice.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath8000-OpenScapeVoice.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Siemens-HiPath8000-OpenScapeVoice.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Siemens-HiPath8000-OpenScapeVoice.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Snort.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Snort.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Snort.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Snort.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/SonicWall.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/SonicWall.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/SonicWall.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/SonicWall.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Sonus.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Sonus.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Sonus.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Sonus.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Sudo.syslog.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Sudo.syslog.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Sudo.syslog.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Sudo.syslog.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/SunILOM.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/SunILOM.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/SunILOM.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/SunILOM.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/SwissQual.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/SwissQual.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/SwissQual.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/SwissQual.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Symbol.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Symbol.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Symbol.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Symbol.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Syslogd.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Syslogd.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Syslogd.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Syslogd.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/SystemEdge.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/SystemEdge.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/SystemEdge.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/SystemEdge.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/TUT.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/TUT.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/TUT.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/TUT.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/TransPath.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/TransPath.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/TransPath.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/TransPath.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Trendmicro.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Trendmicro.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Trendmicro.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Trendmicro.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/TrippLite.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/TrippLite.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/TrippLite.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/TrippLite.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/UPS-MIB.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/UPS-MIB.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/UPS-MIB.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/UPS-MIB.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Uptime.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Uptime.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Uptime.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Uptime.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/VMWare.env.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.env.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/VMWare.env.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.env.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/VMWare.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/VMWare.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/VMWare.obsolete.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.obsolete.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/VMWare.obsolete.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.obsolete.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/VMWare.vc.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.vc.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/VMWare.vc.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.vc.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/VMWare.vminfo.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.vminfo.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/VMWare.vminfo.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/VMWare.vminfo.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Veeam_Backup-Replication.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Veeam_Backup-Replication.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Veeam_Backup-Replication.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Veeam_Backup-Replication.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Veraz.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Veraz.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Veraz.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Veraz.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Waverider.3000.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Waverider.3000.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Waverider.3000.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Waverider.3000.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Websense.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Websense.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Websense.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Websense.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Xerox-V2.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Xerox-V2.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Xerox-V2.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Xerox-V2.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/Xerox.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/Xerox.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/Xerox.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/Xerox.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/fcmgmt.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/fcmgmt.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/fcmgmt.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/fcmgmt.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ietf.dlsw.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.dlsw.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ietf.dlsw.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.dlsw.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ietf.docsis.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.docsis.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ietf.docsis.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.docsis.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ietf.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ietf.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ietf.ptopo.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.ptopo.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ietf.ptopo.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.ptopo.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ietf.sna-dlc.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.sna-dlc.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ietf.sna-dlc.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.sna-dlc.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ietf.tn3270e.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.tn3270e.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ietf.tn3270e.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.tn3270e.events.xml diff --git a/opennms-base-assembly/src/main/filtered/etc/events/ietf.vrrp.events.xml b/opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.vrrp.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/ietf.vrrp.events.xml rename to opennms-base-assembly/src/main/filtered/etc/examples/events/ietf.vrrp.events.xml diff --git a/opennms-config-api/src/main/java/org/opennms/netmgt/config/api/EventConfDao.java b/opennms-config-api/src/main/java/org/opennms/netmgt/config/api/EventConfDao.java index bf7cdd2a07ed..7d87b1ce5bad 100644 --- a/opennms-config-api/src/main/java/org/opennms/netmgt/config/api/EventConfDao.java +++ b/opennms-config-api/src/main/java/org/opennms/netmgt/config/api/EventConfDao.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.xml.eventconf.Event; import org.opennms.netmgt.xml.eventconf.Events; import org.springframework.dao.DataAccessException; @@ -73,11 +74,6 @@ public interface EventConfDao { */ String getEventLabel(String uei); - /** - *

saveCurrent

- */ - void saveCurrent(); - /** *

getEventsByLabel

* @@ -86,33 +82,12 @@ public interface EventConfDao { List getEventsByLabel(); /** - * Adds the event to the root level event config storage (file). - * Does not save (you must save independently with saveCurrent) + * Adds the event to the root level event config storage. * * @param event The fully configured Event object to add. */ void addEvent(Event event); - /** - * Adds the given event to the programmatic event store. This store currently implemented as a file (referenced from eventconf.xml) - * The programmatic store is a separate storage area, so that incidental programmatic editing of events (e.g. custom UEIs for thresholds, edited - * through the Web-UI) does not clutter up the otherwise carefully maintained event files. This method does not save (persist) the changes - * - * @param event The fully configured Event object to add. - */ - void addEventToProgrammaticStore(Event event); - - /** - * Removes the given event from the programmatic event store. This store currently implemented as a file (referenced from eventconf.xml) - * The programmatic store is a separate storage area, so that incidental programmatic editing of events (e.g. custom UEIs for thresholds, edited - * through the Web-UI) does not clutter up the otherwise carefully maintained event files. This method does not save (persist) the changes - * - * @param event The fully configured Event object to remove. - * @returns true if the event was removed, false if it wasn't found (either not in the programmatic store, or the store didn't exist) - * @return a boolean. - */ - boolean removeEventFromProgrammaticStore(Event event); - /** *

isSecureTag

* @@ -143,4 +118,11 @@ public interface EventConfDao { * @return a {@link org.opennms.netmgt.xml.eventconf.Events} object. */ Events getRootEvents(); + + /** + * Load event conf from DB, should replace loading of event conf from filesystem + * @param dbEvents + */ + void loadEventsFromDB(List dbEvents); + } diff --git a/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Event.java b/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Event.java index 05989336b585..3bf6e1d7fd11 100644 --- a/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Event.java +++ b/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Event.java @@ -572,4 +572,12 @@ public String toString() { .toString(); } + public void setEventMatcher(EventMatcher eventMatcher) { + this.m_matcher = eventMatcher; + } + + public EventMatcher getEventMatcher() { + return this.m_matcher; + } + } diff --git a/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Events.java b/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Events.java index 0ca5450445a4..45bc4208f6cd 100644 --- a/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Events.java +++ b/opennms-config-model/src/main/java/org/opennms/netmgt/xml/eventconf/Events.java @@ -470,6 +470,10 @@ public Events getLoadEventsByFile(final String relativePath) { return m_loadedEventFiles.get(relativePath); } + public Map getLoadedEventFiles() { + return m_loadedEventFiles; + } + public void addLoadedEventFile(final String relativePath, final Events events) { if (!m_eventFiles.contains(relativePath)) { m_eventFiles.add(relativePath); diff --git a/opennms-config-tester/src/main/resources/META-INF/opennms/applicationContext-configTester.xml b/opennms-config-tester/src/main/resources/META-INF/opennms/applicationContext-configTester.xml index eab04b5c2db9..d161f92fbeec 100644 --- a/opennms-config-tester/src/main/resources/META-INF/opennms/applicationContext-configTester.xml +++ b/opennms-config-tester/src/main/resources/META-INF/opennms/applicationContext-configTester.xml @@ -186,7 +186,6 @@ - diff --git a/opennms-config/pom.xml b/opennms-config/pom.xml index f5d8ac82f72c..a96e00d57ba0 100644 --- a/opennms-config/pom.xml +++ b/opennms-config/pom.xml @@ -11,6 +11,17 @@ bundle + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + org.apache.felix maven-bundle-plugin diff --git a/opennms-config/src/main/java/org/opennms/netmgt/config/DefaultEventConfDao.java b/opennms-config/src/main/java/org/opennms/netmgt/config/DefaultEventConfDao.java index 4bbd083740af..26f14392ef36 100644 --- a/opennms-config/src/main/java/org/opennms/netmgt/config/DefaultEventConfDao.java +++ b/opennms-config/src/main/java/org/opennms/netmgt/config/DefaultEventConfDao.java @@ -21,21 +21,18 @@ */ package org.opennms.netmgt.config; -import java.io.IOException; import java.util.ArrayList; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; import java.util.stream.Collectors; -import org.opennms.core.config.api.ConfigReloadContainer; import org.opennms.core.xml.JaxbUtils; import org.opennms.netmgt.config.api.EventConfDao; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.xml.eventconf.Event; import org.opennms.netmgt.xml.eventconf.EventLabelComparator; import org.opennms.netmgt.xml.eventconf.EventMatchers; @@ -48,65 +45,26 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataRetrievalFailureException; public class DefaultEventConfDao implements EventConfDao, InitializingBean { - private static final Logger LOG = LoggerFactory.getLogger(DefaultEventConfDao.class); - private static final String DEFAULT_PROGRAMMATIC_STORE_RELATIVE_PATH = "events/programmatic.events.xml"; - /** - * Relative URL for the programmatic store configuration, relative to the - * root configuration resource (which must be resolvable to a URL). - */ - private String m_programmaticStoreRelativePath = DEFAULT_PROGRAMMATIC_STORE_RELATIVE_PATH; + private static final Logger LOG = LoggerFactory.getLogger(DefaultEventConfDao.class); private Events m_events; - private Resource m_configResource; - private Partition m_partition; - /** - * Used to keep track of the last modified time for the loaded event files. - * See the reloadConfig() for details. - */ - private Map m_lastModifiedEventFiles = new LinkedHashMap(); - - private ConfigReloadContainer m_extContainer; - - public String getProgrammaticStoreRelativeUrl() { - return m_programmaticStoreRelativePath; - } - - public void setProgrammaticStoreRelativeUrl(String programmaticStoreRelativeUrl) { - m_programmaticStoreRelativePath = programmaticStoreRelativeUrl; - } - - void validateConfig(final Resource resource) throws DataAccessException { - final Events events; - - try { - events = JaxbUtils.unmarshal(Events.class, resource, true); - } catch (Exception e) { - LOG.error("Eventd configuration validation failed! Cannot parse file {}", resource.getFilename(), e); - throw new DataRetrievalFailureException("Eventd configuration validation failed! Cannot parse file " + resource.getFilename()); - } + public DefaultEventConfDao() { + m_events = new Events(); + m_partition = new EnterpriseIdPartition(); + m_events.initialize(m_partition, new EventOrdering()); + } - for (final String eventFilename : events.getEventFiles()) { - validateConfig(Events.getRelative(m_configResource, eventFilename)); - } - } @Override public void reload() throws DataAccessException { - validateConfig(m_configResource); - try { - reloadConfig(); - } catch (Exception e) { - throw new DataRetrievalFailureException("Unable to load " + m_configResource, e); - } + // Reload happens whenever DB gets updated, no need for explicit reload } @Override @@ -163,11 +121,6 @@ public String getEventLabel(final String uei) { return event == null ? null : event.getEventLabel(); } - @Override - public void saveCurrent() { - m_events.save(m_configResource); - } - public List getAllEvents() { return m_events.forEachEvent(new ArrayList<>(), (EventCallback>) (accum, event) -> { accum.add(event); @@ -198,34 +151,6 @@ public void addEvent(Event event) { m_events.initialize(m_partition, new EventOrdering()); } - @Override - public void addEventToProgrammaticStore(Event event) { - Events programmaticEvents = m_events.getLoadEventsByFile(m_programmaticStoreRelativePath); - if (programmaticEvents == null) { - programmaticEvents = new Events(); - m_events.addLoadedEventFile(m_programmaticStoreRelativePath, programmaticEvents); - } - - programmaticEvents.addEvent(event); - m_events.initialize(m_partition, new EventOrdering()); - - } - - @Override - public boolean removeEventFromProgrammaticStore(Event event) { - Events programmaticEvents = m_events.getLoadEventsByFile(m_programmaticStoreRelativePath); - if (programmaticEvents == null) return false; - - programmaticEvents.removeEvent(event); - if (programmaticEvents.getEvents().size() <= 0) { - m_events.removeLoadedEventFile(m_programmaticStoreRelativePath); - } - - m_events.initialize(m_partition, new EventOrdering()); - - return true; - } - @Override public boolean isSecureTag(String tag) { return m_events.isSecureTag(tag); @@ -253,14 +178,71 @@ public Events getRootEvents() { return m_events; } - public void setConfigResource(Resource configResource) throws IOException { - m_configResource = configResource; + @Override + public void loadEventsFromDB(List dbEvents) { + + // Group events by source and sort by source fileOrder + Map> eventsBySource = dbEvents.stream() + .collect(Collectors.groupingBy( + event -> event.getSource().getName(), + LinkedHashMap::new, + Collectors.toList() + )); + + // Sort sources by fileOrder + List>> sortedSources = sortSourcesByFileOrder(eventsBySource); + + Events rootEvents = new Events(); + // Build Events per source + for (Map.Entry> sourceEntry : sortedSources) { + Events eventsForSource = buildEventsForSource(sourceEntry.getValue()); + rootEvents.addLoadedEventFile(sourceEntry.getKey(), eventsForSource); + } + + synchronized (this) { + m_partition = new EnterpriseIdPartition(); + rootEvents.initialize(m_partition, new EventOrdering()); + m_events = rootEvents; + } + } + + private List>> sortSourcesByFileOrder(Map> eventsBySource) { + return eventsBySource.entrySet().stream() + .sorted(Map.Entry.comparingByValue((events1, events2) -> { + Integer order1 = events1.get(0).getSource().getFileOrder(); + Integer order2 = events2.get(0).getSource().getFileOrder(); + return Integer.compare(order2 != null ? order2 : 0, order1 != null ? order1 : 0); + })) + .toList(); + } + + private Events buildEventsForSource(List sourceEvents) { + Events eventsForSource = new Events(); + for (EventConfEvent dbEvent : sourceEvents) { + parseAndAddEvent(eventsForSource, dbEvent); + } + return eventsForSource; + } + + private void parseAndAddEvent(Events eventsForSource, EventConfEvent dbEvent) { + String xmlContent = dbEvent.getXmlContent(); + if (xmlContent != null && !xmlContent.trim().isEmpty()) { + try { + Event event = JaxbUtils.unmarshal(Event.class, xmlContent); + if (event != null) { + eventsForSource.addEvent(event); + } + } catch (Exception e) { + LOG.warn("Failed to parse event XML content for UEI {}", dbEvent.getUei(), e); + } + } } + @Override public void afterPropertiesSet() throws DataAccessException { - loadConfig(); - initExtensions(); + // Event Conf gets loaded by loadEventsFromDB. + // Since this Class can't access DB at bean creation time, this is delegated to EventConfPersistenceService } private static class EnterpriseIdPartition implements Partition { @@ -288,67 +270,5 @@ public String group(org.opennms.netmgt.xml.event.Event matchingEvent) { } - private synchronized void reloadConfig() throws DataAccessException { - try { - // Load the root event file - Events events = JaxbUtils.unmarshal(Events.class, m_configResource); - // Insert events exposed via the service registry - m_extContainer.reload(); - Events extEvents = m_extContainer.getObject(); - if (extEvents != null) { - // Prioritize events loaded from the registry along with any loaded from the root config - events.getEvents().addAll(0, extEvents.getEvents()); - if (LOG.isDebugEnabled()) { - LOG.debug("Events with the following UEIs are contributed by one or more extensions: {}", extEvents.getEvents().stream() - .map(Event::getUei) - .collect(Collectors.joining(","))); - } - } - - // Hash the list of event files for efficient lookup - Set eventFiles = new HashSet<>(); - eventFiles.addAll(events.getEventFiles()); - - // Copy the loaded event files from the current root to the new root - // if and only if they exist in the new root - for (String eventFile : m_events.getEventFiles()) { - if (!eventFiles.contains(eventFile)) { - m_lastModifiedEventFiles.remove(eventFile); - continue; - } - events.addLoadedEventFile(eventFile, m_events.getLoadEventsByFile(eventFile)); - } - - // Load/reload the event files as necessary - events.loadEventFilesIfModified(m_configResource, m_lastModifiedEventFiles); - - // Order the events for efficient searching - events.initialize(m_partition, new EventOrdering()); - - m_events = events; - } catch (Exception e) { - throw new DataRetrievalFailureException("Unable to load " + m_configResource, e); - } - } - - private synchronized void loadConfig() throws DataAccessException { - try { - Events events = JaxbUtils.unmarshal(Events.class, m_configResource); - m_lastModifiedEventFiles = events.loadEventFiles(m_configResource); - - m_partition = new EnterpriseIdPartition(); - events.initialize(m_partition, new EventOrdering()); - - m_events = events; - } catch (Exception e) { - throw new DataRetrievalFailureException("Unabled to load " + m_configResource, e); - } - } - - private void initExtensions() { - m_extContainer = new ConfigReloadContainer.Builder<>(Events.class) - .withFolder((accumulator, next) -> accumulator.getEvents().addAll(next.getEvents())) - .build(); - } } diff --git a/opennms-config/src/main/resources/META-INF/opennms/applicationContext-commonConfigs.xml b/opennms-config/src/main/resources/META-INF/opennms/applicationContext-commonConfigs.xml index 992e2b2eba55..fad511e67cea 100644 --- a/opennms-config/src/main/resources/META-INF/opennms/applicationContext-commonConfigs.xml +++ b/opennms-config/src/main/resources/META-INF/opennms/applicationContext-commonConfigs.xml @@ -59,13 +59,7 @@ - - - - - - diff --git a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDaoReloadTest.java b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDaoReloadTest.java index 935b37d613f9..8f559de3ca01 100644 --- a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDaoReloadTest.java +++ b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDaoReloadTest.java @@ -26,6 +26,7 @@ import java.io.File; import java.io.IOException; +import java.util.List; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -34,6 +35,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.opennms.core.test.MockLogAppender; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.xml.eventconf.Event; import org.springframework.core.io.ClassPathResource; @@ -63,12 +65,13 @@ public void tearDown() { public void canReloadEventsInClasspath() throws IOException { // Load DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(getResourceForRelativePath("reloaded/eventconf.xml")); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("reloaded/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); // Reload - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("reloaded/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); } @@ -89,12 +92,13 @@ public void canReloadEventsOnDisk() throws IOException { // Load DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new FileSystemResource(eventconfXml)); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); // Reload - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); } @@ -120,8 +124,8 @@ public void canReloadEvents() throws Exception { // Load DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new FileSystemResource(eventconfXml)); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); // Replace the eventconf.xml with one that doesn't reference any files @@ -130,7 +134,8 @@ public void canReloadEvents() throws Exception { eventconfXml); // Reload - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(1, eventConfDao.getAllEvents().size()); // Put the original eventconf.xml back @@ -138,7 +143,8 @@ public void canReloadEvents() throws Exception { eventconfXml); // Reload - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); // Replace the BGP4.events.xml with another that has a few more events @@ -147,7 +153,8 @@ public void canReloadEvents() throws Exception { bgp4eventsXml); // Reload - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(5, eventConfDao.getAllEvents().size()); } @@ -162,8 +169,8 @@ public void canMaintainOrderOnReload() throws Exception { // Load DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new FileSystemResource(eventconfXml)); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(0, eventConfDao.getAllEvents().size()); EventBuilder eb = new EventBuilder("uei.opennms.org/test/order", "JUnit"); @@ -176,7 +183,8 @@ public void canMaintainOrderOnReload() throws Exception { copyEventConfig("order/1.events.xml", "1.events.xml"); // Reload - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(1, eventConfDao.getAllEvents().size()); event = eventConfDao.findByEvent(eb.getEvent()); @@ -188,7 +196,8 @@ public void canMaintainOrderOnReload() throws Exception { copyEventConfig("order/2.events.xml", "2.events.xml"); // Reload - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(eventconfXml)); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(2, eventConfDao.getAllEvents().size()); event = eventConfDao.findByEvent(eb.getEvent()); @@ -208,15 +217,13 @@ private Resource getResourceForRelativePath(String resourceSuffix) { @Test public void NMS15289_working() throws IOException { DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(getResourceForRelativePath("reloaded/eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("reloaded/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); - eventConfDao.setConfigResource(getResourceForRelativePath("NMS-15289/working-eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("NMS-15289/working-eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); // reload should work assertEquals(1, eventConfDao.getAllEvents().size()); @@ -225,15 +232,13 @@ public void NMS15289_working() throws IOException { @Test(expected = DataRetrievalFailureException.class) public void NMS15289_notFound() throws IOException { DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(getResourceForRelativePath("reloaded/eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("reloaded/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); - eventConfDao.setConfigResource(getResourceForRelativePath("NMS-15289/broken0-eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("NMS-15289/broken0-eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); // reload should be skipped assertEquals(3, eventConfDao.getAllEvents().size()); @@ -242,15 +247,13 @@ public void NMS15289_notFound() throws IOException { @Test(expected = DataRetrievalFailureException.class) public void NMS15289_brokenRoot() throws IOException { DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(getResourceForRelativePath("reloaded/eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("reloaded/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); - eventConfDao.setConfigResource(getResourceForRelativePath("NMS-15289/broken1-eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("NMS-15289/broken1-eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); // reload should be skipped assertEquals(3, eventConfDao.getAllEvents().size()); @@ -259,15 +262,13 @@ public void NMS15289_brokenRoot() throws IOException { @Test(expected = DataRetrievalFailureException.class) public void NMS15289_brokenChild() throws IOException { DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(getResourceForRelativePath("reloaded/eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("reloaded/eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); assertEquals(3, eventConfDao.getAllEvents().size()); - eventConfDao.setConfigResource(getResourceForRelativePath("NMS-15289/broken2-eventconf.xml")); - eventConfDao.afterPropertiesSet(); - eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(getResourceForRelativePath("NMS-15289/broken2-eventconf.xml")); + eventConfDao.loadEventsFromDB(eventConfEventList); // reload should be skipped assertEquals(3, eventConfDao.getAllEvents().size()); diff --git a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDataTest.java b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDataTest.java index c8ec90dcbef3..06c46ab66797 100644 --- a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDataTest.java +++ b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfDataTest.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import org.junit.After; @@ -38,6 +39,7 @@ import org.opennms.core.test.MockLogAppender; import org.opennms.core.utils.Base64; import org.opennms.netmgt.eventd.datablock.EventConfData; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.xml.event.Event; import org.opennms.netmgt.xml.eventconf.LogDestType; @@ -53,8 +55,9 @@ public void setUp() throws Exception { MockLogAppender.setupLogging(false); eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new FileSystemResource(ConfigurationTestUtils.getFileForResource(this, "eventconf.xml"))); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(ConfigurationTestUtils.getFileForResource(this, "eventconf.xml"))); + eventConfDao.loadEventsFromDB(eventConfEventList); + } diff --git a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfMatcherTest.java b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfMatcherTest.java index 9e7fe999c62d..4eb5146d8480 100644 --- a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfMatcherTest.java +++ b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfMatcherTest.java @@ -28,12 +28,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.io.File; +import java.util.List; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.opennms.core.test.MockLogAppender; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.xml.eventconf.Event; import org.springframework.core.io.FileSystemResource; @@ -46,8 +48,8 @@ public class EventConfMatcherTest { public void setUp() throws Exception { MockLogAppender.setupLogging(); eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new FileSystemResource(new File("src/test/resources/matcher-test.events.xml"))); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(new File("src/test/resources/matcher-test.events.xml"))); + eventConfDao.loadEventsFromDB(eventConfEventList); Assert.assertEquals(9, eventConfDao.getAllEvents().size()); } diff --git a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfPriorityTest.java b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfPriorityTest.java index 969aae9e2299..48aeabc90c67 100644 --- a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfPriorityTest.java +++ b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfPriorityTest.java @@ -32,6 +32,7 @@ import org.junit.Before; import org.junit.Test; import org.opennms.core.test.MockLogAppender; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.xml.eventconf.Event; import org.springframework.core.io.FileSystemResource; @@ -53,8 +54,9 @@ public void tearDown() { @Test public void canFindHigherPriorityInFile() throws Exception { - eventConfDao.setConfigResource(new FileSystemResource(new File("src/test/resources/priority/eventconf.xml"))); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(new File("src/test/resources/priority/eventconf.xml"))); + eventConfDao.loadEventsFromDB(eventConfEventList); + Assert.assertEquals(3, eventConfDao.getAllEvents().size()); EventBuilder eb = new EventBuilder("uei.opennms.org/vendor/3Com/traps/a3ComFddiMACNeighborChangeEvent", "JUnit"); @@ -70,8 +72,8 @@ public void canFindHigherPriorityInFile() throws Exception { @Test public void canFindHigherPriorityInLaterFile() throws Exception { - eventConfDao.setConfigResource(new FileSystemResource(new File("src/test/resources/priority/eventconf2.xml"))); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(new File("src/test/resources/priority/eventconf2.xml"))); + eventConfDao.loadEventsFromDB(eventConfEventList); Assert.assertEquals(4, eventConfDao.getAllEvents().size()); EventBuilder eb = new EventBuilder("uei.opennms.org/vendor/3Com/traps/a3ComFddiMACNeighborChangeEvent", "JUnit"); @@ -87,8 +89,8 @@ public void canFindHigherPriorityInLaterFile() throws Exception { @Test public void canUseHighestPriorityDefnWhenInRoot() throws Exception { - eventConfDao.setConfigResource(new FileSystemResource(new File("src/test/resources/priority/eventconf3.xml"))); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(new File("src/test/resources/priority/eventconf3.xml"))); + eventConfDao.loadEventsFromDB(eventConfEventList); Assert.assertEquals(4, eventConfDao.getAllEvents().size()); EventBuilder eb = new EventBuilder("uei.opennms.org/vendor/3Com/traps/a3ComFddiMACNeighborChangeEvent", "JUnit"); @@ -104,8 +106,8 @@ public void canUseHighestPriorityDefnWhenInRoot() throws Exception { @Test public void doesNotDuplicateWhenGettingByUEI() throws Exception { - eventConfDao.setConfigResource(new FileSystemResource(new File("src/test/resources/priority/eventconf3.xml"))); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(new File("src/test/resources/priority/eventconf3.xml"))); + eventConfDao.loadEventsFromDB(eventConfEventList); Assert.assertEquals(4, eventConfDao.getAllEvents().size()); EventBuilder eb = new EventBuilder("uei.opennms.org/vendor/3Com/traps/a3ComFddiMACNeighborChangeEvent", "JUnit"); diff --git a/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfTestUtil.java b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfTestUtil.java new file mode 100644 index 000000000000..93c5d4e51382 --- /dev/null +++ b/opennms-config/src/test/java/org/opennms/netmgt/config/EventConfTestUtil.java @@ -0,0 +1,120 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.config; + +import org.apache.commons.lang.StringUtils; +import org.opennms.core.xml.JaxbUtils; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.netmgt.model.events.EventConfSourceMetadataDto; +import org.opennms.netmgt.xml.eventconf.Events; +import org.springframework.core.io.Resource; +import org.springframework.dao.DataRetrievalFailureException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +public final class EventConfTestUtil { + + private static final AtomicLong sourceIdGenerator = new AtomicLong(); + private static final AtomicLong eventIdGenerator = new AtomicLong(); + + public static List parseResourcesAsEventConfEvents(Resource configResource) throws IOException { + List eventConfEventList = new ArrayList<>(); + + try { + Events unmarshalEvents = JaxbUtils.unmarshal(Events.class, configResource); + unmarshalEvents.loadEventFiles(configResource); + unmarshalEvents.getLoadedEventFiles().put(configResource.getFilename(), unmarshalEvents); + + Map fileEventsMap = unmarshalEvents.getLoadedEventFiles(); + int fileOrder = fileEventsMap.size(); + + for (Map.Entry entry : fileEventsMap.entrySet()) { + String fileName = entry.getKey() == null ? "" : entry.getKey(); + Events events = entry.getValue(); + + String withoutExtension = fileName.endsWith(".xml") + ? fileName.substring(0, fileName.lastIndexOf(".xml")) + : fileName; + + EventConfSourceMetadataDto metadataDto = new EventConfSourceMetadataDto.Builder() + .filename(withoutExtension) + .now(new Date()) + .vendor(StringUtils.substringBefore(fileName, ".")) + .username("system") + .description("") + .eventCount(events.getEvents().size()) + .fileOrder(fileOrder--) + .build(); + + EventConfSource source = createSource(metadataDto); + + eventConfEventList.addAll( + getEventConfEventList(source, events, metadataDto.getUsername(), metadataDto.getNow()) + ); + } + } catch (Exception e) { + throw new DataRetrievalFailureException("Unable to load " + configResource, e); + } + + return eventConfEventList; + } + + private static EventConfSource createSource(final EventConfSourceMetadataDto eventConfSourceMetadataDto) { + EventConfSource source = new EventConfSource(); + source.setId(sourceIdGenerator.incrementAndGet()); + source.setCreatedTime(eventConfSourceMetadataDto.getNow()); + source.setName(eventConfSourceMetadataDto.getFilename()); + source.setFileOrder(eventConfSourceMetadataDto.getFileOrder()); + source.setEventCount(eventConfSourceMetadataDto.getEventCount()); + source.setEnabled(true); + source.setUploadedBy(eventConfSourceMetadataDto.getUsername()); + source.setLastModified(eventConfSourceMetadataDto.getNow()); + source.setVendor(eventConfSourceMetadataDto.getVendor()); + source.setDescription(eventConfSourceMetadataDto.getDescription()); + return source; + } + + private static List getEventConfEventList(EventConfSource source, Events events, String username, Date now) { + List eventEntities = events.getEvents().stream().map(parsed -> { + EventConfEvent event = new EventConfEvent(); + event.setId(eventIdGenerator.incrementAndGet()); + event.setSource(source); + event.setUei(parsed.getUei()); + event.setEventLabel(parsed.getEventLabel()); + event.setDescription(parsed.getDescr()); + event.setEnabled(true); + event.setXmlContent(JaxbUtils.marshal(parsed)); + event.setCreatedTime(now); + event.setLastModified(now); + event.setModifiedBy(username); + return event; + }).toList(); + return eventEntities; + } + +} diff --git a/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactoryIT.java b/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactoryIT.java index 4c4061502ce0..41224dbc2d6b 100644 --- a/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactoryIT.java +++ b/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactoryIT.java @@ -55,6 +55,7 @@ import org.opennms.core.utils.InetAddressUtils; import org.opennms.core.xml.JaxbUtils; import org.opennms.netmgt.events.api.EventConstants; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.model.events.snmp.SyntaxToEvent; import org.opennms.netmgt.snmp.SnmpObjId; @@ -89,14 +90,15 @@ public class EventconfFactoryIT { @Before public void setUp() throws Exception { - m_eventConfDao = new DefaultEventConfDao(); - m_eventConfDao.setConfigResource(new FileSystemResource(ConfigurationTestUtils.getFileForConfigFile("eventconf.xml"))); - m_eventConfDao.afterPropertiesSet(); + m_eventConfDao = new DefaultEventConfDao(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new ClassPathResource("etc/eventconf.xml")); + m_eventConfDao.loadEventsFromDB(eventConfEventList); } @Test public void testIsSecureTagWhenExists() { - assertTrue("isSecureTag(\"logmsg\") should be true", m_eventConfDao.isSecureTag("logmsg")); + //In the new implementation of loadEventsFromDB, we are no longer saving the global attribute and its corresponding value. + assertFalse("isSecureTag(\"logmsg\") should be true", m_eventConfDao.isSecureTag("logmsg")); } @Test @@ -436,8 +438,10 @@ public void testGetAlarmType() { //Ensure reload does indeed reload fresh data @Test public void testReload() throws Exception { - m_eventConfDao.setConfigResource(new ClassPathResource(getResourceForRelativePath("eventconf-speedtest/eventconf.xml"))); + //m_eventConfDao.setConfigResource(new ClassPathResource(getResourceForRelativePath("eventconf-speedtest/eventconf.xml"))); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new ClassPathResource(getResourceForRelativePath("eventconf-speedtest/eventconf.xml"))); + m_eventConfDao.loadEventsFromDB(eventConfEventList); String newUEI="uei.opennms.org/custom/newTestUEI"; List events=m_eventConfDao.getEvents(knownUEI1); Event event=(Event)events.get(0); @@ -453,7 +457,9 @@ public void testReload() throws Exception { //Now reload without saving - should not find the new one, but should find the old one try { - m_eventConfDao.reload(); + // m_eventConfDao.reload(); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new ClassPathResource(getResourceForRelativePath("eventconf-speedtest/eventconf.xml"))); + m_eventConfDao.loadEventsFromDB(eventConfEventList); } catch (Throwable e) { e.printStackTrace(); fail("Should not have had exception while reloading factory "+e.getMessage()); @@ -590,7 +596,7 @@ public void testLoadConfigurationWithClassPathInclude() throws Exception { */ @Test public void testIncludedEventFilesExistAndNoExtras() throws Exception { - File eventConfFile = ConfigurationTestUtils.getFileForConfigFile("eventconf.xml"); + File eventConfFile = new ClassPathResource("etc/eventconf.xml").getFile(); File eventsDirFile = new File(eventConfFile.getParentFile(), "events"); assertTrue("events directory exists at " + eventsDirFile.getAbsolutePath(), eventsDirFile.exists()); assertTrue("events directory is a directory at " + eventsDirFile.getAbsolutePath(), eventsDirFile.isDirectory()); @@ -631,8 +637,8 @@ public boolean accept(File file, String name) { @Test public void testLoadStandardConfiguration() throws Exception { DefaultEventConfDao dao = new DefaultEventConfDao(); - dao.setConfigResource(new FileSystemResource(ConfigurationTestUtils.getFileForConfigFile("eventconf.xml"))); - dao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(ConfigurationTestUtils.getFileForConfigFile("eventconf.xml"))); + dao.loadEventsFromDB(eventConfEventList); } private DefaultEventConfDao loadConfiguration(String relativeResourcePath) throws DataAccessException, IOException { @@ -641,15 +647,15 @@ private DefaultEventConfDao loadConfiguration(String relativeResourcePath) throw private DefaultEventConfDao loadConfiguration(String relativeResourcePath, boolean passFile) throws DataAccessException, IOException { DefaultEventConfDao dao = new DefaultEventConfDao(); - + List eventConfEventList = new ArrayList<>(); if (passFile) { URL url = getUrlForRelativeResourcePath(relativeResourcePath); - dao.setConfigResource(new MockFileSystemResourceWithInputStream(new File(url.getFile()), getFilteredInputStreamForConfig(relativeResourcePath))); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new MockFileSystemResourceWithInputStream(new File(url.getFile()), getFilteredInputStreamForConfig(relativeResourcePath))); } else { - dao.setConfigResource(new InputStreamResource(getFilteredInputStreamForConfig(relativeResourcePath))); + eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new InputStreamResource(getFilteredInputStreamForConfig(relativeResourcePath))); } - - dao.afterPropertiesSet(); + + dao.loadEventsFromDB(eventConfEventList); return dao; } diff --git a/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactorySaveTest.java b/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactorySaveTest.java index 7f0b7f03c784..e69de29bb2d1 100644 --- a/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactorySaveTest.java +++ b/opennms-config/src/test/java/org/opennms/netmgt/config/EventconfFactorySaveTest.java @@ -1,265 +0,0 @@ -/* - * Licensed to The OpenNMS Group, Inc (TOG) under one or more - * contributor license agreements. See the LICENSE.md file - * distributed with this work for additional information - * regarding copyright ownership. - * - * TOG licenses this file to You under the GNU Affero General - * Public License Version 3 (the "License") or (at your option) - * any later version. You may not use this file except in - * compliance with the License. You may obtain a copy of the - * License at: - * - * https://www.gnu.org/licenses/agpl-3.0.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package org.opennms.netmgt.config; - -import java.io.File; -import java.util.List; - -import org.apache.commons.io.FileUtils; -import org.opennms.netmgt.xml.eventconf.Event; -import org.opennms.netmgt.xml.eventconf.LogDestType; -import org.opennms.netmgt.xml.eventconf.Logmsg; -import org.opennms.test.FileAnticipator; -import org.springframework.core.io.FileSystemResource; - -import junit.framework.TestCase; - -/** - * - * @author DJ Gregor - * @author Craig Miskell - */ -public class EventconfFactorySaveTest extends TestCase { - private static final String knownUEI1="uei.opennms.org/opennmsConfig/eventconf"; - private static final String knownSubfileUEI1="uei.opennms.org/IETF/Bridge/traps/newRoot"; - - private static final String newUEI="uei.opennms.org/custom/addedUEI"; - private static final String newEventLabel="A New Event which is added to the eventconf"; - private static final String newDescr="A slightly longer descriptive bit of text"; - private static final LogDestType newDest=LogDestType.LOGNDISPLAY; - private static final String newContent="Test message"; - private static final String newSeverity="Warning"; - - private FileAnticipator m_fa; - private DefaultEventConfDao m_eventConfDao; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - m_fa = new FileAnticipator(); - - //Create a temporary directory - File origHome = new File("src/test/resources"); - File origEtc = new File(origHome, "etc"); - File origEvents = new File(origEtc, "events"); - - File tempHome = m_fa.getTempDir(); - File tempEtc = m_fa.expecting(tempHome, "etc"); - File tempEvents = m_fa.expecting(tempEtc, "events"); - - File eventConf = createTempCopy(m_fa, origEtc, tempEtc, "eventconf.xml"); - createTempCopy(m_fa, origEvents, tempEvents, "Standard.events.xml"); - createTempCopy(m_fa, origEvents, tempEvents, "Syslog.test.events.xml"); - createTempCopy(m_fa, origEvents, tempEvents, "Syslog.LoadTest.events.xml"); - - m_eventConfDao = new DefaultEventConfDao(); - m_eventConfDao.setConfigResource(new FileSystemResource(eventConf)); - m_eventConfDao.afterPropertiesSet(); - } - - @Override - protected void tearDown() throws Exception { - m_fa.deleteExpected(); - m_fa.tearDown(); - super.tearDown(); - } - - /** - * Copys sourceDir/relativeFilePath to destDir/relativeFilePath - * - * @param sourceDir - * @param destDir - * @param relativeFilePath - */ - private static File createTempCopy(FileAnticipator fa, File sourceDir, File destDir, String file) throws Exception { - FileUtils.copyFile(new File(sourceDir, file), new File(destDir, file)); - return fa.expecting(destDir, file); - } - - public void testSave() throws Exception { - String newUEI1="uei.opennms.org/custom/newTestUEI1"; - String newUEI2="uei.opennms.org/custom/newTestUEI2"; - - //Now do the test - { - m_eventConfDao.reload(); - List events=m_eventConfDao.getEvents(knownUEI1); - Event event=events.get(0); - event.setUei(newUEI1); - } - - m_eventConfDao.saveCurrent(); - - m_eventConfDao.reload(); //The reload might happen as part of the saveCurrent, but is not assured. We do so here to be certain - { - List events=m_eventConfDao.getEvents(knownUEI1); - assertNull("Shouldn't be any events by that uei", events); - - events=m_eventConfDao.getEvents(newUEI1); - assertNotNull("Should be at least one event", events); - assertEquals("Should be only one event", 1, events.size()); - Event event=events.get(0); - assertEquals("Should be the new UEI", newUEI1, event.getUei()); - } - - //Check that we can change and save a UEI in a sub file - { - List events=m_eventConfDao.getEvents(knownSubfileUEI1); - Event event=events.get(0); - event.setUei(newUEI2); - } - - m_eventConfDao.saveCurrent(); - - m_eventConfDao.reload(); //The reload might happen as part of the saveCurrent, but is not assured. We do so here to be certain - { - List events=m_eventConfDao.getEvents(knownSubfileUEI1); - assertNull("Shouldn't be any events by that uei", events); - - events=m_eventConfDao.getEvents(newUEI2); - assertNotNull("Should be at least one event", events); - assertEquals("Should be only one event", 1, events.size()); - Event event=events.get(0); - assertEquals("Should be the new UEI", newUEI2, event.getUei()); - } - - } - - private static Event getAddableEvent() { - Event event=new Event(); - event.setUei(newUEI); - event.setEventLabel(newEventLabel); - event.setDescr(newDescr); - Logmsg logmsg=new Logmsg(); - logmsg.setDest(newDest); - logmsg.setContent(newContent); - event.setLogmsg(logmsg); - event.setSeverity(newSeverity); - return event; - } - - private static void checkAddableEvent(Event event) { - assertEquals("Should be the new UEI", newUEI, event.getUei()); - assertEquals(newEventLabel, event.getEventLabel()); - assertEquals(newDescr, event.getDescr()); - assertEquals(newDest, event.getLogmsg().getDest()); - assertEquals(newContent, event.getLogmsg().getContent()); - assertEquals(newSeverity, event.getSeverity()); - } - - public void testAddEvent() { - Event event=getAddableEvent(); - - //The tested event - m_eventConfDao.addEvent(event); - - { - List events=m_eventConfDao.getEvents(newUEI); - assertNotNull("Should be at least one event", events); - assertEquals("Should be only one event", 1, events.size()); - Event fetchedEvent=events.get(0); - checkAddableEvent(fetchedEvent); - } - - m_eventConfDao.saveCurrent(); - m_eventConfDao.reload(); - - { - //Check that the new Event is still there - List events=m_eventConfDao.getEvents(newUEI); - assertNotNull("Should be at least one event", events); - assertEquals("Should be only one event", 1, events.size()); - Event fetchedEvent=events.get(0); - checkAddableEvent(fetchedEvent); - } - } - - /** - * Test adding and event to a specific file - * - */ - public void testAddEventToProgrammaticStore() { - Event event=getAddableEvent(); - - m_eventConfDao.addEventToProgrammaticStore(event); - - //Check that the new Event is still there - { - List events=m_eventConfDao.getEvents(newUEI); - - assertNotNull("Should be at least one event", events); - assertEquals("Should be only one event", 1, events.size()); - Event fetchedEvent=events.get(0); - checkAddableEvent(fetchedEvent); - } - - m_eventConfDao.saveCurrent(); - m_eventConfDao.reload(); - - //We are expecting this new file to be there - if it's not, that's an issue - m_fa.expecting(new File(m_fa.getTempDir().getAbsolutePath()+File.separator+"etc"+File.separator+"events"),"programmatic.events.xml"); - //Check again after the reload - { - List events=m_eventConfDao.getEvents(newUEI); - - assertNotNull("Should be at least one event", events); - assertEquals("Should be only one event", 1, events.size()); - Event fetchedEvent=events.get(0); - checkAddableEvent(fetchedEvent); - } - } - - public void testRemoveEventToProgrammaticStore() { - Event event=getAddableEvent(); - - m_eventConfDao.addEventToProgrammaticStore(event); - { - //Check that the new Event is still there - List events=m_eventConfDao.getEvents(newUEI); - assertNotNull("Should be at least one event", events); - assertEquals("Should be only one event", 1, events.size()); - Event fetchedEvent=events.get(0); - checkAddableEvent(fetchedEvent); - } - - //Check before the save/reload - assertTrue("remove should have returned true", m_eventConfDao.removeEventFromProgrammaticStore(event)); - { - List events=m_eventConfDao.getEvents(newUEI); - assertNull(events); - } - - m_eventConfDao.saveCurrent(); - m_eventConfDao.reload(); - - //Should get a "false" when the event is already missing - assertFalse("remove should have returned false",m_eventConfDao.removeEventFromProgrammaticStore(event)); - //Check again after save/reload - - { - List events=m_eventConfDao.getEvents(newUEI); - assertNull(events); - } - - } -} diff --git a/opennms-config/src/test/resources/etc/eventconf.xml b/opennms-config/src/test/resources/etc/eventconf.xml index 4a3ba518ac3a..5a68edf6af17 100644 --- a/opennms-config/src/test/resources/etc/eventconf.xml +++ b/opennms-config/src/test/resources/etc/eventconf.xml @@ -27,5 +27,6 @@ events/Standard.events.xml events/Syslog.test.events.xml events/Syslog.LoadTest.events.xml - + events/opennms.pollerd.events.xml + diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.pollerd.events.xml b/opennms-config/src/test/resources/etc/events/opennms.pollerd.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/opennms.pollerd.events.xml rename to opennms-config/src/test/resources/etc/events/opennms.pollerd.events.xml diff --git a/opennms-dao-api/src/main/java/org/opennms/netmgt/dao/api/EventConfEventDao.java b/opennms-dao-api/src/main/java/org/opennms/netmgt/dao/api/EventConfEventDao.java new file mode 100755 index 000000000000..cc4bde3b3d0d --- /dev/null +++ b/opennms-dao-api/src/main/java/org/opennms/netmgt/dao/api/EventConfEventDao.java @@ -0,0 +1,55 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.dao.api; + +import org.opennms.netmgt.model.EventConfEvent; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public interface EventConfEventDao extends OnmsDao { + + EventConfEvent get(Long id); + + List findBySourceId(Long sourceId); + + EventConfEvent findByUei(String uei); + + List findEnabledEvents(); + + void deleteBySourceId(Long sourceId); + + void deleteAll(final Collection list); + + List filterEventConf(String uei, String vendor, String sourceName, int offset, int limit); + + void updateEventEnabledFlag(Long sourceId, List eventIds, boolean enabled); + + Map findBySourceId(Long sourceId, String eventFilter, String eventSortBy, String eventOrder, Integer totalRecords, Integer offset, Integer limit); + + void saveAll(Collection events); + + EventConfEvent findBySourceIdAndEventId(Long sourceId,Long eventId); + + void deleteByEventIds(Long sourceId,List eventIds); +} diff --git a/opennms-dao-api/src/main/java/org/opennms/netmgt/dao/api/EventConfSourceDao.java b/opennms-dao-api/src/main/java/org/opennms/netmgt/dao/api/EventConfSourceDao.java new file mode 100755 index 000000000000..376c1c47bd2c --- /dev/null +++ b/opennms-dao-api/src/main/java/org/opennms/netmgt/dao/api/EventConfSourceDao.java @@ -0,0 +1,60 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.dao.api; + +import org.opennms.netmgt.model.EventConfSource; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public interface EventConfSourceDao extends OnmsDao { + + EventConfSource get(Long id); + + EventConfSource findByName(String name); + + List findAllEnabled(); + + List findByVendor(String vendor); + + List findAllByFileOrder(); + + Map getIdToNameMap(); + + void saveOrUpdate(EventConfSource source); + + void delete(EventConfSource source); + + void deleteAll(final Collection list); + + void updateEnabledFlag(final Collection sourceIds, boolean enabled, boolean cascadeToEvents); + + Map filterEventConfSource(String filter, String sortBy, String order, Integer totalRecords, + Integer offset, Integer limit); + + void deleteBySourceIds(List sourceIds); + + List findAllNames(); + + Integer findMaxFileOrder(); +} diff --git a/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventConfDao.java b/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventConfDao.java index 0ee47bb01bd1..62d492818000 100644 --- a/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventConfDao.java +++ b/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventConfDao.java @@ -37,6 +37,7 @@ import org.apache.commons.io.IOUtils; import org.opennms.core.xml.JaxbUtils; import org.opennms.netmgt.config.api.EventConfDao; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.xml.eventconf.EnterpriseIdPartition; import org.opennms.netmgt.xml.eventconf.Event; import org.opennms.netmgt.xml.eventconf.EventLabelComparator; @@ -132,11 +133,6 @@ public String getEventLabel(final String uei) { return getEventLabels().get(uei); } - @Override - public void saveCurrent() { - m_events.save(m_resource); - } - @Override public List getEventsByLabel() { SortedSet events = m_events.forEachEvent(new TreeSet(new EventLabelComparator()), new EventCallback>() { @@ -154,16 +150,6 @@ public void addEvent(final Event event) { m_events.addEvent(event); } - @Override - public void addEventToProgrammaticStore(final Event event) { - m_events.addEvent(event); - } - - @Override - public boolean removeEventFromProgrammaticStore(final Event event) { - return m_events.removeEvent(event); - } - @Override public boolean isSecureTag(final String tag) { return m_events.isSecureTag(tag); @@ -188,4 +174,10 @@ public Events getRootEvents() { return m_events; } + @Override + public void loadEventsFromDB(List dbEvents) { + + } + + } diff --git a/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventIpcManager.java b/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventIpcManager.java index 60fb4e064e90..495ebaebf825 100644 --- a/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventIpcManager.java +++ b/opennms-dao-mock/src/main/java/org/opennms/netmgt/dao/mock/MockEventIpcManager.java @@ -50,6 +50,7 @@ import org.opennms.netmgt.events.api.EventWriter; import org.opennms.netmgt.events.api.model.IEvent; import org.opennms.netmgt.events.api.model.ImmutableMapper; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.xml.event.Event; import org.opennms.netmgt.xml.event.Log; import org.opennms.netmgt.xml.eventconf.Events; @@ -109,9 +110,6 @@ public static class EmptyEventConfDao implements EventConfDao { @Override public void addEvent(final org.opennms.netmgt.xml.eventconf.Event event) {} - @Override - public void addEventToProgrammaticStore(final org.opennms.netmgt.xml.eventconf.Event event) {} - @Override public org.opennms.netmgt.xml.eventconf.Event findByEvent(final Event matchingEvent) { return null; @@ -156,17 +154,15 @@ public boolean isSecureTag(final String tag) { public void reload() throws DataAccessException {} @Override - public boolean removeEventFromProgrammaticStore(final org.opennms.netmgt.xml.eventconf.Event event) { - return false; + public Events getRootEvents() { + return null; } @Override - public void saveCurrent() {} + public void loadEventsFromDB(List dbEvents) { - @Override - public Events getRootEvents() { - return null; } + } public static interface SendNowHook { diff --git a/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/AbstractDaoHibernate.java b/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/AbstractDaoHibernate.java index 9fcb9b5e9d7b..ec72534c0403 100644 --- a/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/AbstractDaoHibernate.java +++ b/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/AbstractDaoHibernate.java @@ -486,4 +486,23 @@ private void logExtraSaveOrUpdateExceptionInformation(final T entity, final Data cause = cause.getCause(); } } + + public List findWithPagination(final String query, final Object[] values, final int offset, final int limit) { + return (List) getHibernateTemplate().execute(session -> { + Query hqlQuery = session.createQuery(query); + + // Set positional parameters + if (values != null) { + for (int i = 0; i < values.length; i++) { + hqlQuery.setParameter(i, values[i]); + } + } + + // Set pagination + hqlQuery.setFirstResult(offset); // offset + hqlQuery.setMaxResults(limit); // limit + + return hqlQuery.list(); + }); + } } diff --git a/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/EventConfEventDaoHibernate.java b/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/EventConfEventDaoHibernate.java new file mode 100755 index 000000000000..9c696a3bf0ef --- /dev/null +++ b/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/EventConfEventDaoHibernate.java @@ -0,0 +1,228 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.dao.hibernate; + +import org.opennms.netmgt.dao.api.EventConfEventDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class EventConfEventDaoHibernate + extends AbstractDaoHibernate + implements EventConfEventDao { + + private static final Logger LOG = LoggerFactory.getLogger(EventConfEventDaoHibernate.class); + + public EventConfEventDaoHibernate() { + super(EventConfEvent.class); + } + + @Override + public List findBySourceId(Long sourceId) { + return find("from EventConfEvent e where e.source.id = ? order by e.createdTime desc", sourceId); + } + + @Override + public EventConfEvent findByUei(String uei) { + List list = find("from EventConfEvent e where e.uei = ?", uei); + return list.isEmpty() ? null : list.get(0); + } + + public List filterEventConf(final String uei, final String vendor, final String sourceName, final int offset, final int limit) { + List queryParamList = new ArrayList<>(); + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("from EventConfEvent e where 1=1 "); + if (uei != null && !uei.trim().isEmpty()) { + queryBuilder.append(" and lower(e.uei) like ? escape '\\' "); + queryParamList.add("%" + escapeLike(uei.trim().toLowerCase()) + "%"); // contains match + } + + if (vendor != null && !vendor.trim().isEmpty()) { + queryBuilder.append(" and lower(e.source.vendor) like ? escape '\\' "); + queryParamList.add("%" + escapeLike(vendor.trim().toLowerCase()) + "%"); + } + + if (sourceName != null && !sourceName.trim().isEmpty()) { + queryBuilder.append(" and lower(e.source.name) like ? escape '\\' "); + queryParamList.add("%" + escapeLike(sourceName.trim().toLowerCase()) + "%"); + } + + queryBuilder.append(" order by e.createdTime desc "); + + return findWithPagination(queryBuilder.toString(), queryParamList.toArray(), offset, limit); + } + + @Override + public Map findBySourceId(Long sourceId, String eventFilter, String eventSortBy, String eventOrder, Integer totalRecords, Integer offset, Integer limit) { + + int resultCount = (totalRecords != null) ? totalRecords : 0; + List queryParams = new ArrayList<>(); + List conditions = new ArrayList<>(); + + String whereClause = "where e.source.id = ? "; + queryParams.add(sourceId); + + // Add filter conditions dynamically + if (eventFilter != null && !eventFilter.trim().isEmpty()) { + String escapedFilter = "%" + escapeLike(eventFilter.trim().toLowerCase()) + "%"; + conditions.add("lower(e.uei) like ? escape '\\'"); + queryParams.add(escapedFilter); + + conditions.add("lower(e.eventLabel) like ? escape '\\'"); + queryParams.add(escapedFilter); + + conditions.add("lower(e.description) like ? escape '\\'"); + queryParams.add(escapedFilter); + + } + + whereClause = whereClause + (conditions.isEmpty() ? "" : " AND ( " + String.join(" OR ", conditions)+ ")"); + + // COUNT QUERY: get total matching records if not already provided + if (resultCount == 0) { + String countQuery = "select count(e.id) from EventConfEvent e " + whereClause; + resultCount = super.queryInt(countQuery, queryParams.toArray()); + } + + // DATA QUERY: fetch paginated results if resultCount > 0 + List eventConfEventList = Collections.emptyList(); + if (resultCount > 0) { + + String orderBy = ""; + String sortField = eventSortBy; + + String sortOrder = "ASC".equalsIgnoreCase(eventOrder) ? "ASC" : "DESC"; + + Set allowedSortFields = Set.of("uei", "eventLabel", "description", "enabled"); + + if (eventSortBy == null || !allowedSortFields.contains(eventSortBy)) { + sortField = "createdTime"; + } + + orderBy = " order by " + sortField + " " + sortOrder; + + String dataQuery = "from EventConfEvent e " + whereClause + orderBy; + eventConfEventList = findWithPagination(dataQuery, queryParams.toArray(), offset, limit); + } + + // Return map with results + return Map.of("totalRecords", resultCount, "eventConfEventList", eventConfEventList); + } + + @Override + public void saveAll(Collection events) { + if (events == null || events.isEmpty()) { + return; + } + + int batchSize = 50; + int i = 0; + for (EventConfEvent event : events) { + getHibernateTemplate().save(event); + i++; + if (i % batchSize == 0) { + getHibernateTemplate().flush(); + getHibernateTemplate().clear(); + } + + } + getHibernateTemplate().flush(); + getHibernateTemplate().clear(); + } + + /** + * Escapes special characters (% , _ , \, ., /, [, ]) in a string + * to make it safe for SQL LIKE queries. + * + * @param input the input string + * @return the escaped string + */ + private String escapeLike(String input) { + return input + .replace("\\", "\\\\") + .replace("%", "\\%") + .replace("_", "\\_") + .replace("@", "\\@") + .replace("/", "\\/") + .replace("[", "\\[") + .replace("]", "\\]") + .replace(".", "\\."); + } + + @Override + public List findEnabledEvents() { + return find("from EventConfEvent e where e.enabled = true order by e.id asc"); + } + + @Override + public void deleteBySourceId(Long sourceId) { + getHibernateTemplate().bulkUpdate("delete from EventConfEvent e where e.source.id = ?", sourceId); + } + + @Override + public void deleteAll(final Collection list) { + super.deleteAll(list); + } + + @Override + public void updateEventEnabledFlag(Long sourceId, List eventIds, boolean enabled) { + if (eventIds == null || eventIds.isEmpty()) { + LOG.warn("No event IDs provided for update. Skipping..."); + return; + } + + var session = getSessionFactory().getCurrentSession(); + String hql = "update EventConfEvent e set e.enabled = :enabled " + + "where e.source.id = :sourceId and e.id in (:eventIds)"; + + var query = session.createQuery(hql); + query.setParameter("enabled", enabled); + query.setParameter("sourceId", sourceId); + query.setParameterList("eventIds", eventIds); + + int updatedCount = query.executeUpdate(); + LOG.info("Updated {} events (enabled={}) for sourceId={}", updatedCount, enabled, sourceId); + } + + @Override + public void deleteByEventIds(Long sourceId, List eventIds) { + int deletedCount = getHibernateTemplate().execute(session -> + session.createQuery("delete from EventConfEvent e where e.source.id = :sourceId and e.id in (:ids)") + .setParameter("sourceId", sourceId) + .setParameterList("ids", eventIds) + .executeUpdate() + ); + LOG.info("Deleted {} EventConfEvent(s) with IDs: {} for sourceId: {}", deletedCount, eventIds, sourceId); + } + + @Override + public EventConfEvent findBySourceIdAndEventId(Long sourceId, Long eventId) { + return findUnique("from EventConfEvent e where e.source.id = ? AND e.id = ? ", sourceId, eventId); + } +} diff --git a/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/EventConfSourceDaoHibernate.java b/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/EventConfSourceDaoHibernate.java new file mode 100755 index 000000000000..0fbaca897645 --- /dev/null +++ b/opennms-dao/src/main/java/org/opennms/netmgt/dao/hibernate/EventConfSourceDaoHibernate.java @@ -0,0 +1,231 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.dao.hibernate; + +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; + +public class EventConfSourceDaoHibernate + extends AbstractDaoHibernate + implements EventConfSourceDao { + + private static final Logger LOG = LoggerFactory.getLogger(EventConfSourceDaoHibernate.class); + + public EventConfSourceDaoHibernate() { + super(EventConfSource.class); + } + + @Override + public EventConfSource get(Long id) { + return super.get(id); + } + + @Override + public EventConfSource findByName(String name) { + List list = find("from EventConfSource s where s.name = ?", name); + return list.isEmpty() ? null : list.get(0); + } + + @Override + public List findAllEnabled() { + return find("from EventConfSource s where s.enabled = true order by s.fileOrder"); + } + + @Override + public List findByVendor(String vendor) { + return find("from EventConfSource s where s.vendor = ?", vendor); + } + + @Override + public List findAllByFileOrder() { + return find("from EventConfSource s order by s.fileOrder"); + } + + @Override + public Map getIdToNameMap() { + return findObjects(Object[].class, + "select s.id, s.name from EventConfSource s").stream() + .collect(Collectors.toMap( + row -> (Long) row[0], + row -> (String) row[1] + )); + } + + @Override + public void deleteAll(final Collection list) { + super.deleteAll(list); + } + + @Override + public void updateEnabledFlag(Collection sourceIds, boolean enabled, boolean cascadeToEvents) { + if (sourceIds == null || sourceIds.isEmpty()) { + return; + } + String hqlSource = "update EventConfSource s set s.enabled = :enabled where s.id in (:ids)"; + getSessionFactory().getCurrentSession() + .createQuery(hqlSource) + .setParameter("enabled", enabled) + .setParameterList("ids", sourceIds) + .executeUpdate(); + + if (cascadeToEvents) { + String hqlEvents = "update EventConfEvent e set e.enabled = :enabled where e.source.id in (:ids)"; + getSessionFactory().getCurrentSession() + .createQuery(hqlEvents) + .setParameter("enabled", enabled) + .setParameterList("ids", sourceIds) + .executeUpdate(); + } + + LOG.info("Set enabled={} for sources {} (cascadeToEvents={})", enabled, sourceIds, cascadeToEvents); + } + + @Override + public Map filterEventConfSource(final String filter, final String sortBy, final String order, + final Integer totalRecords, final Integer offset, Integer limit) { + + int resultCount = (totalRecords != null) ? totalRecords : 0; + List eventConfSourceList = Collections.emptyList(); + try { + List queryParams = new ArrayList<>(); + List conditions = new ArrayList<>(); + + // Add filter conditions dynamically + if (filter != null && !filter.trim().isEmpty()) { + String escapedFilter = "%" + escapeLike(filter.trim().toLowerCase()) + "%"; + conditions.add("lower(s.name) like ? escape '\\'"); + queryParams.add(escapedFilter); + + conditions.add("lower(s.vendor) like ? escape '\\'"); + queryParams.add(escapedFilter); + + conditions.add("lower(s.description) like ? escape '\\'"); + queryParams.add(escapedFilter); + + } + + String whereClause = conditions.isEmpty() ? "" : " where " + String.join(" OR ", conditions); + + // COUNT QUERY: get total matching records if not already provided + if (resultCount == 0) { + String countQuery = "select count(s.id) from EventConfSource s " + whereClause; + resultCount = super.queryInt(countQuery, queryParams.toArray()); + } + + // DATA QUERY: fetch paginated results + if (resultCount > 0) { + + String orderBy = ""; + String sortField = sortBy; + + String sortOrder = "ASC".equalsIgnoreCase(order) ? "ASC" : "DESC"; + + Set allowedSortFields = Set.of("name", "vendor", "description", "fileOrder", "eventCount"); + + if (!allowedSortFields.contains(sortBy)) { + sortField = "createdTime"; + } + + orderBy = " order by " + sortField + " " + sortOrder; + + String dataQuery = "from EventConfSource s " + whereClause + orderBy; + eventConfSourceList = findWithPagination(dataQuery, queryParams.toArray(), offset, limit); + } + + } catch (Exception e ) { + LOG.debug("Error filterEventConfSource method while fetching the records {} ", e); + } + + // Return map with results + return Map.of("totalRecords", resultCount, "eventConfSourceList", eventConfSourceList); + + } + + @Override + public Integer findMaxFileOrder() { + Integer maxOrder = (Integer) getSessionFactory().getCurrentSession() + .createQuery("SELECT MAX(e.fileOrder) FROM EventConfSource e") + .uniqueResult(); + + return maxOrder != null ? maxOrder : 0; + } + + + @Override + public void deleteBySourceIds(List sourceIds) { + int deletedCount = getHibernateTemplate().execute(session -> + session.createQuery("delete from EventConfSource s where s.id in (:ids)") + .setParameterList("ids", sourceIds) + .executeUpdate() + ); + LOG.info("Deleted {} EventConfSource(s) with IDs: {}", deletedCount, sourceIds); + } + @Override + public List findAllNames() { + return findObjects( + String.class, + "select distinct s.name from EventConfSource s " + + ); + } + + + + @Override + public void saveOrUpdate(EventConfSource source) { + super.saveOrUpdate(source); + } + + @Override + public void delete(EventConfSource source) { + super.delete(source); + } + + /** + * Escapes special characters (%, _, \, /, [, ]) in a string + * to make it safe for SQL LIKE queries. + * + * @param input the input string + * @return the escaped string + */ + private String escapeLike(String input) { + return input + .replace("\\", "\\\\") + .replace("%", "\\%") + .replace("_", "\\_") + .replace("@", "\\@") + .replace("/", "\\/") + .replace("[", "\\[") + .replace("]", "\\]") + .replace(".", "\\."); + } +} diff --git a/opennms-dao/src/main/resources/META-INF/opennms/applicationContext-shared.xml b/opennms-dao/src/main/resources/META-INF/opennms/applicationContext-shared.xml index c1c3601be65d..7b98cf2e0862 100644 --- a/opennms-dao/src/main/resources/META-INF/opennms/applicationContext-shared.xml +++ b/opennms-dao/src/main/resources/META-INF/opennms/applicationContext-shared.xml @@ -136,6 +136,19 @@ + + + + + + + + + + + + + diff --git a/opennms-dao/src/test/java/org/opennms/netmgt/dao/EventConfEventDaoIT.java b/opennms-dao/src/test/java/org/opennms/netmgt/dao/EventConfEventDaoIT.java new file mode 100755 index 000000000000..3aad782f5fbb --- /dev/null +++ b/opennms-dao/src/test/java/org/opennms/netmgt/dao/EventConfEventDaoIT.java @@ -0,0 +1,375 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.dao; + +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opennms.core.spring.BeanUtils; +import org.opennms.core.test.OpenNMSJUnit4ClassRunner; +import org.opennms.core.test.db.annotations.JUnitTemporaryDatabase; +import org.opennms.netmgt.dao.api.EventConfEventDao; +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.test.JUnitConfigurationEnvironment; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; + +@RunWith(OpenNMSJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "classpath:/META-INF/opennms/applicationContext-soa.xml", + "classpath:/META-INF/opennms/applicationContext-dao.xml", + "classpath:/META-INF/opennms/applicationContext-mockConfigManager.xml", + "classpath:/META-INF/opennms/applicationContext-commonConfigs.xml", +}) +@JUnitConfigurationEnvironment +@JUnitTemporaryDatabase +public class EventConfEventDaoIT implements InitializingBean { + + @Autowired + private EventConfEventDao m_eventDao; + + @Autowired + private EventConfSourceDao m_eventSourceDao; + + private EventConfSource m_source; + + @Autowired + private SessionFactory sessionFactory; + + private int defaultEventConfEventCount; + @Before + @Transactional + public void setUp() { + m_source = new EventConfSource(); + m_source.setName("test-source"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test event source"); + m_source.setVendor("TestVendor"); + m_source.setUploadedBy("JUnitTest"); + m_source.setEventCount(0); + m_source.setLastModified(new Date()); + + List event = m_eventDao.findAll(); + defaultEventConfEventCount = event.size(); + + m_eventSourceDao.saveOrUpdate(m_source); + m_eventSourceDao.flush(); + + insertEvent("uei.opennms.org/internal/discoveryConfigChange", + "Discovery configuration changed", + "The discovery configuration has been changed and should be reloaded", + "Normal"); + + insertEvent("uei.opennms.org/internal/discovery/hardwareInventoryFailed", + "Hardware discovery failed", + "The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.", + "Minor"); + + insertEvent("uei.opennms.org/internal/discovery/hardwareInventorySuccessful", + "Hardware discovery successful", + "The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has been completed successfully.", + "Normal"); + + insertEvent("uei.opennms.org/internal/discovery/newSuspect", + "New suspect discovered", + "A new interface (%interface%) has been discovered in location %parm[location]% and is being queued for a services scan.", + "Warning"); + } + + @After + @Transactional + public void tearDown() { + var listofConfig = m_eventDao.findAll(); + var listOfSource = m_eventSourceDao.findAll(); + m_eventDao.deleteAll(listofConfig); + m_eventSourceDao.deleteAll(listOfSource); + m_eventDao.flush(); + m_eventSourceDao.flush(); + } + + private void insertEvent(String uei, String label, String description, String severity) { + EventConfEvent event = new EventConfEvent(); + event.setUei(uei); + event.setEventLabel(label); + event.setDescription(description); + event.setXmlContent("" + uei + ""); + event.setSource(m_source); + event.setEnabled(true); + event.setCreatedTime(new Date()); + event.setLastModified(new Date()); + event.setModifiedBy("JUnitTest"); + + m_eventDao.saveOrUpdate(event); + } + + @Test + @Transactional + public void testFindAllEventConfEvents() { + List event = m_eventDao.findAll(); + int eventSize = event.size() - defaultEventConfEventCount; + assertNotNull("Expected to find all events", event); + assertEquals(4, eventSize); + + } + + @Test + @Transactional + public void testGetById() { + List events = m_eventDao.findAll(); + int eventSize = events.size() - defaultEventConfEventCount; + assertNotNull("Events should not be null", events); + assertEquals(4, eventSize); + EventConfEvent result = m_eventDao.get(events.get(0).getId()); + assertNotNull("Fetched event should not be null", result); + assertEquals(events.get(0).getUei(), result.getUei()); + } + + @Test + @Transactional + public void testFindBySourceId() { + List events = m_eventDao.findBySourceId(m_source.getId()); + assertNotNull(events); + assertFalse(events.isEmpty()); + } + + @Test + @Transactional + public void testFindByUei() { + EventConfEvent event = m_eventDao.findByUei("uei.opennms.org/internal/discoveryConfigChange"); + assertNotNull("Event with matching UEI should be found", event); + assertEquals("uei.opennms.org/internal/discoveryConfigChange", event.getUei()); + } + + @Test + @Transactional + public void testFindEnabledEvents() { + List enabledEvents = m_eventDao.findEnabledEvents(); + int enabledEventsSize = enabledEvents.size() - defaultEventConfEventCount; + assertNotNull("Enabled events should be found", enabledEvents); + assertEquals(4, enabledEventsSize); + + EventConfEvent event = enabledEvents.get(0); + event.setEnabled(false); + m_eventDao.saveOrUpdate(event); + + List updatedEnabled = m_eventDao.findEnabledEvents(); + int updatedEnabledSize = updatedEnabled.size() - defaultEventConfEventCount; + assertEquals(3, updatedEnabledSize); + } + + @Test + @Transactional + public void testDeleteBySourceId() { + List beforeDelete = m_eventDao.findBySourceId(m_source.getId()); + assertEquals(4, beforeDelete.size()); + + m_eventDao.deleteBySourceId(m_source.getId()); + + List afterDelete = m_eventDao.findBySourceId(m_source.getId()); + assertEquals(0, afterDelete.size()); + } + + @Test + @Transactional + public void testUpdateEventEnabledFlag() { + m_source = new EventConfSource(); + m_source.setName("testEventEnabledFlagName"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test event source"); + m_source.setVendor("TestVendor1"); + m_source.setUploadedBy("JUnitTest"); + m_source.setEventCount(2); + m_source.setLastModified(new Date()); + + List event = m_eventDao.findAll(); + defaultEventConfEventCount = event.size(); + + m_eventSourceDao.saveOrUpdate(m_source); + m_eventSourceDao.flush(); + + insertEvent("uei.opennms.org/internal/discoveryConfigChange11", "Discovery configuration changed testing", "The discovery configuration has been changed and should be reloaded", "Normal"); + + insertEvent("uei.opennms.org/internal/discovery/hardwareInventoryFailed22", "Hardware discovery failed testing", "The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.", "Minor"); + + EventConfSource source = m_eventSourceDao.findByName("testEventEnabledFlagName"); + + EventConfEvent discoveryEvent = m_eventDao.findByUei("uei.opennms.org/internal/discoveryConfigChange11"); + EventConfEvent hardwareEvent = m_eventDao.findByUei("uei.opennms.org/internal/discovery/hardwareInventoryFailed22"); + + // disable events + m_eventDao.updateEventEnabledFlag(source.getId(), List.of(discoveryEvent.getId(), hardwareEvent.getId()), false); + sessionFactory.getCurrentSession().flush(); + sessionFactory.getCurrentSession().clear(); + + // verify disabled state + EventConfEvent refreshedDiscoveryEvent = m_eventDao.findByUei("uei.opennms.org/internal/discoveryConfigChange11"); + EventConfEvent refreshedHardwareEvent = m_eventDao.findByUei("uei.opennms.org/internal/discovery/hardwareInventoryFailed22"); + assertFalse(refreshedDiscoveryEvent.getEnabled()); + assertFalse(refreshedHardwareEvent.getEnabled()); + + // enable events + m_eventDao.updateEventEnabledFlag(source.getId(), List.of(discoveryEvent.getId(), hardwareEvent.getId()), true); + sessionFactory.getCurrentSession().flush(); + sessionFactory.getCurrentSession().clear(); + + // verify enabled state + refreshedDiscoveryEvent = m_eventDao.findByUei("uei.opennms.org/internal/discoveryConfigChange11"); + refreshedHardwareEvent = m_eventDao.findByUei("uei.opennms.org/internal/discovery/hardwareInventoryFailed22"); + assertTrue(refreshedDiscoveryEvent.getEnabled()); + assertTrue(refreshedHardwareEvent.getEnabled()); + } + + @Test + @Transactional + public void testDeleteByEventIds() { + m_source = new EventConfSource(); + m_source.setName("testDeleteEvents"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test events from a source"); + m_source.setVendor("TestVendor1"); + m_source.setUploadedBy("JUnitTest"); + m_source.setEventCount(3); + m_source.setLastModified(new Date()); + + List event = m_eventDao.findAll(); + defaultEventConfEventCount = event.size(); + + m_eventSourceDao.saveOrUpdate(m_source); + m_eventSourceDao.flush(); + + insertEvent("uei.opennms.org/internal/discovery/hardwareInventoryFailed11", "Hardware discovery failed testing11", "The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed 11.", "Minor"); + insertEvent("uei.opennms.org/internal/discovery/hardwareInventoryFailed22", "Hardware discovery failed testing22", "The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed 22.", "Minor"); + insertEvent("uei.opennms.org/internal/discovery/hardwareInventoryFailed33", "Hardware discovery failed testing33", "The hardware discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed 33.", "Minor"); + EventConfSource source = m_eventSourceDao.findByName("testDeleteEvents"); + + EventConfEvent hardwareInventoryFailed11 = m_eventDao.findByUei("uei.opennms.org/internal/discovery/hardwareInventoryFailed11"); + EventConfEvent hardwareInventoryFailed22 = m_eventDao.findByUei("uei.opennms.org/internal/discovery/hardwareInventoryFailed22"); + + // delete events for source "testDeleteEvents" + m_eventDao.deleteByEventIds(source.getId(), List.of(hardwareInventoryFailed11.getId(), hardwareInventoryFailed22.getId())); + sessionFactory.getCurrentSession().flush(); + sessionFactory.getCurrentSession().clear(); + + // verify deleted events + List updatedEvents = m_eventDao.findBySourceId(source.getId()); + assertEquals(1, updatedEvents.size()); + } + + @Transactional(propagation = Propagation.REQUIRES_NEW) + public EventConfEvent reloadEvent(String uei) { + return m_eventDao.findByUei(uei); + } + + + @Test + @Transactional + public void testSaveAllEvents() { + int totalEvents = 55; + List bulkEvents = new ArrayList<>(); + for (int i = 0; i < totalEvents; i++) { + EventConfEvent event = getEventConfEvent(i); + bulkEvents.add(event); + } + + m_eventDao.saveAll(bulkEvents); + + List allEvents = m_eventDao.findBySourceId(m_source.getId()); + assertNotNull(allEvents); + assertEquals(4 + totalEvents, allEvents.size()); + } + + private EventConfEvent getEventConfEvent(int i) { + EventConfEvent event = new EventConfEvent(); + event.setUei("uei.opennms.org/test/bulk/" + i); + event.setEventLabel("Bulk Event " + i); + event.setDescription("Test bulk event " + i); + event.setXmlContent("uei.opennms.org/test/bulk/" + i + ""); + event.setSource(m_source); + event.setEnabled(true); + event.setCreatedTime(new Date()); + event.setLastModified(new Date()); + event.setModifiedBy("testUser"); + return event; + } + + + + @Test + @Transactional + public void testFindBySourceIdAndEventId() { + m_source = new EventConfSource(); + m_source.setName("sourceAndEventTesting"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test event source"); + m_source.setVendor("TestVendor2"); + m_source.setUploadedBy("testCases"); + m_source.setEventCount(2); + m_source.setLastModified(new Date()); + + List event = m_eventDao.findAll(); + defaultEventConfEventCount = event.size(); + + m_eventSourceDao.saveOrUpdate(m_source); + m_eventSourceDao.flush(); + + insertEvent("uei.opennms.org/internal/trigger", "Trigger event", "Trigger event testing description", "Normal"); + + insertEvent("uei.opennms.org/internal/clear", "Clear event testing", "The clear (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.", "Minor"); + m_eventDao.flush(); + EventConfSource source = m_eventSourceDao.findByName("sourceAndEventTesting"); + EventConfEvent clearEvent = m_eventDao.findByUei("uei.opennms.org/internal/clear"); + + EventConfEvent dbEvent = m_eventDao.findBySourceIdAndEventId(source.getId(),clearEvent.getId()); + assertEquals("uei.opennms.org/internal/clear", dbEvent.getUei()); + + } + + @Override + public void afterPropertiesSet() throws Exception { + BeanUtils.assertAutowiring(this); + } + +} diff --git a/opennms-dao/src/test/java/org/opennms/netmgt/dao/EventConfSourceDaoIT.java b/opennms-dao/src/test/java/org/opennms/netmgt/dao/EventConfSourceDaoIT.java new file mode 100755 index 000000000000..8f26c816ad4c --- /dev/null +++ b/opennms-dao/src/test/java/org/opennms/netmgt/dao/EventConfSourceDaoIT.java @@ -0,0 +1,557 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.dao; + +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opennms.core.spring.BeanUtils; +import org.opennms.core.test.OpenNMSJUnit4ClassRunner; +import org.opennms.core.test.db.annotations.JUnitTemporaryDatabase; +import org.opennms.core.xml.JaxbUtils; +import org.opennms.netmgt.dao.api.EventConfEventDao; +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.test.JUnitConfigurationEnvironment; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@RunWith(OpenNMSJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "classpath:/META-INF/opennms/applicationContext-soa.xml", + "classpath:/META-INF/opennms/applicationContext-dao.xml", + "classpath:/META-INF/opennms/applicationContext-mockConfigManager.xml", + "classpath:/META-INF/opennms/applicationContext-commonConfigs.xml", +}) +@JUnitConfigurationEnvironment +@JUnitTemporaryDatabase +public class EventConfSourceDaoIT implements InitializingBean { + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + private EventConfSourceDao m_dao; + + @Autowired + EventConfEventDao m_eventDao; + + private EventConfSource m_source; + + private int defaultEventSize; + + @Before + @Transactional + public void setUp() { + defaultEventSize = m_eventDao.findAll().size(); + m_source = new EventConfSource(); + m_source.setName("JUnit Source"); + m_source.setVendor("TestVendor"); + m_source.setEnabled(true); + m_source.setFileOrder(42); + m_source.setDescription("JUnit Description"); + m_source.setEventCount(5); + m_source.setCreatedTime(new Date()); + m_source.setLastModified(new Date()); + m_source.setUploadedBy("JUnit"); + + m_dao.saveOrUpdate(m_source); + } + + @After + @Transactional + public void tearDown() { + var listofConfig = m_eventDao.findAll(); + var listOfSource = m_dao.findAll(); + m_eventDao.deleteAll(listofConfig); + m_dao.deleteAll(listOfSource); + m_dao.flush(); + m_eventDao.flush(); + + } + + @Test + @Transactional + public void testFindByName() { + EventConfSource found = m_dao.findByName("JUnit Source"); + assertNotNull(found); + assertEquals("JUnit Description", found.getDescription()); + } + + @Test + @Transactional + public void testVendorIsPersisted() { + EventConfSource found = m_dao.findByName("JUnit Source"); + assertNotNull(found); + assertEquals("TestVendor", found.getVendor()); + } + + @Test + @Transactional + public void testFileOrderIsPersisted() { + EventConfSource found = m_dao.findByName("JUnit Source"); + assertNotNull(found); + assertEquals(Integer.valueOf(42), found.getFileOrder()); + } + + @Test + @Transactional + public void testFindAllEnabled() { + List list = m_dao.findAllEnabled(); + assertFalse(list.isEmpty()); + assertTrue(list.stream().anyMatch(s -> s.getName().equals("JUnit Source"))); + } + + @Test + @Transactional + public void testGetIdToNameMap() { + Map map = m_dao.getIdToNameMap(); + assertNotNull(map); + assertTrue(map.containsValue("JUnit Source")); + } + + @Test + public void testEventConfFilesExists() throws IOException { + String[] xmlFiles = { + "eventconf-test-1.xml", + "eventconf-test-2.xml" + }; + + for (String fileName : xmlFiles) { + try (InputStream input = getClass().getClassLoader().getResourceAsStream(fileName)) { + assertNotNull("File should be available in classpath: " + fileName, input); + } + } + } + + @Test + @Transactional + public void testLoadAndPersistEventsFromSingleXmlFile() throws Exception { + + var m_source1 = new EventConfSource(); + m_source1.setName("test-source"); + m_source1.setEnabled(true); + m_source1.setCreatedTime(new Date()); + m_source1.setFileOrder(1); + m_source1.setDescription("Test event source"); + m_source1.setVendor("TestVendor"); + m_source1.setUploadedBy("JUnitTest"); + m_source1.setEventCount(9); + m_source1.setLastModified(new Date()); + + m_dao.saveOrUpdate(m_source1); + m_dao.flush(); + + org.opennms.netmgt.xml.eventconf.Events events = + JaxbUtils.unmarshal(org.opennms.netmgt.xml.eventconf.Events.class, + getClass().getClassLoader().getResourceAsStream("eventconf-test-1.xml")); + + assertNotNull("Parsed Events should not be null", events); + assertFalse("Parsed Events should not be empty", events.getEvents().isEmpty()); + assertEquals("Should have 9 events from XML", 9, events.getEvents().size()); + + for (var xmlEvent : events.getEvents()) { + EventConfEvent jpaEvent = new EventConfEvent(); + jpaEvent.setUei(xmlEvent.getUei()); + jpaEvent.setDescription(xmlEvent.getDescr()); + jpaEvent.setXmlContent(xmlEvent.toString()); + jpaEvent.setEnabled(true); + jpaEvent.setCreatedTime(new Date()); + jpaEvent.setLastModified(new Date()); + jpaEvent.setModifiedBy("XMLTest"); + jpaEvent.setSource(m_source1); + + m_eventDao.saveOrUpdate(jpaEvent); + } + m_eventDao.flush(); + List savedEvents = m_eventDao.findBySourceId(m_source1.getId()); + assertEquals("Should have saved 9 events from XML", 9, savedEvents.size()); + } + + + @Test + @Transactional + public void testLoadAndPersistMultipleEventConfFiles() throws Exception { + // List of XML files to test + String[] xmlFiles = { + "eventconf-test-1.xml", // has 9 events + "eventconf-test-2.xml" // assume it has 3 events + }; + + int totalExpectedEventCount = 0; + List allSourceIds = new ArrayList<>(); + + for (int i = 0; i < xmlFiles.length; i++) { + String file = xmlFiles[i]; + + // Create EventConfSource per file + EventConfSource source = new EventConfSource(); + source.setName("test-source-" + i); + source.setEnabled(true); + source.setCreatedTime(new Date()); + source.setFileOrder(i + 1); + source.setDescription("Source for " + file); + source.setVendor("JUnitVendor"); + source.setUploadedBy("JUnitTest"); + source.setLastModified(new Date()); + + org.opennms.netmgt.xml.eventconf.Events events = + JaxbUtils.unmarshal(org.opennms.netmgt.xml.eventconf.Events.class, + getClass().getClassLoader().getResourceAsStream(file)); + + assertNotNull("Events should not be null for file: " + file, events); + assertFalse("Event list should not be empty for file: " + file, events.getEvents().isEmpty()); + + int eventCount = events.getEvents().size(); + totalExpectedEventCount += eventCount; + source.setEventCount(eventCount); + + m_dao.saveOrUpdate(source); + m_dao.flush(); + allSourceIds.add(source.getId()); + + // Persist events + for (var xmlEvent : events.getEvents()) { + EventConfEvent jpaEvent = new EventConfEvent(); + jpaEvent.setUei(xmlEvent.getUei()); + jpaEvent.setDescription(xmlEvent.getDescr()); + jpaEvent.setXmlContent(xmlEvent.toString()); + jpaEvent.setEnabled(true); + jpaEvent.setCreatedTime(new Date()); + jpaEvent.setLastModified(new Date()); + jpaEvent.setModifiedBy("XMLTest"); + jpaEvent.setSource(source); + + m_eventDao.saveOrUpdate(jpaEvent); + } + + m_eventDao.flush(); + + // Verify events for this source + List savedForSource = m_eventDao.findBySourceId(source.getId()); + assertEquals("Event count mismatch for " + file, eventCount, savedForSource.size()); + } + + List allEvents = m_eventDao.findAll(); + assertEquals("Total event count mismatch across all files", totalExpectedEventCount, allEvents.size()); + } + + @Test + @Transactional + public void testDeleteBySourceIds() throws Exception { + // List of XML files to test + String[] xmlFiles = { + "eventconf-test-1.xml", + "eventconf-test-2.xml" + }; + + int totalExpectedEventCount = 0; + List allSourceIds = new ArrayList<>(); + + for (int i = 0; i < xmlFiles.length; i++) { + String file = xmlFiles[i]; + + EventConfSource source = new EventConfSource(); + source.setName("test-source-" + i); + source.setEnabled(true); + source.setCreatedTime(new Date()); + source.setFileOrder(i + 1); + source.setDescription("Source for " + file); + source.setVendor("JUnitVendor"); + source.setUploadedBy("JUnitTest"); + source.setLastModified(new Date()); + + org.opennms.netmgt.xml.eventconf.Events events = + JaxbUtils.unmarshal(org.opennms.netmgt.xml.eventconf.Events.class, + getClass().getClassLoader().getResourceAsStream(file)); + + assertNotNull("Events should not be null for file: " + file, events); + assertFalse("Event list should not be empty for file: " + file, events.getEvents().isEmpty()); + + int eventCount = events.getEvents().size(); + totalExpectedEventCount += eventCount; + source.setEventCount(eventCount); + + m_dao.saveOrUpdate(source); + m_dao.flush(); + allSourceIds.add(source.getId()); + + for (var xmlEvent : events.getEvents()) { + EventConfEvent jpaEvent = new EventConfEvent(); + jpaEvent.setUei(xmlEvent.getUei()); + jpaEvent.setDescription(xmlEvent.getDescr()); + jpaEvent.setXmlContent(xmlEvent.toString()); + jpaEvent.setEnabled(true); + jpaEvent.setCreatedTime(new Date()); + jpaEvent.setLastModified(new Date()); + jpaEvent.setModifiedBy("XMLTest"); + jpaEvent.setSource(source); + + m_eventDao.saveOrUpdate(jpaEvent); + } + + m_eventDao.flush(); + } + final var eventConfSources = m_dao.findAll(); + m_dao.deleteBySourceIds(eventConfSources.stream().map(EventConfSource::getId).collect(Collectors.toList())); + final var deletedEventConfSources = m_dao.findAll(); + assertEquals(0,deletedEventConfSources.size()); + } + + + @Test + @Transactional + public void testLoadAndPersistMultipleEventConfFilesAndUpdateEnabledFlag() throws Exception { + String[] xmlFiles = {"eventconf-test-1.xml", + "eventconf-test-2.xml" + }; + + int totalExpectedEventCount = 0; + List allSourceIds = new ArrayList<>(); + + for (int i = 0; i < xmlFiles.length; i++) { + String file = xmlFiles[i]; + + EventConfSource source = new EventConfSource(); + source.setName("test-source-" + i); + source.setEnabled(true); + source.setCreatedTime(new Date()); + source.setFileOrder(i + 1); + source.setDescription("Source for " + file); + source.setVendor("testVendor"); + source.setUploadedBy("Test"); + source.setLastModified(new Date()); + + org.opennms.netmgt.xml.eventconf.Events events = JaxbUtils.unmarshal(org.opennms.netmgt.xml.eventconf.Events.class, getClass().getClassLoader().getResourceAsStream(file)); + + int eventCount = events.getEvents().size(); + totalExpectedEventCount += eventCount; + source.setEventCount(eventCount); + + m_dao.saveOrUpdate(source); + m_dao.flush(); + allSourceIds.add(source.getId()); + + for (var xmlEvent : events.getEvents()) { + EventConfEvent jpaEvent = new EventConfEvent(); + jpaEvent.setUei(xmlEvent.getUei()); + jpaEvent.setDescription(xmlEvent.getDescr()); + jpaEvent.setXmlContent(xmlEvent.toString()); + jpaEvent.setEnabled(true); + jpaEvent.setCreatedTime(new Date()); + jpaEvent.setLastModified(new Date()); + jpaEvent.setModifiedBy("XMLTest"); + jpaEvent.setSource(source); + + m_eventDao.saveOrUpdate(jpaEvent); + } + m_eventDao.flush(); + List savedForSource = m_eventDao.findBySourceId(source.getId()); + assertEquals("Event count mismatch for " + file, eventCount, savedForSource.size()); + } + + List allEvents = m_eventDao.findAll(); + assertEquals("Total event count mismatch across all files", totalExpectedEventCount, allEvents.size() - defaultEventSize); + + m_dao.updateEnabledFlag(allSourceIds, false, false); + sessionFactory.getCurrentSession().clear(); + for (Long sourceId : allSourceIds) { + final var source = m_dao.get(sourceId); + assertFalse("Source should be disabled", source.getEnabled()); + + List events = m_eventDao.findBySourceId(sourceId); + assertFalse("Events should still be enabled when cascade=false", events.isEmpty() && events.stream().anyMatch(EventConfEvent::getEnabled)); + } + + m_dao.updateEnabledFlag(allSourceIds, true, true); + sessionFactory.getCurrentSession().clear(); + for (final var sourceId : allSourceIds) { + final var source = m_dao.get(sourceId); + assertTrue("Source should be enabled", source.getEnabled()); + + List events = m_eventDao.findBySourceId(sourceId); + assertFalse("Events should not be empty", events.isEmpty()); + assertTrue("All events should be enabled when cascade=true", events.stream().allMatch(EventConfEvent::getEnabled)); + } + } + + @Test + @Transactional + public void testFindAllNamesReturnsPersistedNames() { + List names = m_dao.findAllNames(); + + assertNotNull("Names list should not be null", names); + assertFalse("Names list should not be empty", names.isEmpty()); + assertTrue("Names should contain the persisted source", names.contains("JUnit Source")); + } + + @Test + @Transactional + public void testFindAllNamesRespectsFileOrder() { + EventConfSource source1 = new EventConfSource(); + source1.setName("Source-A"); + source1.setVendor("VendorA"); + source1.setEnabled(true); + source1.setFileOrder(1); + source1.setDescription("First Source"); + source1.setEventCount(1); + source1.setCreatedTime(new Date()); + source1.setLastModified(new Date()); + source1.setUploadedBy("JUnit"); + m_dao.saveOrUpdate(source1); + + EventConfSource source2 = new EventConfSource(); + source2.setName("Source-B"); + source2.setVendor("VendorB"); + source2.setEnabled(true); + source2.setFileOrder(2); + source2.setDescription("Second Source"); + source2.setEventCount(2); + source2.setCreatedTime(new Date()); + source2.setLastModified(new Date()); + source2.setUploadedBy("JUnit"); + m_dao.saveOrUpdate(source2); + + m_dao.flush(); + + List names = m_dao.findAllNames(); + + assertNotNull(names); + } + + @Test + @Transactional + public void testFindAllNamesWhenNoSourcesExist() { + m_dao.deleteAll(m_dao.findAll()); + m_dao.flush(); + + List names = m_dao.findAllNames(); + + assertNotNull("Names list should not be null even if empty", names); + assertTrue("Names list should be empty when no sources exist", names.isEmpty()); + } + + + + @Override + public void afterPropertiesSet() throws Exception { + BeanUtils.assertAutowiring(this); + } + + @Test + public void testFilterEventConfSource_ReturnsValidRecords() { + EventConfSource source1 = new EventConfSource(); + source1.setName("opennms.test.events"); + source1.setFileOrder(1); + source1.setEventCount(5); + source1.setEnabled(true); + source1.setCreatedTime(new Date()); + source1.setLastModified(new Date()); + source1.setVendor("opennms"); + source1.setDescription("Open Network Monitoring System"); + m_dao.saveOrUpdate(source1); + + EventConfSource source2 = new EventConfSource(); + source2.setName("cisco.test.events"); + source2.setFileOrder(2); + source2.setEventCount(3); + source2.setEnabled(true); + source2.setCreatedTime(new Date()); + source2.setLastModified(new Date()); + source2.setVendor("cisco"); + source2.setDescription("Cisco Events"); + m_dao.saveOrUpdate(source2); + + // Inline helper for reusing assertions + BiConsumer, String> assertSourceName = + (result, expectedName) -> { + assertNotNull(result); + List list = (List) result.get("eventConfSourceList"); + assertEquals(result.get("totalRecords"), list.size()); + assertEquals(expectedName, ((EventConfSource) list.get(0)).getName()); + }; + + // 1. Exact filter, ascending by name + Map result = m_dao.filterEventConfSource("opennms.test.events", "name", "asc", 0, 0, 10); + assertEquals(1, result.get("totalRecords")); + assertSourceName.accept(result, "opennms.test.events"); + + // 2. Partial filter, ascending by name + result = m_dao.filterEventConfSource("test.events", "name", "asc", 0, 0, 10); + assertEquals(2, result.get("totalRecords")); + assertSourceName.accept(result, "cisco.test.events"); // asc = cisco first + + // 3. Partial filter, descending by name + result = m_dao.filterEventConfSource("test.events", "name", "desc", 0, 0, 10); + assertEquals(2, result.get("totalRecords")); + assertSourceName.accept(result, "opennms.test.events"); // desc = opennms first + + // 4. Partial filter, ascending by fileOrder + result = m_dao.filterEventConfSource("test.events", "fileOrder", "asc", 0, 0, 10); + assertEquals(2, result.get("totalRecords")); + assertSourceName.accept(result, "opennms.test.events"); // fileOrder 1 first + + // 5. Filter by description + result = m_dao.filterEventConfSource("Open Network Monitoring System", "fileOrder", "asc", 0, 0, 10); + assertEquals(1, result.get("totalRecords")); + assertSourceName.accept(result, "opennms.test.events"); + + // 6. Filter by vendor (case-insensitive) + result = m_dao.filterEventConfSource("CISCO", "fileOrder", "asc", 0, 0, 10); + assertEquals(1, result.get("totalRecords")); + assertSourceName.accept(result, "cisco.test.events"); + + // 7. Pagination (only second record returned) + result = m_dao.filterEventConfSource("test.events", "name", "asc", 0, 1, 1); + assertEquals(2, result.get("totalRecords")); + List list = (List) result.get("eventConfSourceList"); + assertEquals(1, list.size()); + assertEquals("opennms.test.events", ((EventConfSource) list.get(0)).getName()); + } + + @Test + public void testFilterEventConfSource_ReturnsEmptyMap() { + Map result = m_dao.filterEventConfSource( + null, null, null, null, 0, 5); + assertNotNull(result); + assertFalse(result.isEmpty()); + } +} \ No newline at end of file diff --git a/opennms-dao/src/test/resources/eventconf-test-1.xml b/opennms-dao/src/test/resources/eventconf-test-1.xml new file mode 100644 index 000000000000..ca0585287765 --- /dev/null +++ b/opennms-dao/src/test/resources/eventconf-test-1.xml @@ -0,0 +1,66 @@ + + + + uei.opennms.org/tests/syslogd/substrUeiRewriteTest + Syslogd test event: substrUeiRewriteTest + This is only a test + <p>Syslogd test event: substrUeiRewriteTest</p> + Warning + + + uei.opennms.org/tests/syslogd/regexUeiRewriteTest + Syslogd test event: regexUeiRewriteTest + This is only a test + <p>Syslogd test event: regexUeiRewriteTest</p> + Warning + + + uei.opennms.org/tests/syslogd/regexParameterAssignmentTest/bothKinds + Syslogd test event: regexParameterAssignmentTest/bothKinds + This is only a test + <p>Syslogd test event: regexParameterAssignmentTest/bothKinds</p> + Warning + + + uei.opennms.org/tests/syslogd/regexParameterAssignmentTest/userSpecifiedOnly + Syslogd test event: regexParameterAssignmentTest/userSpecifiedOnly + This is only a test + <p>Syslogd test event: regexParameterAssignmentTest/userSpecifiedOnly</p> + Warning + + + uei.opennms.org/tests/syslogd/nonMessageMatch/processOnly + Syslogd test event: nonMessageMatch/processOnly + This is only a test + <p>Syslogd test event: nonMessageMatch/processOnly</p> + Warning + + + uei.opennms.org/tests/syslogd/nonMessageMatch/facilityOnly + Syslogd test event: nonMessageMatch/facilityOnly + This is only a test + <p>Syslogd test event: nonMessageMatch/facilityOnly</p> + Warning + + + uei.opennms.org/tests/syslogd/nonMessageMatch/facilitySeverity + Syslogd test event: nonMessageMatch/facilitySeverity + This is only a test + <p>Syslogd test event: nonMessageMatch/facilitySeverity</p> + Warning + + + uei.opennms.org/tests/syslogd/nonMessageMatch/facilitySeverityProcess + Syslogd test event: nonMessageMatch/facilitySeverityProcess + This is only a test + <p>Syslogd test event: nonMessageMatch/facilitySeverityProcess</p> + Warning + + + uei.opennms.org/tests/syslogd/nonMessageMatch/severityOnly + Syslogd test event: nonMessageMatch/severityOnly + This is only a test + <p>Syslogd test event: nonMessageMatch/severityOnly</p> + Major + + \ No newline at end of file diff --git a/opennms-dao/src/test/resources/eventconf-test-2.xml b/opennms-dao/src/test/resources/eventconf-test-2.xml new file mode 100644 index 000000000000..6e33148183fd --- /dev/null +++ b/opennms-dao/src/test/resources/eventconf-test-2.xml @@ -0,0 +1,21 @@ + + + + uei.opennms.org/test/1 + Test Event 1 + This is a test event description 1 + Major + + + uei.opennms.org/test/2 + Test Event 2 + This is a test event description 2 + Minor + + + uei.opennms.org/test/3 + Test Event 3 + This is a test event description 3 + Critical + + diff --git a/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfEvent.java b/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfEvent.java new file mode 100755 index 000000000000..187e9ed54d0f --- /dev/null +++ b/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfEvent.java @@ -0,0 +1,159 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.model; + + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.io.Serializable; +import java.util.Date; + +@Entity +@Table(name = "eventconf_events") +public class EventConfEvent implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "event_seq") + @SequenceGenerator(name = "event_seq", sequenceName = "eventconf_events_id_seq", allocationSize = 1) + private Long id; + + @ManyToOne(optional = false) + @JoinColumn(name = "source_id", nullable = false) + private EventConfSource source; + + @Column(nullable = false, length = 256) + private String uei; + + @Column(name = "event_label", columnDefinition = "text") + private String eventLabel; + + @Column(columnDefinition = "text") + private String description; + + @Column(nullable = false) + private Boolean enabled; + + @Column(name = "xml_content", columnDefinition = "text", nullable = false) + private String xmlContent; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_time") + private Date createdTime; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "last_modified") + private Date lastModified; + + @Column(name = "modified_by", length = 256) + private String modifiedBy; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public EventConfSource getSource() { + return source; + } + + public void setSource(EventConfSource source) { + this.source = source; + } + + public String getUei() { + return uei; + } + + public void setUei(String uei) { + this.uei = uei; + } + + public String getEventLabel() { + return eventLabel; + } + + public void setEventLabel(String eventLabel) { + this.eventLabel = eventLabel; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public String getXmlContent() { + return xmlContent; + } + + public void setXmlContent(String xmlContent) { + this.xmlContent = xmlContent; + } + + public Date getCreatedTime() { + return createdTime; + } + + public void setCreatedTime(Date createdTime) { + this.createdTime = createdTime; + } + + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(String modifiedBy) { + this.modifiedBy = modifiedBy; + } +} diff --git a/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfEventDto.java b/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfEventDto.java new file mode 100755 index 000000000000..36bed5bb304b --- /dev/null +++ b/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfEventDto.java @@ -0,0 +1,132 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.opennms.netmgt.model; + +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +public class EventConfEventDto { + + private Long id; + private String uei; + private String eventLabel; + private String description; + private Boolean enabled; + private String xmlContent; + private Date createdTime; + private Date lastModified; + private String modifiedBy; + + // Flattened fields from EventConfSource + private String sourceName; + private String vendor; + private Integer fileOrder; + + public EventConfEventDto() { + } + + public EventConfEventDto(Long id, String uei, String eventLabel, String description, Boolean enabled, + String xmlContent, Date createdTime, Date lastModified, String modifiedBy, + String sourceName, String vendor, Integer fileOrder) { + this.id = id; + this.uei = uei; + this.eventLabel = eventLabel; + this.description = description; + this.enabled = enabled; + this.xmlContent = xmlContent; + this.createdTime = createdTime; + this.lastModified = lastModified; + this.modifiedBy = modifiedBy; + this.sourceName = sourceName; + this.vendor = vendor; + this.fileOrder = fileOrder; + } + + // Getters and Setters + public Long getId() { return id; } + public void setId(Long id) { this.id = id; } + + public String getUei() { return uei; } + public void setUei(String uei) { this.uei = uei; } + + public String getEventLabel() { return eventLabel; } + public void setEventLabel(String eventLabel) { this.eventLabel = eventLabel; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public Boolean getEnabled() { return enabled; } + public void setEnabled(Boolean enabled) { this.enabled = enabled; } + + public String getXmlContent() { return xmlContent; } + public void setXmlContent(String xmlContent) { this.xmlContent = xmlContent; } + + public Date getCreatedTime() { return createdTime; } + public void setCreatedTime(Date createdTime) { this.createdTime = createdTime; } + + public Date getLastModified() { return lastModified; } + public void setLastModified(Date lastModified) { this.lastModified = lastModified; } + + public String getModifiedBy() { return modifiedBy; } + public void setModifiedBy(String modifiedBy) { this.modifiedBy = modifiedBy; } + + public String getSourceName() { return sourceName; } + public void setSourceName(String sourceName) { this.sourceName = sourceName; } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public Integer getFileOrder() { + return fileOrder; + } + + public void setFileOrder(Integer fileOrder) { + this.fileOrder = fileOrder; + } + + public static List fromEntity(List entityList) { + + return entityList.stream() + .map(e -> new EventConfEventDto( + e.getId(), + e.getUei(), + e.getEventLabel(), + e.getDescription(), + e.getEnabled(), + e.getXmlContent(), + e.getCreatedTime(), + e.getLastModified(), + e.getModifiedBy(), + e.getSource() != null ? e.getSource().getName() : null, + e.getSource() != null ? e.getSource().getVendor() : null, + e.getSource() != null ? e.getSource().getFileOrder() : null + )) + .collect(Collectors.toList()); + } +} diff --git a/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfSource.java b/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfSource.java new file mode 100755 index 000000000000..f1ad3b2fc786 --- /dev/null +++ b/opennms-model/src/main/java/org/opennms/netmgt/model/EventConfSource.java @@ -0,0 +1,169 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.model; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Entity +@Table(name = "eventconf_sources") +public class EventConfSource implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "source_seq") + @SequenceGenerator(name = "source_seq", sequenceName = "eventconf_sources_id_seq", allocationSize = 1) + private Long id; + + @Column(nullable = false, length = 256) + private String name; + + @Column(columnDefinition = "text") + private String description; + + @Column(length = 128) + private String vendor; + + @Column(name = "file_order", nullable = false) + private Integer fileOrder; + + @Column(nullable = false) + private Boolean enabled = true; + + @Column(name = "event_count") + private Integer eventCount = 0; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_time") + private Date createdTime; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "last_modified") + private Date lastModified; + + @Column(name = "uploaded_by", length = 256) + private String uploadedBy; + + @OneToMany(mappedBy = "source", cascade = CascadeType.ALL, orphanRemoval = true) + private List events; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public Integer getFileOrder() { + return fileOrder; + } + + public void setFileOrder(Integer fileOrder) { + this.fileOrder = fileOrder; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Integer getEventCount() { + return eventCount; + } + + public void setEventCount(Integer eventCount) { + this.eventCount = eventCount; + } + + public Date getCreatedTime() { + return createdTime; + } + + public void setCreatedTime(Date createdTime) { + this.createdTime = createdTime; + } + + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public String getUploadedBy() { + return uploadedBy; + } + + public void setUploadedBy(String uploadedBy) { + this.uploadedBy = uploadedBy; + } + + public List getEvents() { + return events; + } + + public void setEvents(List events) { + this.events = events; + } +} diff --git a/opennms-model/src/main/java/org/opennms/netmgt/model/events/EnableDisableConfSourceEventsPayload.java b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EnableDisableConfSourceEventsPayload.java new file mode 100644 index 000000000000..b2a1d6d42d44 --- /dev/null +++ b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EnableDisableConfSourceEventsPayload.java @@ -0,0 +1,50 @@ + +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.model.events; + +import java.util.List; + +public class EnableDisableConfSourceEventsPayload { + private boolean enable; + private List eventsIds; + + public EnableDisableConfSourceEventsPayload() { + } + + public boolean isEnable() { + return enable; + } + + public void setEnable(boolean enable) { + this.enable = enable; + } + + public List getEventsIds() { + return eventsIds; + } + + public void setEventsIds(List eventsIds) { + this.eventsIds = eventsIds; + } + +} diff --git a/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSourceDeletePayload.java b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSourceDeletePayload.java new file mode 100644 index 000000000000..b72456b778a4 --- /dev/null +++ b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSourceDeletePayload.java @@ -0,0 +1,42 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.model.events; + +import java.util.List; + +public class EventConfSourceDeletePayload { + private List sourceIds; + + public EventConfSourceDeletePayload() { + + } + + public List getSourceIds() { + return sourceIds; + } + + public void setSourceIds(List sourceIds) { + this.sourceIds = sourceIds; + } + + +} diff --git a/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSourceMetadataDto.java b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSourceMetadataDto.java new file mode 100644 index 000000000000..a460582408ff --- /dev/null +++ b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSourceMetadataDto.java @@ -0,0 +1,120 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.model.events; + +import java.util.Date; + + +public class EventConfSourceMetadataDto { + private String filename; + private int eventCount; + private int fileOrder; + private String username; + private Date now; + private String vendor; + private String description; + + // Private constructor to enforce use of builder + private EventConfSourceMetadataDto(Builder builder) { + this.filename = builder.filename; + this.eventCount = builder.eventCount; + this.fileOrder = builder.fileOrder; + this.username = builder.username; + this.now = builder.now; + this.vendor = builder.vendor; + this.description = builder.description; + } + + // Getters + public String getFilename() { + return filename; + } + public int getEventCount() { + return eventCount; + } + public int getFileOrder() { + return fileOrder; + } + public String getUsername() { + return username; + } + public Date getNow() { + return now; + } + public String getVendor() { + return vendor; + } + public String getDescription() { + return description; + } + + + // Builder class + public static class Builder { + private String filename; + private int eventCount; + private int fileOrder; + private String username; + private Date now; + private String vendor; + private String description; + + public Builder filename(String filename) { + this.filename = filename; + return this; + } + + public Builder eventCount(int eventCount) { + this.eventCount = eventCount; + return this; + } + + public Builder fileOrder(int fileOrder) { + this.fileOrder = fileOrder; + return this; + } + + public Builder username(String username) { + this.username = username; + return this; + } + + public Builder now(Date now) { + this.now = now; + return this; + } + + public Builder vendor(String vendor) { + this.vendor = vendor; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public EventConfSourceMetadataDto build() { + return new EventConfSourceMetadataDto(this); + } + } +} diff --git a/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSrcEnableDisablePayload.java b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSrcEnableDisablePayload.java new file mode 100644 index 000000000000..390a7ca2f213 --- /dev/null +++ b/opennms-model/src/main/java/org/opennms/netmgt/model/events/EventConfSrcEnableDisablePayload.java @@ -0,0 +1,66 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.netmgt.model.events; + +import java.util.List; + +public class EventConfSrcEnableDisablePayload { + private Boolean enabled; + private Boolean cascadeToEvents; + private List sourceIds; + + public EventConfSrcEnableDisablePayload() { + + } + + public EventConfSrcEnableDisablePayload(Boolean enabled, Boolean cascadeToEvents, List sourceIds) { + this.enabled = enabled; + this.cascadeToEvents = cascadeToEvents; + this.sourceIds = sourceIds; + } + + public void setCascadeToEvents(Boolean cascadeToEvents) { + this.cascadeToEvents = cascadeToEvents; + } + + public void setSourceIds(List sourceIds) { + this.sourceIds = sourceIds; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Boolean getEnabled() { + return enabled; + } + + public List getSourceIds() { + return sourceIds; + } + + public Boolean getCascadeToEvents() { + return cascadeToEvents; + } + + +} diff --git a/opennms-services/pom.xml b/opennms-services/pom.xml index e89eabec87ff..b25cb2f15d55 100644 --- a/opennms-services/pom.xml +++ b/opennms-services/pom.xml @@ -518,5 +518,12 @@ ${project.version} compile + + org.opennms + opennms-config + ${project.version} + test-jar + test + diff --git a/opennms-services/src/test/java/org/opennms/netmgt/mock/OpenNMSITCase.java b/opennms-services/src/test/java/org/opennms/netmgt/mock/OpenNMSITCase.java index 08da8e6a50b5..548e0b1f615d 100644 --- a/opennms-services/src/test/java/org/opennms/netmgt/mock/OpenNMSITCase.java +++ b/opennms-services/src/test/java/org/opennms/netmgt/mock/OpenNMSITCase.java @@ -37,6 +37,7 @@ import org.opennms.core.utils.InetAddressUtils; import org.opennms.core.sysprops.SystemProperties; import org.opennms.netmgt.config.DefaultEventConfDao; +import org.opennms.netmgt.config.EventConfTestUtil; import org.opennms.netmgt.config.SnmpPeerFactory; import org.opennms.netmgt.dao.mock.JdbcEventdServiceManager; import org.opennms.netmgt.eventd.AbstractEventUtil; @@ -52,6 +53,7 @@ import org.opennms.netmgt.events.api.EventIpcManagerFactory; import org.opennms.netmgt.events.api.EventProcessor; import org.opennms.netmgt.events.api.EventProxy; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.snmp.SnmpAgentConfig; import org.opennms.netmgt.snmp.SnmpUtils; import org.opennms.test.mock.MockUtil; @@ -165,8 +167,8 @@ public void setUp() throws Exception { */ File configFile = ConfigurationTestUtils.getFileForResource(this, "/org/opennms/netmgt/mock/eventconf.xml"); DefaultEventConfDao eventConfDao = new DefaultEventConfDao(); - eventConfDao.setConfigResource(new FileSystemResource(configFile)); - eventConfDao.afterPropertiesSet(); + List eventConfEventList = EventConfTestUtil.parseResourcesAsEventConfEvents(new FileSystemResource(configFile)); + eventConfDao.loadEventsFromDB(eventConfEventList); EventExpander eventExpander = new EventExpander(m_registry); eventExpander.setEventConfDao(eventConfDao); diff --git a/opennms-services/src/test/java/org/opennms/netmgt/notifd/BroadcastEventProcessorIT.java b/opennms-services/src/test/java/org/opennms/netmgt/notifd/BroadcastEventProcessorIT.java index 257ee1977154..fdd271cc60b6 100644 --- a/opennms-services/src/test/java/org/opennms/netmgt/notifd/BroadcastEventProcessorIT.java +++ b/opennms-services/src/test/java/org/opennms/netmgt/notifd/BroadcastEventProcessorIT.java @@ -31,25 +31,38 @@ import java.util.Date; import java.util.Map; import java.util.TreeMap; +import java.util.List; import org.junit.Assert; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.opennms.netmgt.config.EventConfTestUtil; import org.opennms.netmgt.config.NotificationManager; +import org.opennms.netmgt.config.api.EventConfDao; import org.opennms.netmgt.config.notifications.Notification; import org.opennms.netmgt.events.api.EventConstants; import org.opennms.netmgt.mock.MockEventUtil; import org.opennms.netmgt.mock.MockService; +import org.opennms.netmgt.model.EventConfEvent; import org.opennms.netmgt.model.events.EventBuilder; import org.opennms.netmgt.xml.event.Event; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; public class BroadcastEventProcessorIT extends NotificationsITCase { + @Autowired + private EventConfDao eventConfDao; + @Before @Override public void setUp() throws Exception { + List events = EventConfTestUtil.parseResourcesAsEventConfEvents( + new FileSystemResource("src/test/resources/org/opennms/netmgt/notifd/eventconf.xml")); + // Load into DB + eventConfDao.loadEventsFromDB(events); super.setUp(); m_anticipator.setExpectedDifference(3000); diff --git a/opennms-services/src/test/resources/META-INF/opennms/applicationContext-notifdTest.xml b/opennms-services/src/test/resources/META-INF/opennms/applicationContext-notifdTest.xml index aa90a655b42c..fc581c8adc79 100644 --- a/opennms-services/src/test/resources/META-INF/opennms/applicationContext-notifdTest.xml +++ b/opennms-services/src/test/resources/META-INF/opennms/applicationContext-notifdTest.xml @@ -58,12 +58,25 @@ - - - - - + + + + + + + + + + + + + + + + + + diff --git a/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/EventConfPersistenceService.java b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/EventConfPersistenceService.java new file mode 100644 index 000000000000..4f19c14a4655 --- /dev/null +++ b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/EventConfPersistenceService.java @@ -0,0 +1,283 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.web.rest.v2; + + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import org.apache.commons.lang.StringUtils; +import org.opennms.core.xml.JaxbUtils; +import org.opennms.netmgt.config.api.EventConfDao; +import org.opennms.netmgt.dao.api.EventConfEventDao; +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.netmgt.model.events.EventConfSourceDeletePayload; +import org.opennms.netmgt.model.events.EnableDisableConfSourceEventsPayload; +import org.opennms.netmgt.model.events.EventConfSourceMetadataDto; +import org.opennms.netmgt.model.events.EventConfSrcEnableDisablePayload; +import org.opennms.netmgt.xml.eventconf.Event; +import org.opennms.netmgt.xml.eventconf.Events; +import org.opennms.web.rest.v2.model.EventConfEventDeletePayload; +import org.opennms.web.rest.v2.model.EventConfEventEditRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityNotFoundException; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class EventConfPersistenceService { + + private static final Logger LOG = LoggerFactory.getLogger(EventConfPersistenceService.class); + + @Autowired + private EventConfSourceDao eventConfSourceDao; + + @Autowired + private EventConfEventDao eventConfEventDao; + + @Autowired + private EventConfDao eventConfDao; + + private final ThreadFactory eventConfThreadFactory = new ThreadFactoryBuilder() + .setNameFormat("load-eventConf-%d") + .build(); + + private final ExecutorService eventConfExecutor = Executors.newSingleThreadExecutor(eventConfThreadFactory); + + @PostConstruct + public void init() { + // Asynchronously load events from DB in order to not to block startup + eventConfExecutor.execute(this::reloadEventsFromDB); + } + + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void persistEventConfFile(final Events events, final EventConfSourceMetadataDto eventConfSourceMetadataDto) { + EventConfSource source = createOrUpdateSource(eventConfSourceMetadataDto); + eventConfEventDao.deleteBySourceId(source.getId()); + saveEvents(source, events, eventConfSourceMetadataDto.getUsername(), eventConfSourceMetadataDto.getNow()); + } + + @Transactional + public Long addEventConfSourceEvent(final Long sourceId, final String userName, Event event) { + final Date now = new Date(); + EventConfSource eventConfSource = eventConfSourceDao.get(sourceId); + Long eventConfId = saveEvent(eventConfSource, event, userName, now); + eventConfSource.setEventCount(eventConfSource.getEventCount() + 1); + eventConfSourceDao.saveOrUpdate(eventConfSource); + return eventConfId; + } + + public List findEventConfByFilters(String uei, String vendor, String sourceName, int offset, int limit) { + return eventConfEventDao.filterEventConf(uei, vendor, sourceName, offset, limit); + } + + @Transactional + public void updateSourceAndEventEnabled(final EventConfSrcEnableDisablePayload eventConfSrcEnableDisablePayload) { + eventConfSourceDao.updateEnabledFlag(eventConfSrcEnableDisablePayload.getSourceIds(),eventConfSrcEnableDisablePayload.getEnabled(),eventConfSrcEnableDisablePayload.getCascadeToEvents()); + } + + + @Transactional + public void deleteEventConfSources(EventConfSourceDeletePayload eventConfSourceDeletePayload) throws Exception { + eventConfSourceDao.deleteBySourceIds(eventConfSourceDeletePayload.getSourceIds()); + } + + @Transactional + public void enableDisableConfSourcesEvents(final Long sourceId, final EnableDisableConfSourceEventsPayload enableDisableConfSourceEventsPayload) { + eventConfEventDao.updateEventEnabledFlag(sourceId,enableDisableConfSourceEventsPayload.getEventsIds(),enableDisableConfSourceEventsPayload.isEnable()); + } + + + @Transactional + public void updateEventConfEvent(final Long sourceId, final Long eventId, EventConfEventEditRequest payload) { + + try { + EventConfEvent eventConfEvent = eventConfEventDao.findBySourceIdAndEventId(sourceId,eventId); + if (eventConfEvent == null) { + throw new EntityNotFoundException(String.format("EventConfEvent not found for eventId=%d", eventId)); + } + eventConfEvent.setUei(payload.getEvent().getUei()); + eventConfEvent.setEventLabel(payload.getEvent().getEventLabel()); + eventConfEvent.setDescription(payload.getEvent().getDescr()); + eventConfEvent.setEnabled(payload.getEnabled()); + eventConfEvent.setXmlContent(JaxbUtils.marshal(payload.getEvent())); + eventConfEvent.setLastModified(new Date()); + + eventConfEventDao.saveOrUpdate(eventConfEvent); + + } catch (Exception e) { + throw new RuntimeException("Failed to update EventConfEvent XML for eventId=" + eventId, e); + } + } + + private EventConfSource createOrUpdateSource(final EventConfSourceMetadataDto eventConfSourceMetadataDto) { + EventConfSource source = eventConfSourceDao.findByName(eventConfSourceMetadataDto.getFilename()); + if (source == null) { + source = new EventConfSource(); + source.setCreatedTime(eventConfSourceMetadataDto.getNow()); + source.setFileOrder(eventConfSourceMetadataDto.getFileOrder()); + } + source.setName(eventConfSourceMetadataDto.getFilename()); + source.setEventCount(eventConfSourceMetadataDto.getEventCount()); + source.setEnabled(true); + source.setUploadedBy(eventConfSourceMetadataDto.getUsername()); + source.setLastModified(eventConfSourceMetadataDto.getNow()); + source.setVendor(eventConfSourceMetadataDto.getVendor()); + source.setDescription(eventConfSourceMetadataDto.getDescription()); + eventConfSourceDao.saveOrUpdate(source); + return eventConfSourceDao.get(source.getId()); + } + + private void saveEvents(EventConfSource source, Events events, String username, Date now) { + List eventEntities = events.getEvents().stream().map(parsed -> { + EventConfEvent event = new EventConfEvent(); + event.setSource(source); + event.setUei(parsed.getUei()); + event.setEventLabel(parsed.getEventLabel()); + event.setDescription(parsed.getDescr()); + event.setEnabled(true); + event.setXmlContent(JaxbUtils.marshal(parsed)); + event.setCreatedTime(now); + event.setLastModified(now); + event.setModifiedBy(username); + return event; + }).toList(); + + eventConfEventDao.saveAll(eventEntities); + } + + private Long saveEvent(EventConfSource source, Event event, String username, Date now) { + EventConfEvent eventConfEvent = new EventConfEvent(); + eventConfEvent.setSource(source); + eventConfEvent.setUei(event.getUei()); + eventConfEvent.setEventLabel(event.getEventLabel()); + eventConfEvent.setDescription(event.getDescr()); + eventConfEvent.setEnabled(true); + eventConfEvent.setXmlContent(JaxbUtils.marshal(event)); + eventConfEvent.setCreatedTime(now); + eventConfEvent.setLastModified(now); + eventConfEvent.setModifiedBy(username); + return eventConfEventDao.save(eventConfEvent); + } + + protected void reloadEventsFromDB() { + final long startTime = System.currentTimeMillis(); + List dbEvents = eventConfEventDao.findEnabledEvents(); + eventConfDao.loadEventsFromDB(dbEvents); + final long endTime = System.currentTimeMillis(); + LOG.info("Time to reload events from DB: {} ms", (endTime - startTime)); + } + + @PreDestroy + public void shutdown() { + eventConfExecutor.shutdown(); + } + + private void saveEventsToDatabase() { + + Map fileEventsMap = eventConfDao.getRootEvents().getLoadedEventFiles(); + int fileOrder = 1; + for (Map.Entry entry : fileEventsMap.entrySet()) { + String fileName = entry.getKey(); + if (fileName.startsWith("events/")) { + String[] parts = fileName.split("/"); + fileName = parts[parts.length - 1]; + } + Events events = entry.getValue(); + + if (fileName.startsWith("opennms")) { + String withoutExtension = fileName.endsWith(".xml") + ? fileName.substring(0, fileName.lastIndexOf(".xml")) + : fileName; + EventConfSourceMetadataDto metadataDto = new EventConfSourceMetadataDto.Builder().filename(withoutExtension).now(new Date()).vendor(StringUtils.substringBefore(fileName, ".")).username("system-migration").description("").eventCount(events.getEvents().size()).fileOrder(fileOrder++).build(); + persistEventConfFile(events, metadataDto); + } + } + } + + public void reloadEventsIntoMemory() { + // Schedule reload only AFTER transaction commits + eventConfExecutor.execute(EventConfPersistenceService.this::reloadEventsFromDB); + } + + public Map filterConfEventsBySourceId(Long sourceId, String eventFilter, String eventSortBy, + String eventOrder, Integer totalRecords, Integer offset, + Integer limit) { + return eventConfEventDao.findBySourceId(sourceId, eventFilter, eventSortBy, eventOrder, totalRecords, offset, limit); + } + + public Map filterEventConfSource(String filter, String sortBy, String order, Integer totalRecords, Integer offset, Integer limit) { + return eventConfSourceDao.filterEventConfSource(filter, sortBy, order, totalRecords, offset, limit); + } + + @Transactional + public void deleteEventsForSource(final Long sourceId, final EventConfEventDeletePayload eventConfEventDeletePayload) throws Exception { + if (eventConfEventDeletePayload.getEventIds() == null || eventConfEventDeletePayload.getEventIds().isEmpty()) { + throw new IllegalArgumentException("Event IDs to delete must not be empty"); + } + + EventConfSource source = eventConfSourceDao.get(sourceId); + if (source == null) { + throw new EntityNotFoundException("EventConfSource not found for id: " + sourceId); + } + final Set databaseEventIds = source.getEvents() + .stream() + .map(EventConfEvent::getId) + .collect(Collectors.toSet()); + + final var requestEventIds = eventConfEventDeletePayload.getEventIds(); + final var existingEventIds = requestEventIds.stream() + .filter(databaseEventIds::contains) + .toList(); + + if (existingEventIds.isEmpty()) { + throw new EntityNotFoundException("No matching events found in database for deletion. Request IDs: " + requestEventIds); + } + final var currentCount = source.getEventCount(); + final int deleteCount = existingEventIds.size(); + + if (deleteCount >= currentCount) { + LOG.info("Deleting entire sourceId={} as all {} events are removed.", sourceId, deleteCount); + eventConfSourceDao.delete(source); + } else { + LOG.info("Deleting {} events from sourceId={} (remaining count={})", deleteCount, sourceId, currentCount - deleteCount); + eventConfEventDao.deleteByEventIds(sourceId, existingEventIds); + source.setEventCount(currentCount - deleteCount); + eventConfSourceDao.saveOrUpdate(source); + } + } +} diff --git a/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/EventConfRestService.java b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/EventConfRestService.java new file mode 100644 index 000000000000..386abb3febe2 --- /dev/null +++ b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/EventConfRestService.java @@ -0,0 +1,456 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.opennms.web.rest.v2; + +import org.apache.commons.lang.StringUtils; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.opennms.core.xml.JaxbUtils; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.netmgt.model.events.EnableDisableConfSourceEventsPayload; +import org.opennms.netmgt.model.events.EventConfSourceDeletePayload; +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.EventConfEventDto; +import org.opennms.netmgt.model.events.EventConfSourceMetadataDto; +import org.opennms.netmgt.model.events.EventConfSrcEnableDisablePayload; +import org.opennms.netmgt.xml.eventconf.Event; +import org.opennms.netmgt.xml.eventconf.Events; +import org.opennms.web.rest.v2.api.EventConfRestApi; +import org.opennms.web.rest.v2.model.EventConfEventDeletePayload; +import org.opennms.web.rest.v2.model.EventConfEventEditRequest; +import org.opennms.web.rest.v2.model.EventConfSourceDto; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.persistence.EntityNotFoundException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.Serializable; +import java.util.Map; +import java.util.List; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.Date; +import java.util.Optional; +import java.util.Objects; +import java.util.stream.Collectors; + +@Component +public class EventConfRestService implements EventConfRestApi { + + private static final Logger LOG = LoggerFactory.getLogger(EventConfRestService.class); + + @Autowired + private EventConfPersistenceService eventConfPersistenceService; + + @Autowired + private EventConfSourceDao eventConfSourceDao; + + @Override + public Response uploadEventConfFiles(final List attachments, final SecurityContext securityContext) { + final String username = getUsername(securityContext); + final Date now = new Date(); + int maxFileOrder = Optional.ofNullable(eventConfSourceDao.findMaxFileOrder()).orElse(0); + + final Map fileMap = new LinkedHashMap<>(); + for (Attachment attachment : attachments) { + String filename = attachment.getContentDisposition().getParameter("filename"); + String basename = stripPathAndExtension(filename); + + if (basename == null || basename.isEmpty()) { + LOG.warn("Skipping attachment with invalid filename: {}", filename); + continue; + } + + if (fileMap.containsKey(basename)) { + String existingFilename = fileMap.get(basename).getContentDisposition().getParameter("filename"); + LOG.warn("Duplicate basename detected: '{}' and '{}' resolve to same name '{}'. Keeping first file.", + existingFilename, filename, basename); + continue; + } + + fileMap.put(basename, attachment); + } + + List orderedFiles = new ArrayList<>(fileMap.keySet()); + + final List> successList = new ArrayList<>(); + final List> errorList = new ArrayList<>(); + + final long dbStartTime = System.currentTimeMillis(); + for (final String fileName : orderedFiles) { + final Attachment attachment = fileMap.get(fileName); + if (attachment == null) { + continue; + } + + Events fileEvents; + try (InputStream stream = attachment.getObject(InputStream.class)) { + fileEvents = parseEventFile(new ByteArrayInputStream(stream.readAllBytes())); + } catch (Exception e) { + errorList.add(buildErrorResponse(fileName, e)); + continue; + } + + try { + final EventConfSource existingSource = eventConfSourceDao.findByName(fileName); + final int fileOrder = (existingSource != null) + ? existingSource.getFileOrder() + : ++maxFileOrder; + + eventConfPersistenceService.persistEventConfFile( + fileEvents, + buildMetadata(fileName, "", fileEvents, fileOrder, username, now)); + successList.add(buildSuccessResponse(fileName, fileEvents)); + } catch (Exception e) { + errorList.add(buildErrorResponse(fileName, e)); + } + } + final long dbEndTime = System.currentTimeMillis(); + LOG.info("Time to add {} files to DB: {} ms", orderedFiles.size(), (dbEndTime - dbStartTime)); + + eventConfPersistenceService.reloadEventsIntoMemory(); + + return Response.ok(Map.of("success", successList, "errors", errorList)).build(); + } + + @Override + public Response filterEventConf(String uei, String vendor, String sourceName, int offset, int limit, SecurityContext securityContext) { + + // Return 400 Bad Request if offset is negative or limit is less than 1 + if (offset < 0 || limit < 1) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + + // Call the persistence service + List results = eventConfPersistenceService.findEventConfByFilters(uei, vendor, sourceName, offset, limit); + if (results == null || results.isEmpty()) { + // Return 204 No Content if no matching records found + return Response.noContent().build(); + } + + List dtoList = EventConfEventDto.fromEntity(results); + + // Return the matching results + return Response.ok(dtoList).build(); + } + + @Override + public Response enableDisableEventConfSources(final EventConfSrcEnableDisablePayload payload, SecurityContext securityContext) throws Exception { + + if (payload == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("Request body cannot be null").build(); + } + + if (payload.getEnabled() == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("The 'enabled' flag must be provided (true/false).").build(); + } + + if (payload.getSourceIds() == null || payload.getSourceIds().isEmpty()) { + return Response.status(Response.Status.BAD_REQUEST).entity("At least one sourceId must be provided.").build(); + } + + try { + eventConfPersistenceService.updateSourceAndEventEnabled(payload); + eventConfPersistenceService.reloadEventsIntoMemory(); + return Response.ok().entity("EventConf sources updated successfully.").build(); + + } catch (EntityNotFoundException ex) { + return Response.status(Response.Status.NOT_FOUND).entity("One or more sourceIds were not found: " + ex.getMessage()).build(); + } catch (Exception ex) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Unexpected error occurred: " + ex.getMessage()).build(); + } + } + + @Override + public Response filterConfEventsBySourceId(Long sourceId, String eventFilter, String eventSortBy, + String eventOrder, Integer totalRecords, Integer offset, + Integer limit, SecurityContext securityContext) { + + // Return 400 Bad Request if sourceId is null, invalid sourceId, offset < 0 or limit < 1 + if (Objects.requireNonNullElse(sourceId, 0L) <= 0L || Objects.requireNonNullElse(offset, 0) < 0 + || Objects.requireNonNullElse(limit, 0) < 1) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(Map.of("error", "Invalid sourceId/offset/limit values")) + .build(); + } + + // Call service to fetch results + Map result = eventConfPersistenceService.filterConfEventsBySourceId(sourceId, eventFilter, + eventSortBy, eventOrder, totalRecords, offset, limit); + + // Check if no data found + if (result == null + || result.isEmpty() + || (result.containsKey("totalRecords") && ((Integer) result.get("totalRecords")) == 0)) { + return Response.noContent().build(); // 204 No Content + } + + List dtoList = + EventConfEventDto.fromEntity((List) result.get("eventConfEventList")); + + // Build response + return Response.ok(Map.of("totalRecords", result.get("totalRecords"), "eventConfSourceList", dtoList)) + .build(); + } + + @Override + public Response filterEventConfSource(String filter, String sortBy, String order, Integer totalRecords, + Integer offset, Integer limit, SecurityContext securityContext) { + + // Return 400 Bad Request if offset < 0 or limit < 1 + if (Objects.requireNonNullElse(offset, 0) < 0 || Objects.requireNonNullElse(limit, 0) < 1) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(Map.of("error", "Invalid offset/limit values")) + .build(); + } + + // Call service to fetch results + Map result = eventConfPersistenceService.filterEventConfSource(filter, sortBy, order, + totalRecords, offset, limit); + + // Check if no data found + if (result == null + || result.isEmpty() + || (result.containsKey("totalRecords") && ((Integer) result.get("totalRecords")) == 0)) { + return Response.noContent().build(); // 204 No Content + } + + List dtoList = + EventConfSourceDto.fromEntity((List) result.get("eventConfSourceList")); + + // Build response + return Response.ok(Map.of("totalRecords", result.get("totalRecords"), "eventConfSourceList", dtoList)) + .build(); + } + + @Override + public Response deleteEventConfSources(EventConfSourceDeletePayload payload, SecurityContext securityContext) throws Exception { + + if (payload == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("Request body cannot be null").build(); + } + + if (payload.getSourceIds() == null || payload.getSourceIds().isEmpty()) { + return Response.status(Response.Status.BAD_REQUEST).entity("At least one sourceId must be provided.").build(); + } + + try { + eventConfPersistenceService.deleteEventConfSources(payload); + eventConfPersistenceService.reloadEventsIntoMemory(); + return Response.ok().entity("EventConf sources deleted successfully.").build(); + + } catch (EntityNotFoundException ex) { + return Response.status(Response.Status.NOT_FOUND).entity("One or more sourceIds were not found: " + ex.getMessage()).build(); + } catch (Exception ex) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Unexpected error occurred: " + ex.getMessage()).build(); + } + + } + + @Override + public Response enableDisableEventConfSourcesEvents(final Long sourceId, EnableDisableConfSourceEventsPayload payload, SecurityContext securityContext) throws Exception { + + if (payload == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("Request body cannot be null").build(); + } + + if (payload.getEventsIds() == null || payload.getEventsIds().isEmpty()) { + return Response.status(Response.Status.BAD_REQUEST).entity("At least one eventConfEventsIds must be provided.").build(); + } + + try { + eventConfPersistenceService.enableDisableConfSourcesEvents(sourceId, payload); + eventConfPersistenceService.reloadEventsIntoMemory(); + return Response.ok().entity("EventConfEvents updated successfully.").build(); + + } catch (EntityNotFoundException ex) { + return Response.status(Response.Status.NOT_FOUND).entity("One or more eventConfEvents were not found: " + ex.getMessage()).build(); + } catch (Exception ex) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Unexpected error occurred: " + ex.getMessage()).build(); + } + } + @Override + public Response getEventConfSourcesNames(SecurityContext securityContext) throws Exception { + try { + final var sourceNames = eventConfSourceDao.findAllNames(); + return Response.ok(sourceNames).build(); + } catch (Exception e) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity("Failed to fetch EventConf source names: " + e.getMessage()).build(); + } + } + + @Override + public Response addEventConfSourceEvent(Long sourceId, Event event, SecurityContext securityContext) throws Exception { + try { + validateAddEvent(sourceId,event); + final String username = getUsername(securityContext); + final var id = eventConfPersistenceService.addEventConfSourceEvent(sourceId,username, event); + eventConfPersistenceService.reloadEventsIntoMemory(); + return Response + .status(Response.Status.CREATED) + .entity(id) + .build(); + } catch (EntityNotFoundException ex) { + return Response + .status(Response.Status.NOT_FOUND) + .entity("Source with ID " + sourceId + " not found") + .build(); + } catch (IllegalArgumentException ex) { + return Response + .status(Response.Status.BAD_REQUEST) + .entity("Invalid event payload: " + ex.getMessage()) + .build(); + } + } + + + + @Override + public Response updateEventConfEvent(Long sourceId, Long eventId, EventConfEventEditRequest payload, SecurityContext securityContext) throws Exception { + if (payload == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("Request body cannot be null").build(); + } + try { + eventConfPersistenceService.updateEventConfEvent(sourceId,eventId, payload); + eventConfPersistenceService.reloadEventsIntoMemory(); + return Response.ok().entity("EventConfEvent updated successfully.").build(); + + } catch (EntityNotFoundException ex) { + return Response.status(Response.Status.NOT_FOUND).entity("eventConfEvent were not found: " + ex.getMessage()).build(); + } catch (Exception ex) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Unexpected error occurred: " + ex.getMessage()).build(); + } + } + + @Override + public Response deleteEventsForSource(Long sourceId, EventConfEventDeletePayload payload, SecurityContext securityContext) throws Exception { + if (sourceId == null || sourceId <= 0) { + throw new IllegalArgumentException("Invalid sourceId: must be a positive number"); + } + + if (payload == null || payload.getEventIds() == null || payload.getEventIds().isEmpty()) { + throw new IllegalArgumentException("Event IDs to delete must not be null or empty"); + } + + try { + eventConfPersistenceService.deleteEventsForSource(sourceId, payload); + eventConfPersistenceService.reloadEventsIntoMemory(); + return Response.ok().entity("EventConf events deleted successfully.").build(); + + } catch (EntityNotFoundException ex) { + return Response.status(Response.Status.NOT_FOUND).entity("One or more eventIds were not found: " + ex.getMessage()) + .build(); + } catch (Exception ex) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Unexpected error occurred: " + ex.getMessage()) + .build(); + } + } + private Events parseEventFile(final InputStream inputStream) throws Exception { + return JaxbUtils.unmarshal(Events.class, inputStream); + } + + private String getUsername(final SecurityContext context) { + return (context != null && context.getUserPrincipal() != null) ? context.getUserPrincipal().getName() : "unknown"; + } + + private Map buildSuccessResponse(String filename, Events events) { + Map entry = new LinkedHashMap<>(); + entry.put("file", filename); + entry.put("eventCount", events.getEvents().size()); + entry.put("vendor", StringUtils.substringBefore(filename, ".")); + List> eventSummaries = events + .getEvents() + .stream() + .map(e -> Map.of("uei", e.getUei(), "label", e.getEventLabel(), "description", e.getEventLabel(), "enabled", true)) + .collect(Collectors.toList()); + entry.put("events", eventSummaries); + + return entry; + } + + private Map buildErrorResponse(String filename, Exception ex) { + Map entry = new LinkedHashMap<>(); + entry.put("file", filename); + entry.put("error", ex.getClass().getSimpleName() + ": " + ex.getMessage()); + return entry; + } + + private EventConfSourceMetadataDto buildMetadata(String fileName, String description, Events events, int fileOrder, + String username, Date now) { + return new EventConfSourceMetadataDto.Builder() + .filename(fileName) + .eventCount(events.getEvents().size()) + .fileOrder(fileOrder) + .username(username) + .now(now) + .vendor(StringUtils.substringBefore(fileName, ".")) + .description(description) + .build(); + } + + private String stripPathAndExtension(final String filename) { + if (filename == null) return null; + + // Strip folder paths (handle both / and \ separators) + String basename = filename; + int lastSlash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\')); + if (lastSlash != -1) { + basename = filename.substring(lastSlash + 1); + } + + // Strip extension + int dotIndex = basename.lastIndexOf('.'); + String result = (dotIndex == -1) ? basename : basename.substring(0, dotIndex); + + // Trim trailing/leading whitespace from result + return result.trim(); + } + + private void validateAddEvent(Long sourceId, Event event) { + if (sourceId == null || sourceId <= 0) { + throw new IllegalArgumentException("Invalid sourceId: must be a positive number"); + } + EventConfSource eventConfSource = eventConfSourceDao.get(sourceId); + if (eventConfSource == null) { + throw new EntityNotFoundException("Source with id " + sourceId + " does not exist"); + } + if (event == null) { + throw new IllegalArgumentException("Event payload is missing"); + } + requireNonBlank(event.getUei(), "Event 'uei' is required"); + requireNonBlank(event.getEventLabel(), "Event 'event-label' is required"); + requireNonBlank(event.getSeverity(), "Event 'severity' is required"); + } + + private void requireNonBlank(String value, String message) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException(message); + } + } +} diff --git a/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/api/EventConfRestApi.java b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/api/EventConfRestApi.java new file mode 100644 index 000000000000..19f58039b65e --- /dev/null +++ b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/api/EventConfRestApi.java @@ -0,0 +1,262 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License"); you may not use + * this file except in compliance with the License. + * https://www.gnu.org/licenses/agpl-3.0.txt + */ +package org.opennms.web.rest.v2.api; + +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.opennms.netmgt.model.events.EnableDisableConfSourceEventsPayload; +import org.opennms.netmgt.model.events.EventConfSourceDeletePayload; +import org.opennms.web.rest.v2.model.EventConfEventEditRequest; +import org.opennms.netmgt.xml.eventconf.Event; +import org.opennms.netmgt.model.events.EventConfSrcEnableDisablePayload; +import org.opennms.web.rest.v2.model.EventConfEventDeletePayload; + + +import javax.ws.rs.QueryParam; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PATCH; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.PUT; +import javax.ws.rs.DELETE; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.SecurityContext; +import java.util.List; + +@Path("eventconf") +@Tag(name = "EventConf", description = "EventConf API") +public interface EventConfRestApi { + + @POST + @Path("/upload") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces("application/json") + @Operation( + summary = "Upload eventconf files", + description = "Upload one or more eventconf files including optional eventconf.xml to determine file order.", + operationId = "uploadEventConfFiles" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Upload successful"), + @ApiResponse(responseCode = "400", description = "Invalid eventconf.xml or request") + }) + Response uploadEventConfFiles(@Multipart("upload") List attachments, + @Context SecurityContext securityContext) throws Exception; + + @GET + @Path("filter") + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + @Operation( + summary = "Filter EventConf Records", + description = "Fetch EventConf records based on provided filters such as UEI, vendor, source and name.", + operationId = "filterEventConf" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "EventConf records retrieved successfully", + content = @Content), + @ApiResponse(responseCode = "400", description = "Bad Request – invalid or missing input parameters", + content = @Content), + @ApiResponse(responseCode = "204", description = "No matching EventConf records found for the given criteria", + content = @Content) + }) + Response filterEventConf( + @QueryParam("uei") String uei, + @QueryParam("vendor") String vendor, + @QueryParam("sourceName") String sourceName, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit, + @Context SecurityContext securityContext ); + + @PATCH + @Path("/sources/status") + @Produces("application/json") + @Consumes("application/json") + @Operation( + summary = "Enable/Disable EventConf Sources", + description = "Enable or disable one or more sources (and optionally cascade to their events)", + operationId = "enableDisableEventConfSources" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Updated successfully"), + @ApiResponse(responseCode = "400", description = "Invalid request") + }) + Response enableDisableEventConfSources(EventConfSrcEnableDisablePayload eventConfSrcEnableDisablePayload, @Context SecurityContext securityContext) throws Exception; + + @GET + @Path("filter/{sourceId}/events") + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + @Operation( + summary = "Get EventConfEvents by Source ID with filtering and sorting", + description = """ + Retrieves EventConfEvent records for the given source ID with optional filtering, sorting, and pagination. + - `eventFilter`: case-insensitive match on UEI, Event Label, or Description. + - `eventSortBy`: sort field `uei`, `eventLabel`, `description`, `enabled` defaults to `createdTime` if invalid. + - `eventOrder`: `asc` or `desc` (default: `desc`). + - `offset` and `limit`: for pagination.""", + operationId = "filterConfEventBySourceId" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "EventConf records retrieved successfully", + content = @Content), + @ApiResponse(responseCode = "400", description = "Bad Request – invalid or missing input parameters", + content = @Content), + @ApiResponse(responseCode = "204", description = "No matching EventConfEvent record found for the given criteria", + content = @Content) + }) + Response filterConfEventsBySourceId( + @PathParam("sourceId") Long sourceId, + @QueryParam("eventFilter") String eventFilter, + @QueryParam("eventSortBy") String eventSortBy, + @QueryParam("eventOrder") String eventOrder, + @QueryParam("totalRecords") Integer totalRecords, + @QueryParam("offset") Integer offset, + @QueryParam("limit") Integer limit, + @Context SecurityContext securityContext ); + + + @DELETE + @Path("/sources") + @Consumes(MediaType.APPLICATION_JSON) + @Produces("application/json") + @Operation( + summary = "Delete EventConf Sources", + description = "Delete one or more eventConf sources by their IDs.", + operationId = "deleteEventConfSources" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Sources deleted successfully"), + @ApiResponse(responseCode = "400", description = "Invalid request (missing/invalid IDs)"), + @ApiResponse(responseCode = "404", description = "One or more sources not found") + }) + Response deleteEventConfSources(EventConfSourceDeletePayload eventConfSourceDeletePayload, + @Context SecurityContext securityContext) throws Exception; + + @PATCH + @Path("/sources/{sourceId}/events/status") + @Consumes(MediaType.APPLICATION_JSON) + @Produces("application/json") + @Operation( + summary = "Update EventConf Sources events", + description = "Update one or more eventConf sources by their events IDs.", + operationId = "enableDisableConfSourcesEvents" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Updated successfully"), + @ApiResponse(responseCode = "400", description = "Invalid request (missing/invalid IDs)"), + @ApiResponse(responseCode = "404", description = "One or more sources not found") + }) + Response enableDisableEventConfSourcesEvents(@PathParam("sourceId") final Long sourceId,EnableDisableConfSourceEventsPayload enableDisableConfSourceEventsPayload, + @Context SecurityContext securityContext) throws Exception; + @GET + @Path("filter/sources") + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Filter EventConfSource Records", + description = "Fetch EventConfSource records based on provided filters such as name, vendor, description, fileOrder and eventCount.", + operationId = "filterEventConfSource" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "EventConfSource records retrieved successfully", + content = @Content), + @ApiResponse(responseCode = "400", description = "Bad Request – invalid or missing input parameters", + content = @Content), + @ApiResponse(responseCode = "204", description = "No matching EventConfSource records found for the given criteria", + content = @Content) + }) + Response filterEventConfSource( + @QueryParam("filter") String filter, + @QueryParam("sortBy") String sortBy, + @QueryParam("order") String order, + @QueryParam("totalRecords") Integer totalRecords, + @QueryParam("offset") Integer offset, + @QueryParam("limit") Integer limit, + @Context SecurityContext securityContext ); + + + + @GET + @Path("/sources/names") + @Produces("application/json") + @Operation( + summary = "Get EventConf Source Names", + description = "Retrieve the names of all EventConf sources stored in the database.", + operationId = "getEventConfSourcesNames" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved source names"), + @ApiResponse(responseCode = "500", description = "Internal server error") + }) + Response getEventConfSourcesNames(@Context SecurityContext securityContext) throws Exception; + + @POST + @Path("/sources/{sourceId}/events") + @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Add a new event to an EventConfSource", + description = "Creates and adds a new event under the given EventConfSource by its ID.", + operationId = "addEventConfSourceEvent") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Event created successfully"), + @ApiResponse(responseCode = "400", description = "Invalid request (missing/invalid data)"), + @ApiResponse(responseCode = "404", description = "EventConfSource not found")}) + Response addEventConfSourceEvent(@PathParam("sourceId") final Long sourceId, Event event, @Context SecurityContext securityContext) throws Exception; + + + + @PUT + @Path("/sources/{sourceId}/events/{eventId}") + @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + @Produces("application/json") + @Operation( + summary = "Update EventConf Event", + description = "Update eventConf event by sourceId and eventId.", + operationId = "updateEventConfEvent" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Updated successfully"), + @ApiResponse(responseCode = "400", description = "Invalid request"), + @ApiResponse(responseCode = "404", description = "One or more sources not found") + }) + Response updateEventConfEvent(@PathParam("sourceId") final Long sourceId,@PathParam("eventId") final Long eventId, EventConfEventEditRequest payload, + @Context SecurityContext securityContext) throws Exception; + @DELETE + @Path("/sources/{sourceId}/events") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Delete Events for a Source", + description = "Delete one or more events belonging to the specified eventConf source.", + operationId = "deleteEventsForSource" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Events deleted successfully"), + @ApiResponse(responseCode = "400", description = "Invalid request (missing/invalid event IDs)"), + @ApiResponse(responseCode = "404", description = "Source or one or more events not found") + }) + Response deleteEventsForSource( + @PathParam("sourceId") Long sourceId, + EventConfEventDeletePayload eventConfEventDeletePayload, + @Context SecurityContext securityContext + ) throws Exception; + + +} diff --git a/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfEventDeletePayload.java b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfEventDeletePayload.java new file mode 100644 index 000000000000..83ba925f61b1 --- /dev/null +++ b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfEventDeletePayload.java @@ -0,0 +1,41 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.web.rest.v2.model; + +import java.util.List; + +public class EventConfEventDeletePayload { + private List eventIds; + + public EventConfEventDeletePayload() { + + } + + public List getEventIds() { + return eventIds; + } + + public void setEventIds(List eventIds) { + this.eventIds = eventIds; + } + +} diff --git a/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfEventEditRequest.java b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfEventEditRequest.java new file mode 100644 index 000000000000..ee12c2a484f2 --- /dev/null +++ b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfEventEditRequest.java @@ -0,0 +1,56 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.web.rest.v2.model; + +import org.opennms.netmgt.xml.eventconf.Event; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; + +@XmlRootElement(name = "eventEdit") +@XmlAccessorType(XmlAccessType.FIELD) +public class EventConfEventEditRequest implements Serializable { + + private Boolean enabled; + + @XmlElement(name = "event", namespace = "http://xmlns.opennms.org/xsd/eventconf") + private org.opennms.netmgt.xml.eventconf.Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } +} \ No newline at end of file diff --git a/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfSourceDto.java b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfSourceDto.java new file mode 100644 index 000000000000..1143055a1947 --- /dev/null +++ b/opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/EventConfSourceDto.java @@ -0,0 +1,115 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.opennms.web.rest.v2.model; + +import org.opennms.netmgt.model.EventConfSource; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +public class EventConfSourceDto { + + private Long id; + private String name; + private String description; + private String vendor; + private Integer fileOrder; + private Boolean enabled; + private Integer eventCount; + private Date createdTime; + private Date lastModified; + private String uploadedBy; + + // All-args constructor + public EventConfSourceDto(Long id, String name, String description, String vendor, + Integer fileOrder, Boolean enabled, Integer eventCount, + Date createdTime, Date lastModified, String uploadedBy) { + this.id = id; + this.name = name; + this.description = description; + this.vendor = vendor; + this.fileOrder = fileOrder; + this.enabled = enabled; + this.eventCount = eventCount; + this.createdTime = createdTime; + this.lastModified = lastModified; + this.uploadedBy = uploadedBy; + } + + // Getters & setters + public Long getId() { return id; } + public void setId(Long id) { this.id = id; } + + public String getName() { return name; } + public void setName(String name) { this.name = name; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public String getVendor() { return vendor; } + public void setVendor(String vendor) { this.vendor = vendor; } + + public Integer getFileOrder() { return fileOrder; } + public void setFileOrder(Integer fileOrder) { this.fileOrder = fileOrder; } + + public Boolean getEnabled() { return enabled; } + public void setEnabled(Boolean enabled) { this.enabled = enabled; } + + public Integer getEventCount() { return eventCount; } + public void setEventCount(Integer eventCount) { this.eventCount = eventCount; } + + public Date getCreatedTime() { return createdTime; } + public void setCreatedTime(Date createdTime) { this.createdTime = createdTime; } + + public Date getLastModified() { return lastModified; } + public void setLastModified(Date lastModified) { this.lastModified = lastModified; } + + public String getUploadedBy() { return uploadedBy; } + public void setUploadedBy(String uploadedBy) { this.uploadedBy = uploadedBy; } + + // Mapper for single entity + public static EventConfSourceDto fromEntity(EventConfSource entity) { + return new EventConfSourceDto( + entity.getId(), + entity.getName(), + entity.getDescription(), + entity.getVendor(), + entity.getFileOrder(), + entity.getEnabled(), + entity.getEventCount(), + entity.getCreatedTime(), + entity.getLastModified(), + entity.getUploadedBy() + ); + } + + // Mapper for list + public static List fromEntity(List entityList) { + if (entityList == null ) return Collections.emptyList(); + return entityList.stream() + .map(EventConfSourceDto::fromEntity) + .collect(Collectors.toList()); + } +} diff --git a/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-alt.json b/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-alt.json index fc4b926df668..8baaeb35375b 100644 --- a/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-alt.json +++ b/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-alt.json @@ -169,7 +169,7 @@ { "id": "customizeEvents", "name": "Customize Events", - "url": "admin/manageEvents.jsp", + "url": "ui/index.html#/event-config", "locationMatch": "", "roles": null }, diff --git a/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-default.json b/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-default.json index 79211a48f51c..9cf77ba2edd4 100644 --- a/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-default.json +++ b/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-default.json @@ -478,7 +478,7 @@ { "id": "customizeEvents", "name": "Customize Events", - "url": "admin/manageEvents.jsp", + "url": "ui/index.html#/event-config", "locationMatch": "", "roles": null }, diff --git a/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template.json b/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template.json index 79211a48f51c..9cf77ba2edd4 100644 --- a/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template.json +++ b/opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template.json @@ -478,7 +478,7 @@ { "id": "customizeEvents", "name": "Customize Events", - "url": "admin/manageEvents.jsp", + "url": "ui/index.html#/event-config", "locationMatch": "", "roles": null }, diff --git a/opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/EventConfPersistenceServiceIT.java b/opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/EventConfPersistenceServiceIT.java new file mode 100755 index 000000000000..ac4ffaac0c6f --- /dev/null +++ b/opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/EventConfPersistenceServiceIT.java @@ -0,0 +1,878 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.web.rest.v2; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opennms.core.test.OpenNMSJUnit4ClassRunner; +import org.opennms.core.test.db.annotations.JUnitTemporaryDatabase; +import org.opennms.core.xml.JaxbUtils; +import org.opennms.netmgt.config.api.EventConfDao; +import org.opennms.netmgt.dao.api.EventConfEventDao; +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.netmgt.model.events.EnableDisableConfSourceEventsPayload; +import org.opennms.netmgt.model.events.EventConfSourceDeletePayload; +import org.opennms.netmgt.model.events.EventConfSourceMetadataDto; +import org.opennms.netmgt.model.events.EventConfSrcEnableDisablePayload; +import org.opennms.netmgt.xml.eventconf.Event; +import org.opennms.netmgt.xml.eventconf.Events; +import org.opennms.test.JUnitConfigurationEnvironment; +import org.opennms.web.rest.v2.model.EventConfEventDeletePayload; +import org.opennms.web.rest.v2.model.EventConfEventEditRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +@RunWith(OpenNMSJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(locations = {"classpath:/META-INF/opennms/applicationContext-soa.xml", + "classpath:/META-INF/opennms/applicationContext-commonConfigs.xml", + "classpath:/META-INF/opennms/applicationContext-dao.xml", + "classpath*:/META-INF/opennms/component-dao.xml", + "classpath:/META-INF/opennms/mockEventIpcManager.xml", + "classpath:/applicationContext-rest-test.xml" + +}) +@JUnitConfigurationEnvironment +@JUnitTemporaryDatabase +public class EventConfPersistenceServiceIT { + + @Autowired + private EventConfSourceDao eventConfSourceDao; + + @Autowired + private EventConfEventDao eventConfEventDao; + + @Autowired + private EventConfDao eventConfDao; + + @Autowired + private EventConfPersistenceService eventConfPersistenceService; + + private int defaultEventConfSize; + private int defaultEventConfEventSize; + + @Before + @Transactional + public void setUp() { + defaultEventConfSize = eventConfSourceDao.findAllByFileOrder().size(); + defaultEventConfEventSize = eventConfEventDao.findAll().size(); + } + + + @Test + @JUnitTemporaryDatabase + @Transactional + public void testPersistNewEventConfSourceAndEvents() { + String filename = "test-events.xml"; + String username = "integration_test_user"; + Date now = new Date(); + EventConfSourceMetadataDto metadata = new EventConfSourceMetadataDto.Builder().filename(filename).eventCount(1).fileOrder(0).username(username).now(now).vendor("test-vendor").description("integration test file").build(); + Event event = new Event(); + event.setUei("uei.opennms.org/test/it"); + event.setEventLabel("IT Event"); + event.setDescr("This is an integration test event."); + event.setSeverity("Normal"); + Events events = new Events(); + events.getEvents().add(event); + eventConfPersistenceService.persistEventConfFile(events, metadata); + + List sources = eventConfSourceDao.findAllByFileOrder(); + assertEquals(1, sources.size() - defaultEventConfSize); + EventConfSource source = sources.get(0); + assertEquals(filename, source.getName()); + assertEquals("integration test file", source.getDescription()); + assertEquals("test-vendor", source.getVendor()); + assertEquals(username, source.getUploadedBy()); + + List dbEvents = eventConfEventDao.findEnabledEvents(); + assertEquals(1, dbEvents.size() - defaultEventConfEventSize); + EventConfEvent persistedEvent = dbEvents.get(defaultEventConfEventSize); + assertEquals("uei.opennms.org/test/it", persistedEvent.getUei()); + assertEquals("IT Event", persistedEvent.getEventLabel()); + assertEquals("This is an integration test event.", persistedEvent.getDescription()); + Assert.assertTrue(persistedEvent.getEnabled()); + assertEquals(username, persistedEvent.getModifiedBy()); + } + + @Test + @JUnitTemporaryDatabase + @Transactional + public void testPersistUpdatesExistingSource() { + String filename = "existing-source"; + String username = "test_user"; + Date now = new Date(); + EventConfSourceMetadataDto metadata = new EventConfSourceMetadataDto.Builder().filename(filename).eventCount(2).fileOrder(0).username(username).now(now).vendor("update-vendor").description("original entry").build(); + Event event = new Event(); + event.setUei("uei.opennms.org/test/update"); + event.setEventLabel("Initial Event"); + event.setDescr("Initial Description"); + event.setSeverity("Normal"); + Events events = new Events(); + events.getEvents().add(event); + eventConfPersistenceService.persistEventConfFile(events, metadata); + + EventConfSourceMetadataDto updatedMetadata = new EventConfSourceMetadataDto.Builder().filename(filename).eventCount(3).fileOrder(1).username("updated_user").now(new Date()).vendor("updated-vendor").description("updated entry").build(); + Event updatedEvent = new Event(); + updatedEvent.setUei("uei.opennms.org/test/update2"); + updatedEvent.setEventLabel("Updated Event"); + updatedEvent.setDescr("Updated Description"); + updatedEvent.setSeverity("Normal"); + Events updatedEvents = new Events(); + updatedEvents.getEvents().add(updatedEvent); + eventConfPersistenceService.persistEventConfFile(updatedEvents, updatedMetadata); + List sources = eventConfSourceDao.findAllByFileOrder(); + + assertEquals(1, sources.size() - defaultEventConfSize); + EventConfSource source = sources.get(0); + assertEquals(filename, source.getName()); + Assert.assertEquals("existing-source", source.getName()); + Assert.assertEquals("updated entry", source.getDescription()); + Assert.assertEquals("updated-vendor", source.getVendor()); + Assert.assertEquals("updated_user", source.getUploadedBy()); + Assert.assertEquals(0, (int) source.getFileOrder()); + List updatedDbEvents = eventConfEventDao.findEnabledEvents(); + assertEquals(1, updatedDbEvents.size() - defaultEventConfEventSize); + EventConfEvent finalEvent = updatedDbEvents.get(defaultEventConfEventSize); + assertEquals("uei.opennms.org/test/update2", finalEvent.getUei()); + assertEquals("Updated Description", finalEvent.getDescription()); + } + + @Test + @JUnitTemporaryDatabase + @Transactional + public void testFilterEventConf_ShouldReturnFilteredResults() { + // Arrange: Persist multiple events with different vendors, UEIs, and source names + String filename1 = "vendor-cisco.xml"; + String filename2 = "vendor-hp.xml"; + String username = "filter_test_user"; + Date now = new Date(); + + // First metadata (Cisco vendor) + EventConfSourceMetadataDto ciscoMetadata = new EventConfSourceMetadataDto.Builder() + .filename(filename1) + .eventCount(1) + .fileOrder(1) + .username(username) + .now(now) + .vendor("Cisco") + .description("Cisco events") + .build(); + + Event ciscoEvent = new Event(); + ciscoEvent.setUei("uei.opennms.org/vendor/cisco"); + ciscoEvent.setEventLabel("Cisco Event"); + ciscoEvent.setDescr("Cisco test event"); + ciscoEvent.setSeverity("Normal"); + + Events ciscoEvents = new Events(); + ciscoEvents.getEvents().add(ciscoEvent); + + eventConfPersistenceService.persistEventConfFile(ciscoEvents, ciscoMetadata); + + // Second metadata (HP vendor) + EventConfSourceMetadataDto hpMetadata = new EventConfSourceMetadataDto.Builder() + .filename(filename2) + .eventCount(1) + .fileOrder(2) + .username(username) + .now(now) + .vendor("HP") + .description("HP events") + .build(); + + Event hpEvent = new Event(); + hpEvent.setUei("uei.opennms.org/vendor/hp"); + hpEvent.setEventLabel("HP Event"); + hpEvent.setDescr("HP test event"); + hpEvent.setSeverity("Normal"); + + Events hpEvents = new Events(); + hpEvents.getEvents().add(hpEvent); + + eventConfPersistenceService.persistEventConfFile(hpEvents, hpMetadata); + + // Act: Filter only Cisco events + List filteredResults = eventConfPersistenceService.findEventConfByFilters( + null, // uei + "Cisco", // vendor + null, // sourceName + 0, //offset + 10 //limit + ); + + // Assert + assertNotNull(filteredResults); + Assert.assertFalse(filteredResults.isEmpty()); + Assert.assertTrue(filteredResults.stream() + .allMatch(e -> "Cisco".equals(e.getSource().getVendor()))); + Assert.assertTrue(filteredResults.stream() + .anyMatch(e -> e.getUei().contains("cisco"))); + } + + @Test + public void filter_shouldReturnEmptyList_whenNoMatchesFound() { + List results = eventConfPersistenceService + .findEventConfByFilters("nonexistent-uei", "nonexistent-vendor", "nonexistent-source", 0, 10); + + assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + } + + @Test + @JUnitTemporaryDatabase + public void testUpdateSourceAndEventEnabled() { + String username = "test_user"; + Date now = new Date(); + + String filename1 = "source-file-1"; + EventConfSourceMetadataDto metadata1 = new EventConfSourceMetadataDto.Builder() + .filename(filename1) + .eventCount(1) + .fileOrder(1) + .username(username) + .now(now) + .vendor("vendor-1") + .description("first entry") + .build(); + + Event event1 = new Event(); + event1.setUei("uei.opennms.org/test/update/1"); + event1.setEventLabel("Event One"); + event1.setDescr("Description for Event One"); + event1.setSeverity("Normal"); + + Events events1 = new Events(); + events1.getEvents().add(event1); + + eventConfPersistenceService.persistEventConfFile(events1, metadata1); + + String filename2 = "source-file-2"; + EventConfSourceMetadataDto metadata2 = new EventConfSourceMetadataDto.Builder() + .filename(filename2) + .eventCount(1) + .fileOrder(2) + .username(username) + .now(now) + .vendor("vendor-2") + .description("second entry") + .build(); + + Event event2 = new Event(); + event2.setUei("uei.opennms.org/test/update/2"); + event2.setEventLabel("Event Two"); + event2.setDescr("Description for Event Two"); + event2.setSeverity("Warning"); + + Events events2 = new Events(); + events2.getEvents().add(event2); + + eventConfPersistenceService.persistEventConfFile(events2, metadata2); + + List sourcesIds = eventConfSourceDao.findAll() + .stream().map(EventConfSource::getId).toList(); + // Disable eventConfSources and eventConfEvents. + EventConfSrcEnableDisablePayload eventConfSrcDisablePayload = new EventConfSrcEnableDisablePayload(false, true, sourcesIds); + eventConfPersistenceService.updateSourceAndEventEnabled(eventConfSrcDisablePayload); + List eventConfSources = eventConfSourceDao.findAll(); + assertTrue(eventConfSources.stream().noneMatch(EventConfSource::getEnabled)); + List eventConfEvents = eventConfEventDao.findAll(); + assertTrue(eventConfEvents.stream().noneMatch(EventConfEvent::getEnabled)); + + // Enable eventConfSources and eventConfEvents. + EventConfSrcEnableDisablePayload eventConfSrcEnablePayload = new EventConfSrcEnableDisablePayload(true, true, sourcesIds); + eventConfPersistenceService.updateSourceAndEventEnabled(eventConfSrcEnablePayload); + List enableEventConfSources = eventConfSourceDao.findAll(); + assertFalse(enableEventConfSources.stream().noneMatch(EventConfSource::getEnabled)); + List enableEventConfEvents = eventConfEventDao.findAll(); + assertFalse(enableEventConfEvents.stream().noneMatch(EventConfEvent::getEnabled)); + } + + @Test + @Transactional + public void testFilterConfEventsBySourceId_ShouldReturnFilteredResults() { + String filename1 = "vendor-cisco.xml"; + String filename2 = "vendor-hp.xml"; + String username = "filter_test_user"; + Date now = new Date(); + + // First metadata (Cisco vendor) + EventConfSourceMetadataDto ciscoMetadata = new EventConfSourceMetadataDto.Builder() + .filename(filename1) + .eventCount(1) + .fileOrder(1) + .username(username) + .now(now) + .vendor("Cisco") + .description("Cisco events") + .build(); + + Event ciscoEvent = new Event(); + ciscoEvent.setUei("uei.opennms.org/vendor/cisco"); + ciscoEvent.setEventLabel("Cisco Event"); + ciscoEvent.setDescr("Cisco test event"); + ciscoEvent.setSeverity("Normal"); + + Events ciscoEvents = new Events(); + ciscoEvents.getEvents().add(ciscoEvent); + + eventConfPersistenceService.persistEventConfFile(ciscoEvents, ciscoMetadata); + + // Second metadata (HP vendor) + EventConfSourceMetadataDto hpMetadata = new EventConfSourceMetadataDto.Builder() + .filename(filename2) + .eventCount(1) + .fileOrder(2) + .username(username) + .now(now) + .vendor("HP") + .description("HP events") + .build(); + + Event hpEvent = new Event(); + hpEvent.setUei("uei.opennms.org/vendor/hp"); + hpEvent.setEventLabel("HP Event"); + hpEvent.setDescr("HP test event"); + hpEvent.setSeverity("Normal"); + + Events hpEvents = new Events(); + hpEvents.getEvents().add(hpEvent); + + eventConfPersistenceService.persistEventConfFile(hpEvents, hpMetadata); + + EventConfSource eventConfSource = eventConfSourceDao.findByName("vendor-hp.xml"); + Assert.assertNotNull(eventConfSource); + + Map result = eventConfPersistenceService.filterConfEventsBySourceId(eventConfSource.getId(), + "", "", "", 0, 0, 10); + Assert.assertNotNull(result); + Assert.assertTrue(result.containsKey("totalRecords")); + Assert.assertEquals(1, result.get("totalRecords")); + Assert.assertTrue(result.containsKey("eventConfEventList")); + + List eventConfEventList = (List) result.get("eventConfEventList"); + + Assert.assertNotNull(eventConfEventList); + Assert.assertFalse(eventConfEventList.isEmpty()); + Assert.assertTrue(eventConfEventList.stream().allMatch(e -> "HP Event".equals(e.getEventLabel()))); + + + + eventConfSource = eventConfSourceDao.findByName("vendor-cisco.xml"); + Assert.assertNotNull(eventConfSource); + + result = eventConfPersistenceService.filterConfEventsBySourceId(eventConfSource.getId(), "", + "", "", 0, 0, 10); + Assert.assertNotNull(result); + Assert.assertTrue(result.containsKey("totalRecords")); + Assert.assertEquals(1, result.get("totalRecords")); + Assert.assertTrue(result.containsKey("eventConfEventList")); + + eventConfEventList = (List) result.get("eventConfEventList"); + + + Assert.assertNotNull(eventConfEventList); + Assert.assertFalse(eventConfEventList.isEmpty()); + Assert.assertTrue(eventConfEventList.stream().allMatch(e -> "Cisco Event".equals(e.getEventLabel()))); + } + + @Test + @Transactional + public void testFilterConfEventsBySourceId_ShouldReturnEmptyResults() { + Long sourceId = 8000L; + Map result = eventConfPersistenceService.filterConfEventsBySourceId(sourceId, "", + "", "" , 0, 0, 10); + Assert.assertNotNull(result); + Assert.assertTrue(result.containsKey("totalRecords")); + Assert.assertEquals(0, result.get("totalRecords")); + Assert.assertTrue(result.containsKey("eventConfEventList")); + + List eventConfEventList = (List) result.get("eventConfEventList"); + Assert.assertNotNull(eventConfEventList); + Assert.assertTrue(eventConfEventList.isEmpty()); + } + + @Test + @JUnitTemporaryDatabase + @Transactional + public void testLoadingOfEventsInMemory() { + + // Call loadEventsFromDB directly + var dbEvents = eventConfEventDao.findEnabledEvents(); + eventConfDao.loadEventsFromDB(dbEvents); + var event = eventConfDao.findByUei("uei.opennms.org/circuitBreaker/stateChange"); + assertNotNull(event); + // This is not unique uei so getEventByUeiOptimistic will exclude this. + var uniqueEvent = eventConfDao.getRootEvents().getEventByUeiOptimistic("uei.opennms.org/circuitBreaker/stateChange"); + assertNull(uniqueEvent); + assertEquals(defaultEventConfEventSize, eventConfDao.getEventUEIs().size()); + + } + + @Test + @JUnitTemporaryDatabase + @Transactional + public void testDeleteEventConfSources() throws Exception { + String username = "test_user"; + Date now = new Date(); + + String filename1 = "source-file-1.xml"; + EventConfSourceMetadataDto metadata1 = new EventConfSourceMetadataDto.Builder() + .filename(filename1) + .eventCount(1) + .fileOrder(1) + .username(username) + .now(now) + .vendor("vendor-1") + .description("first entry") + .build(); + + Event event1 = new Event(); + event1.setUei("uei.opennms.org/test/update/1"); + event1.setEventLabel("Event One"); + event1.setDescr("Description for Event One"); + event1.setSeverity("Normal"); + + Events events1 = new Events(); + events1.getEvents().add(event1); + + eventConfPersistenceService.persistEventConfFile(events1, metadata1); + + String filename2 = "source-file-2.xml"; + EventConfSourceMetadataDto metadata2 = new EventConfSourceMetadataDto.Builder() + .filename(filename2) + .eventCount(1) + .fileOrder(2) + .username(username) + .now(now) + .vendor("vendor-2") + .description("second entry") + .build(); + + Event event2 = new Event(); + event2.setUei("uei.opennms.org/test/update/2"); + event2.setEventLabel("Event Two"); + event2.setDescr("Description for Event Two"); + event2.setSeverity("Warning"); + + Events events2 = new Events(); + events2.getEvents().add(event2); + + eventConfPersistenceService.persistEventConfFile(events2, metadata2); + + List sourcesIds = eventConfSourceDao.findAll() + .stream().map(EventConfSource::getId).toList(); + // delete eventConfSources and its related events + EventConfSourceDeletePayload eventConfSrcDisablePayload = new EventConfSourceDeletePayload(); + eventConfSrcDisablePayload.setSourceIds(sourcesIds); + eventConfPersistenceService.deleteEventConfSources(eventConfSrcDisablePayload); + List eventConfSources = eventConfSourceDao.findAll(); + assertTrue(eventConfSources.isEmpty()); + + } + + @Test + @JUnitTemporaryDatabase + public void testEnableDisableEventConfSourcesEvents() { + String username = "test_user"; + Date now = new Date(); + + String filename1 = "source-file-1.xml"; + EventConfSourceMetadataDto metadata1 = new EventConfSourceMetadataDto.Builder() + .filename(filename1) + .eventCount(1) + .fileOrder(1) + .username(username) + .now(now) + .vendor("vendor-1") + .description("first entry") + .build(); + + Event event1 = new Event(); + event1.setUei("uei.opennms.org/test/trigger/1"); + event1.setEventLabel("Event One"); + event1.setDescr("Description for Event One"); + event1.setSeverity("Normal"); + + Events events1 = new Events(); + events1.getEvents().add(event1); + + eventConfPersistenceService.persistEventConfFile(events1, metadata1); + + String filename2 = "source-file-2.xml"; + EventConfSourceMetadataDto metadata2 = new EventConfSourceMetadataDto.Builder() + .filename(filename2) + .eventCount(1) + .fileOrder(2) + .username(username) + .now(now) + .vendor("vendor-2") + .description("second entry") + .build(); + + Event event2 = new Event(); + event2.setUei("uei.opennms.org/test/clear/2"); + event2.setEventLabel("Event Two"); + event2.setDescr("Description for Event Two"); + event2.setSeverity("Warning"); + + Events events2 = new Events(); + events2.getEvents().add(event2); + + eventConfPersistenceService.persistEventConfFile(events2, metadata2); + + // Retrieve initial events + EventConfEvent triggerEvent = eventConfEventDao.findByUei("uei.opennms.org/test/trigger/1"); + + long sourceId = triggerEvent.getSource().getId(); + + // Disable events + EnableDisableConfSourceEventsPayload disablePayload = new EnableDisableConfSourceEventsPayload(); + disablePayload.setEventsIds(List.of(triggerEvent.getId())); + disablePayload.setEnable(false); + + eventConfPersistenceService.enableDisableConfSourcesEvents(sourceId, disablePayload); + + // Verify disabled state + EventConfEvent disabledTriggerEvent = eventConfEventDao.findByUei("uei.opennms.org/test/trigger/1"); + + assertFalse(disabledTriggerEvent.getEnabled()); + + // Enable events + EnableDisableConfSourceEventsPayload enablePayload = new EnableDisableConfSourceEventsPayload(); + enablePayload.setEventsIds(List.of(triggerEvent.getId())); + enablePayload.setEnable(true); + + eventConfPersistenceService.enableDisableConfSourcesEvents(sourceId, enablePayload); + + // Verify enabled state + EventConfEvent enabledTriggerEvent = eventConfEventDao.findByUei("uei.opennms.org/test/trigger/1"); + + assertTrue(enabledTriggerEvent.getEnabled()); + } + + @Test + @JUnitTemporaryDatabase + public void testAddEventConfSourceEvent() { + String username = "test_user"; + Date now = new Date(); + String filename1 = "source-file-1.xml"; + EventConfSourceMetadataDto metadata1 = new EventConfSourceMetadataDto + .Builder() + .filename(filename1) + .eventCount(1) + .fileOrder(1) + .username(username) + .now(now) + .vendor("vendor-1") + .description("first entry") + .build(); + + Event event1 = new Event(); + event1.setUei("uei.opennms.org/test/trigger/1"); + event1.setEventLabel("Event One"); + event1.setDescr("Description for Event One"); + event1.setSeverity("Normal"); + + Events events1 = new Events(); + events1.getEvents().add(event1); + + eventConfPersistenceService.persistEventConfFile(events1, metadata1); + + EventConfSource eventConfSource = eventConfSourceDao.findByName("source-file-1.xml"); + assertNotNull("Event Source not found against name Cisco.airespace ", eventConfSource); + + String xmlEvent = """ + + uei.opennms.org/vendor/test/test1 + Test1: Adding new test event + Add new test event + Warning + + """; + Event event = JaxbUtils.unmarshal(Event.class, xmlEvent); + eventConfPersistenceService.addEventConfSourceEvent(eventConfSource.getId(), username, event); + + EventConfEvent newlyAddedEvent = eventConfEventDao.findByUei("uei.opennms.org/vendor/test/test1"); + assertNotNull(newlyAddedEvent); + } + + @Test + @Transactional + public void testUpdateEventConfEventWithXml() throws Exception { + EventConfSource m_source = new EventConfSource(); + m_source.setName("testEventEnabledFlagTest"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test event source"); + m_source.setVendor("TestVendor1"); + m_source.setUploadedBy("JUnitTest"); + m_source.setEventCount(2); + m_source.setLastModified(new Date()); + + eventConfSourceDao.saveOrUpdate(m_source); + eventConfSourceDao.flush(); + + insertEvent(m_source, "uei.opennms.org/internal/trigger", "Trigger configuration changed testing", "The Trigger configuration has been changed and should be reloaded", "Normal"); + + insertEvent(m_source, "uei.opennms.org/internal/clear", "Clear discovery failed testing", "The Clear discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.", "Minor"); + + EventConfSource source = eventConfSourceDao.findByName("testEventEnabledFlagTest"); + + EventConfEvent triggerEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/trigger"); + EventConfEvent clearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + + // xml payload + EventConfEventEditRequest payload = new EventConfEventEditRequest(); + String xmlPayload = """ + + uei.opennms.org/internal/clear + Clear label changed. + Clear Description changed. + Major + + """; + Event event = JaxbUtils.unmarshal(Event.class, xmlPayload); + payload.setEvent(event); + payload.setEnabled(true); + + eventConfPersistenceService.updateEventConfEvent(source.getId(), clearEvent.getId(), payload); + + EventConfEvent updatedClearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + assertEquals("Clear label changed.", updatedClearEvent.getEventLabel()); + assertEquals("Clear Description changed.", updatedClearEvent.getDescription()); + + // verify xml content updated or not. + Event dbEvent = JaxbUtils.unmarshal(Event.class, updatedClearEvent.getXmlContent()); + assertEquals("Clear label changed.", dbEvent.getEventLabel()); + assertEquals("Clear Description changed.", dbEvent.getDescr()); + + } + + @Test + @Transactional + public void testUpdateEventConfEventWithJson() throws Exception { + EventConfSource m_source = new EventConfSource(); + m_source.setName("testEventJsonPayload"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test event source"); + m_source.setVendor("TestVendor1"); + m_source.setUploadedBy("JUnitTest"); + m_source.setEventCount(2); + m_source.setLastModified(new Date()); + + eventConfSourceDao.saveOrUpdate(m_source); + eventConfSourceDao.flush(); + + insertEvent(m_source, "uei.opennms.org/internal/trigger", "Trigger configuration changed testing", "The Trigger configuration has been changed and should be reloaded", "Normal"); + + insertEvent(m_source, "uei.opennms.org/internal/clear", "Clear discovery failed testing", "The Clear discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.", "Minor"); + + EventConfSource source = eventConfSourceDao.findByName("testEventJsonPayload"); + + EventConfEvent clearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + + String jsonPayload = """ + { + "enabled": true, + "event": { + "uei": "uei.opennms.org/internal/clear", + "eventLabel": "Clear label changed.", + "descr": "Clear Description changed.", + "severity": "Major" + } + } + """; + ObjectMapper mapper = new ObjectMapper(); + EventConfEventEditRequest payload = mapper.readValue(jsonPayload, EventConfEventEditRequest.class); + + eventConfPersistenceService.updateEventConfEvent(source.getId(),clearEvent.getId(), payload); + + EventConfEvent updatedClearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + assertEquals("Clear label changed.", updatedClearEvent.getEventLabel()); + assertEquals("Clear Description changed.", updatedClearEvent.getDescription()); + + // verify xml content updated correctly + Event dbEvent = JaxbUtils.unmarshal(Event.class, updatedClearEvent.getXmlContent()); + assertEquals("Clear label changed.", dbEvent.getEventLabel()); + assertEquals("Clear Description changed.", dbEvent.getDescr()); + } + + private void insertEvent(EventConfSource m_source,String uei, String label, String description, String severity) { + EventConfEvent event = new EventConfEvent(); + event.setUei(uei); + event.setEventLabel(label); + event.setDescription(description); + event.setXmlContent("" + uei + ""); + event.setSource(m_source); + event.setEnabled(true); + event.setCreatedTime(new Date()); + event.setLastModified(new Date()); + event.setModifiedBy("JUnitTest"); + + eventConfEventDao.saveOrUpdate(event); + } + @Test + @JUnitTemporaryDatabase + @Transactional + public void testDeleteEventsForSource() throws Exception { + String username = "test_user"; + Date now = new Date(); + + String filename1 = "source-file-1.xml"; + EventConfSourceMetadataDto metadata1 = new EventConfSourceMetadataDto.Builder() + .filename(filename1) + .eventCount(3) + .fileOrder(1) + .username(username) + .now(now) + .vendor("vendor-1") + .description("first entry") + .build(); + + Event event1 = new Event(); + event1.setUei("uei.opennms.org/test/update/1"); + event1.setEventLabel("Event One"); + event1.setDescr("Description for Event One"); + event1.setSeverity("Normal"); + + Event event2 = new Event(); + event2.setUei("uei.opennms.org/test/update/2"); + event2.setEventLabel("Event Two"); + event2.setDescr("Description for Event Two"); + event2.setSeverity("Warning"); + + Event event3 = new Event(); + event3.setUei("uei.opennms.org/test/update/3"); + event3.setEventLabel("Event three"); + event3.setDescr("Description for Event three"); + event3.setSeverity("Major"); + + Events events1 = new Events(); + events1.getEvents().addAll(List.of(event1, event2, event3)); + + eventConfPersistenceService.persistEventConfFile(events1, metadata1); + + EventConfSource eventConfSource = eventConfSourceDao.findByName("source-file-1.xml"); + List eventConfEvents = eventConfEventDao.findBySourceId(eventConfSource.getId()); + + Long sourceId = eventConfSource.getId(); + Long eventId1 = eventConfEvents.stream() + .filter(event -> event.getUei().equals("uei.opennms.org/test/update/2")) + .findFirst() + .get().getId(); + + Long eventId2 = eventConfEvents.stream() + .filter(event -> event.getUei().equals("uei.opennms.org/test/update/3")) + .findFirst() + .get().getId(); + + // delete eventConfSources and its related events + EventConfEventDeletePayload eventConfEventDeletePayload = new EventConfEventDeletePayload(); + eventConfEventDeletePayload.setEventIds(List.of(eventId1, eventId2)); + eventConfPersistenceService.deleteEventsForSource(sourceId, eventConfEventDeletePayload); + + List updatedEventsBySource = eventConfEventDao.findBySourceId(eventConfSource.getId()); + assertEquals(1, updatedEventsBySource.size()); + EventConfSource updatedSource = eventConfSourceDao.findByName("source-file-1.xml"); + assertEquals(Integer.valueOf(1),updatedSource.getEventCount()); + } + + @Test + @JUnitTemporaryDatabase + @Transactional + public void shouldDeleteSource_whenAllEventsAreDeleted() throws Exception { + String username = "test_user"; + Date now = new Date(); + + String filename1 = "source-file-1.xml"; + EventConfSourceMetadataDto metadata1 = new EventConfSourceMetadataDto.Builder() + .filename(filename1) + .eventCount(2) + .fileOrder(1) + .username(username) + .now(now) + .vendor("vendor-1") + .description("first entry") + .build(); + + Event event1 = new Event(); + event1.setUei("uei.opennms.org/test/update/1"); + event1.setEventLabel("Event One"); + event1.setDescr("Description for Event One"); + event1.setSeverity("Normal"); + + Event event2 = new Event(); + event2.setUei("uei.opennms.org/test/update/2"); + event2.setEventLabel("Event Two"); + event2.setDescr("Description for Event Two"); + event2.setSeverity("Warning"); + + + Events events1 = new Events(); + events1.getEvents().addAll(List.of(event1, event2)); + + eventConfPersistenceService.persistEventConfFile(events1, metadata1); + + EventConfSource eventConfSource = eventConfSourceDao.findByName("source-file-1.xml"); + List eventConfEvents = eventConfEventDao.findBySourceId(eventConfSource.getId()); + + Long sourceId = eventConfSource.getId(); + Long eventId1 = eventConfEvents.stream() + .filter(event -> event.getUei().equals("uei.opennms.org/test/update/1")) + .findFirst() + .get().getId(); + + Long eventId2 = eventConfEvents.stream() + .filter(event -> event.getUei().equals("uei.opennms.org/test/update/2")) + .findFirst() + .get().getId(); + + // delete eventConfSources and its related events + EventConfEventDeletePayload eventConfEventDeletePayload = new EventConfEventDeletePayload(); + eventConfEventDeletePayload.setEventIds(List.of(eventId1, eventId2)); + eventConfPersistenceService.deleteEventsForSource(sourceId, eventConfEventDeletePayload); + + List updatedEventsBySource = eventConfEventDao.findBySourceId(eventConfSource.getId()); + assertEquals(0, updatedEventsBySource.size()); + } +} + diff --git a/opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/EventConfRestServiceIT.java b/opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/EventConfRestServiceIT.java new file mode 100644 index 000000000000..bf45f062e42c --- /dev/null +++ b/opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/EventConfRestServiceIT.java @@ -0,0 +1,681 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.web.rest.v2; + + +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition; +import org.hibernate.SessionFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opennms.core.test.OpenNMSJUnit4ClassRunner; +import org.opennms.core.test.db.annotations.JUnitTemporaryDatabase; +import org.opennms.core.xml.JaxbUtils; +import org.opennms.netmgt.model.EventConfEventDto; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.events.EventConfSrcEnableDisablePayload; +import org.opennms.netmgt.dao.api.EventConfEventDao; +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.netmgt.model.events.EnableDisableConfSourceEventsPayload; +import org.opennms.netmgt.model.events.EventConfSourceDeletePayload; +import org.opennms.netmgt.xml.eventconf.Event; +import org.opennms.test.JUnitConfigurationEnvironment; +import org.opennms.web.rest.v2.api.EventConfRestApi; +import org.opennms.web.rest.v2.model.EventConfEventEditRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.transaction.annotation.Transactional; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; +import java.io.InputStream; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import java.util.Date; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(OpenNMSJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(locations = {"classpath:/META-INF/opennms/applicationContext-soa.xml", + "classpath:/META-INF/opennms/applicationContext-commonConfigs.xml", + "classpath:/META-INF/opennms/applicationContext-dao.xml", + "classpath*:/META-INF/opennms/component-dao.xml", + "classpath:/META-INF/opennms/mockEventIpcManager.xml", + "classpath:/applicationContext-rest-test.xml" + +}) + +@JUnitConfigurationEnvironment +@JUnitTemporaryDatabase +public class EventConfRestServiceIT { + + @Autowired + private EventConfRestApi eventConfRestApi; + + private SecurityContext securityContext; + + @Autowired + private EventConfSourceDao eventConfSourceDao; + + @Autowired + private EventConfEventDao eventConfEventDao; + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + private EventConfPersistenceService eventConfPersistenceService; + + @Before + public void setUp() { + Principal principal = mock(Principal.class); + when(principal.getName()).thenReturn("integration-user"); + securityContext = mock(SecurityContext.class); + when(securityContext.getUserPrincipal()).thenReturn(principal); + } + @Test + @Transactional + public void testEventsConfWithoutEventConfXMLFiles() throws Exception { + String[] filenames = {"opennms.alarm.events.xml", "Cisco.airespace.xml"}; + List attachments = new ArrayList<>(); + + for (final var name : filenames) { + final var path = "/EVENTS-CONF/" + name; + final var is = getClass().getResourceAsStream(path); + assertNotNull("Resource not found: " + path, is); + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(name); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + attachments.add(att); + } + + Response resp = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + @SuppressWarnings("unchecked") Map entity = (Map) resp.getEntity(); + @SuppressWarnings("unchecked") List> success = (List>) entity.get("success"); + @SuppressWarnings("unchecked") List> errors = (List>) entity.get("errors"); + + assertEquals(filenames.length, success.size()); + assertEquals("opennms.alarm.events", success.get(0).get("file")); + assertEquals(3, success.get(0).get("eventCount")); + assertEquals("opennms", success.get(0).get("vendor")); + assertEquals("Cisco.airespace", success.get(1).get("file")); + assertEquals(101, success.get(1).get("eventCount")); + assertEquals("Cisco", success.get(1).get("vendor")); + assertTrue(errors.isEmpty()); + } + + @Test + @Transactional + public void testEmptyAttachments_ShouldReturnEmptyResults() throws Exception { + List attachments = new ArrayList<>(); + Response resp = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + + Map entity = (Map) resp.getEntity(); + List> success = (List>) entity.get("success"); + List> errors = (List>) entity.get("errors"); + + assertTrue(success.isEmpty()); + assertTrue(errors.isEmpty()); + } + + @Test + @Transactional + public void testNullSecurityContext_ShouldSetUnknownUser() throws Exception { + String filename = "Cisco.airespace.xml"; + InputStream is = getClass().getResourceAsStream("/EVENTS-CONF/" + filename); + assertNotNull(is); + + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(filename); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + + List attachments = List.of(att); + + Response resp = eventConfRestApi.uploadEventConfFiles(attachments, null); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + Map entity = (Map) resp.getEntity(); + List> success = (List>) entity.get("success"); + + assertEquals(1, success.size()); + assertEquals("Cisco", success.get(0).get("vendor")); + } + + @Test + @Transactional + public void testMalformedEventFile_ShouldAppearInErrors() throws Exception { + String filename = "test.invalid.xml"; + InputStream is = getClass().getResourceAsStream("/EVENTS-CONF/" + filename); + + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(filename); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + + List attachments = List.of(att); + + Response resp = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + Map entity = (Map) resp.getEntity(); + List> success = (List>) entity.get("success"); + List> errors = (List>) entity.get("errors"); + + assertTrue(success.isEmpty()); + assertEquals(1, errors.size()); + assertEquals("test.invalid", errors.get(0).get("file")); + assertTrue(errors.get(0).get("error").toString().contains("Exception")); + } + + @Test + @Transactional + public void testFilterEventConf_ShouldReturnFilteredResults() throws Exception { + // Step 1: Seed DB with events from known XMLs + String[] filenames = {"opennms.alarm.events.xml", "Cisco.airespace.xml"}; + List attachments = new ArrayList<>(); + + for (final var name : filenames) { + final var path = "/EVENTS-CONF/" + name; + final var is = getClass().getResourceAsStream(path); + assertNotNull("Resource not found: " + path, is); + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(name); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + attachments.add(att); + } + Response uploadResp = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), uploadResp.getStatus()); + + // Step 2: Call the filter API + Response resp = eventConfRestApi.filterEventConf(null, "Cisco", null, 0, 10, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + + List results = (List) resp.getEntity(); + + // Step 3: Assertions + assertNotNull(results); + assertFalse(results.isEmpty()); + assertTrue(results.stream() + .allMatch(e -> "Cisco".equals(e.getVendor()))); + } + + @Test + @Transactional + public void testFilterEventConf_NoFilters_ShouldReturnAllResults() { + // Call without any filters + Response resp = eventConfRestApi.filterEventConf(null, null, null,0, 10, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + } + + + @Test + @Transactional + public void testEventConfSourcesEnabledDisabled() throws Exception { + String[] filenames = {"eventconf.xml", "opennms.alarm.events.xml", "Cisco.airespace.xml"}; + List attachments = new ArrayList<>(); + + for (final var name : filenames) { + final var path = "/EVENTS-CONF/" + name; + final var is = getClass().getResourceAsStream(path); + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(name); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + attachments.add(att); + } + eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + List sourcesIds = eventConfSourceDao.findAll().stream().map(EventConfSource::getId).toList(); + // Disable eventConfSources and eventConfEvents. + EventConfSrcEnableDisablePayload eventConfSrcDisablePayload = new EventConfSrcEnableDisablePayload(false, true, sourcesIds); + eventConfRestApi.enableDisableEventConfSources(eventConfSrcDisablePayload, securityContext); + sessionFactory.getCurrentSession().flush(); + sessionFactory.getCurrentSession().clear(); + List eventConfSources = eventConfSourceDao.findAll(); + assertTrue(eventConfSources.stream().noneMatch(EventConfSource::getEnabled)); + List eventConfEvents = eventConfEventDao.findAll(); + assertTrue(eventConfEvents.stream().noneMatch(EventConfEvent::getEnabled)); + + // Enable eventConfSources and eventConfEvents. + EventConfSrcEnableDisablePayload eventConfSrcEnablePayload = new EventConfSrcEnableDisablePayload(true, true, sourcesIds); + eventConfRestApi.enableDisableEventConfSources(eventConfSrcEnablePayload, securityContext); + sessionFactory.getCurrentSession().flush(); + sessionFactory.getCurrentSession().clear(); + List enableEventConfSources = eventConfSourceDao.findAll(); + assertFalse(enableEventConfSources.stream().noneMatch(EventConfSource::getEnabled)); + List enableEventConfEvents = eventConfEventDao.findAll(); + assertFalse(enableEventConfEvents.stream().noneMatch(EventConfEvent::getEnabled)); + } + + + @Test + @Transactional + public void testEnableDisableEventConfSourcesEvents() throws Exception { + EventConfSource m_source = new EventConfSource(); + m_source.setName("testEventEnabledFlagTest"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test event source"); + m_source.setVendor("TestVendor1"); + m_source.setUploadedBy("JUnitTest"); + m_source.setEventCount(2); + m_source.setLastModified(new Date()); + + eventConfSourceDao.saveOrUpdate(m_source); + eventConfSourceDao.flush(); + + insertEvent(m_source,"uei.opennms.org/internal/trigger", "Trigger configuration changed testing", "The Trigger configuration has been changed and should be reloaded", "Normal"); + + insertEvent(m_source,"uei.opennms.org/internal/clear", "Clear discovery failed testing", "The Clear discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.", "Minor"); + + EventConfSource source = eventConfSourceDao.findByName("testEventEnabledFlagTest"); + + EventConfEvent triggerEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/trigger"); + EventConfEvent clearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + + // Disable events + EnableDisableConfSourceEventsPayload disablePayload = new EnableDisableConfSourceEventsPayload(); + disablePayload.setEventsIds(List.of(triggerEvent.getId(), clearEvent.getId())); + disablePayload.setEnable(false); + + eventConfRestApi.enableDisableEventConfSourcesEvents(source.getId(), disablePayload, securityContext); + sessionFactory.getCurrentSession().flush(); + sessionFactory.getCurrentSession().clear(); + // Verify disabled state + EventConfEvent disabledTriggerEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/trigger"); + EventConfEvent disabledClearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + + assertFalse(disabledTriggerEvent.getEnabled()); + assertFalse(disabledClearEvent.getEnabled()); + + // Enable events + EnableDisableConfSourceEventsPayload enablePayload = new EnableDisableConfSourceEventsPayload(); + enablePayload.setEventsIds(List.of(triggerEvent.getId(), clearEvent.getId())); + enablePayload.setEnable(true); + + eventConfRestApi.enableDisableEventConfSourcesEvents(source.getId(), enablePayload, securityContext); + sessionFactory.getCurrentSession().flush(); + sessionFactory.getCurrentSession().clear(); + // Verify enabled state + EventConfEvent enabledTriggerEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/trigger"); + EventConfEvent enabledClearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + + assertTrue(enabledTriggerEvent.getEnabled()); + assertTrue(enabledClearEvent.getEnabled()); + } + + @Test + public void testEnableDisableEventConfSources_InvalidPayload() throws Exception { + EventConfSrcEnableDisablePayload payload = new EventConfSrcEnableDisablePayload(null, null, Collections.emptyList()); + Response response = eventConfRestApi.enableDisableEventConfSources(payload, null); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + assertTrue(((String) response.getEntity()).contains("enabled")); + } + + @Test + @Transactional + public void testFilterEventConfEventBySourceId_ShouldReturnBADRequest() { + // Invalid Source ID + Response resp = eventConfRestApi.filterConfEventsBySourceId(-1L, "", "", "", 0, 0, 10, securityContext); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + + // Null Source ID + resp = eventConfRestApi.filterConfEventsBySourceId(null, "", "", "", 0, 0, 10, securityContext); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + + // Invalid offset (negative) + resp = eventConfRestApi.filterConfEventsBySourceId(1L, "", "", "", 0, -5, 10, securityContext); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + + // Invalid limit (zero) + resp = eventConfRestApi.filterConfEventsBySourceId(1L, "", "", "", 0, 0, 0, securityContext); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + + // Invalid limit (negative) + resp = eventConfRestApi.filterConfEventsBySourceId(1L, "", "", "", 0, 0, -1, securityContext); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + + } + + @Test + @Transactional + public void testFilterEventConfEventBySourceId_ShouldReturnNoContent() throws Exception { + // Create a source with no events + EventConfSource source = new EventConfSource(); + source.setName("emptySource"); + source.setEnabled(true); + source.setCreatedTime(new Date()); + source.setFileOrder(1); + source.setDescription("Source with no events"); + source.setVendor("TestVendor"); + source.setUploadedBy("JUnitTest"); + source.setEventCount(0); + source.setLastModified(new Date()); + eventConfSourceDao.saveOrUpdate(source); + eventConfSourceDao.flush(); + + // Valid sourceId but no matching records + Response resp = eventConfRestApi.filterConfEventsBySourceId(source.getId(), "NonExistingFilter", "", "", 0, 0, 10, securityContext); + assertEquals(Response.Status.NO_CONTENT.getStatusCode(), resp.getStatus()); + + // Source ID not found + resp = eventConfRestApi.filterConfEventsBySourceId(99999L, "", "", "", 0, 0, 10, securityContext); + assertEquals(Response.Status.NO_CONTENT.getStatusCode(), resp.getStatus()); + } + + @Test + @Transactional + public void testFilterEventConfEventBySourceId_ShouldReturnOkResponse() throws Exception { + // Step 1: Seed DB with events from known XMLs + String[] filenames = {"opennms.alarm.events.xml", "Cisco.airespace.xml"}; + List attachments = new ArrayList<>(); + + for (final var name : filenames) { + final var path = "/EVENTS-CONF/" + name; + final var is = getClass().getResourceAsStream(path); + assertNotNull("Resource not found: " + path, is); + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(name); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + attachments.add(att); + } + + Response uploadResp = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), uploadResp.getStatus()); + + List eventConfSourceList = eventConfSourceDao.findAll(); + + EventConfSource eventConfSource = eventConfSourceDao.findByName("Cisco.airespace"); + assertNotNull("Event Source not found against name Cisco.airespace ", eventConfSource); + + // Valid Source Id + Response resp = eventConfRestApi.filterConfEventsBySourceId(eventConfSource.getId(), "","","",0, 0, 10, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + } + + + @Test + @Transactional + public void testDeleteEventConfSources_Success() throws Exception { + String[] filenames = {"eventconf.xml", "opennms.alarm.events.xml", "Cisco.airespace.xml"}; + List attachments = new ArrayList<>(); + + for (final var name : filenames) { + final var path = "/EVENTS-CONF/" + name; + final var is = getClass().getResourceAsStream(path); + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(name); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + attachments.add(att); + } + eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + List sourcesIds = eventConfSourceDao.findAll().stream().map(EventConfSource::getId).toList(); + // Delete eventConfSources. + EventConfSourceDeletePayload payload = new EventConfSourceDeletePayload(); + payload.setSourceIds(sourcesIds); + + eventConfRestApi.deleteEventConfSources(payload, securityContext); + List eventConfSources = eventConfSourceDao.findAll(); + assertEquals(0, eventConfSources.size()); + + } + + @Test + public void testDeleteEventConfSources_EmptySourceIds() throws Exception { + EventConfSourceDeletePayload payload = new EventConfSourceDeletePayload(); + payload.setSourceIds(Collections.emptyList()); + + Response response = eventConfRestApi.deleteEventConfSources(payload, securityContext); + + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + assertTrue(((String) response.getEntity()).contains("At least one sourceId")); + + } + private void insertEvent(EventConfSource m_source,String uei, String label, String description, String severity) { + EventConfEvent event = new EventConfEvent(); + event.setUei(uei); + event.setEventLabel(label); + event.setDescription(description); + event.setXmlContent("" + uei + ""); + event.setSource(m_source); + event.setEnabled(true); + event.setCreatedTime(new Date()); + event.setLastModified(new Date()); + event.setModifiedBy("JUnitTest"); + + eventConfEventDao.saveOrUpdate(event); + } + @Test + @Transactional + public void testGetEventConfSourcesNames() throws Exception { + String[] filenames = {"opennms.alarm.events.xml", "Cisco.airespace.xml"}; + List attachments = new ArrayList<>(); + + for (final var name : filenames) { + final var path = "/EVENTS-CONF/" + name; + final var is = getClass().getResourceAsStream(path); + assertNotNull("Resource not found: " + path, is); + + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(name); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + + attachments.add(att); + } + + Response uploadResp = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), uploadResp.getStatus()); + + Response resp = eventConfRestApi.getEventConfSourcesNames(securityContext); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + + @SuppressWarnings("unchecked") + List sourceNames = (List) resp.getEntity(); + + assertNotNull(sourceNames); + assertFalse(sourceNames.isEmpty()); + assertTrue(sourceNames.stream().anyMatch(name -> name.contains("Cisco.airespace"))); + + // test when no sources exists in db + final var eventConfSources = eventConfSourceDao.findAll(); + eventConfSourceDao.deleteAll(eventConfSources); + Response sourceNamesResponse = eventConfRestApi.getEventConfSourcesNames(securityContext); + assertEquals(Response.Status.OK.getStatusCode(), sourceNamesResponse.getStatus()); + @SuppressWarnings("unchecked") + final var eventConfEmptySourceNames = (List) sourceNamesResponse.getEntity(); + assertNotNull(eventConfEmptySourceNames); + assertTrue("Expected empty list when no EventConfSources exist", eventConfEmptySourceNames.isEmpty()); + } + + + @Test + @Transactional + public void testAddEventConfSourceEvent_ShouldAddNewEventConfEvent() throws Exception { + String[] filenames = {"opennms.alarm.events.xml", "Cisco.airespace.xml"}; + List attachments = new ArrayList<>(); + + for (final var name : filenames) { + final var path = "/EVENTS-CONF/" + name; + final var is = getClass().getResourceAsStream(path); + assertNotNull("Resource not found: " + path, is); + Attachment att = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(name); + when(att.getContentDisposition()).thenReturn(cd); + when(att.getObject(InputStream.class)).thenReturn(is); + attachments.add(att); + } + + Response uploadResp = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + assertEquals(Response.Status.OK.getStatusCode(), uploadResp.getStatus()); + + EventConfSource eventConfSource = eventConfSourceDao.findByName("Cisco.airespace"); + assertNotNull("Event Source not found against name Cisco.airespace ", eventConfSource); + + String xmlEvent = """ + + uei.opennms.org/vendor/test/test1 + Test1: Adding new test event + Add new test event + Warning + + """; + + Event event = JaxbUtils.unmarshal(Event.class, xmlEvent); + + Response resp = eventConfRestApi.addEventConfSourceEvent(eventConfSource.getId(), event, securityContext); + assertEquals(Response.Status.CREATED.getStatusCode(), resp.getStatus()); + } + + @Test + @Transactional + public void testUpdateEventConfEvent() throws Exception { + EventConfSource m_source = new EventConfSource(); + m_source.setName("testEventEnabledFlagTest"); + m_source.setEnabled(true); + m_source.setCreatedTime(new Date()); + m_source.setFileOrder(1); + m_source.setDescription("Test event source"); + m_source.setVendor("TestVendor1"); + m_source.setUploadedBy("JUnitTest"); + m_source.setEventCount(2); + m_source.setLastModified(new Date()); + + eventConfSourceDao.saveOrUpdate(m_source); + eventConfSourceDao.flush(); + + insertEvent(m_source,"uei.opennms.org/internal/trigger", "Trigger configuration changed testing", "The Trigger configuration has been changed and should be reloaded", "Normal"); + + insertEvent(m_source,"uei.opennms.org/internal/clear", "Clear discovery failed testing", "The Clear discovery (%parm[method]%) on node %nodelabel% (IP address %interface%) has failed.", "Minor"); + + EventConfSource source = eventConfSourceDao.findByName("testEventEnabledFlagTest"); + EventConfEvent clearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + + EventConfEventEditRequest payload = new EventConfEventEditRequest(); + Event event = JaxbUtils.unmarshal(Event.class,""" + + uei.opennms.org/internal/clear + Clear label changed. + Clear Description changed. + Major + + """); + payload.setEvent(event); + payload.setEnabled(true); + + Response response = eventConfRestApi.updateEventConfEvent(source.getId(),clearEvent.getId(),payload,securityContext); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + EventConfEvent updatedClearEvent = eventConfEventDao.findByUei("uei.opennms.org/internal/clear"); + assertEquals("Clear label changed.", updatedClearEvent.getEventLabel()); + assertEquals("Clear Description changed.", updatedClearEvent.getDescription()); + + // verify xml content updated or not. + Event dbEvent = JaxbUtils.unmarshal(Event.class,updatedClearEvent.getXmlContent()); + assertEquals("Clear label changed.", dbEvent.getEventLabel()); + assertEquals("Clear Description changed.", dbEvent.getDescr()); + + } + + @Test + @Transactional + public void testUploadEventConfFiles_WithFolderPath() throws Exception { + // Test that folder paths are stripped and whitespace is trimmed + String realXmlFile = "opennms.alarm.events.xml"; + String path = "/EVENTS-CONF/" + realXmlFile; + + String filenameWithPath = "subfolder/nested/test-unix-path.events .xml"; + + InputStream is = getClass().getResourceAsStream(path); + assertNotNull("Resource not found: " + path, is); + + Attachment attachment = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(filenameWithPath); + when(attachment.getContentDisposition()).thenReturn(cd); + when(attachment.getObject(InputStream.class)).thenReturn(is); + + List attachments = List.of(attachment); + Response response = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + EventConfSource source = eventConfSourceDao.findByName("test-unix-path.events"); + assertNotNull(source); + assertEquals("test-unix-path.events", source.getName()); + } + + @Test + @Transactional + public void testUploadEventConfFiles_WithWindowsPath() throws Exception { + // Test Windows-style backslash paths + String realXmlFile = "Cisco.airespace.xml"; + String path = "/EVENTS-CONF/" + realXmlFile; + + String filenameWithPath = "folder\\subfolder\\test-windows-path.events.xml"; + + InputStream is = getClass().getResourceAsStream(path); + assertNotNull("Resource not found: " + path, is); + + Attachment attachment = mock(Attachment.class); + ContentDisposition cd = mock(ContentDisposition.class); + when(cd.getParameter("filename")).thenReturn(filenameWithPath); + when(attachment.getContentDisposition()).thenReturn(cd); + when(attachment.getObject(InputStream.class)).thenReturn(is); + + List attachments = List.of(attachment); + Response response = eventConfRestApi.uploadEventConfFiles(attachments, securityContext); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + EventConfSource source = eventConfSourceDao.findByName("test-windows-path.events"); + assertNotNull(source); + assertEquals("test-windows-path.events", source.getName()); + } +} diff --git a/opennms-webapp-rest/src/test/resources/EVENTS-CONF/Cisco.airespace.xml b/opennms-webapp-rest/src/test/resources/EVENTS-CONF/Cisco.airespace.xml new file mode 100644 index 000000000000..7ba7d3117c9b --- /dev/null +++ b/opennms-webapp-rest/src/test/resources/EVENTS-CONF/Cisco.airespace.xml @@ -0,0 +1,4877 @@ + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 1 + + + uei.opennms.org/vendor/cisco/bsnDot11StationDisassociate + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11StationDisassociate + <p>The disassociate notification shall be sent when the Station +sends a Disassociation frame. The value of the notification +shall include the MAC address of the MAC to which the +Disassociation frame was sent and the reason for the +disassociation</p><table> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationReasonCode</b></td><td> + %parm[#3]%;</td><td><p> + unspecified(1) + previousAuthNotValid(2) + deauthenticationLeaving(3) + disassociationDueToInactivity(4) + disassociationAPBusy(5) + class2FrameFromNonAuthStation(6) + class2FrameFromNonAssStation(7) + disassociationStaHasLeft(8) + staReqAssociationWithoutAuth(9) + missingReasonCode(99) + </p></td></tr> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11StationDisassociate trap received + bsnStationAPMacAddr=%parm[#1]% + bsnStationAPIfSlotId=%parm[#2]% + bsnStationReasonCode=%parm[#3]% + bsnStationMacAddress=%parm[#4]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 2 + + + uei.opennms.org/vendor/cisco/bsnDot11StationDeauthenticate + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11StationDeauthenticate + <p>The deauthenticate notification shall be sent when the Station +sends a Deauthentication frame. The value of the notification +shall include the MAC address of the MAC to which the +Deauthentication frame was sent and the reason for the +deauthentication.</p><table> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationReasonCode</b></td><td> + %parm[#3]%;</td><td><p> + unspecified(1) + previousAuthNotValid(2) + deauthenticationLeaving(3) + disassociationDueToInactivity(4) + disassociationAPBusy(5) + class2FrameFromNonAuthStation(6) + class2FrameFromNonAssStation(7) + disassociationStaHasLeft(8) + staReqAssociationWithoutAuth(9) + missingReasonCode(99) + </p></td></tr> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11StationDeauthenticate trap received + bsnStationAPMacAddr=%parm[#1]% + bsnStationAPIfSlotId=%parm[#2]% + bsnStationReasonCode=%parm[#3]% + bsnStationMacAddress=%parm[#4]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 3 + + + uei.opennms.org/vendor/cisco/bsnDot11StationAuthenticateFail + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11StationAuthenticateFail + <p>The authenticate failure notification shall be sent when the +Station sends an Authentication frame with a status code other +than 'successful'. The value of the notification shall include +the MAC address of the MAC to which the Authentication +frame was sent and the reason for the authentication failure.</p><table> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationReasonCode</b></td><td> + %parm[#3]%;</td><td><p> + unspecified(1) + previousAuthNotValid(2) + deauthenticationLeaving(3) + disassociationDueToInactivity(4) + disassociationAPBusy(5) + class2FrameFromNonAuthStation(6) + class2FrameFromNonAssStation(7) + disassociationStaHasLeft(8) + staReqAssociationWithoutAuth(9) + missingReasonCode(99) + </p></td></tr> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11StationAuthenticateFail trap received + bsnStationAPMacAddr=%parm[#1]% + bsnStationAPIfSlotId=%parm[#2]% + bsnStationReasonCode=%parm[#3]% + bsnStationMacAddress=%parm[#4]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 4 + + + uei.opennms.org/vendor/cisco/bsnDot11StationAssociateFail + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11StationAssociateFail + <p>The associate failure notification shall be sent when the +Station sends an Association frame with a status code other +than 'successful'. The value of the notification +shall include the MAC address of the MAC to which the +Authentication frame was sent and the reason for the +authentication failure.</p><table> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationReasonCode</b></td><td> + %parm[#3]%;</td><td><p> + unspecified(1) + previousAuthNotValid(2) + deauthenticationLeaving(3) + disassociationDueToInactivity(4) + disassociationAPBusy(5) + class2FrameFromNonAuthStation(6) + class2FrameFromNonAssStation(7) + disassociationStaHasLeft(8) + staReqAssociationWithoutAuth(9) + missingReasonCode(99) + </p></td></tr> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11StationAssociateFail trap received + bsnStationAPMacAddr=%parm[#1]% + bsnStationAPIfSlotId=%parm[#2]% + bsnStationReasonCode=%parm[#3]% + bsnStationMacAddress=%parm[#4]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 5 + + + uei.opennms.org/vendor/cisco/bsnAPUp + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPUp + <p>When Airespace AP operation status goes up this trap will be +sent</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnAPUp trap received + bsnAPDot3MacAddress=%parm[#1]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 6 + + + uei.opennms.org/vendor/cisco/bsnAPDown + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPDown + <p>When Airespace AP operation status goes down this trap will be +sent</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnAPDown trap received + bsnAPDot3MacAddress=%parm[#1]%</p> + + Major + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 7 + + + uei.opennms.org/vendor/cisco/bsnAPAssociated + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPAssociated + <p>When Airespace AP Associates to a Airespace Switch, AP +associated notification will be sent with dot3 MAC address of +Airespace AP.This will help management system to discover +Airespace AP and add to system.</p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPPortNumberTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPAssociated trap received + bsnAPMacAddrTrapVariable=%parm[#1]% + bsnAPPortNumberTrapVariable=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 8 + + + uei.opennms.org/vendor/cisco/bsnAPDisassociated + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPDisassociated + <p>When Airespace AP disassociates from Airespace Switch, AP +disassociated notification will be sent with dot3 MAC address +of Airespace AP management system to remove Airespace AP from +this Airespace Switch</p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnAPDisassociated trap received + bsnAPMacAddrTrapVariable=%parm[#1]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 9 + + + uei.opennms.org/vendor/cisco/bsnAPIfUp + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPIfUp + <p>When Airespace AP's interface's operation status goes up this +trap will be sent</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPPortNumber</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfUpDownCause</b></td><td> + %parm[#4]%;</td><td><p> + unknown(0) + radioFailure(1) + radioLowPower(2) + maxRetransmission(3) + echoTimeout(4) + configAP(5) + configRadio(6) + configNetwork(7) + </p></td></tr></table> + <p> + bsnAPIfUp trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPPortNumber=%parm[#3]% + bsnAPIfUpDownCause=%parm[#4]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 10 + + + uei.opennms.org/vendor/cisco/bsnAPIfDown + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPIfDown + <p>When Airespace AP's interface's operation status goes down +this trap will be sent.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPAdminStatus</b></td><td> + %parm[#3]%;</td><td><p> + enable(1) + disable(2) + </p></td></tr> + <tr><td><b> + + bsnAPIfAdminStatus</b></td><td> + %parm[#4]%;</td><td><p> + enable(1) + disable(2) + </p></td></tr> + <tr><td><b> + + bsnAPIfUpDownCause</b></td><td> + %parm[#5]%;</td><td><p> + unknown(0) + radioFailure(1) + radioLowPower(2) + maxRetransmission(3) + echoTimeout(4) + configAP(5) + configRadio(6) + configNetwork(7) + </p></td></tr></table> + <p> + bsnAPIfDown trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPAdminStatus=%parm[#3]% + bsnAPIfAdminStatus=%parm[#4]% + bsnAPIfUpDownCause=%parm[#5]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 11 + + + uei.opennms.org/vendor/cisco/bsnAPLoadProfileFailed + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPLoadProfileFailed + <p>When LOAD Profile state changes from PASS to FAIL, +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable/disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPLoadProfileFailed trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 12 + + + uei.opennms.org/vendor/cisco/bsnAPNoiseProfileFailed + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPNoiseProfileFailed + <p>When Noise Profile state changes from PASS to FAIL, +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable/disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPNoiseProfileFailed trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 13 + + + uei.opennms.org/vendor/cisco/bsnAPInterferenceProfileFailed + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPInterferenceProfileFailed + <p>When Interference Profile state changes from PASS to FAIL, +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable/disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPInterferenceProfileFailed trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 14 + + + uei.opennms.org/vendor/cisco/bsnAPCoverageProfileFailed + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPCoverageProfileFailed + <p>When Coverage Profile state changes from PASS to FAIL, +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable/disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPNameTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPSlotIdTrapVariable</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPCoverageThresholdTrapVariable</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPCoverageFailedClients</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPCoverageTotalClients</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClientMacAddr</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClientRssi</b></td><td> + %parm[#8]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClientSnr</b></td><td> + %parm[#9]%;</td><td><p></p></td></tr></table> + <p> + bsnAPCoverageProfileFailed trap received + bsnAPMacAddrTrapVariable=%parm[#1]% + bsnAPNameTrapVariable=%parm[#2]% + bsnAPSlotIdTrapVariable=%parm[#3]% + bsnAPCoverageThresholdTrapVariable=%parm[#4]% + bsnAPCoverageFailedClients=%parm[#5]% + bsnAPCoverageTotalClients=%parm[#6]% + bsnClientMacAddr=%parm[#7]% + bsnClientRssi=%parm[#8]% + bsnClientSnr=%parm[#9]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 15 + + + uei.opennms.org/vendor/cisco/bsnAPCurrentTxPowerChanged + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPCurrentTxPowerChanged + <p>Whenever dynamic algorithms are running and +bsnAPIfPhyPowerAutomaticOn is true, Airespace AP Interface's +CurrentTxPower might get updated by algorithm. When +this occurs notification will be sent with Dot3 MAC address of +Airespace AP and slot ID of Airespace AP IF along with the +currentTxPower for this Airespace AP IF</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfPhyTxPowerLevel</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr></table> + <p> + bsnAPCurrentTxPowerChanged trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfPhyTxPowerLevel=%parm[#3]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 16 + + + uei.opennms.org/vendor/cisco/bsnAPCurrentChannelChanged + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPCurrentChannelChanged + <p>Whenever dynamic algorithms are running and +bsnAPIfPhyChannelAutomaticOn is true, Airespace AP +Interface's CurrentChannel might get updated by algorithm. +When this occurs notification will be sent with Dot3 MAC +address of Airespace AP and slot ID of Airespace AP IF along +with the currentChannel for this Airespace AP IF</p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPSlotIdTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPChannelNumberTrapVariable</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnInterferenceEnergyBeforeChannelUpdate</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnInterferenceEnergyAfterChannelUpdate</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr></table> + <p> + bsnAPCurrentChannelChanged trap received + bsnAPMacAddrTrapVariable=%parm[#1]% + bsnAPSlotIdTrapVariable=%parm[#2]% + bsnAPChannelNumberTrapVariable=%parm[#3]% + bsnInterferenceEnergyBeforeChannelUpdate=%parm[#4]% + bsnInterferenceEnergyAfterChannelUpdate=%parm[#5]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 21 + + + uei.opennms.org/vendor/cisco/bsnRrmDot11aGroupingDone + AIRESPACE-WIRELESS-MIB defined trap event: bsnRrmDot11aGroupingDone + <p>When Grouping is done, this notification will be sent from the +previous Group Leader where grouping algorithm was run. It has +MAC address of the new Group Leader.</p><table> + <tr><td><b> + + bsnRrmDot11aGroupLeaderMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnRrmDot11aGroupingDone trap received + bsnRrmDot11aGroupLeaderMacAddr=%parm[#1]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 22 + + + uei.opennms.org/vendor/cisco/bsnRrmDot11bGroupingDone + AIRESPACE-WIRELESS-MIB defined trap event: bsnRrmDot11bGroupingDone + <p>When Grouping is done, this notification will be sent from the +previous Group Leader where grouping algorithm was run. It has +MAC address of the new Group Leader.</p><table> + <tr><td><b> + + bsnRrmDot11bGroupLeaderMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnRrmDot11bGroupingDone trap received + bsnRrmDot11bGroupLeaderMacAddr=%parm[#1]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 23 + + + uei.opennms.org/vendor/cisco/bsnConfigSaved + AIRESPACE-WIRELESS-MIB defined trap event: bsnConfigSaved + <p>When configuration is save either from CLI or web interface +This trap will be sent to inform NMS to do refresh</p><table></table> + <p> + bsnConfigSaved trap received</p> + + Indeterminate + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 24 + + + uei.opennms.org/vendor/cisco/bsnDot11EssCreated + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11EssCreated + <p>Whenever a new Ess (WLAN) is created, this notification will +be sent along with EssIndex</p><table> + <tr><td><b> + + bsnDot11EssIndex</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11EssCreated trap received + bsnDot11EssIndex=%parm[#1]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 25 + + + uei.opennms.org/vendor/cisco/bsnDot11EssDeleted + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11EssDeleted + <p>Whenever a Ess (WLAN)is deleted, this notification will be +sent along with EssIndex</p><table> + <tr><td><b> + + bsnDot11EssIndex</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11EssDeleted trap received + bsnDot11EssIndex=%parm[#1]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 26 + + + uei.opennms.org/vendor/cisco/bsnRADIUSServerNotResponding + AIRESPACE-WIRELESS-MIB defined trap event: bsnRADIUSServerNotResponding + <p>This trap is to indicate that no RADIUS server(s) are responding +to authentication requests sent by the RADIUS client within the +MWAR device(Switch).</p><table></table> + <p> + bsnRADIUSServerNotResponding trap received</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 27 + + + 1 + 1 + + + uei.opennms.org/vendor/cisco/bsnAuthenticationFailureMgmt + AIRESPACE-WIRELESS-MIB defined trap event: bsnAuthenticationFailure + <p>This trap is to inform that client authentication failure has +occured at MWAR(Switch). This could be cli/web user, wlan user, +or Mac Authorized user. ServiceType will indicate which type of +user it is and userName will be cli/web/wlan userName or +MacAddress of Mac Authorized User</p><table> + <tr><td><b> + + bsnAuthFailureUserType</b></td><td> + %parm[#1]%;</td><td><p> + mgmtUser(1) + wlanUser(2) + macFilter(3) + </p></td></tr> + <tr><td><b> + + bsnAuthFailureUserName</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAuthenticationFailure trap received + bsnAuthFailureUserType=%parm[#1]% + bsnAuthFailureUserName=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 27 + + + uei.opennms.org/vendor/cisco/bsnAuthenticationFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnAuthenticationFailure + <p>This trap is to inform that client authentication failure has +occured at MWAR(Switch). This could be cli/web user, wlan user, +or Mac Authorized user. ServiceType will indicate which type of +user it is and userName will be cli/web/wlan userName or +MacAddress of Mac Authorized User</p><table> + <tr><td><b> + + bsnAuthFailureUserType</b></td><td> + %parm[#1]%;</td><td><p> + mgmtUser(1) + wlanUser(2) + macFilter(3) + </p></td></tr> + <tr><td><b> + + bsnAuthFailureUserName</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAuthenticationFailure trap received + bsnAuthFailureUserType=%parm[#1]% + bsnAuthFailureUserName=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 28 + + + uei.opennms.org/vendor/cisco/bsnIpsecEspAuthFailureTrap + AIRESPACE-WIRELESS-MIB defined trap event: bsnIpsecEspAuthFailureTrap + <p>IPsec packets with invalid hashes were found in an inbound +ESP SA. The total number of authentication errors +accumulated is sent for the specific row of the +ipsecSaEspInTable table for the SA; this provides the +identity of the SA in which the error occurred. + +Implementations SHOULD send one trap per SA (within a +reasonable time period), rather than sending one trap per +packet.</p><table> + <tr><td><b> + + bsnRemoteIPv4Address</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIpsecErrorCount</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnIpsecEspAuthFailureTrap trap received + bsnRemoteIPv4Address=%parm[#1]% + bsnIpsecErrorCount=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 29 + + + uei.opennms.org/vendor/cisco/bsnIpsecEspReplayFailureTrap + AIRESPACE-WIRELESS-MIB defined trap event: bsnIpsecEspReplayFailureTrap + <p>IPsec packets with invalid sequence numbers were found in +an inbound ESP SA. The total number of replay errors +accumulated is sent for the specific row of the +ipsecSaEspInTable table for the SA; this provides the +identity of the SA in which the error occurred. + +Implementations SHOULD send one trap per SA (within a +reasonable time period), rather than sending one trap per +packet.</p><table> + <tr><td><b> + + bsnRemoteIPv4Address</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIpsecErrorCount</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnIpsecEspReplayFailureTrap trap received + bsnRemoteIPv4Address=%parm[#1]% + bsnIpsecErrorCount=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 31 + + + uei.opennms.org/vendor/cisco/bsnIpsecEspInvalidSpiTrap + AIRESPACE-WIRELESS-MIB defined trap event: bsnIpsecEspInvalidSpiTrap + <p>A packet with an unknown SPI was detected from the +specified peer with the specified SPI using the specified +protocol. The destination address of the received packet is +specified by ipsecLocalAddress. + +The value ifIndex may be 0 if this optional linkage is +unsupported. + +If the object ipsecSecurityProtocol has the value for +IPcomp, then the ipsecSPI object is the CPI of the packet. + +Implementations SHOULD send one trap per peer (within a +reasonable time period), rather than sending one trap per +packet.</p><table> + <tr><td><b> + + bsnRemoteIPv4Address</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIpsecSPI</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnIpsecEspInvalidSpiTrap trap received + bsnRemoteIPv4Address=%parm[#1]% + bsnIpsecSPI=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 33 + + + uei.opennms.org/vendor/cisco/bsnIpsecIkeNegFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnIpsecIkeNegFailure + <p>An attempt to negotiate a phase 1 IKE SA failed. +The notification counts are also sent as part of the trap, +along with the current value of the total negotiation error +counters for ISAKMP.</p><table> + <tr><td><b> + + bsnRemoteIPv4Address</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRemoteUdpPort</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIkeAuthMethod</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIkeTotalInitFailures</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIkeTotalInitNoResponses</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIkeTotalRespFailures</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnNotifiesSent</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnNotifiesReceived</b></td><td> + %parm[#8]%;</td><td><p></p></td></tr></table> + <p> + bsnIpsecIkeNegFailure trap received + bsnRemoteIPv4Address=%parm[#1]% + bsnRemoteUdpPort=%parm[#2]% + bsnIkeAuthMethod=%parm[#3]% + bsnIkeTotalInitFailures=%parm[#4]% + bsnIkeTotalInitNoResponses=%parm[#5]% + bsnIkeTotalRespFailures=%parm[#6]% + bsnNotifiesSent=%parm[#7]% + bsnNotifiesReceived=%parm[#8]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 34 + + + uei.opennms.org/vendor/cisco/bsnIpsecSuiteNegFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnIpsecSuiteNegFailure + <p>An attempt to negotiate a phase 2 SA suite for the +specified selector failed. +The current total failure counts are passed as well as the +notification type counts for the notify involved in the +failure.</p><table> + <tr><td><b> + + bsnRemoteIPv4Address</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSuiteInitFailures</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSuiteRespondFailures</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnNotifiesSent</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnNotifiesReceived</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr></table> + <p> + bsnIpsecSuiteNegFailure trap received + bsnRemoteIPv4Address=%parm[#1]% + bsnSuiteInitFailures=%parm[#2]% + bsnSuiteRespondFailures=%parm[#3]% + bsnNotifiesSent=%parm[#4]% + bsnNotifiesReceived=%parm[#5]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 35 + + + uei.opennms.org/vendor/cisco/bsnIpsecInvalidCookieTrap + AIRESPACE-WIRELESS-MIB defined trap event: bsnIpsecInvalidCookieTrap + <p>ISAKMP packets with invalid cookies were detected from the +specified source, intended for the specified destination. + +The initiator and responder cookies are also sent with the +trap. + +The current count is sent to allow the trap to accurately +relfect dropped and throttled traps. + +Implementations SHOULD send one trap per peer (within a +reasonable time period, rather than sending one trap per +packet.</p><table> + <tr><td><b> + + bsnRemoteIPv4Address</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRemoteUdpPort</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnInitiatorCookie</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnResponderCookie</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnIsakmpInvalidCookies</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr></table> + <p> + bsnIpsecInvalidCookieTrap trap received + bsnRemoteIPv4Address=%parm[#1]% + bsnRemoteUdpPort=%parm[#2]% + bsnInitiatorCookie=%parm[#3]% + bsnResponderCookie=%parm[#4]% + bsnIsakmpInvalidCookies=%parm[#5]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 36 + + + uei.opennms.org/vendor/cisco/bsnRogueAPDetected + AIRESPACE-WIRELESS-MIB defined trap event: bsnRogueAPDetected + <p>When a Rogue AP is detected this Trap will be sent out along +with APMacAddress on which its detected</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPMacAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPSlotId</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPSsid</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPChannelNumber</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPRSSI</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPSNR</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPOnWiredNetwork</b></td><td> + %parm[#8]%;</td><td><p> + no(0) + yes(1) + </p></td></tr> + <tr><td><b> + + bsnRogueAdhocMode</b></td><td> + %parm[#9]%;</td><td><p> + no(0) + yes(1) + </p></td></tr> + <tr><td><b> + + bsnRogueAPRadioType</b></td><td> + %parm[#10]%;</td><td><p> + dot11b(1) + dot11a(2) + unknown(3) + </p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPName</b></td><td> + %parm[#11]%;</td><td><p></p></td></tr></table> + <p> + bsnRogueAPDetected trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnRogueAPAirespaceAPMacAddress=%parm[#2]% + bsnRogueAPAirespaceAPSlotId=%parm[#3]% + bsnRogueAPSsid=%parm[#4]% + bsnRogueAPChannelNumber=%parm[#5]% + bsnRogueAPAirespaceAPRSSI=%parm[#6]% + bsnRogueAPAirespaceAPSNR=%parm[#7]% + bsnRogueAPOnWiredNetwork=%parm[#8]% + bsnRogueAdhocMode=%parm[#9]% + bsnRogueAPRadioType=%parm[#10]% + bsnRogueAPAirespaceAPName=%parm[#11]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 37 + + + uei.opennms.org/vendor/cisco/bsnAPLoadProfileUpdatedToPass + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPLoadProfileUpdatedToPass + <p>When LOAD Profile state changes from FAIL to PASSt this +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable/disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPLoadProfileUpdatedToPass trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 38 + + + uei.opennms.org/vendor/cisco/bsnAPNoiseProfileUpdatedToPass + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPNoiseProfileUpdatedToPass + <p>When Noise Profile state changes from FAIL tp PASS, +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable/disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPNoiseProfileUpdatedToPass trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 39 + + + uei.opennms.org/vendor/cisco/bsnAPInterferenceProfileUpdatedToPass + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPInterferenceProfileUpdatedToPass + <p>When Interference Profile state changes from FAIL tp PASS, +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable /disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPInterferenceProfileUpdatedToPass trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 40 + + + uei.opennms.org/vendor/cisco/bsnAPCoverageProfileUpdatedToPass + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPCoverageProfileUpdatedToPass + <p>When Coverage Profile state changes from FAIL tp PASS, +notification will be sent with Dot3 MAC address of Airespace +AP and slot ID of Airespace AP IF. This trap sending can be +enable/disable using bsnRrmProfileTrapControlFlag </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnAPCoverageProfileUpdatedToPass trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 41 + + + uei.opennms.org/vendor/cisco/bsnRogueAPRemoved + AIRESPACE-WIRELESS-MIB defined trap event: bsnRogueAPRemoved + <p>When a Rogue AP that was detected earlier no longer exists +this Trap will be sent out along +with APMacAddress on which its detected</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPMacAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPSlotId</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPRadioType</b></td><td> + %parm[#4]%;</td><td><p> + dot11b(1) + dot11a(2) + unknown(3) + </p></td></tr> + <tr><td><b> + + bsnRogueAPAirespaceAPName</b></td><td> + %parm[#5]%;</td><td><p></p></td></tr></table> + <p> + bsnRogueAPRemoved trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnRogueAPAirespaceAPMacAddress=%parm[#2]% + bsnRogueAPAirespaceAPSlotId=%parm[#3]% + bsnRogueAPRadioType=%parm[#4]% + bsnRogueAPAirespaceAPName=%parm[#5]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 42 + + + uei.opennms.org/vendor/cisco/bsnRadiosExceedLicenseCount + AIRESPACE-WIRELESS-MIB defined trap event: bsnRadiosExceedLicenseCount + <p>Whenever the currently associated Radios exceed the License Count +This trap will be sent to annoy the Customer</p><table> + <tr><td><b> + + bsnCurrentRadiosCount</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnLicenseRadioCount</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnRadiosExceedLicenseCount trap received + bsnCurrentRadiosCount=%parm[#1]% + bsnLicenseRadioCount=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 43 + + + uei.opennms.org/vendor/cisco/bsnSensedTemperatureOutOfRange + AIRESPACE-WIRELESS-MIB defined trap event: bsnSensedTemperatureTooHigh + <p>Temperature sensor temp too High - temp is too high on the unit. +Immediate action should be taken</p><table> + <tr><td><b> + + bsnSensorTemperature</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnSensedTemperatureTooHigh trap received + bsnSensorTemperature=%parm[#1]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 44 + + + uei.opennms.org/vendor/cisco/bsnSensedTemperatureOutOfRange + AIRESPACE-WIRELESS-MIB defined trap event: bsnSensedTemperatureTooLow + <p>Temperature sensor temp too Low - temp is too low on the unit. +Immediate action should be taken</p><table> + <tr><td><b> + + bsnSensorTemperature</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnSensedTemperatureTooLow trap received + bsnSensorTemperature=%parm[#1]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 45 + + + uei.opennms.org/vendor/cisco/bsnTemperatureSensorFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnTemperatureSensorFailure + <p>Temperature sensor hw failure - temp sensor has failed. +Temperature is unknown</p><table></table> + <p> + bsnTemperatureSensorFailure trap received</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 46 + + + uei.opennms.org/vendor/cisco/bsnTemperatureSensorClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnTemperatureSensorClear + <p>Temperature sensor clear -- temp sensor alarm condition is over. +sensor is operating within proper temp range</p><table> + <tr><td><b> + + bsnSensorTemperature</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnTemperatureSensorClear trap received + bsnSensorTemperature=%parm[#1]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 47 + + + uei.opennms.org/vendor/cisco/bsnPOEControllerFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnPOEControllerFailure + <p>POE Controller has failed. Its a very critical trap. +User intervention is required.</p><table></table> + <p> + bsnPOEControllerFailure trap received</p> + + Major + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 48 + + + uei.opennms.org/vendor/cisco/bsnMaxRogueCountExceeded + AIRESPACE-WIRELESS-MIB defined trap event: bsnMaxRogueCountExceeded + <p>The number of rogues has exceeded the maximum Rogues allowed</p><table> + <tr><td><b> + + bsnMaxRogueCount</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnMaxRogueCountExceeded trap received + bsnMaxRogueCount=%parm[#1]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 49 + + + uei.opennms.org/vendor/cisco/bsnMaxRogueCountClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnMaxRogueCountClear + <p>The number of rogues is within the maximum Rogues allowed</p><table> + <tr><td><b> + + bsnMaxRogueCount</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnMaxRogueCountClear trap received + bsnMaxRogueCount=%parm[#1]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 50 + + + uei.opennms.org/vendor/cisco/bsnApMaxRogueCountExceeded + AIRESPACE-WIRELESS-MIB defined trap event: bsnApMaxRogueCountExceeded + <p>The number of rogues has exceeded the maximum Rogues allowed on +the AP</p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnMaxRogueCount</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnApMaxRogueCountExceeded trap received + bsnAPMacAddrTrapVariable=%parm[#1]% + bsnMaxRogueCount=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 51 + + + uei.opennms.org/vendor/cisco/bsnApMaxRogueCountClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnApMaxRogueCountClear + <p>The number of rogues is within the maximum Rogues allowed on the +AP</p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnMaxRogueCount</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnApMaxRogueCountClear trap received + bsnAPMacAddrTrapVariable=%parm[#1]% + bsnMaxRogueCount=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 52 + + + uei.opennms.org/vendor/cisco/bsnDot11StationBlacklisted + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11StationBlacklisted + <p>The station blacklisted notification shall be sent when the +client is blacklisted. The reason could be repeated auth or +association failures or IP Address theft. +The value of the notification shall include the MAC address +of the MAC to which the Authentication frame was sent, the +MAC and Slot Id of AP that client was associated to and the +reason for black listing.</p><table> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationBlacklistingReasonCode</b></td><td> + %parm[#3]%;</td><td><p> + failed80211Auth(1) + failedAssociation(2) + ipTheft(3) + failed8021xAuth(4) + failedWebAuth(5) + </p></td></tr> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11StationBlacklisted trap received + bsnStationAPMacAddr=%parm[#1]% + bsnStationAPIfSlotId=%parm[#2]% + bsnStationBlacklistingReasonCode=%parm[#3]% + bsnStationMacAddress=%parm[#4]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 53 + + + uei.opennms.org/vendor/cisco/bsnDot11StationAssociate + AIRESPACE-WIRELESS-MIB defined trap event: bsnDot11StationAssociate + <p>The associate notification shall be sent when any of the +watchlisted clients(present on at least one watch list) +associates with an AP. The value of the notification +shall include the MAC address and the Slot ID of the radio +to which the station Associated.</p><table> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationUserName</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr></table> + <p> + bsnDot11StationAssociate trap received + bsnStationAPMacAddr=%parm[#1]% + bsnStationAPIfSlotId=%parm[#2]% + bsnStationMacAddress=%parm[#3]% + bsnStationUserName=%parm[#4]%</p> + + Major + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 55 + + + uei.opennms.org/vendor/cisco/bsnApBigNavDosAttack + AIRESPACE-WIRELESS-MIB defined trap event: bsnApBigNavDosAttack + <p>The AP sent a string of messages with large NAV field and all +802.11 traffic on that channel was suspended.</p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPSlotIdTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnNavDosAttackSourceMacAddr</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr></table> + <p> + bsnApBigNavDosAttack trap received + bsnAPMacAddrTrapVariable=%parm[#1]% + bsnAPSlotIdTrapVariable=%parm[#2]% + bsnNavDosAttackSourceMacAddr=%parm[#3]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 56 + + + uei.opennms.org/vendor/cisco/bsnTooManyUnsuccessLoginAttempts + AIRESPACE-WIRELESS-MIB defined trap event: bsnTooManyUnsuccessLoginAttempts + <p>The Management User made too many unsuccessful login attempts.</p><table> + <tr><td><b> + + bsnUserIpAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationUserName</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + bsnTooManyUnsuccessLoginAttempts trap received + bsnUserIpAddress=%parm[#1]% + bsnStationUserName=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 57 + + + uei.opennms.org/vendor/cisco/bsnWepKeyDecryptError + AIRESPACE-WIRELESS-MIB defined trap event: bsnWepKeyDecryptError + <p>Issued when a decrypt error occurrs. The WEP Key configured at +the station may be wrong.</p><table> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr></table> + <p> + bsnWepKeyDecryptError trap received + bsnStationMacAddress=%parm[#1]% + bsnStationAPMacAddr=%parm[#2]% + bsnStationAPIfSlotId=%parm[#3]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 58 + + + uei.opennms.org/vendor/cisco/bsnWpaMicErrorCounterActivated + AIRESPACE-WIRELESS-MIB defined trap event: bsnWpaMicErrorCounterActivated + <p>Issued when a WPA MIC error occurs and a counter measure is +activated at the AP.</p><table> + <tr><td><b> + + bsnStationMacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPMacAddr</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnStationAPIfSlotId</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnWlanIdTrapVariable</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr></table> + <p> + bsnWpaMicErrorCounterActivated trap received + bsnStationMacAddress=%parm[#1]% + bsnStationAPMacAddr=%parm[#2]% + bsnStationAPIfSlotId=%parm[#3]% + bsnWlanIdTrapVariable=%parm[#4]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 59 + + + 2 + 0 + + + uei.opennms.org/vendor/cisco/bsnRogueAPDetectedOnWiredNetworkClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnRogueAPDetectedOnWiredNetwork + <p>When a Rogue is detected on the wired network this trap will +be sent out. +The same trap with bsnRogueAPOnWiredNetwork set to no will +clear the previous trap.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPOnWiredNetwork</b></td><td> + %parm[#2]%;</td><td><p> + no(0) + yes(1) + </p></td></tr></table> + <p> + bsnRogueAPDetectedOnWiredNetwork trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnRogueAPOnWiredNetwork=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 59 + + + uei.opennms.org/vendor/cisco/bsnRogueAPDetectedOnWiredNetwork + AIRESPACE-WIRELESS-MIB defined trap event: bsnRogueAPDetectedOnWiredNetwork + <p>When a Rogue is detected on the wired network this trap will +be sent out. +The same trap with bsnRogueAPOnWiredNetwork set to no will +clear the previous trap.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPOnWiredNetwork</b></td><td> + %parm[#2]%;</td><td><p> + no(0) + yes(1) + </p></td></tr></table> + <p> + bsnRogueAPDetectedOnWiredNetwork trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnRogueAPOnWiredNetwork=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 60 + + + uei.opennms.org/vendor/cisco/bsnApHasNoRadioCards + AIRESPACE-WIRELESS-MIB defined trap event: bsnApHasNoRadioCards + <p>When an AP has no radio cards present on it, the switch +sends this trap.</p><table> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + bsnApHasNoRadioCards trap received + bsnAPMacAddrTrapVariable=%parm[#1]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 61 + + + 1 + 1 + + + 5 + 1 + + + uei.opennms.org/vendor/cisco/bsnDuplicateIpAddressReportedByAPClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnDuplicateIpAddressReported + <p>This trap is issued when the switch or an AP detects another +machine using its IP Address. The first variable has value +yes if the duplicate IP is reported by an AP. In that case, +the second attribute will carry the AP MAC Address. The third +variable is the duplicate IP address in question and the last +attribute is the MAC Address of the machine that is found to +be using the duplicate IP.</p><table> + <tr><td><b> + + bsnDuplicateIpReportedByAP</b></td><td> + %parm[#1]%;</td><td><p> + no(0) + yes(1) + </p></td></tr> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapVariable</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapClear</b></td><td> + %parm[#5]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnDuplicateIpAddressReported trap received + bsnDuplicateIpReportedByAP=%parm[#1]% + bsnAPMacAddrTrapVariable=%parm[#2]% + bsnDuplicateIpTrapVariable=%parm[#3]% + bsnRogueAPDot11MacAddress=%parm[#4]% + bsnDuplicateIpTrapClear=%parm[#5]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 61 + + + 1 + 1 + + + uei.opennms.org/vendor/cisco/bsnDuplicateIpAddressReportedByAP + AIRESPACE-WIRELESS-MIB defined trap event: bsnDuplicateIpAddressReported + <p>This trap is issued when the switch or an AP detects another +machine using its IP Address. The first variable has value +yes if the duplicate IP is reported by an AP. In that case, +the second attribute will carry the AP MAC Address. The third +variable is the duplicate IP address in question and the last +attribute is the MAC Address of the machine that is found to +be using the duplicate IP.</p><table> + <tr><td><b> + + bsnDuplicateIpReportedByAP</b></td><td> + %parm[#1]%;</td><td><p> + no(0) + yes(1) + </p></td></tr> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapVariable</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapClear</b></td><td> + %parm[#5]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnDuplicateIpAddressReported trap received + bsnDuplicateIpReportedByAP=%parm[#1]% + bsnAPMacAddrTrapVariable=%parm[#2]% + bsnDuplicateIpTrapVariable=%parm[#3]% + bsnRogueAPDot11MacAddress=%parm[#4]% + bsnDuplicateIpTrapClear=%parm[#5]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 61 + + + 5 + 1 + + + uei.opennms.org/vendor/cisco/bsnDuplicateIpAddressReportedBySwitchClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnDuplicateIpAddressReported + <p>This trap is issued when the switch or an AP detects another +machine using its IP Address. The first variable has value +yes if the duplicate IP is reported by an AP. In that case, +the second attribute will carry the AP MAC Address. The third +variable is the duplicate IP address in question and the last +attribute is the MAC Address of the machine that is found to +be using the duplicate IP.</p><table> + <tr><td><b> + + bsnDuplicateIpReportedByAP</b></td><td> + %parm[#1]%;</td><td><p> + no(0) + yes(1) + </p></td></tr> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapVariable</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapClear</b></td><td> + %parm[#5]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnDuplicateIpAddressReported trap received + bsnDuplicateIpReportedByAP=%parm[#1]% + bsnAPMacAddrTrapVariable=%parm[#2]% + bsnDuplicateIpTrapVariable=%parm[#3]% + bsnRogueAPDot11MacAddress=%parm[#4]% + bsnDuplicateIpTrapClear=%parm[#5]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 61 + + + uei.opennms.org/vendor/cisco/bsnDuplicateIpAddressReportedBySwitch + AIRESPACE-WIRELESS-MIB defined trap event: bsnDuplicateIpAddressReported + <p>This trap is issued when the switch or an AP detects another +machine using its IP Address. The first variable has value +yes if the duplicate IP is reported by an AP. In that case, +the second attribute will carry the AP MAC Address. The third +variable is the duplicate IP address in question and the last +attribute is the MAC Address of the machine that is found to +be using the duplicate IP.</p><table> + <tr><td><b> + + bsnDuplicateIpReportedByAP</b></td><td> + %parm[#1]%;</td><td><p> + no(0) + yes(1) + </p></td></tr> + <tr><td><b> + + bsnAPMacAddrTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapVariable</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#4]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnDuplicateIpTrapClear</b></td><td> + %parm[#5]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnDuplicateIpAddressReported trap received + bsnDuplicateIpReportedByAP=%parm[#1]% + bsnAPMacAddrTrapVariable=%parm[#2]% + bsnDuplicateIpTrapVariable=%parm[#3]% + bsnRogueAPDot11MacAddress=%parm[#4]% + bsnDuplicateIpTrapClear=%parm[#5]%</p> + + Major + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 62 + + + 4 + 1 + + + uei.opennms.org/vendor/cisco/bsnAPContainedAsARogueClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPContainedAsARogue + <p>When our AP detects that it is being contained by another AP, +this trap is issued. The clear flag is true if the AP is no +longer being contained.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnAPContainedAsARogue trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfType=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 62 + + + uei.opennms.org/vendor/cisco/bsnAPContainedAsARogue + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPContainedAsARogue + <p>When our AP detects that it is being contained by another AP, +this trap is issued. The clear flag is true if the AP is no +longer being contained.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnAPContainedAsARogue trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfType=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Major + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 63 + + + 2 + 1 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidSsidClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidSsid + <p>Issued when a Trusted Rogue AP is auto contained for advertising +invalid SSID. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidSsid trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 63 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidSsid + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidSsid + <p>Issued when a Trusted Rogue AP is auto contained for advertising +invalid SSID. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidSsid trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 64 + + + 2 + 1 + + + uei.opennms.org/vendor/cisco/bsnTrustedApIsMissingClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApIsMissing + <p>Issued when a Trusted Rogue AP is missing or has failed. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApIsMissing trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 64 + + + uei.opennms.org/vendor/cisco/bsnTrustedApIsMissing + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApIsMissing + <p>Issued when a Trusted Rogue AP is missing or has failed. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApIsMissing trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 65 + + + 2 + 1 + + + uei.opennms.org/vendor/cisco/bsnAdhocRogueAutoContainedClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnAdhocRogueAutoContained + <p>Issued when an Adhoc Rogue is auto contained. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnAdhocRogueAutoContained trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 65 + + + uei.opennms.org/vendor/cisco/bsnAdhocRogueAutoContained + AIRESPACE-WIRELESS-MIB defined trap event: bsnAdhocRogueAutoContained + <p>Issued when an Adhoc Rogue is auto contained. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnAdhocRogueAutoContained trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 66 + + + 2 + 1 + + + uei.opennms.org/vendor/cisco/bsnRogueApAutoContainedClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnRogueApAutoContained + <p>Issued when a Rogue AP is auto contained for advertising our SSID. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnRogueApAutoContained trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 66 + + + uei.opennms.org/vendor/cisco/bsnRogueApAutoContained + AIRESPACE-WIRELESS-MIB defined trap event: bsnRogueApAutoContained + <p>Issued when a Rogue AP is auto contained for advertising our SSID. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#2]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnRogueApAutoContained trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnClearTrapVariable=%parm[#2]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 67 + + + 4 + 1 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidEncryptionClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidEncryption + <p>Issued when a Trusted Rogue AP is auto contained for using +invalid encryption. The second param is for the encryption used +and the third param is for encryption required. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnTrustedApEncryptionUsed</b></td><td> + %parm[#2]%;</td><td><p> + none(0) + open(1) + wep(2) + wpa(3) + </p></td></tr> + <tr><td><b> + + bsnTrustedApEncryptionRequired</b></td><td> + %parm[#3]%;</td><td><p> + none(0) + open(1) + wep(2) + wpa(3) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidEncryption trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnTrustedApEncryptionUsed=%parm[#2]% + bsnTrustedApEncryptionRequired=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 67 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidEncryption + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidEncryption + <p>Issued when a Trusted Rogue AP is auto contained for using +invalid encryption. The second param is for the encryption used +and the third param is for encryption required. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnTrustedApEncryptionUsed</b></td><td> + %parm[#2]%;</td><td><p> + none(0) + open(1) + wep(2) + wpa(3) + </p></td></tr> + <tr><td><b> + + bsnTrustedApEncryptionRequired</b></td><td> + %parm[#3]%;</td><td><p> + none(0) + open(1) + wep(2) + wpa(3) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidEncryption trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnTrustedApEncryptionUsed=%parm[#2]% + bsnTrustedApEncryptionRequired=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 68 + + + 4 + 1 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidRadioPolicyClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidRadioPolicy + <p>Issued when a Trusted Rogue AP is auto contained for using +invalid radio policy. The second param is for the radio policy +used and the third param is for radio policy required. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnTrustedApRadioPolicyUsed</b></td><td> + %parm[#2]%;</td><td><p> + none(0) + dot11b(1) + dot11a(2) + dot11bg(3) + </p></td></tr> + <tr><td><b> + + bsnTrustedApRadioPolicyRequired</b></td><td> + %parm[#3]%;</td><td><p> + none(0) + dot11b(1) + dot11a(2) + dot11bg(3) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidRadioPolicy trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnTrustedApRadioPolicyUsed=%parm[#2]% + bsnTrustedApRadioPolicyRequired=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 68 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidRadioPolicy + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidRadioPolicy + <p>Issued when a Trusted Rogue AP is auto contained for using +invalid radio policy. The second param is for the radio policy +used and the third param is for radio policy required. +If the clear variable has value true, then the trap clears the +earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnTrustedApRadioPolicyUsed</b></td><td> + %parm[#2]%;</td><td><p> + none(0) + dot11b(1) + dot11a(2) + dot11bg(3) + </p></td></tr> + <tr><td><b> + + bsnTrustedApRadioPolicyRequired</b></td><td> + %parm[#3]%;</td><td><p> + none(0) + dot11b(1) + dot11a(2) + dot11bg(3) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidRadioPolicy trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnTrustedApRadioPolicyUsed=%parm[#2]% + bsnTrustedApRadioPolicyRequired=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 69 + + + 2 + 1 + + + uei.opennms.org/vendor/cisco/bsnNetworkStateChangedEnable + AIRESPACE-WIRELESS-MIB defined trap event: bsnNetworkStateChanged + <p>When the 802.11a or b/g network state is changed this trap +is issued.</p><table> + <tr><td><b> + + bsnNetworkType</b></td><td> + %parm[#1]%;</td><td><p> + dot11b(1) + dot11a(2) + </p></td></tr> + <tr><td><b> + + bsnNetworkState</b></td><td> + %parm[#2]%;</td><td><p> + disable(0) + enable(1) + </p></td></tr></table> + <p> + bsnNetworkStateChanged trap received + bsnNetworkType=%parm[#1]% + bsnNetworkState=%parm[#2]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 69 + + + uei.opennms.org/vendor/cisco/bsnNetworkStateChangedDisable + AIRESPACE-WIRELESS-MIB defined trap event: bsnNetworkStateChanged + <p>When the 802.11a or b/g network state is changed this trap +is issued.</p><table> + <tr><td><b> + + bsnNetworkType</b></td><td> + %parm[#1]%;</td><td><p> + dot11b(1) + dot11a(2) + </p></td></tr> + <tr><td><b> + + bsnNetworkState</b></td><td> + %parm[#2]%;</td><td><p> + disable(0) + enable(1) + </p></td></tr></table> + <p> + bsnNetworkStateChanged trap received + bsnNetworkType=%parm[#1]% + bsnNetworkState=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 70 + + + 8 + 1 + + + uei.opennms.org/vendor/cisco/bsnSignatureAttackDetectedClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnSignatureAttackDetected + <p>This trap is sent out when a signature attack is detected by +the switch. The standard and custom signatures are predefined +on the switch (see bsnSignatureConfig group). The signatures +also defines if its detection should be reported. The trap +variables bsnSignatureName and bsnSignatureDescription are +retrieved from the detected signature definition. Clear Trap +Variable is turned on when the signature attack stops. The +signature's quiet time configuration speicifes the time after +which the clear trap would be sent. bsnSignatureMacInfo +indicates whether the signature is used to track +pattern matches for all source MAC addresses together or +seperately for individual source MAC addresses. +bsnSignatureAttackFrequency will carry the value for a +specific MAC address or for all MAC addresses depending on +bsnSignatureMacInfo. </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPName</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#4]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr> + <tr><td><b> + + bsnSignatureType</b></td><td> + %parm[#5]%;</td><td><p> + standard(0) + custom(1) + </p></td></tr> + <tr><td><b> + + bsnSignatureName</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureDescription</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#8]%;</td><td><p> + false(0) + true(1) + </p></td></tr> + <tr><td><b> + + bsnSignatureAttackPreced</b></td><td> + %parm[#9]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureAttackFrequency</b></td><td> + %parm[#10]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureAttackChannel</b></td><td> + %parm[#11]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureAttackerMacAddress</b></td><td> + %parm[#12]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureMacInfo</b></td><td> + %parm[#13]%;</td><td><p> + bsnSignatureMacAll(0) + bsnSignatureMacIndividual(1) + bsnSignatureMacBoth(2) + </p></td></tr></table> + <p> + bsnSignatureAttackDetected trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPName=%parm[#3]% + bsnAPIfType=%parm[#4]% + bsnSignatureType=%parm[#5]% + bsnSignatureName=%parm[#6]% + bsnSignatureDescription=%parm[#7]% + bsnClearTrapVariable=%parm[#8]% + bsnSignatureAttackPreced=%parm[#9]% + bsnSignatureAttackFrequency=%parm[#10]% + bsnSignatureAttackChannel=%parm[#11]% + bsnSignatureAttackerMacAddress=%parm[#12]% + bsnSignatureMacInfo=%parm[#13]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 70 + + + uei.opennms.org/vendor/cisco/bsnSignatureAttackDetected + AIRESPACE-WIRELESS-MIB defined trap event: bsnSignatureAttackDetected + <p>This trap is sent out when a signature attack is detected by +the switch. The standard and custom signatures are predefined +on the switch (see bsnSignatureConfig group). The signatures +also defines if its detection should be reported. The trap +variables bsnSignatureName and bsnSignatureDescription are +retrieved from the detected signature definition. Clear Trap +Variable is turned on when the signature attack stops. The +signature's quiet time configuration speicifes the time after +which the clear trap would be sent. bsnSignatureMacInfo +indicates whether the signature is used to track +pattern matches for all source MAC addresses together or +seperately for individual source MAC addresses. +bsnSignatureAttackFrequency will carry the value for a +specific MAC address or for all MAC addresses depending on +bsnSignatureMacInfo. </p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPName</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#4]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr> + <tr><td><b> + + bsnSignatureType</b></td><td> + %parm[#5]%;</td><td><p> + standard(0) + custom(1) + </p></td></tr> + <tr><td><b> + + bsnSignatureName</b></td><td> + %parm[#6]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureDescription</b></td><td> + %parm[#7]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#8]%;</td><td><p> + false(0) + true(1) + </p></td></tr> + <tr><td><b> + + bsnSignatureAttackPreced</b></td><td> + %parm[#9]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureAttackFrequency</b></td><td> + %parm[#10]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureAttackChannel</b></td><td> + %parm[#11]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureAttackerMacAddress</b></td><td> + %parm[#12]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnSignatureMacInfo</b></td><td> + %parm[#13]%;</td><td><p> + bsnSignatureMacAll(0) + bsnSignatureMacIndividual(1) + bsnSignatureMacBoth(2) + </p></td></tr></table> + <p> + bsnSignatureAttackDetected trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPName=%parm[#3]% + bsnAPIfType=%parm[#4]% + bsnSignatureType=%parm[#5]% + bsnSignatureName=%parm[#6]% + bsnSignatureDescription=%parm[#7]% + bsnClearTrapVariable=%parm[#8]% + bsnSignatureAttackPreced=%parm[#9]% + bsnSignatureAttackFrequency=%parm[#10]% + bsnSignatureAttackChannel=%parm[#11]% + bsnSignatureAttackerMacAddress=%parm[#12]% + bsnSignatureMacInfo=%parm[#13]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 71 + + + uei.opennms.org/vendor/cisco/bsnAPRadioCardTxFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPRadioCardTxFailure + <p>This trap is sent by the switch when a radio card on an AP +stops transmitting.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr></table> + <p> + bsnAPRadioCardTxFailure trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfType=%parm[#3]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 72 + + + uei.opennms.org/vendor/cisco/bsnAPRadioCardTxFailureClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPRadioCardTxFailureClear + <p>This trap is sent by the switch when a radio card on an AP +starts transmitting again after a prior failure.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr></table> + <p> + bsnAPRadioCardTxFailureClear trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfType=%parm[#3]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 73 + + + uei.opennms.org/vendor/cisco/bsnAPRadioCardRxFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPRadioCardRxFailure + <p>This trap is sent by the switch when a radio card on an AP +stops receiving.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr></table> + <p> + bsnAPRadioCardRxFailure trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfType=%parm[#3]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 74 + + + uei.opennms.org/vendor/cisco/bsnAPRadioCardRxFailureClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPRadioCardRxFailureClear + <p>This trap is sent by the switch when a radio card on an AP +starts receiving again after a prior failure.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr></table> + <p> + bsnAPRadioCardRxFailureClear trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfType=%parm[#3]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 75 + + + uei.opennms.org/vendor/cisco/bsnAPImpersonationDetected + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPImpersonationDetected + <p>This trap is sent by the switch when a radio of an +authenticated AP hears from another AP whose MAC Address +neither matches that of a rogue's and nor is it an +authenticated neighbor of the detecting AP.</p><table> + <tr><td><b> + + bsnImpersonatedAPMacAddr</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfType</b></td><td> + %parm[#4]%;</td><td><p> + dot11b(1) + dot11a(2) + uwb(4) + </p></td></tr></table> + <p> + bsnAPImpersonationDetected trap received + bsnImpersonatedAPMacAddr=%parm[#1]% + bsnAPDot3MacAddress=%parm[#2]% + bsnAPIfSlotId=%parm[#3]% + bsnAPIfType=%parm[#4]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 76 + + + 4 + 1 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidPreambleClear + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidPreamble + <p>Issued when a Trusted Rogue AP is auto contained for using invalid +preamble. The second param is for the preamble used and the third +param is for preamble required. If the clear variable has value +true, then the trap clears the earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnTrustedApPreambleUsed</b></td><td> + %parm[#2]%;</td><td><p> + none(0) + short(1) + long(2) + </p></td></tr> + <tr><td><b> + + bsnTrustedApPreambleRequired</b></td><td> + %parm[#3]%;</td><td><p> + none(0) + short(1) + long(2) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidPreamble trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnTrustedApPreambleUsed=%parm[#2]% + bsnTrustedApPreambleRequired=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 76 + + + uei.opennms.org/vendor/cisco/bsnTrustedApHasInvalidPreamble + AIRESPACE-WIRELESS-MIB defined trap event: bsnTrustedApHasInvalidPreamble + <p>Issued when a Trusted Rogue AP is auto contained for using invalid +preamble. The second param is for the preamble used and the third +param is for preamble required. If the clear variable has value +true, then the trap clears the earlier alert.</p><table> + <tr><td><b> + + bsnRogueAPDot11MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnTrustedApPreambleUsed</b></td><td> + %parm[#2]%;</td><td><p> + none(0) + short(1) + long(2) + </p></td></tr> + <tr><td><b> + + bsnTrustedApPreambleRequired</b></td><td> + %parm[#3]%;</td><td><p> + none(0) + short(1) + long(2) + </p></td></tr> + <tr><td><b> + + bsnClearTrapVariable</b></td><td> + %parm[#4]%;</td><td><p> + false(0) + true(1) + </p></td></tr></table> + <p> + bsnTrustedApHasInvalidPreamble trap received + bsnRogueAPDot11MacAddress=%parm[#1]% + bsnTrustedApPreambleUsed=%parm[#2]% + bsnTrustedApPreambleRequired=%parm[#3]% + bsnClearTrapVariable=%parm[#4]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 77 + + + uei.opennms.org/vendor/cisco/bsnAPIPAddressFallback + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPIPAddressFallback + <p>This trap is sent out when an AP, with the configured static +ip-address, fails to establish connection with outside world +and starts using DHCP as a fallback option.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnApIpAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPStaticIPAddress</b></td><td> + %parm[#3]%;</td><td><p></p></td></tr></table> + <p> + bsnAPIPAddressFallback trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnApIpAddress=%parm[#2]% + bsnAPStaticIPAddress=%parm[#3]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 78 + + + uei.opennms.org/vendor/cisco/bsnAPFunctionalityDisabled + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPFunctionalityDisabled + <p>This trap is sent out when AP functionality on the switch is +disabled because the License key has expired +or has been deleted or doesn't match the switch image.</p><table> + <tr><td><b> + + bsnApFunctionalityDisableReasonCode</b></td><td> + %parm[#1]%;</td><td><p> + unknown(0) + licenseKeyExpired(1) + licenseKeyDeleted(2) + licenseKeyFeatureMismatch(3) + </p></td></tr> + <tr><td><b> + + bsnLicenseKeyTrapVariable</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnLicenseKeyFeatureSetTrapVariable</b></td><td> + %parm[#3]%;</td><td><p> + wps(1) + all(2) + </p></td></tr></table> + <p> + bsnAPFunctionalityDisabled trap received + bsnApFunctionalityDisableReasonCode=%parm[#1]% + bsnLicenseKeyTrapVariable=%parm[#2]% + bsnLicenseKeyFeatureSetTrapVariable=%parm[#3]%</p> + + Major + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 79 + + + uei.opennms.org/vendor/cisco/bsnAPRegulatoryDomainMismatch + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPRegulatoryDomainMismatch + <p>This trap is generated if an AP's regulatory domain doesn't +match the country the switch is configured for. Due to the +mismatch, the AP will fail to associate with the Switch.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPName</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnApRegulatoryDomain</b></td><td> + %parm[#3]%;</td><td><p> + a(0) + e(1) + i(6) + j(9) + c(16) + n(21) + k(32) + p(33) + s(34) + t(35) + r(48) + notavailable(65535) + </p></td></tr> + <tr><td><b> + + bsnGlobalDot11CountryIndex</b></td><td> + %parm[#4]%;</td><td><p> + usa(1) + canada(2) + france(3) + japan(4) + mexico(5) + spain(6) + usalegacy(7) + korearepublic(8) + australia(9) + austria(10) + belgium(11) + denmark(12) + finland(13) + germany(14) + greece(15) + ireland(16) + italy(17) + luxembourg(18) + netherlands(19) + portugal(20) + sweden(21) + unitedkingdom(22) + none(23) + india(24) + hongkong(25) + switzerland(26) + iceland(27) + norway(28) + singapore(29) + thailand(30) + taiwan(31) + cyprus(33) + czechrepublic(34) + estonia(35) + hungary(36) + lithuania(37) + latvia(38) + malaysia(39) + newzealand(40) + poland(41) + slovenia(42) + slovakrepublic(43) + southafrica(44) + usachan165(45) + israel(46) + israelOutdoor(47) + argentina(48) + brazil(49) + saudiArabia(51) + turkey(52) + indonesia(53) + china(54) + koreaExtended(55) + japan2(56) + gibraltar(57) + liechtenstein(58) + malta(59) + monaco(60) + romania(61) + russianfederation(62) + chile(63) + colombia(64) + panama(65) + peru(66) + venezuela(67) + philippines(68) + </p></td></tr></table> + <p> + bsnAPRegulatoryDomainMismatch trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPName=%parm[#2]% + bsnApRegulatoryDomain=%parm[#3]% + bsnGlobalDot11CountryIndex=%parm[#4]%</p> + + Major + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 80 + + + uei.opennms.org/vendor/cisco/bsnRxMulticastQueueFull + AIRESPACE-WIRELESS-MIB defined trap event: bsnRxMulticastQueueFull + <p>This trap indicates that the CPU's Receive Multicast Queue is +Full.</p><table></table> + <p> + bsnRxMulticastQueueFull trap received</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 81 + + + uei.opennms.org/vendor/cisco/bsnRadarChannelDetected + AIRESPACE-WIRELESS-MIB defined trap event: bsnRadarChannelDetected + <p>This trap is sent when radar signals are detected on the +current channel</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfPhyChannelNumber</b></td><td> + %parm[#3]%;</td><td><p> + ch1(1) + ch2(2) + ch3(3) + ch4(4) + ch5(5) + ch6(6) + ch7(7) + ch8(8) + ch9(9) + ch10(10) + ch11(11) + ch12(12) + ch13(13) + ch14(14) + ch34(34) + ch36(36) + ch38(38) + ch40(40) + ch42(42) + ch44(44) + ch46(46) + ch48(48) + ch52(52) + ch56(56) + ch60(60) + ch64(64) + ch100(100) + ch104(104) + ch108(108) + ch112(112) + ch116(116) + ch120(120) + ch124(124) + ch128(128) + ch132(132) + ch136(136) + ch140(140) + ch149(149) + ch153(153) + ch157(157) + ch161(161) + ch165(165) + ch169(169) + </p></td></tr></table> + <p> + bsnRadarChannelDetected trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfPhyChannelNumber=%parm[#3]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 82 + + + uei.opennms.org/vendor/cisco/bsnRadarChannelCleared + AIRESPACE-WIRELESS-MIB defined trap event: bsnRadarChannelCleared + <p>This trap will be generated, if a radar trap has been +generated earlier, after the expiry of Non-Occupancy Period.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfPhyChannelNumber</b></td><td> + %parm[#3]%;</td><td><p> + ch1(1) + ch2(2) + ch3(3) + ch4(4) + ch5(5) + ch6(6) + ch7(7) + ch8(8) + ch9(9) + ch10(10) + ch11(11) + ch12(12) + ch13(13) + ch14(14) + ch34(34) + ch36(36) + ch38(38) + ch40(40) + ch42(42) + ch44(44) + ch46(46) + ch48(48) + ch52(52) + ch56(56) + ch60(60) + ch64(64) + ch100(100) + ch104(104) + ch108(108) + ch112(112) + ch116(116) + ch120(120) + ch124(124) + ch128(128) + ch132(132) + ch136(136) + ch140(140) + ch149(149) + ch153(153) + ch157(157) + ch161(161) + ch165(165) + ch169(169) + </p></td></tr></table> + <p> + bsnRadarChannelCleared trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPIfPhyChannelNumber=%parm[#3]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 83 + + + uei.opennms.org/vendor/cisco/bsnAPAuthorizationFailure + AIRESPACE-WIRELESS-MIB defined trap event: bsnAPAuthorizationFailure + <p>This trap is sent out in case of authorization failure while +attempting to associate the AP to the controller. +bsnAPDot3MacAddress represents the mac-address of that AP. +bsnAPName is name of AP</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPName</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPAuthCertificateType</b></td><td> + %parm[#3]%;</td><td><p> + unknown(0) + mic(1) + ssc(2) + </p></td></tr> + <tr><td><b> + + bsnAPAuthorizationFailureCause</b></td><td> + %parm[#4]%;</td><td><p> + unknown(0) + keymismatch(1) + entrydoesnotexist(2) + invalidCertifcate(3) + entryIsMIC(4) + </p></td></tr></table> + <p> + bsnAPAuthorizationFailure trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPName=%parm[#2]% + bsnAPAuthCertificateType=%parm[#3]% + bsnAPAuthorizationFailureCause=%parm[#4]%</p> + + Indeterminate + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 84 + + + uei.opennms.org/vendor/cisco/radioCoreDumpTrap + AIRESPACE-WIRELESS-MIB defined trap event: radioCoreDumpTrap + <p>When radio module in AP dumps core, it informs controller and +controller generates this trap. The core file can be retrieved +on demand.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + radioCoreDumpTrap trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 85 + + + uei.opennms.org/vendor/cisco/invalidRadioTrap + AIRESPACE-WIRELESS-MIB defined trap event: invalidRadioTrap + <p>This trap will be generated when an AP has joined is using +unsupported radio or a radio slot not currently not being +used.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPIfSlotId</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPInvalidRadioType</b></td><td> + %parm[#3]%;</td><td><p> + unsupportedRadio(0) + </p></td></tr></table> + <p> + invalidRadioTrap trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPIfSlotId=%parm[#2]% + bsnAPInvalidRadioType=%parm[#3]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 86 + + + uei.opennms.org/vendor/cisco/countryChangeTrap + AIRESPACE-WIRELESS-MIB defined trap event: countryChangeTrap + <p>This trap will be generated when an operator changes the +country of operation. New country code will be sent in trap.</p><table> + <tr><td><b> + + bsnGlobalDot11CountryIndex</b></td><td> + %parm[#1]%;</td><td><p> + usa(1) + canada(2) + france(3) + japan(4) + mexico(5) + spain(6) + usalegacy(7) + korearepublic(8) + australia(9) + austria(10) + belgium(11) + denmark(12) + finland(13) + germany(14) + greece(15) + ireland(16) + italy(17) + luxembourg(18) + netherlands(19) + portugal(20) + sweden(21) + unitedkingdom(22) + none(23) + india(24) + hongkong(25) + switzerland(26) + iceland(27) + norway(28) + singapore(29) + thailand(30) + taiwan(31) + cyprus(33) + czechrepublic(34) + estonia(35) + hungary(36) + lithuania(37) + latvia(38) + malaysia(39) + newzealand(40) + poland(41) + slovenia(42) + slovakrepublic(43) + southafrica(44) + usachan165(45) + israel(46) + israelOutdoor(47) + argentina(48) + brazil(49) + saudiArabia(51) + turkey(52) + indonesia(53) + china(54) + koreaExtended(55) + japan2(56) + gibraltar(57) + liechtenstein(58) + malta(59) + monaco(60) + romania(61) + russianfederation(62) + chile(63) + colombia(64) + panama(65) + peru(66) + venezuela(67) + philippines(68) + </p></td></tr></table> + <p> + countryChangeTrap trap received + bsnGlobalDot11CountryIndex=%parm[#1]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 87 + + + uei.opennms.org/vendor/cisco/unsupportedAPTrap + AIRESPACE-WIRELESS-MIB defined trap event: unsupportedAPTrap + <p>This trap will be generated when unsupported AP try to join +40xx/410x or 3500 with 64MB flash.</p><table> + <tr><td><b> + + bsnAPDot3MacAddress</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr> + <tr><td><b> + + bsnAPName</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr></table> + <p> + unsupportedAPTrap trap received + bsnAPDot3MacAddress=%parm[#1]% + bsnAPName=%parm[#2]%</p> + + Minor + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 88 + + + uei.opennms.org/vendor/cisco/heartbeatLossTrap + AIRESPACE-WIRELESS-MIB defined trap event: heartbeatLossTrap + <p>This trap will be generated when controller loses +connection with the Supervisor Switch in which it +is physically embedded and doesn't hear the +heartbeat keepalives from the Supervisor. </p><table></table> + <p> + heartbeatLossTrap trap received</p> + + Warning + + + + + + id + .1.3.6.1.4.1.14179.2.6.3 + + + generic + 6 + + + specific + 89 + + + uei.opennms.org/vendor/cisco/locationNotifyTrap + AIRESPACE-WIRELESS-MIB defined trap event: locationNotifyTrap + <p>This trap will be generated by the location server +for notifications of location events.</p><table> + <tr><td><b> + + locationNotifyContent</b></td><td> + %parm[#1]%;</td><td><p></p></td></tr></table> + <p> + locationNotifyTrap trap received + locationNotifyContent=%parm[#1]%</p> + + Normal + + + + + + id + .1.3.6.1.4.1.9.9.599 + + + generic + 6 + + + specific + 1 + + + 1 + 2 + + + uei.opennms.org/vendor/cisco/traps/ciscoLwappDot11ClientKeyDecryptErrorWEP + CISCO-LWAPP-DOT11-CLIENT-MIB defined trap event: ciscoLwappDot11ClientKeyDecryptError + <p>Issued when a decrypt error occurs. The WEP WPA or WPA2 Key +configured at the station may be wrong.</p><table> + <tr><td><b> + + cldcAssociationMode</b></td><td> + %parm[#1]%;</td><td><p> + unknown(1) + wep(2) + wpa(3) + wpa2(4) + </p></td></tr> + <tr><td><b> + + cldcApMacAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + cldcIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11bg(1) + dot11a(2) + uwb(3) + </p></td></tr></table> + <p> + ciscoLwappDot11ClientKeyDecryptError trap received + cldcAssociationMode=%parm[#1]% + cldcApMacAddress=%parm[#2]% + cldcIfType=%parm[#3]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.9.9.599 + + + generic + 6 + + + specific + 1 + + + 1 + 3 + + + uei.opennms.org/vendor/cisco/traps/ciscoLwappDot11ClientKeyDecryptErrorWPA + CISCO-LWAPP-DOT11-CLIENT-MIB defined trap event: ciscoLwappDot11ClientKeyDecryptError + <p>Issued when a decrypt error occurs. The WEP WPA or WPA2 Key +configured at the station may be wrong.</p><table> + <tr><td><b> + + cldcAssociationMode</b></td><td> + %parm[#1]%;</td><td><p> + unknown(1) + wep(2) + wpa(3) + wpa2(4) + </p></td></tr> + <tr><td><b> + + cldcApMacAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + cldcIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11bg(1) + dot11a(2) + uwb(3) + </p></td></tr></table> + <p> + ciscoLwappDot11ClientKeyDecryptError trap received + cldcAssociationMode=%parm[#1]% + cldcApMacAddress=%parm[#2]% + cldcIfType=%parm[#3]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.9.9.599 + + + generic + 6 + + + specific + 1 + + + 1 + 4 + + + uei.opennms.org/vendor/cisco/traps/ciscoLwappDot11ClientKeyDecryptErrorWPA2 + CISCO-LWAPP-DOT11-CLIENT-MIB defined trap event: ciscoLwappDot11ClientKeyDecryptError + <p>Issued when a decrypt error occurs. The WEP WPA or WPA2 Key +configured at the station may be wrong.</p><table> + <tr><td><b> + + cldcAssociationMode</b></td><td> + %parm[#1]%;</td><td><p> + unknown(1) + wep(2) + wpa(3) + wpa2(4) + </p></td></tr> + <tr><td><b> + + cldcApMacAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + cldcIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11bg(1) + dot11a(2) + uwb(3) + </p></td></tr></table> + <p> + ciscoLwappDot11ClientKeyDecryptError trap received + cldcAssociationMode=%parm[#1]% + cldcApMacAddress=%parm[#2]% + cldcIfType=%parm[#3]%</p> + + Warning + + + + + + id + .1.3.6.1.4.1.9.9.599 + + + generic + 6 + + + specific + 1 + + + uei.opennms.org/vendor/cisco/traps/ciscoLwappDot11ClientKeyDecryptErrorUnknown + CISCO-LWAPP-DOT11-CLIENT-MIB defined trap event: ciscoLwappDot11ClientKeyDecryptError + <p>Issued when a decrypt error occurs. The WEP WPA or WPA2 Key +configured at the station may be wrong.</p><table> + <tr><td><b> + + cldcAssociationMode</b></td><td> + %parm[#1]%;</td><td><p> + unknown(1) + wep(2) + wpa(3) + wpa2(4) + </p></td></tr> + <tr><td><b> + + cldcApMacAddress</b></td><td> + %parm[#2]%;</td><td><p></p></td></tr> + <tr><td><b> + + cldcIfType</b></td><td> + %parm[#3]%;</td><td><p> + dot11bg(1) + dot11a(2) + uwb(3) + </p></td></tr></table> + <p> + ciscoLwappDot11ClientKeyDecryptError trap received + cldcAssociationMode=%parm[#1]% + cldcApMacAddress=%parm[#2]% + cldcIfType=%parm[#3]%</p> + + Indeterminate + + + \ No newline at end of file diff --git a/opennms-webapp-rest/src/test/resources/EVENTS-CONF/eventconf.xml b/opennms-webapp-rest/src/test/resources/EVENTS-CONF/eventconf.xml new file mode 100644 index 000000000000..fe01c94664ff --- /dev/null +++ b/opennms-webapp-rest/src/test/resources/EVENTS-CONF/eventconf.xml @@ -0,0 +1,15 @@ + + + + logmsg + operaction + autoaction + tticket + script + + + + + events/opennms.alarm.events.xml + events/Cisco.airespace.xml + diff --git a/opennms-base-assembly/src/main/filtered/etc/events/opennms.alarm.events.xml b/opennms-webapp-rest/src/test/resources/EVENTS-CONF/opennms.alarm.events.xml similarity index 100% rename from opennms-base-assembly/src/main/filtered/etc/events/opennms.alarm.events.xml rename to opennms-webapp-rest/src/test/resources/EVENTS-CONF/opennms.alarm.events.xml diff --git a/opennms-webapp-rest/src/test/resources/EVENTS-CONF/test.invalid.xml b/opennms-webapp-rest/src/test/resources/EVENTS-CONF/test.invalid.xml new file mode 100644 index 000000000000..b3bc8e4b55cc --- /dev/null +++ b/opennms-webapp-rest/src/test/resources/EVENTS-CONF/test.invalid.xml @@ -0,0 +1,4 @@ + + + + diff --git a/opennms-webapp-rest/src/test/resources/applicationContext-rest-test.xml b/opennms-webapp-rest/src/test/resources/applicationContext-rest-test.xml index 1bac829e28dd..fefa36f61f93 100644 --- a/opennms-webapp-rest/src/test/resources/applicationContext-rest-test.xml +++ b/opennms-webapp-rest/src/test/resources/applicationContext-rest-test.xml @@ -9,6 +9,9 @@ + + + diff --git a/opennms-webapp/src/main/java/org/opennms/web/controller/admin/thresholds/ThresholdController.java b/opennms-webapp/src/main/java/org/opennms/web/controller/admin/thresholds/ThresholdController.java index 7d0ddc654fdf..397fecb91b69 100644 --- a/opennms-webapp/src/main/java/org/opennms/web/controller/admin/thresholds/ThresholdController.java +++ b/opennms-webapp/src/main/java/org/opennms/web/controller/admin/thresholds/ThresholdController.java @@ -53,6 +53,7 @@ import org.opennms.netmgt.xml.eventconf.LogDestType; import org.opennms.netmgt.xml.eventconf.Logmsg; import org.opennms.web.api.Util; +import org.opennms.web.services.EventConfProgrammaticService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; @@ -88,7 +89,7 @@ public class ThresholdController extends AbstractController implements Initializ private EventConfDao m_eventConfDao; - private boolean eventConfChanged = false; + private EventConfProgrammaticService eventConfProgrammaticService; @Autowired private WriteableThresholdingDao thresholdingDao; @@ -519,17 +520,6 @@ private void saveChanges() throws ServletException { } catch (Throwable e) { throw new ServletException("Could not save the changes to the threshold because " + e.getMessage(), e); } - - if (eventConfChanged) { - try { - m_eventConfDao.saveCurrent(); - sendNotifEvent(createEventBuilder(EventConstants.EVENTSCONFIG_CHANGED_EVENT_UEI).getEvent()); - } catch (Throwable e) { - throw new ServletException("Could not save the changes to the event configuration because " + e.getMessage(), e); - } - eventConfChanged = false; - } - } private ModelAndView deleteThreshold(String thresholdIndexString, String groupName) throws ServletException { @@ -708,8 +698,9 @@ private void ensureUEIInEventConf(org.opennms.netmgt.xml.eventconf.Event source, event.setAlarmData(alarmData); } } - m_eventConfDao.addEventToProgrammaticStore(event); - eventConfChanged = true; + // Save the event to DB + eventConfProgrammaticService.saveEventToDB(event, "Web UI"); + eventConfProgrammaticService.reloadEventsFromDB(); } } @@ -870,4 +861,13 @@ public void setEventConfDao(EventConfDao eventConfDao) { m_eventConfDao = eventConfDao; } + /** + *

setEventConfProgrammaticService

+ * + * @param eventConfProgrammaticService a {@link EventConfProgrammaticService} object. + */ + public void setEventConfProgrammaticService(EventConfProgrammaticService eventConfProgrammaticService) { + this.eventConfProgrammaticService = eventConfProgrammaticService; + } + } diff --git a/opennms-webapp/src/main/java/org/opennms/web/services/EventConfProgrammaticService.java b/opennms-webapp/src/main/java/org/opennms/web/services/EventConfProgrammaticService.java new file mode 100644 index 000000000000..186e495b958a --- /dev/null +++ b/opennms-webapp/src/main/java/org/opennms/web/services/EventConfProgrammaticService.java @@ -0,0 +1,173 @@ +/* + * Licensed to The OpenNMS Group, Inc (TOG) under one or more + * contributor license agreements. See the LICENSE.md file + * distributed with this work for additional information + * regarding copyright ownership. + * + * TOG licenses this file to You under the GNU Affero General + * Public License Version 3 (the "License") or (at your option) + * any later version. You may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at: + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.opennms.web.services; + +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import org.opennms.core.xml.JaxbUtils; +import org.opennms.netmgt.config.api.EventConfDao; +import org.opennms.netmgt.dao.api.EventConfEventDao; +import org.opennms.netmgt.dao.api.EventConfSourceDao; +import org.opennms.netmgt.model.EventConfEvent; +import org.opennms.netmgt.model.EventConfSource; +import org.opennms.netmgt.xml.eventconf.Event; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service for managing programmatically generated events (e.g., from ThresholdController). + * This service persists events to the database under the "opennms.programmatic.events" source + * and reloads them into memory via EventConfDao. + */ +public class EventConfProgrammaticService { + + private static final Logger LOG = LoggerFactory.getLogger(EventConfProgrammaticService.class); + + private static final String PROGRAMMATIC_SOURCE_NAME = "opennms.programmatic.events"; + private static final String VENDOR = "opennms"; + + private EventConfSourceDao eventConfSourceDao; + private EventConfEventDao eventConfEventDao; + private EventConfDao eventConfDao; + + private final ThreadFactory eventConfThreadFactory = new ThreadFactoryBuilder() + .setNameFormat("load-eventConf-programmatic-%d") + .build(); + + private final ExecutorService eventConfExecutor = Executors.newSingleThreadExecutor(eventConfThreadFactory); + + /** + * Saves an event to the programmatic events source in the database. + * Creates the source if it doesn't exist. + * + * @param event The event to save + * @param username The username of the user creating the event + */ + @Transactional + public void saveEventToDB(Event event, String username) { + EventConfSource source = getOrCreateProgrammaticSource(); + saveEvent(source, event, username, new Date()); + + // Update event count + source.setEventCount(source.getEventCount() + 1); + eventConfSourceDao.save(source); + } + + /** + * Gets or creates the programmatic events source. + * + * @return The EventConfSource for programmatic events + */ + private EventConfSource getOrCreateProgrammaticSource() { + EventConfSource source = eventConfSourceDao.findByName(PROGRAMMATIC_SOURCE_NAME); + if (source == null) { + LOG.info("Creating new programmatic event source: {}", PROGRAMMATIC_SOURCE_NAME); + source = new EventConfSource(); + source.setName(PROGRAMMATIC_SOURCE_NAME); + source.setVendor(VENDOR); + source.setDescription("Programmatically generated events (e.g., from thresholds)"); + source.setEnabled(true); + source.setEventCount(0); + source.setUploadedBy("system"); + Date now = new Date(); + source.setCreatedTime(now); + source.setLastModified(now); + + // Get max file order and add 1 to ensure programmatic events are loaded last + Integer maxFileOrder = eventConfSourceDao.findMaxFileOrder(); + source.setFileOrder(maxFileOrder != null ? maxFileOrder + 1 : 1); + + eventConfSourceDao.saveOrUpdate(source); + } + return source; + } + + /** + * Saves a single event to the database. + * + * @param source The EventConfSource to associate with this event + * @param event The event to save + * @param username The username of the user creating the event + * @param now The current timestamp + */ + private void saveEvent(EventConfSource source, Event event, String username, Date now) { + EventConfEvent eventConfEvent = new EventConfEvent(); + eventConfEvent.setSource(source); + eventConfEvent.setUei(event.getUei()); + eventConfEvent.setEventLabel(event.getEventLabel()); + eventConfEvent.setDescription(event.getDescr()); + eventConfEvent.setEnabled(true); + eventConfEvent.setXmlContent(JaxbUtils.marshal(event)); + eventConfEvent.setCreatedTime(now); + eventConfEvent.setLastModified(now); + eventConfEvent.setModifiedBy(username); + eventConfEventDao.save(eventConfEvent); + } + + /** + * Reloads all enabled events from the database into memory. + */ + public void reloadEventsFromDB() { + eventConfExecutor.execute(() -> { + List dbEvents = eventConfEventDao.findEnabledEvents(); + LOG.info("Reloading {} events from database into memory", dbEvents.size()); + eventConfDao.loadEventsFromDB(dbEvents); + }); + } + + /** + * Sets the EventConfSourceDao. + * + * @param eventConfSourceDao The DAO for EventConfSource + */ + public void setEventConfSourceDao(EventConfSourceDao eventConfSourceDao) { + this.eventConfSourceDao = eventConfSourceDao; + } + + /** + * Sets the EventConfEventDao. + * + * @param eventConfEventDao The DAO for EventConfEvent + */ + public void setEventConfEventDao(EventConfEventDao eventConfEventDao) { + this.eventConfEventDao = eventConfEventDao; + } + + /** + * Sets the EventConfDao. + * + * @param eventConfDao The DAO for EventConf + */ + public void setEventConfDao(EventConfDao eventConfDao) { + this.eventConfDao = eventConfDao; + } + + public void shutdown() { + eventConfExecutor.shutdown(); + } +} diff --git a/opennms-webapp/src/main/webapp/WEB-INF/dispatcher-servlet.xml b/opennms-webapp/src/main/webapp/WEB-INF/dispatcher-servlet.xml index d745216cd662..3e4ee283ecc6 100644 --- a/opennms-webapp/src/main/webapp/WEB-INF/dispatcher-servlet.xml +++ b/opennms-webapp/src/main/webapp/WEB-INF/dispatcher-servlet.xml @@ -265,9 +265,16 @@
+ + + + + + + diff --git a/smoke-test/src/test/java/org/opennms/smoketest/IntegrationAPIIT.java b/smoke-test/src/test/java/org/opennms/smoketest/IntegrationAPIIT.java index e0f01f889d9b..27f0849215d2 100644 --- a/smoke-test/src/test/java/org/opennms/smoketest/IntegrationAPIIT.java +++ b/smoke-test/src/test/java/org/opennms/smoketest/IntegrationAPIIT.java @@ -29,6 +29,7 @@ import java.net.InetSocketAddress; import org.junit.ClassRule; +import org.junit.Ignore; import org.junit.Test; import org.opennms.smoketest.stacks.OpenNMSStack; import org.opennms.smoketest.utils.CommandTestUtils; @@ -37,6 +38,7 @@ import org.slf4j.LoggerFactory; @org.junit.experimental.categories.Category(org.opennms.smoketest.junit.MinionTests.class) +@Ignore ("see https://opennms.atlassian.net/browse/MPLUG-78") public class IntegrationAPIIT { private static final Logger LOG = LoggerFactory.getLogger(IntegrationAPIIT.class); diff --git a/smoke-test/src/test/java/org/opennms/smoketest/MenuHeaderIT.java b/smoke-test/src/test/java/org/opennms/smoketest/MenuHeaderIT.java index edf8c2936f76..f8da5c335c6a 100644 --- a/smoke-test/src/test/java/org/opennms/smoketest/MenuHeaderIT.java +++ b/smoke-test/src/test/java/org/opennms/smoketest/MenuHeaderIT.java @@ -212,7 +212,7 @@ public void testMenuEntries() throws Exception { wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='card-header']/span[text()='Notification queries']"))); clickMenuItem("administrationMenu", "Customize Events"); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//ol[@class='breadcrumb']/li[contains(text()[normalize-space()], 'Manage Events Configuration')]"))); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='app']//div[@class='event-config']//div[@class='heading']//h1[text()='Event Configuration']"))); clickMenuItem("administrationMenu", "Customize Data Collection Groups"); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//ol[@class='breadcrumb']/li[contains(text()[normalize-space()], 'Manage SNMP Collections and Data Collection Groups')]"))); diff --git a/ui/package.json b/ui/package.json index 16e77f5d5f96..acc609576409 100644 --- a/ui/package.json +++ b/ui/package.json @@ -15,6 +15,9 @@ "watch:dev": "vue-tsc --noEmit && vite build --base=/opennms/ui/ --minify false --watch", "serve": "vite preview", "test": "vitest run", + "test:watch": "vitest watch", + "test:coverage": "vitest --coverage", + "test:coverage:sonar": "vitest run --coverage", "lint": "eslint --ignore-path ../.gitignore --ext .ts,.vue .", "lint:fix": "eslint --ignore-path ../.gitignore --ext .ts,.vue . --fix", "format": "prettier --ignore-path ../.gitignore --write \"**/*.+(ts)\"" @@ -24,6 +27,7 @@ "@featherds/app-layout": "^0.12.42", "@featherds/app-rail": "^0.12.42", "@featherds/autocomplete": "^0.12.42", + "@featherds/back-button": "^0.12.42", "@featherds/button": "^0.12.42", "@featherds/checkbox": "0.12.42", "@featherds/chips": "0.12.42", @@ -53,6 +57,7 @@ "@featherds/tabs": "0.12.42", "@featherds/textarea": "0.12.42", "@featherds/tooltip": "0.12.42", + "@featherds/toggle-button": "^0.12.42", "@featherds/utils": "0.12.42", "@vueuse/core": "^9.13.0", "ace-builds": "^1.32.6", @@ -63,6 +68,7 @@ "d3": "^7.8.5", "date-fns": "^2.30.0", "date-fns-tz": "^2.0.1", + "fast-xml-parser": "^5.3.0", "dotenv": "^17.2.3", "ip-regex": "^5.0.0", "is-ip": "^5.0.1", @@ -78,6 +84,7 @@ "splitpanes": "^3.1.5", "uuid": "^10.0.0", "vite-svg-loader": "^4.0.0", + "vkbeautify": "^0.99.3", "vue": "^3.5.14", "vue-diff": "^1.2.4", "vue-router": "^4.2.4", @@ -95,6 +102,7 @@ "@types/node": ">=20", "@types/splitpanes": "^2.2.1", "@types/uuid": "^10.0.0", + "@types/vkbeautify": "^0.99.4", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-vue": "^5.2.4", diff --git a/ui/src/components/Common/TableCard.vue b/ui/src/components/Common/TableCard.vue new file mode 100644 index 000000000000..47f32593cb05 --- /dev/null +++ b/ui/src/components/Common/TableCard.vue @@ -0,0 +1,17 @@ + + + diff --git a/ui/src/components/EventConfigEventCreate/AlarmDataInfo.vue b/ui/src/components/EventConfigEventCreate/AlarmDataInfo.vue new file mode 100644 index 000000000000..58c25c1d5736 --- /dev/null +++ b/ui/src/components/EventConfigEventCreate/AlarmDataInfo.vue @@ -0,0 +1,117 @@ + + + + + + diff --git a/ui/src/components/EventConfigEventCreate/BasicInformation.vue b/ui/src/components/EventConfigEventCreate/BasicInformation.vue new file mode 100644 index 000000000000..9a63735f5363 --- /dev/null +++ b/ui/src/components/EventConfigEventCreate/BasicInformation.vue @@ -0,0 +1,578 @@ + + + + + + diff --git a/ui/src/components/EventConfigEventCreate/MaskElements.vue b/ui/src/components/EventConfigEventCreate/MaskElements.vue new file mode 100644 index 000000000000..af803f772a7f --- /dev/null +++ b/ui/src/components/EventConfigEventCreate/MaskElements.vue @@ -0,0 +1,150 @@ + + + + + + diff --git a/ui/src/components/EventConfigEventCreate/MaskVarbinds.vue b/ui/src/components/EventConfigEventCreate/MaskVarbinds.vue new file mode 100644 index 000000000000..a60aeb9d73a7 --- /dev/null +++ b/ui/src/components/EventConfigEventCreate/MaskVarbinds.vue @@ -0,0 +1,144 @@ + + + + + + diff --git a/ui/src/components/EventConfigEventCreate/VarbindsDecode.vue b/ui/src/components/EventConfigEventCreate/VarbindsDecode.vue new file mode 100644 index 000000000000..e4a5b9affc05 --- /dev/null +++ b/ui/src/components/EventConfigEventCreate/VarbindsDecode.vue @@ -0,0 +1,210 @@ + + + + + + diff --git a/ui/src/components/EventConfigEventCreate/constants.ts b/ui/src/components/EventConfigEventCreate/constants.ts new file mode 100644 index 000000000000..1417e2e1c637 --- /dev/null +++ b/ui/src/components/EventConfigEventCreate/constants.ts @@ -0,0 +1,87 @@ +import { ISelectItemType } from '@featherds/select' + +export const MAX_MASK_ELEMENTS = 12 + +export const statusOptions: ISelectItemType[] = [ + { _text: 'Enable', _value: 'enable' }, + { _text: 'Disable', _value: 'disable' } +] + +export enum Severity { + Critical = 'Critical', + Major = 'Major', + Minor = 'Minor', + Warning = 'Warning', + Normal = 'Normal', + Indeterminate = 'Indeterminate', + Cleared = 'Cleared' +} + +export const SeverityOptions: ISelectItemType[] = [ + { _text: Severity.Critical, _value: Severity.Critical }, + { _text: Severity.Major, _value: Severity.Major }, + { _text: Severity.Minor, _value: Severity.Minor }, + { _text: Severity.Warning, _value: Severity.Warning }, + { _text: Severity.Normal, _value: Severity.Normal }, + { _text: Severity.Indeterminate, _value: Severity.Indeterminate }, + { _text: Severity.Cleared, _value: Severity.Cleared } +] + +export enum Destination { + LogAndDisplay = 'logndisplay', + LogOnly = 'logonly', + Suppress = 'suppress', + DoNotPersist = 'donotpersist', + DiscardTraps = 'discardtraps' +} + +export const DestinationOptions: ISelectItemType[] = [ + { _text: Destination.LogAndDisplay, _value: Destination.LogAndDisplay }, + { _text: Destination.LogOnly, _value: Destination.LogOnly }, + { _text: Destination.Suppress, _value: Destination.Suppress }, + { _text: Destination.DoNotPersist, _value: Destination.DoNotPersist }, + { _text: Destination.DiscardTraps, _value: Destination.DiscardTraps } +] + +export enum MaskElementName { + Uei = 'uei', + Source = 'source', + NodeId = 'nodeid', + Host = 'host', + Interface = 'interface', + SnmpHost = 'snmphost', + Service = 'service', + Id = 'id', + Specific = 'specific', + Generic = 'generic', + Community = 'community', + Trapoid = 'trapoid' +} + +export const MaskElementNameOptions: ISelectItemType[] = [ + { _text: MaskElementName.Uei, _value: MaskElementName.Uei }, + { _text: MaskElementName.Source, _value: MaskElementName.Source }, + { _text: MaskElementName.NodeId, _value: MaskElementName.NodeId }, + { _text: MaskElementName.Host, _value: MaskElementName.Host }, + { _text: MaskElementName.Interface, _value: MaskElementName.Interface }, + { _text: MaskElementName.SnmpHost, _value: MaskElementName.SnmpHost }, + { _text: MaskElementName.Service, _value: MaskElementName.Service }, + { _text: MaskElementName.Id, _value: MaskElementName.Id }, + { _text: MaskElementName.Specific, _value: MaskElementName.Specific }, + { _text: MaskElementName.Generic, _value: MaskElementName.Generic }, + { _text: MaskElementName.Community, _value: MaskElementName.Community }, + { _text: MaskElementName.Trapoid, _value: MaskElementName.Trapoid } +] + +export enum AlarmType { + One = '1', + Two = '2', + Three = '3' +} + +export const AlarmTypeOptions: ISelectItemType[] = [ + { _text: AlarmType.One, _value: AlarmType.One }, + { _text: AlarmType.Two, _value: AlarmType.Two }, + { _text: AlarmType.Three, _value: AlarmType.Three } +] + diff --git a/ui/src/components/EventConfigEventCreate/eventValidator.ts b/ui/src/components/EventConfigEventCreate/eventValidator.ts new file mode 100644 index 000000000000..37b95421b818 --- /dev/null +++ b/ui/src/components/EventConfigEventCreate/eventValidator.ts @@ -0,0 +1,142 @@ +import { EventFormErrors } from '@/types/eventConfig' + +export const validateEvent = ( + uei: string, + eventLabel: string, + description: string, + severity: string, + dest: string, + logmsg: string, + addAlarmData: boolean, + reductionKey: string, + alarmType: string, + autoClean: boolean, + clearKey: string, + maskElements: Array<{ name?: { _text?: string; _value?: string }; value?: string }>, + varbinds: Array<{ index: string; value: string }>, + varbindsDecode: Array<{ parmId: string; decode: Array<{ key: string; value: string }> }> +): EventFormErrors => { + const errors: EventFormErrors = {} + + if (!uei || uei.trim() === '') { + errors.uei = 'UEI is required.' + } + + if (!eventLabel || eventLabel.trim() === '') { + errors.eventLabel = 'Event Label is required.' + } + + if (!description || description.trim() === '') { + errors.description = 'Description is required.' + } + + if (!logmsg || logmsg.trim() === '') { + errors.logmsg = 'Log Message is required.' + } + + if (!dest || dest.trim() === '') { + errors.dest = 'Destination is required.' + } + + if (!severity || severity.trim() === '') { + errors.severity = 'Severity is required.' + } + + if (addAlarmData) { + if (!reductionKey || reductionKey.trim() === '') { + errors.reductionKey = 'Reduction Key is required when Alarm Data is added.' + } + + if (!alarmType || alarmType.trim() === '') { + errors.alarmType = 'Alarm Type is required when Alarm Data is added.' + } + + if (autoClean) { + if (!clearKey || clearKey.trim() === '') { + errors.clearKey = 'Clear Key is required when Auto Clean is enabled.' + } + } + } + + const maskElementErrors: Array<{ name?: string; value?: string }> = [] + const namesSet = new Set() + maskElements.forEach((element, index) => { + const elementErrors: { name?: string; value?: string } = {} + if (!element.name?._value || element.name?._value.trim() === '') { + elementErrors.name = 'Mask Element Name is required.' + } else if (namesSet.has(element.name._value)) { + elementErrors.name = 'Mask Element Name must be unique.' + } else { + namesSet.add(element.name._value) + } + + if (!element.value || element.value.trim() === '') { + elementErrors.value = 'Mask Element Value is required.' + } + + maskElementErrors[index] = elementErrors + }) + + if (maskElementErrors.some(err => Object.keys(err).length > 0)) { + errors.maskElements = maskElementErrors + } + + if (varbinds && varbinds.length > 0) { + const varbindErrors: Array<{ index?: string; value?: string }> = [] + varbinds.forEach((varbind, index) => { + const varbindError: { index?: string; value?: string } = {} + if (!varbind.index || varbind.index.trim() === '') { + varbindError.index = 'Index is required.' + } + + if (!varbind.value || varbind.value.trim() === '') { + varbindError.value = 'Value is required.' + } + + varbindErrors[index] = varbindError + }) + + if (varbindErrors.some(err => Object.keys(err).length > 0)) { + errors.varbinds = varbindErrors + } + } + + if (varbindsDecode && varbindsDecode.length > 0) { + const varbindDecodeErrors: Array<{ parmId?: string; decode?: Array<{ key?: string; value?: string }> }> = [] + varbindsDecode.forEach((varbindDecode, index) => { + const varbindDecodeError: { parmId?: string; decode?: Array<{ key?: string; value?: string }> } = {} + if (!varbindDecode.parmId || varbindDecode.parmId.trim() === '') { + varbindDecodeError.parmId = 'Parameter ID is required.' + } + + if (varbindDecode.decode && varbindDecode.decode.length > 0) { + const decodeErrors: Array<{ key?: string; value?: string }> = [] + varbindDecode.decode.forEach((decode, decodeIndex) => { + const decodeError: { key?: string; value?: string } = {} + if (!decode.key || decode.key.trim() === '') { + decodeError.key = 'Key is required.' + } + + if (!decode.value || decode.value.trim() === '') { + decodeError.value = 'Value is required.' + } + + decodeErrors[decodeIndex] = decodeError + }) + + if (decodeErrors.some(err => Object.keys(err).length > 0)) { + varbindDecodeError.decode = decodeErrors + } + } + + varbindDecodeErrors[index] = varbindDecodeError + }) + + if (varbindDecodeErrors.some(err => Object.keys(err).length > 0)) { + errors.varbindsDecode = varbindDecodeErrors + } + } + + return errors +} + diff --git a/ui/src/components/EventConfiguration/Dialog/ChangeEventConfigSourceStatusDialog.vue b/ui/src/components/EventConfiguration/Dialog/ChangeEventConfigSourceStatusDialog.vue new file mode 100644 index 000000000000..8a5c94faff63 --- /dev/null +++ b/ui/src/components/EventConfiguration/Dialog/ChangeEventConfigSourceStatusDialog.vue @@ -0,0 +1,67 @@ + + + + + + diff --git a/ui/src/components/EventConfiguration/Dialog/DeleteEventConfigSourceDialog.vue b/ui/src/components/EventConfiguration/Dialog/DeleteEventConfigSourceDialog.vue new file mode 100644 index 000000000000..6f929ade7178 --- /dev/null +++ b/ui/src/components/EventConfiguration/Dialog/DeleteEventConfigSourceDialog.vue @@ -0,0 +1,69 @@ + + + + + + diff --git a/ui/src/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.vue b/ui/src/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.vue new file mode 100644 index 000000000000..7bb5b1b9b142 --- /dev/null +++ b/ui/src/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.vue @@ -0,0 +1,109 @@ + + + + + + diff --git a/ui/src/components/EventConfiguration/Dialog/UploadedFileRenameDialog.vue b/ui/src/components/EventConfiguration/Dialog/UploadedFileRenameDialog.vue new file mode 100644 index 000000000000..0c66749e922f --- /dev/null +++ b/ui/src/components/EventConfiguration/Dialog/UploadedFileRenameDialog.vue @@ -0,0 +1,177 @@ + + + + + + diff --git a/ui/src/components/EventConfiguration/EventConfigSourceTable.vue b/ui/src/components/EventConfiguration/EventConfigSourceTable.vue new file mode 100644 index 000000000000..2049fcb6f5ea --- /dev/null +++ b/ui/src/components/EventConfiguration/EventConfigSourceTable.vue @@ -0,0 +1,309 @@ + + + + + + diff --git a/ui/src/components/EventConfiguration/EventConfigTabContainer.vue b/ui/src/components/EventConfiguration/EventConfigTabContainer.vue new file mode 100644 index 000000000000..d4500457bf7a --- /dev/null +++ b/ui/src/components/EventConfiguration/EventConfigTabContainer.vue @@ -0,0 +1,31 @@ + + + + + + diff --git a/ui/src/components/EventConfiguration/EventConfigUploadFilesTab.vue b/ui/src/components/EventConfiguration/EventConfigUploadFilesTab.vue new file mode 100644 index 000000000000..350e262a3b25 --- /dev/null +++ b/ui/src/components/EventConfiguration/EventConfigUploadFilesTab.vue @@ -0,0 +1,545 @@ + + + + + + diff --git a/ui/src/components/EventConfiguration/eventConfigXmlValidator.ts b/ui/src/components/EventConfiguration/eventConfigXmlValidator.ts new file mode 100644 index 000000000000..e524b61b3518 --- /dev/null +++ b/ui/src/components/EventConfiguration/eventConfigXmlValidator.ts @@ -0,0 +1,102 @@ +import { UploadEventFileType } from '@/types/eventConfig' +import { XMLValidator } from 'fast-xml-parser' + +export const MAX_FILES_UPLOAD = 10 + +export const validateEventConfigFile = async (file: File) => { + const validationErrors: string[] = [] + + try { + const text = await file.text() + + if (text.trim().length === 0) { + validationErrors.push('File is empty') + return { isValid: false, errors: validationErrors } + } + + if (!file.name.endsWith('.events.xml') && !file.name.includes('event')) { + validationErrors.push('File does not appear to be an event configuration file (expected .events.xml extension)') + return { isValid: false, errors: validationErrors } + } + + if (validationErrors.length === 0) { + const parser = new DOMParser() + const xmlDoc = parser.parseFromString(text, 'application/xml') + const result = XMLValidator.validate(text) + if (xmlDoc.querySelector('parsererror')) { + validationErrors.push('Invalid XML format - file contains syntax errors') + return { isValid: false, errors: validationErrors } + } + if (!result) { + validationErrors.push('Invalid XML format - file contains syntax errors') + return { isValid: false, errors: validationErrors } + } + + const eventsElement = xmlDoc.querySelector('events') + if (!eventsElement) { + validationErrors.push('Missing root element') + return { isValid: false, errors: validationErrors } + } + const xmlns = eventsElement.getAttribute('xmlns') || '' + if (xmlns !== 'http://xmlns.opennms.org/xsd/eventconf') { + validationErrors.push('Missing or invalid OpenNMS namespace in element') + return { isValid: false, errors: validationErrors } + } + + const eventElements = eventsElement.querySelectorAll('event') + const childElements = eventsElement.children + if (childElements.length && eventElements.length === 0) { + const childNames = Array.from(childElements) + .map((el) => `<${el.tagName.toLowerCase()}>`) + .join(', ') + validationErrors.push(` element contains ${childNames} but no elements`) + return { isValid: false, errors: validationErrors } + } else if (eventElements.length === 0) { + validationErrors.push('No entries found within element') + return { isValid: false, errors: validationErrors } + } else { + for (const [idx, event] of Array.from(eventElements).entries()) { + const eventErrors = validateEventElement(event, idx + 1) + if (eventErrors) { + validationErrors.push(eventErrors) + return { isValid: false, errors: validationErrors } + } + } + } + } + } catch (error) { + validationErrors.push(`Error reading file content: ${error instanceof Error ? error.message : 'Unknown error'}`) + return { isValid: false, errors: validationErrors } + } + return { + isValid: validationErrors.length === 0, + errors: validationErrors + } +} + +export const validateEventElement = (event: Element, eventNumber: number): string => { + const uei = event.querySelector('uei')?.textContent?.trim() + const label = event.querySelector('event-label')?.textContent?.trim() + const severity = event.querySelector('severity')?.textContent?.trim() + const description = event.querySelector('descr')?.textContent?.trim() + + if (!uei) { + return `Event ${eventNumber}: missing ` + } + if (!label) { + return `Event ${eventNumber}: missing ` + } + if (!severity) { + return `Event ${eventNumber}: missing ` + } + if (!description) { + return `Event ${eventNumber}: missing ` + } + + return '' +} + +export const isDuplicateFile = (fileName: string, existingFiles: UploadEventFileType[]): boolean => { + return !!existingFiles?.some((element) => element.file.name.toLowerCase() === fileName.toLowerCase()) +} + diff --git a/ui/src/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.vue b/ui/src/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.vue new file mode 100644 index 000000000000..e0572cb73331 --- /dev/null +++ b/ui/src/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.vue @@ -0,0 +1,68 @@ + + + + + + diff --git a/ui/src/components/EventConfigurationDetail/Dialog/ChangeEventConfigSourceStatusDialog.vue b/ui/src/components/EventConfigurationDetail/Dialog/ChangeEventConfigSourceStatusDialog.vue new file mode 100644 index 000000000000..a4ac2f23af1d --- /dev/null +++ b/ui/src/components/EventConfigurationDetail/Dialog/ChangeEventConfigSourceStatusDialog.vue @@ -0,0 +1,72 @@ + + + + + + diff --git a/ui/src/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.vue b/ui/src/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.vue new file mode 100644 index 000000000000..b2eb3a125cbd --- /dev/null +++ b/ui/src/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.vue @@ -0,0 +1,73 @@ + + + + + + diff --git a/ui/src/components/EventConfigurationDetail/Dialog/DeleteEventConfigSourceDialog.vue b/ui/src/components/EventConfigurationDetail/Dialog/DeleteEventConfigSourceDialog.vue new file mode 100644 index 000000000000..e008f08bb28b --- /dev/null +++ b/ui/src/components/EventConfigurationDetail/Dialog/DeleteEventConfigSourceDialog.vue @@ -0,0 +1,69 @@ + + + + + + diff --git a/ui/src/components/EventConfigurationDetail/EventConfigEventTable.vue b/ui/src/components/EventConfigurationDetail/EventConfigEventTable.vue new file mode 100644 index 000000000000..8ee84925616c --- /dev/null +++ b/ui/src/components/EventConfigurationDetail/EventConfigEventTable.vue @@ -0,0 +1,354 @@ + + + + + + diff --git a/ui/src/components/Nodes/ColumnSelectionDrawer.vue b/ui/src/components/Nodes/ColumnSelectionDrawer.vue index b76a59f13832..e553ca58ea9d 100644 --- a/ui/src/components/Nodes/ColumnSelectionDrawer.vue +++ b/ui/src/components/Nodes/ColumnSelectionDrawer.vue @@ -2,9 +2,9 @@
diff --git a/ui/src/components/Nodes/NodeAdvancedFiltersDrawer.vue b/ui/src/components/Nodes/NodeAdvancedFiltersDrawer.vue index e3a0c4e07dda..64500ea997ff 100644 --- a/ui/src/components/Nodes/NodeAdvancedFiltersDrawer.vue +++ b/ui/src/components/Nodes/NodeAdvancedFiltersDrawer.vue @@ -2,7 +2,7 @@ +
+ +
+
+

No event configuration found.

+ + Go Back + +
+ + + + + + diff --git a/ui/src/containers/EventConfiguration.vue b/ui/src/containers/EventConfiguration.vue new file mode 100644 index 000000000000..e883cda79985 --- /dev/null +++ b/ui/src/containers/EventConfiguration.vue @@ -0,0 +1,25 @@ + + + + + + diff --git a/ui/src/containers/EventConfigurationDetail.vue b/ui/src/containers/EventConfigurationDetail.vue new file mode 100644 index 000000000000..3871e19a5333 --- /dev/null +++ b/ui/src/containers/EventConfigurationDetail.vue @@ -0,0 +1,219 @@ + + + + + + diff --git a/ui/src/lib/utils.ts b/ui/src/lib/utils.ts index 3d8aa25db327..566ccfcda354 100644 --- a/ui/src/lib/utils.ts +++ b/ui/src/lib/utils.ts @@ -21,7 +21,7 @@ /// export const isNumber = (value: any) => { - return value !== null && value !== undefined && typeof(value) === 'number' + return value !== null && value !== undefined && typeof value === 'number' } export const isConvertibleToInteger = (value: any) => { @@ -38,12 +38,14 @@ export const isConvertibleToInteger = (value: any) => { * Returns true if value is non-null and is a primitive string or a String object */ export const isString = (value: any) => { - return value !== null && (typeof(value) === 'string' || value instanceof String) + return value !== null && (typeof value === 'string' || value instanceof String) } export const ellipsify = (text: string, count: number) => { + const ellipsis = '\u2026' // Unicode for "..." + if (text && count && text.length > count) { - return text.substring(0, count) + '...' + return text.substring(0, count - 1) + ellipsis } return text @@ -59,8 +61,10 @@ export const hasNonEmptyProperty = (obj?: any) => { const keys = Object.getOwnPropertyNames(obj) - return keys.some(k => { + return keys.some((k) => { const value = (obj as any)[k] return value && isString(value) && value.length > 0 }) } + +export const VENDOR_OPENNMS = 'opennms' diff --git a/ui/src/main/router/index.ts b/ui/src/main/router/index.ts index b1690f34135b..126282afb93a 100644 --- a/ui/src/main/router/index.ts +++ b/ui/src/main/router/index.ts @@ -265,6 +265,21 @@ const router = createRouter({ } ] }, + { + path: '/event-config', + name: 'Event Configuration', + component: () => import('@/containers/EventConfiguration.vue') + }, + { + path: '/event-config-details', + name: 'Event Configuration Detail', + component: () => import('@/containers/EventConfigurationDetail.vue') + }, + { + path: '/event-config/create', + name: 'Event Configuration New', + component: () => import('@/containers/EventConfigEventCreate.vue') + }, { path: '/:pathMatch(.*)*', // catch other paths and redirect redirect: '/' diff --git a/ui/src/mappers/eventConfig.mapper.ts b/ui/src/mappers/eventConfig.mapper.ts new file mode 100644 index 000000000000..676f1edcee8c --- /dev/null +++ b/ui/src/mappers/eventConfig.mapper.ts @@ -0,0 +1,104 @@ +import { + EventConfigEvent, + EventConfigEventRequest, + EventConfigEventsResponse, + EventConfigFilesUploadResponse, + EventConfigSource, + EventConfigSourcesResponse +} from '@/types/eventConfig' +import vkbeautify from 'vkbeautify' + +export const mapUploadedEventConfigFilesResponseFromServer = (response: any): EventConfigFilesUploadResponse => { + return { + errors: response.errors.map((err: any) => ({ + file: err.file, + error: err.error + })), + success: response.success.map((success: any) => ({ + file: success.file + })) + } +} + +export const mapEventConfigSourceFromServer = (source: any): EventConfigSource => { + return { + id: source.id, + name: source.name, + description: source.description, + enabled: source.enabled, + eventCount: source.eventCount, + fileOrder: source.fileOrder, + vendor: source.vendor, + uploadedBy: source.uploadedBy, + createdTime: new Date(source.createdTime), + lastModified: new Date(source.lastModified) + } +} + +export const mapEventConfSourceResponseFromServer = (response: any): EventConfigSourcesResponse => { + return { + sources: response.eventConfSourceList.map((source: any) => mapEventConfigSourceFromServer(source)), + totalRecords: response.totalRecords + } +} + +const extractSeverity = (xmlContent: string): string | null => { + let severity: string | null + + if (xmlContent) { + try { + const parser = new DOMParser() + const xmlDoc = parser.parseFromString(xmlContent, 'application/xml') + const severityElement = xmlDoc.getElementsByTagName('severity')[0] + severity = severityElement ? severityElement.textContent : null + return severity + } catch (e) { + severity = null + return severity + } + } else { + severity = null + return severity + } +} + +export const mapEventConfigEventFromServer = (event: any): EventConfigEvent => { + return { + id: event.id, + uei: event.uei, + eventLabel: event.eventLabel, + description: event.description, + severity: extractSeverity(event.xmlContent) || '', + enabled: event.enabled, + xmlContent: event.xmlContent, + createdTime: new Date(event.createdTime), + lastModified: new Date(event.lastModified), + modifiedBy: event.modifiedBy, + sourceName: event.sourceName, + vendor: event.vendor, + fileOrder: event.fileOrder + } +} + +export const mapEventConfigEventsResponseFromServer = (response: any): EventConfigEventsResponse => { + return { + events: response.eventConfSourceList.map((event: any) => mapEventConfigEventFromServer(event)), + totalRecords: response.totalRecords + } +} + +export const mapEventConfigEventToServer = (event: EventConfigEvent): EventConfigEventRequest => { + const newEvent: Partial = { + uei: event.uei, + ['event-label']: event.eventLabel, + descr: event.description, + severity: event.severity + } + + return newEvent as EventConfigEventRequest +} + +export const mapEventConfEventEditRequest = (content: any, status: boolean): string => { + return vkbeautify.xml(`${status}${content as string}`) +} + diff --git a/ui/src/services/eventConfigService.ts b/ui/src/services/eventConfigService.ts new file mode 100644 index 000000000000..c7b917de73b3 --- /dev/null +++ b/ui/src/services/eventConfigService.ts @@ -0,0 +1,331 @@ +import { + mapEventConfEventEditRequest, + mapEventConfigEventsResponseFromServer, + mapEventConfSourceResponseFromServer, + mapUploadedEventConfigFilesResponseFromServer +} from '@/mappers/eventConfig.mapper' +import { + EventConfigEventsResponse, + EventConfigFilesUploadResponse, + EventConfigSourcesResponse +} from '@/types/eventConfig' +import { v2 } from './axiosInstances' + +/** + * Makes a POST request to the REST endpoint to upload event configuration files. + * + * @param files A list of File objects to upload. + * @returns A promise that resolves to an object containing the list of event + * configuration files and any errors encountered during the upload process. + */ +export const uploadEventConfigFiles = async (files: File[]): Promise => { + const formData = new FormData() + const endpoint = '/eventconf/upload' + files.forEach((file) => { + formData.append('upload', file) + }) + + try { + const response = await v2.post(endpoint, formData) + if (response.status !== 200) { + throw new Error(`Failed to upload files: ${response.statusText}`) + } + return mapUploadedEventConfigFilesResponseFromServer(response.data) + } catch (error) { + console.error('Error uploading event config files:', error) + throw error + } +} + +/** + * Makes a DELETE request to the REST endpoint to delete an event configuration source. + * + * @param id The ID of the event configuration source to delete. + * @returns A promise that resolves to a boolean indicating whether the source was deleted successfully. + */ +export const deleteEventConfigSourceById = async (id: number): Promise => { + const endpoint = '/eventconf/sources' + const payload = { + sourceIds: [id] + } + try { + const response = await v2.delete(endpoint, { data: payload }) + return response.status === 200 + } catch (error) { + console.error('Error deleting event config source:', error) + return false + } +} + +/** + * Makes a PUT request to the REST endpoint to update an event configuration event. + * + * @param eventXml The XML string representing the event configuration event to update. + * @param sourceId The ID of the event configuration source under which the event configuration event belongs. + * @param eventId The ID of the event configuration event to update. + * @param status Whether to enable or disable the event configuration event. + * @returns A promise that resolves to a boolean indicating whether the event configuration event was updated successfully. + */ +export const updateEventConfigEventById = async ( + eventXml: string, + sourceId: number, + eventId: number, + status: boolean +): Promise => { + const endpoint = `/eventconf/sources/${sourceId}/events/${eventId}` + const payload = mapEventConfEventEditRequest(eventXml, status) + try { + const response = await v2.put(endpoint, payload, { headers: { 'Content-Type': 'application/xml' } }) + return response.status === 200 + } catch (error) { + console.error('Error Updating event config source:', error) + return false + } +} + +/** + * Makes a POST request to the REST endpoint to create a new event configuration event. + * + * @param eventXml The XML string representing the event configuration event to create. + * @param sourceId The ID of the event configuration source under which the event configuration event belongs. + * @returns A promise that resolves to a boolean indicating whether the event configuration event was created successfully. + */ +export const createEventConfigEvent = async (eventXml: string, sourceId: number): Promise => { + const endpoint = `/eventconf/sources/${sourceId}/events` + try { + const response = await v2.post(endpoint, eventXml, { headers: { 'Content-Type': 'application/xml' } }) + return response.status === 200 || response.status === 201 + } catch (error) { + console.error('Error Creating event config source:', error) + return false + } +} + +/** + * Makes a PATCH request to the REST endpoint to change the status of an event configuration event. + * + * @param eventId The ID of the event configuration event to change the status of. + * @param sourceId The ID of the event configuration source that the event configuration event belongs to. + * @param enable Whether to enable or disable the event configuration event. + * @returns A promise that resolves to a boolean indicating whether the event configuration event status was changed successfully. + */ +export const changeEventConfigEventStatus = async ( + eventId: number, + sourceId: number, + enable: boolean +): Promise => { + const endpoint = `/eventconf/sources/${sourceId}/events/status` + const payload = { + enable, + eventsIds: [eventId] + } + try { + const response = await v2.patch(endpoint, payload) + return response.status === 200 + } catch (error) { + console.error('Error changing event config event status:', error) + return false + } +} + +/** + * Makes a PATCH request to the REST endpoint to change the status of an event configuration source. + * + * @param sourceId The ID of the event configuration source to change the status of. + * @param enabled Whether to enable or disable the event configuration source. + * @returns A promise that resolves to a boolean indicating whether the event configuration source status was changed successfully. + */ +export const changeEventConfigSourceStatus = async (sourceId: number, enabled: boolean): Promise => { + const endpoint = '/eventconf/sources/status' + const payload = { + enabled, + cascadeToEvents: true, + sourceIds: [sourceId] + } + try { + const response = await v2.patch(endpoint, payload) + return response.status === 200 + } catch (error) { + console.error('Error changing event config source status:', error) + return false + } +} + +/** + * Makes a GET request to the REST endpoint to filter event configuration sources. + * + * @param offset The offset of the page of results to return. + * @param limit The maximum number of results to return in a page. + * @param totalRecords The total number of records across all pages. + * @param filter The filter to apply to the results, expressed as a comma-separated list of key-value pairs. + * @param sortBy The field to sort the results by. + * @param order The order in which to sort the results (either "asc" or "desc"). + * @returns A promise that resolves to an `EventConfSourcesResponse` containing the filtered event configuration sources. + */ +export const filterEventConfigSources = async ( + offset: number, + limit: number, + filter: string, + sortBy: string, + order: string +): Promise => { + const endpoint = '/eventconf/filter/sources' + try { + const response = await v2.get(endpoint, { + params: { + offset, + limit, + filter, + sortBy, + order + } + }) + if (response.status === 200) { + return mapEventConfSourceResponseFromServer(response.data) + } else { + throw new Error(`Unexpected response status: ${response.status}`) + } + } catch (error) { + console.error('Error filtering event config sources:', error) + throw error + } +} + +/** + * Makes a GET request to the REST endpoint to filter event configuration events. + * + * @param sourceId The ID of the event configuration source to filter events from. + * @param offset The offset of the page of results to return. + * @param limit The maximum number of results to return in a page. + * @param filter The filter to apply to the results, expressed as a comma-separated list of key-value pairs. + * @param sortBy The field to sort the results by. + * @param order The order in which to sort the results (either "asc" or "desc"). + * @returns A promise that resolves to an `EventConfigEventsResponse` containing the filtered event configuration events. + */ +export const filterEventConfigEvents = async ( + sourceId: number, + offset: number, + limit: number, + eventFilter: string, + eventSortBy: string, + eventOrder: string +): Promise => { + const endpoint = `/eventconf/filter/${sourceId}/events` + try { + const response = await v2.get(endpoint, { + params: { + offset, + limit, + eventFilter, + eventSortBy, + eventOrder + } + }) + if (response.status === 200) { + return mapEventConfigEventsResponseFromServer(response.data) + } else { + throw new Error(`Unexpected response status: ${response.status}`) + } + } catch (error) { + console.error('Error filtering event config events:', error) + throw error + } +} + +/** + * Makes a GET request to the REST endpoint to fetch all source names. + * + * @returns A promise that resolves to an array of strings containing all source names. + */ +export const getAllSourceNames = async (): Promise => { + const endpoint = '/eventconf/sources/names' + try { + const response = await v2.get(endpoint) + if (response.status === 200) { + return response.data as string[] + } else { + throw new Error(`Unexpected response status: ${response.status}`) + } + } catch (error) { + console.error('Error fetching all source names:', error) + throw error + } +} + +/** + * Makes a DELETE request to the REST endpoint to delete one or more event configuration events for a source. + * + * @param sourceId The ID of the event configuration source to delete events from. + * @param eventIds An array of event IDs to delete. + * @returns A promise that resolves to a boolean indicating whether the event configuration events were deleted successfully. + */ +export const deleteEventConfigEventBySourceId = async (sourceId: number, eventIds: number[]): Promise => { + const endpoint = `/eventconf/sources/${sourceId}/events` + const payload = { + eventIds + } + + try { + const response = await v2.delete(endpoint, { data: payload }) + return response.status === 200 + } catch (error) { + console.error('Error deleting event config events:', error) + return false + } +} + + +/** + * Downloads the EventConf XML for the given sourceId. + * + * @param sourceId The ID of the event configuration source to download the XML for. + * @returns A promise that resolves to a boolean indicating whether the XML was downloaded successfully. + */ +export const downloadEventConfXmlBySourceId = async (sourceId: number): Promise => { + if (!sourceId || sourceId <= 0) { + console.error('Invalid sourceId', sourceId) + return false + } + + const endpoint = `/eventconf/sources/${sourceId}/events/download` + try { + const response = await v2.get(endpoint, { responseType: 'blob' }) + if (response.status !== 200) return false + + const filename = extractFilenameFromContentDisposition(response.headers, `eventconf-source-${sourceId}.xml`) + const blob = response.data as Blob + + saveBlobAsFile(blob, filename) + + return true + } catch (error) { + console.error('Error downloading EventConf XML for sourceId', sourceId, error) + return false + } +} + +const extractFilenameFromContentDisposition = (headers: Record | undefined, defaultName: string): string => { + const contentDisposition = headers && (headers['content-disposition'] || headers['Content-Disposition']) as string | undefined + if (!contentDisposition) return defaultName + + const match = /filename\*?=(?:UTF-8'')?["']?([^;"']+)["']?/.exec(contentDisposition) + if (match && match[1]) { + try { + return decodeURIComponent(match[1]) + } catch { + return match[1] + } + } + return defaultName +} + +const saveBlobAsFile = (blob: Blob, filename: string): void => { + const url = URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = filename + document.body.appendChild(a) + a.click() + a.remove() + URL.revokeObjectURL(url) +} \ No newline at end of file diff --git a/ui/src/stores/eventConfigDetailStore.ts b/ui/src/stores/eventConfigDetailStore.ts new file mode 100644 index 000000000000..3ced9eae70a3 --- /dev/null +++ b/ui/src/stores/eventConfigDetailStore.ts @@ -0,0 +1,206 @@ +import { Severity } from '@/components/EventConfigEventCreate/constants' +import { + changeEventConfigEventStatus, + changeEventConfigSourceStatus, + filterEventConfigEvents +} from '@/services/eventConfigService' +import { + EventConfigDetailStoreState, + EventConfigEvent, + EventConfigSource +} from '@/types/eventConfig' +import { defineStore } from 'pinia' + +const defaultPagination = { + page: 1, + pageSize: 10, + total: 0 +} + +export const getDefaultEventConfigEvent = (): EventConfigEvent => ({ + id: new Date().getTime(), // Temporary ID for new events + uei: '', + eventLabel: '', + description: '', + severity: Severity.Normal, + enabled: true, + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 +}) + +export const useEventConfigDetailStore = defineStore('useEventConfigDetailStore', { + state: (): EventConfigDetailStoreState => ({ + events: [], + eventsPagination: { ...defaultPagination }, + eventsSearchTerm: '', + eventsSorting: { + sortOrder: 'desc', + sortKey: 'createdTime' + }, + selectedSource: null, + isLoading: false, + deleteEventConfigEventDialogState: { + visible: false, + eventConfigEvent: null + }, + changeEventConfigEventStatusDialogState: { + visible: false, + eventConfigEvent: null + }, + deleteEventConfigSourceDialogState: { + visible: false, + eventConfigSource: null + }, + changeEventConfigSourceStatusDialogState: { + visible: false, + eventConfigSource: null + } + }), + actions: { + async fetchEventsBySourceId() { + if (!this.selectedSource) { + console.error('No source selected') + return + } + this.isLoading = true + const id = this.selectedSource.id + try { + const response = await filterEventConfigEvents( + id, + (this.eventsPagination.page - 1) * this.eventsPagination.pageSize, + this.eventsPagination.pageSize, + this.eventsSearchTerm, + this.eventsSorting.sortKey, + this.eventsSorting.sortOrder + ) + this.events = response.events + this.eventsPagination.total = response.totalRecords + this.isLoading = false + } catch (error) { + console.error('Error fetching events for source ID:', id, error) + this.isLoading = false + } + }, + setSelectedEventConfigSource(eventConfigSource: EventConfigSource) { + this.selectedSource = eventConfigSource + }, + async onEventsPageChange(page: number) { + this.eventsPagination.page = page + await this.fetchEventsBySourceId() + }, + async onEventsPageSizeChange(pageSize: number) { + this.eventsPagination.page = 1 + this.eventsPagination.pageSize = pageSize + await this.fetchEventsBySourceId() + }, + async onChangeEventsSearchTerm(value: string) { + this.eventsSearchTerm = value ?? '' + this.eventsPagination.page = 1 + await this.fetchEventsBySourceId() + }, + async onEventsSortChange(sortKey: string, sortOrder: string) { + this.eventsSorting.sortKey = sortKey + this.eventsSorting.sortOrder = sortOrder + await this.fetchEventsBySourceId() + }, + async refreshEventConfigEvents() { + this.resetEventsPagination() + this.eventsSearchTerm = '' + this.eventsSorting.sortKey = 'createdTime' + this.eventsSorting.sortOrder = 'desc' + await this.fetchEventsBySourceId() + }, + showDeleteEventConfigEventDialog(eventConfigSource: EventConfigEvent) { + this.deleteEventConfigEventDialogState.visible = true + this.deleteEventConfigEventDialogState.eventConfigEvent = eventConfigSource + }, + hideDeleteEventConfigEventDialog() { + this.deleteEventConfigEventDialogState.visible = false + this.deleteEventConfigEventDialogState.eventConfigEvent = null + }, + async disableEventConfigEvent(eventId: number) { + if (this.selectedSource) { + const response = await changeEventConfigEventStatus(eventId, this.selectedSource.id, false) + if (response) { + await this.fetchEventsBySourceId() + } + } else { + console.error('No source selected') + } + }, + async enableEventConfigEvent(eventId: number) { + if (this.selectedSource) { + const response = await changeEventConfigEventStatus(eventId, this.selectedSource.id, true) + if (response) { + await this.fetchEventsBySourceId() + } + } else { + console.error('No source selected') + } + }, + showChangeEventConfigEventStatusDialog(eventConfigEvent: EventConfigEvent) { + this.changeEventConfigEventStatusDialogState.eventConfigEvent = eventConfigEvent + this.changeEventConfigEventStatusDialogState.visible = true + }, + async hideChangeEventConfigEventStatusDialog() { + this.changeEventConfigEventStatusDialogState.visible = false + this.changeEventConfigEventStatusDialogState.eventConfigEvent = null + await this.fetchEventsBySourceId() + }, + resetEventsPagination() { + this.eventsPagination = { ...defaultPagination } + }, + showDeleteEventConfigSourceDialog(eventConfigSource: EventConfigSource) { + this.deleteEventConfigSourceDialogState.visible = true + this.deleteEventConfigSourceDialogState.eventConfigSource = eventConfigSource + }, + async hideDeleteEventConfigSourceDialog() { + this.deleteEventConfigSourceDialogState.eventConfigSource = null + this.deleteEventConfigSourceDialogState.visible = false + }, + showChangeEventConfigSourceStatusDialog(eventConfigSource: EventConfigSource) { + this.changeEventConfigSourceStatusDialogState.visible = true + this.changeEventConfigSourceStatusDialogState.eventConfigSource = eventConfigSource + }, + hideChangeEventConfigSourceStatusDialog() { + this.changeEventConfigSourceStatusDialogState.visible = false + this.changeEventConfigSourceStatusDialogState.eventConfigSource = null + }, + async disableEventConfigSource(sourceId: number) { + if (sourceId && this.selectedSource) { + const response = await changeEventConfigSourceStatus(sourceId, false) + if (response) { + this.selectedSource.enabled = false + await this.fetchEventsBySourceId() + } + } else { + console.error('No source selected') + throw new Error('No source selected') + } + }, + async enableEventConfigSource(sourceId: number) { + if (sourceId && this.selectedSource) { + const response = await changeEventConfigSourceStatus(sourceId, true) + if (response) { + this.selectedSource.enabled = true + await this.fetchEventsBySourceId() + } + } else { + console.error('No source selected') + throw new Error('No source selected') + } + }, + resetFilters() { + this.resetEventsPagination() + this.eventsSearchTerm = '' + this.eventsSorting.sortKey = 'createdTime' + this.eventsSorting.sortOrder = 'desc' + } + } +}) + diff --git a/ui/src/stores/eventConfigStore.ts b/ui/src/stores/eventConfigStore.ts new file mode 100644 index 000000000000..93be05be602b --- /dev/null +++ b/ui/src/stores/eventConfigStore.ts @@ -0,0 +1,142 @@ +import { + changeEventConfigSourceStatus, + filterEventConfigSources, + getAllSourceNames +} from '@/services/eventConfigService' +import { EventConfigSource, EventConfigStoreState } from '@/types/eventConfig' +import { defineStore } from 'pinia' + +const defaultPagination = { + page: 1, + pageSize: 10, + total: 0 +} + +export const useEventConfigStore = defineStore('useEventConfigStore', { + state: (): EventConfigStoreState => ({ + sources: [], + sourcesPagination: { ...defaultPagination }, + sourcesSearchTerm: '', + sourcesSorting: { + sortOrder: 'desc', + sortKey: 'createdTime' + }, + isLoading: false, + activeTab: 0, + uploadedSourceNames: [], + uploadedEventConfigFilesReportDialogState: { + visible: false + }, + deleteEventConfigSourceDialogState: { + visible: false, + eventConfigSource: null + }, + changeEventConfigSourceStatusDialogState: { + visible: false, + eventConfigSource: null + } + }), + actions: { + async fetchAllSourcesNames() { + this.isLoading = true + try { + const response = await getAllSourceNames() + this.uploadedSourceNames = response + this.isLoading = false + } catch (error) { + console.error('Error fetching all event configuration source names:', error) + this.isLoading = false + } + }, + async fetchEventConfigs() { + this.isLoading = true + try { + const response = await filterEventConfigSources( + (this.sourcesPagination.page - 1) * this.sourcesPagination.pageSize, + this.sourcesPagination.pageSize, + this.sourcesSearchTerm, + this.sourcesSorting.sortKey, + this.sourcesSorting.sortOrder + ) + await this.fetchAllSourcesNames() + this.sources = response.sources + this.sourcesPagination.total = response.totalRecords + this.isLoading = false + } catch (error) { + console.error('Error fetching event configurations:', error) + this.isLoading = false + } + }, + async onSourcePageChange(page: number) { + this.sourcesPagination.page = page + await this.fetchEventConfigs() + }, + async onSourcePageSizeChange(pageSize: number) { + this.sourcesPagination.page = 1 + this.sourcesPagination.pageSize = pageSize + await this.fetchEventConfigs() + }, + async onChangeSourcesSearchTerm(value: string) { + this.sourcesSearchTerm = value ?? '' + this.sourcesPagination.page = 1 + await this.fetchEventConfigs() + }, + async onSourcesSortChange(sortKey: string, sortOrder: string) { + this.sourcesSorting.sortKey = sortKey + this.sourcesSorting.sortOrder = sortOrder + await this.fetchEventConfigs() + }, + resetActiveTab() { + this.activeTab = 0 + }, + showDeleteEventConfigSourceModal(eventConfigSource: EventConfigSource) { + this.deleteEventConfigSourceDialogState.visible = true + this.deleteEventConfigSourceDialogState.eventConfigSource = eventConfigSource + }, + hideDeleteEventConfigSourceModal() { + this.deleteEventConfigSourceDialogState.visible = false + this.deleteEventConfigSourceDialogState.eventConfigSource = null + }, + resetSourcesPagination() { + this.sourcesPagination = { ...defaultPagination } + }, + async refreshEventsSources() { + this.resetSourcesPagination() + this.sourcesSearchTerm = '' + this.sourcesSorting.sortKey = 'createdTime' + this.sourcesSorting.sortOrder = 'desc' + await this.fetchEventConfigs() + }, + showChangeEventConfigSourceStatusDialog(eventConfigSource: EventConfigSource) { + this.changeEventConfigSourceStatusDialogState.visible = true + this.changeEventConfigSourceStatusDialogState.eventConfigSource = eventConfigSource + }, + hideChangeEventConfigSourceStatusDialog() { + this.changeEventConfigSourceStatusDialogState.visible = false + this.changeEventConfigSourceStatusDialogState.eventConfigSource = null + }, + async disableEventConfigSource(sourceId: number) { + if (sourceId) { + const response = await changeEventConfigSourceStatus(sourceId, false) + if (response) { + await this.fetchEventConfigs() + } + } else { + console.error('No source selected') + throw new Error('No source selected') + } + }, + async enableEventConfigSource(sourceId: number) { + if (sourceId) { + const response = await changeEventConfigSourceStatus(sourceId, true) + if (response) { + await this.fetchEventConfigs() + } + } else { + console.error('No source selected') + throw new Error('No source selected') + } + } + } +}) + diff --git a/ui/src/stores/eventModificationStore.ts b/ui/src/stores/eventModificationStore.ts new file mode 100644 index 000000000000..3492de4c776c --- /dev/null +++ b/ui/src/stores/eventModificationStore.ts @@ -0,0 +1,26 @@ +import { CreateEditMode } from '@/types' +import { EventConfigEvent, EventConfigSource, EventModificationStoreState } from '@/types/eventConfig' +import { defineStore } from 'pinia' + +export const useEventModificationStore = defineStore('useEventModificationStore', { + state: (): EventModificationStoreState => ({ + selectedSource: null, + eventModificationState: { + isEditMode: CreateEditMode.None, + eventConfigEvent: null + } + }), + actions: { + setSelectedEventConfigSource(eventConfigSource: EventConfigSource, isEditMode: CreateEditMode, eventConfigEvent: EventConfigEvent | null) { + this.selectedSource = eventConfigSource + this.eventModificationState.isEditMode = isEditMode + this.eventModificationState.eventConfigEvent = eventConfigEvent + }, + resetEventModificationState() { + this.selectedSource = null + this.eventModificationState.isEditMode = CreateEditMode.None + this.eventModificationState.eventConfigEvent = null + } + } +}) + diff --git a/ui/src/styles/_severities.scss b/ui/src/styles/_severities.scss new file mode 100644 index 000000000000..5d9772ee6e26 --- /dev/null +++ b/ui/src/styles/_severities.scss @@ -0,0 +1,105 @@ +/* + The class names are based on the `severity` type of the graphql schema. + enum Severity { + CLEARED + CRITICAL + INDETERMINATE + MAJOR + MINOR + NORMAL + SEVERITY_UNDEFINED + UNRECOGNIZED + WARNING + } +*/ + +@use '@featherds/styles/themes/utils'; +@use '@featherds/styles/themes/variables'; + +$opacity: 0.2; +$solid: 1; + +.critical { + background-color: utils.alpha(variables.$error, $solid); + color: var(variables.$error) !important; +} + +.major { + background-color: utils.alpha(variables.$major, $solid); + color: var(variables.$major) !important; +} + +.minor { + background-color: utils.alpha(variables.$minor, $solid); + color: var(variables.$secondary-text-on-surface) !important; +} + +.warning { + background-color: utils.alpha(variables.$warning, $solid); + color: var(variables.$secondary-text-on-surface) !important; +} + +.indeterminate, +.acknowledged { + background-color: utils.alpha(variables.$indeterminate, $solid); + color: var(variables.$indeterminate) !important; +} + +.normal { + background-color: utils.alpha(variables.$success, $solid); + color: var(variables.$success) !important; +} + +.unacknowledged, +.cleared { + background-color: utils.alpha(variables.$cleared, $solid); + color: var(variables.$cleared) !important; +} + +.unrecognized, +.severity_undefined { + border: 1px solid var(variables.$border-on-surface); +} + +// with opacity +.critical-color { + background-color: utils.alpha(variables.$error, $opacity); + color: var(variables.$error) !important; +} + +.major-color { + background-color: utils.alpha(variables.$major, $opacity); + color: var(variables.$major) !important; +} + +.minor-color { + background-color: utils.alpha(variables.$minor, $opacity); + color: var(variables.$secondary-text-on-surface) !important; +} + +.warning-color { + background-color: utils.alpha(variables.$warning, $opacity); + color: var(variables.$secondary-text-on-surface) !important; +} + +.indeterminate-color, +.acknowledged-color { + background-color: utils.alpha(variables.$indeterminate, $opacity); + color: var(variables.$indeterminate) !important; +} + +.normal-color { + background-color: utils.alpha(variables.$success, $opacity); + color: var(variables.$success) !important; +} + +.cleared-color, +.unacknowledged-color { + background-color: utils.alpha(variables.$cleared, $opacity); + color: var(variables.$cleared) !important; +} + +.unrecognized-color, +.severity_undefined-color { + border: 1px solid var(variables.$border-on-surface); +} diff --git a/ui/src/styles/_transitionDataTable.scss b/ui/src/styles/_transitionDataTable.scss new file mode 100644 index 000000000000..1edfaa3fac96 --- /dev/null +++ b/ui/src/styles/_transitionDataTable.scss @@ -0,0 +1,20 @@ +@use "@featherds/styles/mixins/elevation"; + +.data-table tr, +.data-table div { + @for $i from 1 through 50 { + &:nth-child(#{$i}) { + transition: all 0.3s ease $i * 0.05s; + } + } +} +.data-table-enter-active, +.data-table-leave-active { + transform: translateX(0px); + opacity:1; +} +.data-table-enter-from, +.data-table-leave-to { + transform: translateX(30px); + opacity:0; +} \ No newline at end of file diff --git a/ui/src/types/eventConfig.d.ts b/ui/src/types/eventConfig.d.ts new file mode 100644 index 000000000000..5295227db489 --- /dev/null +++ b/ui/src/types/eventConfig.d.ts @@ -0,0 +1,143 @@ +import { CreateEditMode, Pagination, Sorting } from '.' + +export type EventConfigSource = { + id: number + name: string + vendor: string + description: string + enabled: boolean + eventCount: number + fileOrder: number + uploadedBy: string + createdTime: Date + lastModified: Date +} + +export type EventConfigEvent = { + id: number + uei: string + eventLabel: string + description: string + severity: string + enabled: boolean + xmlContent: string + createdTime: Date + lastModified: Date + modifiedBy: string + sourceName: string + vendor: string + fileOrder: number +} + +export type EventConfigEventRequest = { + uei: string + ['event-label']: string + descr: string + severity: string +} + +export type EventConfigStoreState = { + sources: EventConfigSource[] + sourcesPagination: Pagination + sourcesSearchTerm: string + sourcesSorting: Sorting + isLoading: boolean + activeTab: number + uploadedSourceNames: string[] + uploadedEventConfigFilesReportDialogState: { + visible: boolean + } + deleteEventConfigSourceDialogState: { + visible: boolean + eventConfigSource: EventConfigSource | null + } + changeEventConfigSourceStatusDialogState: { + visible: boolean + eventConfigSource: EventConfigSource | null + } +} + +export type EventConfigDetailStoreState = { + events: EventConfigEvent[] + eventsPagination: Pagination + eventsSearchTerm: string + eventsSorting: Sorting + selectedSource: EventConfigSource | null + isLoading: boolean + deleteEventConfigEventDialogState: { + visible: boolean + eventConfigEvent: EventConfigEvent | null + } + changeEventConfigEventStatusDialogState: { + visible: boolean + eventConfigEvent: EventConfigEvent | null + } + deleteEventConfigSourceDialogState: { + visible: boolean + eventConfigSource: EventConfigSource | null + } + changeEventConfigSourceStatusDialogState: { + visible: boolean + eventConfigSource: EventConfigSource | null + } +} + +export type EventConfigFilesUploadResponse = { + errors: [ + { + file: string + error: string + } + ] + success: [ + { + file: string + } + ] +} + +export type EventConfigSourcesResponse = { + sources: EventConfigSource[] + totalRecords: number +} + +export type EventConfigEventsResponse = { + events: EventConfigEvent[] + totalRecords: number +} + +export interface DrawerState { + visible: boolean + isEventEditorModal: boolean +} + +export type UploadEventFileType = { + file: File + isValid: boolean + errors: string[] + isDuplicate: boolean +} + +export type EventModificationStoreState = { + selectedSource: EventConfigSource | null + eventModificationState: { + isEditMode: CreateEditMode + eventConfigEvent: EventConfigEvent | null + } +} + +export type EventFormErrors = { + uei?: string + eventLabel?: string + description?: string + severity?: string + logmsg?: string + dest?: string + maskElements?: Array<{ name?: string; value?: string }> + varbinds?: Array<{ index?: string; value?: string }> + varbindsDecode?: Array<{ parmId?: string; decode?: Array<{ key?: string; value?: string }> }> + reductionKey?: string + alarmType?: string + clearKey?: string +} + diff --git a/ui/src/types/index.ts b/ui/src/types/index.ts index 5ed8d69821a5..5330e86607bb 100644 --- a/ui/src/types/index.ts +++ b/ui/src/types/index.ts @@ -43,21 +43,21 @@ export interface SearchResultResponse { } export interface SearchResultMatch { - label: string; - value: string; + label: string + value: string } export interface SearchResultItem { - identifier: string - icon: string; - label: string; - url: string; - properties: any; - matches: SearchResultMatch[]; - weight: number; + identifier: string + icon: string + label: string + url: string + properties: any + matches: SearchResultMatch[] + weight: number } -export type SearchResultsByContext = Array<{label: string, results: SearchResultResponse[]}> +export type SearchResultsByContext = Array<{ label: string; results: SearchResultResponse[] }> export interface ApiResponse { count: number @@ -126,7 +126,7 @@ export interface Node { createTime: number foreignId: string foreignSource: string - lastEgressFlow: number // timestamp + lastEgressFlow: number // timestamp lastIngressFlow: number labelSource: string lastCapabilitiesScan: string @@ -199,13 +199,13 @@ export interface MonitoringLocation { priority: number 'location-name': string 'monitoring-area': string - name: string // mapped from 'location-name' after API GET call response - area: string // mapped from 'monitoring-area' after API GET call response + name: string // mapped from 'location-name' after API GET call response + area: string // mapped from 'monitoring-area' after API GET call response } export interface DrawerState { - visible: boolean; - isAdvanceFilterModal: boolean; + visible: boolean + isAdvanceFilterModal: boolean } export interface SnmpInterface { @@ -606,7 +606,24 @@ export enum FilterTypeEnum { export enum Direction { Left = 'left', - Right = 'right', + Right = 'right' +} + +export type Pagination = { + page: number + pageSize: number + total: number +} + +export type Sorting = { + sortOrder: string + sortKey: string +} + +export enum CreateEditMode { + None = 0, + Create = 1, + Edit = 2 } export interface GeolocationConfigOptions { diff --git a/ui/tests/components/EventConfiguration/Dialog/ChangeEventConfigSourceStatusDialog.test.ts b/ui/tests/components/EventConfiguration/Dialog/ChangeEventConfigSourceStatusDialog.test.ts new file mode 100644 index 000000000000..46dde5df43ce --- /dev/null +++ b/ui/tests/components/EventConfiguration/Dialog/ChangeEventConfigSourceStatusDialog.test.ts @@ -0,0 +1,110 @@ +import { mount, VueWrapper } from '@vue/test-utils' +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigStore } from '@/stores/eventConfigStore' +import { FeatherDialog } from '@featherds/dialog' +import { FeatherButton } from '@featherds/button' +import ChangeEventConfigSourceStatusDialog from '@/components/EventConfiguration/Dialog/ChangeEventConfigSourceStatusDialog.vue' + +describe('ChangeEventConfigSourceStatusDialog.vue', () => { + let wrapper: VueWrapper + let store: ReturnType + + beforeEach(() => { + const pinia = createTestingPinia({ + createSpy: vi.fn + }) + + store = useEventConfigStore(pinia) + store.changeEventConfigSourceStatusDialogState.visible = true + store.changeEventConfigSourceStatusDialogState.eventConfigSource = { + id: 1, + name: 'Test Source', + vendor: 'Cisco', + description: '', + enabled: true, + eventCount: 5, + fileOrder: 1, + uploadedBy: 'user', + createdTime: new Date(), + lastModified: new Date() + } + + wrapper = mount(ChangeEventConfigSourceStatusDialog, { + global: { + plugins: [pinia], + stubs: { + FeatherDialog, + FeatherButton + } + } + }) + }) + + afterEach(() => { + wrapper.unmount() + vi.clearAllMocks() + }) + + it('renders dialog correctly with title and message', () => { + const dialog = wrapper.findComponent(FeatherDialog) + expect(dialog.exists()).toBe(true) + expect(dialog.props('labels')?.title).toBe('Change Event Configuration Source Status') + }) + + it('calls hideChangeEventConfigSourceStatusDialog on Cancel click', async () => { + const cancelBtn = wrapper.findAllComponents(FeatherButton).find((btn) => btn.text().toLowerCase() === 'cancel') + + expect(cancelBtn).toBeTruthy() + await cancelBtn?.trigger('click') + + expect(store.hideChangeEventConfigSourceStatusDialog).toHaveBeenCalledTimes(1) + }) + + it('calls disableEventConfigSource on Save click when enabled', async () => { + const saveBtn = wrapper.findAllComponents(FeatherButton).find((btn) => btn.text().toLowerCase() === 'save') + + await saveBtn?.trigger('click') + + expect(store.disableEventConfigSource).toHaveBeenCalledWith(1) + expect(store.hideChangeEventConfigSourceStatusDialog).toHaveBeenCalled() + }) + + it('calls enableEventConfigSource on Save click when disabled', async () => { + store.changeEventConfigSourceStatusDialogState = { + visible: true, + eventConfigSource: { + id: 1, + name: 'Test Source', + vendor: 'Cisco', + description: '', + enabled: false, + eventCount: 5, + fileOrder: 1, + uploadedBy: 'user', + createdTime: new Date(), + lastModified: new Date() + } + } + await wrapper.vm.$nextTick() + + const saveBtn = wrapper.findAllComponents(FeatherButton).find((btn) => btn.text().toLowerCase() === 'save') + + await saveBtn?.trigger('click') + + expect(store.enableEventConfigSource).toHaveBeenCalledWith(1) + expect(store.hideChangeEventConfigSourceStatusDialog).toHaveBeenCalled() + }) + + it('does not crash if dialog state is missing', async () => { + store.changeEventConfigSourceStatusDialogState = {} as any + await wrapper.vm.$nextTick() + expect(wrapper.exists()).toBe(true) + }) + + it('renders FeatherDialog with visible prop true', () => { + const dialog = wrapper.findComponent(FeatherDialog) + expect(dialog.props('modelValue')).toBe(true) + }) +}) + diff --git a/ui/tests/components/EventConfiguration/Dialog/DeleteEventConfigSourceDialog.test.ts b/ui/tests/components/EventConfiguration/Dialog/DeleteEventConfigSourceDialog.test.ts new file mode 100644 index 000000000000..e69a90b8242a --- /dev/null +++ b/ui/tests/components/EventConfiguration/Dialog/DeleteEventConfigSourceDialog.test.ts @@ -0,0 +1,119 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { mount, flushPromises } from '@vue/test-utils' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigStore } from '@/stores/eventConfigStore' +import * as eventConfigService from '@/services/eventConfigService' +import { FeatherButton } from '@featherds/button' +import { FeatherDialog } from '@featherds/dialog' +import DeleteEventConfigSourceDialog from '@/components/EventConfiguration/Dialog/DeleteEventConfigSourceDialog.vue' + +vi.mock('@featherds/dialog', () => ({ + FeatherDialog: { + name: 'FeatherDialog', + template: '
', + props: ['labels', 'modelValue'] + } +})) + +describe('DeleteEventConfigSourceDialog', () => { + let wrapper: any + let store: ReturnType + + beforeEach(async () => { + const pinia = createTestingPinia({ + createSpy: vi.fn, + stubActions: false + }) + + store = useEventConfigStore() + + store.$state = { + deleteEventConfigSourceDialogState: { + visible: true, + eventConfigSource: { + id: 1, + name: 'Test Source', + vendor: 'Test Vendor', + description: 'Test Description', + enabled: true, + eventCount: 5, + fileOrder: 1, + uploadedBy: 'test-user', + createdTime: new Date('2025-10-01T12:00:00Z'), + lastModified: new Date('2025-10-02T12:00:00Z') + } + }, + sources: [], + sourcesPagination: { page: 1, pageSize: 10, total: 0 }, + sourcesSearchTerm: '', + sourcesSorting: { sortOrder: 'desc', sortKey: 'createdTime' }, + isLoading: false, + activeTab: 0, + uploadedSourceNames: [], + uploadedEventConfigFilesReportDialogState: { visible: false }, + changeEventConfigSourceStatusDialogState: { visible: false, eventConfigSource: null } + } + + wrapper = mount(DeleteEventConfigSourceDialog, { + global: { + plugins: [pinia], + components: { + FeatherButton, + FeatherDialog + } + } + }) + + await flushPromises() + }) + + it('renders the dialog when visible is true', () => { + expect(wrapper.findComponent(FeatherDialog).exists()).toBe(true) + expect(wrapper.findComponent(FeatherDialog).props('labels')).toEqual({ + title: 'Delete Event Configuration Source' + }) + }) + + it('displays the correct event configuration source name and event count', () => { + const modalBody = wrapper.find('.modal-body') + expect(modalBody.exists()).toBe(true) + expect(modalBody.text()).toContain('This will delete the event configuration source: Test Source') + expect(modalBody.text()).toContain('This event configuration source has 5 events associated with it') + }) + + it('calls hideDeleteEventConfigSourceModal when Cancel button is clicked', async () => { + const cancelButton = wrapper.findAllComponents(FeatherButton).at(0) + expect(cancelButton.exists()).toBe(true) + await cancelButton.trigger('click') + expect(store.hideDeleteEventConfigSourceModal).toHaveBeenCalled() + }) + + it('calls deleteEventConfigSourceById and handles success when Delete button is clicked', async () => { + vi.spyOn(eventConfigService, 'deleteEventConfigSourceById').mockResolvedValue(true) + const deleteButton = wrapper.findAllComponents(FeatherButton).at(1) + expect(deleteButton.exists()).toBe(true) + await deleteButton.trigger('click') + await flushPromises() + expect(eventConfigService.deleteEventConfigSourceById).toHaveBeenCalledWith(1) + expect(store.hideDeleteEventConfigSourceModal).toHaveBeenCalled() + expect(store.resetSourcesPagination).toHaveBeenCalled() + expect(store.fetchEventConfigs).toHaveBeenCalled() + }) + + it('does not attempt to delete if eventConfigSource is null', async () => { + store.$state.deleteEventConfigSourceDialogState.eventConfigSource = null + await wrapper.vm.$nextTick() + vi.spyOn(eventConfigService, 'deleteEventConfigSourceById').mockResolvedValue(true) + const deleteButton = wrapper.findAllComponents(FeatherButton).at(1) + expect(deleteButton.exists()).toBe(true) + await deleteButton.trigger('click') + await flushPromises() + expect(eventConfigService.deleteEventConfigSourceById).not.toHaveBeenCalled() + }) + + it('hides the dialog when visible is false', async () => { + store.$state.deleteEventConfigSourceDialogState.visible = false + await wrapper.vm.$nextTick() + expect(wrapper.findComponent(FeatherDialog).props('modelValue')).toBe(false) + }) +}) \ No newline at end of file diff --git a/ui/tests/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.test.ts b/ui/tests/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.test.ts new file mode 100644 index 000000000000..ca78380cc141 --- /dev/null +++ b/ui/tests/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.test.ts @@ -0,0 +1,157 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { mount, flushPromises } from '@vue/test-utils' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigStore } from '@/stores/eventConfigStore' +import { FeatherButton } from '@featherds/button' +import { FeatherDialog } from '@featherds/dialog' +import EventConfigFilesUploadReportDialog from '@/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.vue' +import { EventConfigFilesUploadResponse } from '@/types/eventConfig' + +vi.mock('@featherds/dialog', () => ({ + FeatherDialog: { + name: 'FeatherDialog', + template: '
', + props: ['labels', 'modelValue'] + } +})) + +describe('EventConfigFilesUploadReportDialog', () => { + let wrapper: any + let store: ReturnType + + const mockReport = { + success: [{ file: 'file1.json' }], + errors: [{ file: 'file3.json', error: 'Invalid format' }] + } as unknown as EventConfigFilesUploadResponse + + beforeEach(async () => { + const pinia = createTestingPinia({ + createSpy: vi.fn, + stubActions: true + }) + store = useEventConfigStore(pinia) + store.$state = { + uploadedEventConfigFilesReportDialogState: { + visible: true + }, + deleteEventConfigSourceDialogState: { + visible: false, + eventConfigSource: null + }, + changeEventConfigSourceStatusDialogState: { + visible: false, + eventConfigSource: null + }, + sources: [], + sourcesPagination: { page: 1, pageSize: 10, total: 0 }, + sourcesSearchTerm: '', + sourcesSorting: { sortOrder: 'desc', sortKey: 'createdTime' }, + isLoading: false, + activeTab: 0, + uploadedSourceNames: [] + } + + wrapper = mount(EventConfigFilesUploadReportDialog, { + props: { + report: mockReport + }, + global: { + plugins: [pinia], + components: { + FeatherButton, + FeatherDialog + } + } + }) + + await flushPromises() + }) + + it('renders the dialog when visible is true', () => { + expect(wrapper.findComponent(FeatherDialog).exists()).toBe(true) + expect(wrapper.findComponent(FeatherDialog).props('labels')).toEqual({ + title: 'Upload Report', + close: 'Close' + }) + }) + + it('displays the correct status message for mixed success and errors', () => { + const statusMessage = wrapper.find('p').text() + expect(statusMessage).toBe('Some files uploaded successfully, while others failed.') + }) + + it('displays the correct status message for all successes', async () => { + await wrapper.setProps({ + report: { + success: [{ file: 'file1.json' }, { file: 'file2.json' }], + errors: [] + } + }) + await flushPromises() + const statusMessage = wrapper.find('p').text() + expect(statusMessage).toBe('All files uploaded successfully.') + }) + + it('displays the correct status message for all errors', async () => { + await wrapper.setProps({ + report: { + success: [], + errors: [ + { file: 'file3.json', error: 'Invalid format' }, + { file: 'file4.json', error: 'Duplicate file' } + ] + } + }) + await flushPromises() + const statusMessage = wrapper.find('p').text() + expect(statusMessage).toBe('All files failed to upload.') + }) + + it('displays the correct status message for no files', async () => { + await wrapper.setProps({ + report: { + success: [], + errors: [] + } + }) + await flushPromises() + const statusMessage = wrapper.find('p').text() + expect(statusMessage).toBe('No files were uploaded.') + }) + + it('renders success and error file lists correctly', () => { + const successItems = wrapper.findAll('li span.text-success') + const errorItems = wrapper.findAll('li span.text-danger') + expect(successItems).toHaveLength(1) + expect(successItems.at(0)?.text()).toBe('file1.json') + expect(errorItems).toHaveLength(1) + expect(errorItems.at(0)?.text()).toBe('file3.json') + expect(wrapper.text()).toContain('Successfully uploaded') + expect(wrapper.text()).toContain('Failed to upload') + }) + + it('calls fetchEventConfigs and closes dialog when Close button is clicked', async () => { + const closeButton = wrapper.findAllComponents(FeatherButton).at(0) + expect(closeButton.exists()).toBe(true) + await closeButton.trigger('click') + await flushPromises() + expect(store.fetchEventConfigs).toHaveBeenCalled() + expect(store.$state.uploadedEventConfigFilesReportDialogState.visible).toBe(false) + }) + + it('calls fetchEventConfigs, resets active tab, and closes dialog when View Uploaded Files button is clicked', async () => { + const viewButton = wrapper.findAllComponents(FeatherButton).at(1) + expect(viewButton.exists()).toBe(true) + await viewButton.trigger('click') + await flushPromises() + expect(store.fetchEventConfigs).toHaveBeenCalled() + expect(store.resetActiveTab).toHaveBeenCalled() + expect(store.$state.uploadedEventConfigFilesReportDialogState.visible).toBe(false) + }) + + it('hides the dialog when visible is false', async () => { + store.$state.uploadedEventConfigFilesReportDialogState.visible = false + await wrapper.vm.$nextTick() + expect(wrapper.findComponent(FeatherDialog).props('modelValue')).toBe(false) + }) +}) diff --git a/ui/tests/components/EventConfiguration/Dialog/UploadedFileRenameDialog.test.ts b/ui/tests/components/EventConfiguration/Dialog/UploadedFileRenameDialog.test.ts new file mode 100644 index 000000000000..fc0366d28023 --- /dev/null +++ b/ui/tests/components/EventConfiguration/Dialog/UploadedFileRenameDialog.test.ts @@ -0,0 +1,95 @@ +import { flushPromises, mount } from '@vue/test-utils' +import UploadedFileRenameDialog from '@/components/EventConfiguration/Dialog/UploadedFileRenameDialog.vue' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +describe('UploadedFileRenameDialog.vue', () => { + let wrapper: any + + const mockFile = new File([''], 'original.events.xml', { type: 'text/xml' }) + const fileBucket = [ + { + file: mockFile, + isValid: true, + errors: [], + isDuplicate: false + } + ] + + const createWrapper = (visible = true) => + mount(UploadedFileRenameDialog, { + props: { + visible, + index: 0, + fileBucket, + alreadyExistsNames: [] + }, + global: { + mocks: { + } + } + }) + + beforeEach(() => { + wrapper = createWrapper() + }) + + afterEach(() => { + if (wrapper) { + wrapper.unmount() + } + }) + + it('renders dialog title correctly', async () => { + await flushPromises() + expect(wrapper.vm.labels.title).toBe('Rename Uploaded File') + }) + + it('shows validation error for empty file name', async () => { + wrapper.vm.renameFile = true + wrapper.vm.newFileName = '' + wrapper.vm.validateName() + await flushPromises() + + expect(wrapper.vm.error?.toLowerCase()).toContain('empty') + }) + + it('shows validation error for duplicate file name', async () => { + await wrapper.setProps({ alreadyExistsNames: ['duplicate.events.xml'] }) + wrapper.vm.renameFile = true + wrapper.vm.newFileName = 'duplicate.events.xml' + wrapper.vm.validateName() + await flushPromises() + + expect(wrapper.vm.error?.toLowerCase()).toMatch(/already exists/) + }) + + it('passes validation for unique file name', async () => { + wrapper.vm.renameFile = true + wrapper.vm.newFileName = 'unique.events.xml' + wrapper.vm.validateName() + await flushPromises() + + expect(wrapper.vm.error).toBeUndefined() + }) + + it('calls handleDialogHidden when close event occurs', async () => { + const spy = vi.spyOn(wrapper.vm, 'handleDialogHidden') + wrapper.vm.handleDialogHidden() + await flushPromises() + + expect(spy).toHaveBeenCalled() + expect(wrapper.emitted('close')).toBeTruthy() + }) + + it('calls saveChanges when Save Changes button clicked', async () => { + wrapper.vm.renameFile = true + wrapper.vm.newFileName = 'newname.events.xml' + wrapper.vm.validateName() + await flushPromises() + + const spy = vi.spyOn(wrapper.vm, 'saveChanges') + + wrapper.vm.saveChanges() + expect(spy).toHaveBeenCalled() + }) +}) \ No newline at end of file diff --git a/ui/tests/components/EventConfiguration/EventConfigSourceTable.test.ts b/ui/tests/components/EventConfiguration/EventConfigSourceTable.test.ts new file mode 100644 index 000000000000..669d6bde2621 --- /dev/null +++ b/ui/tests/components/EventConfiguration/EventConfigSourceTable.test.ts @@ -0,0 +1,404 @@ +import EventConfigSourceTable from '@/components/EventConfiguration/EventConfigSourceTable.vue' +import { VENDOR_OPENNMS } from '@/lib/utils' +import { downloadEventConfXmlBySourceId } from '@/services/eventConfigService' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import { useEventConfigStore } from '@/stores/eventConfigStore' +import { EventConfigSource } from '@/types/eventConfig' +import { FeatherButton } from '@featherds/button' +import { FeatherDropdown, FeatherDropdownItem } from '@featherds/dropdown' +import { FeatherInput } from '@featherds/input' +import { FeatherPagination } from '@featherds/pagination' +import { FeatherSortHeader, SORT } from '@featherds/table' +import { createTestingPinia } from '@pinia/testing' +import { flushPromises, mount, VueWrapper } from '@vue/test-utils' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +const mockPush = vi.fn() +vi.mock('vue-router', () => ({ + useRouter: () => ({ + push: mockPush + }) +})) + +describe('EventConfigSourceTable.vue', () => { + let wrapper: VueWrapper + let store: ReturnType + let detailStore: ReturnType + let mockSource: EventConfigSource + let openNMSMockSource: EventConfigSource + + beforeEach(async () => { + vi.clearAllMocks() + vi.useFakeTimers() + + const pinia = createTestingPinia({ + createSpy: vi.fn, + stubActions: false + }) + + store = useEventConfigStore(pinia) + detailStore = useEventConfigDetailStore(pinia) + + store.sources = [] + store.sourcesSearchTerm = '' + store.sourcesPagination = { page: 1, pageSize: 10, total: 0 } + store.fetchEventConfigs = vi.fn().mockResolvedValue(undefined) + store.refreshEventsSources = vi.fn().mockResolvedValue(undefined) + store.onChangeSourcesSearchTerm = vi.fn().mockResolvedValue(undefined) + store.onSourcePageChange = vi.fn().mockResolvedValue(undefined) + store.onSourcePageSizeChange = vi.fn().mockResolvedValue(undefined) + store.onSourcesSortChange = vi.fn().mockResolvedValue(undefined) + store.showDeleteEventConfigSourceModal = vi.fn() + store.showChangeEventConfigSourceStatusDialog = vi.fn() + + mockSource = { + id: 1, + name: 'TestSource', + vendor: 'Cisco', + description: 'Test description', + enabled: true, + eventCount: 5, + fileOrder: 1, + uploadedBy: 'TestUser', + createdTime: new Date(), + lastModified: new Date() + } + + openNMSMockSource = { + ...mockSource, + id: 2, + vendor: VENDOR_OPENNMS, + enabled: false, + eventCount: 0, + description: '' + } + + wrapper = mount(EventConfigSourceTable, { + global: { + plugins: [pinia], + components: { + FeatherButton, + FeatherDropdown, + FeatherDropdownItem, + FeatherSortHeader, + FeatherPagination, + FeatherInput + } + } + }) + + await flushPromises() + await nextTick() + }) + + afterEach(() => { + vi.restoreAllMocks() + vi.useRealTimers() + }) + + it('renders correctly and calls fetchEventConfigs on mount', () => { + expect(wrapper.exists()).toBe(true) + expect(store.fetchEventConfigs).toHaveBeenCalled() + }) + + it('renders EmptyList when no sources are available', () => { + store.sources = [] + expect(store.sources.length).toBe(0) + }) + + it('renders table with data when sources exist', () => { + store.sources = [mockSource] + expect(store.sources.length).toBe(1) + expect(store.sources[0].name).toBe('TestSource') + }) + + it('calls refreshEventsSources when refresh button is clicked', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + await wrapper.get('[data-test="refresh-button"]').trigger('click') // Assuming data-test added or use selector for refresh button + expect(store.refreshEventsSources).toHaveBeenCalledTimes(1) + }) + + it('handles search input changes with debouncing', async () => { + const elem = wrapper.get('[data-test="search-input"]') + expect(elem.isVisible()).toBeTruthy() + }) + + it('handles view details button click correctly', () => { + wrapper.vm.onEventClick(mockSource) + + expect(detailStore.setSelectedEventConfigSource).toHaveBeenCalledWith(mockSource) + expect(mockPush).toHaveBeenCalledWith({ + name: 'Event Configuration Detail' + }) + }) + + it('handles sorting changes correctly', () => { + wrapper.vm.sortChanged({ property: 'name', value: 'asc' }) + expect(store.onSourcesSortChange).toHaveBeenCalledWith('name', 'asc') + }) + + it('shows dropdown actions for non-OpenNMS vendors', () => { + expect(mockSource.vendor).not.toBe('OpenNMS') + }) + + it('handles enable/disable source action', () => { + store.showChangeEventConfigSourceStatusDialog(mockSource) + expect(store.showChangeEventConfigSourceStatusDialog).toHaveBeenCalledWith(mockSource) + }) + + it('handles delete source action', () => { + store.showDeleteEventConfigSourceModal(mockSource) + expect(store.showDeleteEventConfigSourceModal).toHaveBeenCalledWith(mockSource) + }) + + it('renders pagination when sources exist', () => { + store.sources = [mockSource] + store.sourcesPagination = { page: 1, pageSize: 10, total: 15 } + expect(store.sourcesPagination.total).toBe(15) + }) + + it('handles page size changes', () => { + store.onSourcePageSizeChange(20) + expect(store.onSourcePageSizeChange).toHaveBeenCalledWith(20) + }) + + it('handles delete source action', async () => { + await store.showDeleteEventConfigSourceModal(mockSource) + expect(store.showDeleteEventConfigSourceModal).toHaveBeenCalledWith(mockSource) + }) + + it('handles enable/disable source action', async () => { + await store.showChangeEventConfigSourceStatusDialog(mockSource) + expect(store.showChangeEventConfigSourceStatusDialog).toHaveBeenCalledWith(mockSource) + }) + + it('renders table rows with correct data including status and event count', async () => { + store.sources = [mockSource, openNMSMockSource] + await wrapper.vm.$nextTick() + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(2) + + // First row + expect(rows[0].get('[data-test="view-button"]').isVisible()).toBe(true) + expect(rows[0].text()).toContain('TestSource') + expect(rows[0].text()).toContain('Cisco') + expect(rows[0].text()).toContain('Test description') + expect(rows[0].text()).toContain('5') + expect(rows[0].text()).toContain('Enabled') + + // Second row (OpenNMS, disabled, zero count, empty desc) + expect(rows[1].text()).toContain(openNMSMockSource.name) + expect(rows[1].text()).toContain(VENDOR_OPENNMS) + expect(rows[1].text()).toContain('') // Empty description + expect(rows[1].text()).toContain('0') + expect(rows[1].text()).toContain('Disabled') + }) + + it('handles search input changes with debouncing and calls onChangeSourcesSearchTerm', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + const searchInput = wrapper.get('[data-test="search-input"] .feather-input') + await searchInput.setValue('test') + vi.advanceTimersByTime(500) + await wrapper.vm.$nextTick() + + expect(store.onChangeSourcesSearchTerm).toHaveBeenCalledWith('test') + }) + + it('clicks view details button in row and navigates correctly', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + await wrapper.get('[data-test="view-button"]').trigger('click') + expect(detailStore.setSelectedEventConfigSource).toHaveBeenCalledWith(mockSource) + expect(mockPush).toHaveBeenCalledWith({ + name: 'Event Configuration Detail' + }) + }) + + it('clicks sort header and triggers onSourcesSortChange, resets other sorts', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + const sortHeader = wrapper.findAllComponents(FeatherSortHeader)[0] // First header (name) + await sortHeader.vm.$emit('sort-changed', { property: 'name', value: SORT.ASCENDING }) + await wrapper.vm.$nextTick() + + expect(store.onSourcesSortChange).toHaveBeenCalledWith('name', SORT.ASCENDING) + expect(wrapper.vm.sort.name).toBe(SORT.ASCENDING) + expect(wrapper.vm.sort.vendor).toBe(SORT.NONE) // Reset others + }) + + it('handles sort change for ascending and resets other sorts', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + wrapper.vm.sortChanged({ property: 'name', value: 'asc' }) + + expect(store.onSourcesSortChange).toHaveBeenCalledWith('name', 'asc') + expect(wrapper.vm.sort.name).toBe('asc') + expect(wrapper.vm.sort.vendor).toBe(SORT.NONE) + }) + + it('handles sort reset to default when value is none', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + wrapper.vm.sortChanged({ property: 'name', value: SORT.NONE }) + + expect(store.onSourcesSortChange).toHaveBeenCalledWith('createdTime', 'desc') + expect(wrapper.vm.sort.name).toBe(SORT.NONE) + }) + + it('renders dropdown for OpenNMS vendor with correct enable/disable text', async () => { + store.sources = [openNMSMockSource] + await wrapper.vm.$nextTick() + + const row = wrapper.find('transition-group-stub tr') + expect(row.exists()).toBe(true) + expect(row.findAll('button')).toHaveLength(3) + + expect(row.findAllComponents(FeatherDropdown)).toHaveLength(1) + + row.findAllComponents(FeatherDropdown)[0].findAll('button')[0].trigger('click') + await wrapper.vm.$nextTick() + + expect(row.findAllComponents(FeatherDropdownItem)).toHaveLength(1) + expect(row.findAllComponents(FeatherDropdownItem)[0].text()).toBe('Enable Source') + }) + + it('renders dropdown for non-OpenNMS vendor with correct enable/disable text', async () => { + const disabledSource = { ...mockSource, enabled: false } + store.sources = [mockSource, disabledSource] + await wrapper.vm.$nextTick() + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(2) + + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + + await buttons1[2].trigger('click') + await wrapper.vm.$nextTick() + + const dropdown1 = rows[0].findAllComponents(FeatherDropdownItem) + + expect(dropdown1[0].text()).toBe('Disable Source') + expect(dropdown1[1].text()).toBe('Delete Source') + + const buttons2 = rows[1].findAll('button') + expect(buttons2.length).toBe(3) + + await buttons2[2].trigger('click') + await wrapper.vm.$nextTick() + + const dropdown2 = rows[1].findAllComponents(FeatherDropdownItem) + expect(buttons1.length).toBe(3) + + expect(dropdown2[0].text()).toBe('Enable Source') + expect(dropdown2[1].text()).toBe('Delete Source') + }) + + it('clicks enable/disable from dropdown and calls showChangeEventConfigSourceStatusDialog', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + await rows[0].findAll('button')[2].trigger('click') + expect(rows[0].findAll('button')).toHaveLength(3) + await wrapper.vm.$nextTick() + + await wrapper.get('[data-test="change-status-button"]').trigger('click') + expect(store.showChangeEventConfigSourceStatusDialog).toHaveBeenCalledWith(mockSource) + }) + + it('clicks download from dropdown and calls downloadEventConfXmlBySourceId', async () => { + store.sources = [mockSource] + const svc = await import('@/services/eventConfigService') + vi.spyOn(svc, 'downloadEventConfXmlBySourceId').mockResolvedValue(false) + await wrapper.vm.$nextTick() + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + await rows[0].findAll('button')[1].trigger('click') + await wrapper.vm.$nextTick() + + expect(downloadEventConfXmlBySourceId).toHaveBeenCalled() + expect(svc.downloadEventConfXmlBySourceId).toHaveBeenCalledWith(mockSource.id) + }) + + it('clicks delete from dropdown and calls showDeleteEventConfigSourceModal', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + await rows[0].findAll('button')[2].trigger('click') + await wrapper.vm.$nextTick() + + await wrapper.get('[data-test="delete-source-button"]').trigger('click') + expect(store.showDeleteEventConfigSourceModal).toHaveBeenCalledWith(mockSource) + }) + + it('renders pagination with correct props and handles page change', async () => { + store.sources = [mockSource] + store.sourcesPagination = { page: 1, pageSize: 10, total: 15 } + await wrapper.vm.$nextTick() + + const pagination = wrapper.getComponent(FeatherPagination) + expect(pagination.props('modelValue')).toBe(1) + expect(pagination.props('pageSize')).toBe(10) + expect(pagination.props('total')).toBe(15) + + await pagination.vm.$emit('update:modelValue', 2) + expect(store.onSourcePageChange).toHaveBeenCalledWith(2) + }) + + it('handles page size change via pagination', async () => { + store.sources = [mockSource] + store.sourcesPagination = { page: 1, pageSize: 10, total: 15 } + await wrapper.vm.$nextTick() + + const pagination = wrapper.getComponent(FeatherPagination) + await pagination.vm.$emit('update:pageSize', 20) + expect(store.onSourcePageSizeChange).toHaveBeenCalledWith(20) + }) + + it('renders dialogs (DeleteEventConfigSourceDialog and ChangeEventConfigSourceStatusDialog)', () => { + expect(wrapper.findComponent({ name: 'DeleteEventConfigSourceDialog' }).exists()).toBe(true) + expect(wrapper.findComponent({ name: 'ChangeEventConfigSourceStatusDialog' }).exists()).toBe(true) + }) + + it('renders EmptyList when no sources are available', async () => { + store.sources = [] + await wrapper.vm.$nextTick() + + expect(wrapper.get('[data-test="empty-list"]').isVisible()).toBe(true) + expect(wrapper.text()).toContain('No results found.') + }) + + it('shows empty state after search with no results', async () => { + store.sources = [mockSource] + await wrapper.vm.$nextTick() + + const searchInput = wrapper.get('[data-test="search-input"] .feather-input') + await searchInput.setValue('nonexistent') + vi.advanceTimersByTime(500) + await flushPromises() + + store.sources = [] + await wrapper.vm.$nextTick() + + expect(wrapper.get('[data-test="empty-list"]').isVisible()).toBe(true) + expect(wrapper.text()).toContain('No results found.') + }) +}) + diff --git a/ui/tests/components/EventConfiguration/EventConfigTabContainer.test.ts b/ui/tests/components/EventConfiguration/EventConfigTabContainer.test.ts new file mode 100644 index 000000000000..a25bd3943c86 --- /dev/null +++ b/ui/tests/components/EventConfiguration/EventConfigTabContainer.test.ts @@ -0,0 +1,170 @@ +import { mount, VueWrapper } from '@vue/test-utils' +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigStore } from '@/stores/eventConfigStore' +import EventConfigTabContainer from '@/components/EventConfiguration/EventConfigTabContainer.vue' +import EventConfigSourceTable from '@/components/EventConfiguration/EventConfigSourceTable.vue' +import EventConfigUploadFilesTab from '@/components/EventConfiguration/EventConfigUploadFilesTab.vue' +import { FeatherTab, FeatherTabContainer, FeatherTabPanel } from '@featherds/tabs' +import { FeatherButton } from '@featherds/button' + +describe('EventConfigTabContainer', () => { + let wrapper: VueWrapper + let store: ReturnType + + beforeEach(() => { + const pinia = createTestingPinia({ + createSpy: vi.fn + }) + + vi.mock('vue-router', () => ({ + useRouter: () => vi.fn() + })) + + store = useEventConfigStore(pinia) + store.activeTab = 0 + wrapper = mount(EventConfigTabContainer, { + global: { + plugins: [pinia], + stubs: { + FeatherButton, + FeatherTab, + FeatherTabContainer, + FeatherTabPanel + } + } + }) + }) + + afterEach(() => { + wrapper.unmount() + vi.clearAllMocks() + }) + + it('renders correctly', () => { + expect(wrapper.exists()).toBe(true) + }) + + it('renders two tabs with correct labels', () => { + const tabs = wrapper.findAllComponents(FeatherTab) + expect(tabs).toHaveLength(2) + expect(tabs[0].text()).toBe('View') + expect(tabs[1].text()).toBe('Upload Files') + }) + + it('renders tab container with correct active tab', () => { + const tabContainer = wrapper.findComponent(FeatherTabContainer) + expect(tabContainer.exists()).toBe(true) + expect(tabContainer.props('modelValue')).toBe(0) + }) + + it('renders both tab panels', () => { + const tabPanels = wrapper.findAllComponents(FeatherTabPanel) + expect(tabPanels).toHaveLength(2) + }) + + it('renders EventConfigSourceTable in first tab panel', () => { + const sourceTable = wrapper.findComponent(EventConfigSourceTable) + expect(sourceTable.exists()).toBe(true) + }) + + it('renders EventConfigUploadFilesTab in second tab panel', () => { + const uploadFilesTab = wrapper.findComponent(EventConfigUploadFilesTab) + expect(uploadFilesTab.exists()).toBe(true) + }) + + it('updates active tab when tab is changed', async () => { + const tabContainer = wrapper.findComponent(FeatherTabContainer) + await tabContainer.setValue(1) + expect(store.activeTab).toBe(1) + }) + + it('renders the component without crashing', () => { + expect(wrapper.exists()).toBe(true) + expect(wrapper.classes()).toContain('event-config-tab-container') + }) + + it('renders with activeTab set to 1 initially (second tab active)', async () => { + store.activeTab = 1 + await wrapper.vm.$nextTick() + + const tabContainer = wrapper.findComponent(FeatherTabContainer) + const panels = tabContainer.findAllComponents(FeatherTabPanel) + + expect(panels.length).toBe(2) + + expect(panels[0].attributes('aria-expanded')).toBe('false') + expect(panels[1].attributes('aria-expanded')).toBe('true') + }) + + it('renders with activeTab set to 1 initially (second tab active)', async () => { + store.activeTab = 0 + await wrapper.vm.$nextTick() + + const tabContainer = wrapper.findComponent(FeatherTabContainer) + const panels = tabContainer.findAllComponents(FeatherTabPanel) + + expect(panels.length).toBe(2) + + expect(panels[0].attributes('aria-expanded')).toBe('true') + expect(panels[1].attributes('aria-expanded')).toBe('false') + }) + + it('does not crash if vue-router mock fails', () => { + // Temporarily break the mock to simulate import failure + vi.doMock('vue-router', () => ({ + useRouter: () => { + throw new Error('Mock fail') + } + })) + expect(() => { + wrapper = mount(EventConfigTabContainer, { + global: { + plugins: [createTestingPinia({ createSpy: vi.fn })], + stubs: { + /* ... same as before */ + } + } + }) + }).not.toThrow() // Or expect specific handling if component catches it + vi.doUnmock('vue-router') + }) + + it('gracefully handles missing Pinia plugin (no store)', () => { + wrapper = mount(EventConfigTabContainer, { + global: { + // No plugins: [pinia] provided + stubs: { + /* ... same as before */ + } + } + }) + // Expect no crash; component should render skeleton (tabs without reactivity) + expect(wrapper.exists()).toBe(true) + expect(wrapper.findComponent(FeatherTabContainer).exists()).toBe(true) + }) + + it('renders tab panels with correct data-test attributes', () => { + const sourcePanel = wrapper.find('.event-configuration-table') + const uploadPanel = wrapper.find('.upload-files-tab') + expect(sourcePanel.exists()).toBe(true) + expect(uploadPanel.exists()).toBe(true) + }) + + it('child components are not re-mounted unnecessarily on tab switch', async () => { + const sourceTable = wrapper.findComponent(EventConfigSourceTable) + const uploadFilesTab = wrapper.findComponent(EventConfigUploadFilesTab) + + // Since children are not stubbed and tabs likely use v-show (not v-if), check existence after switch + expect(sourceTable.exists()).toBe(true) + expect(uploadFilesTab.exists()).toBe(true) + + await wrapper.findComponent(FeatherTabContainer).setValue(1) + await wrapper.vm.$nextTick() + + // Both should still exist (no unmount/remount) + expect(sourceTable.exists()).toBe(true) + expect(uploadFilesTab.exists()).toBe(true) + }) +}) + diff --git a/ui/tests/components/EventConfiguration/EventConfigUploadFilesTab.test.ts b/ui/tests/components/EventConfiguration/EventConfigUploadFilesTab.test.ts new file mode 100644 index 000000000000..3a79d5fdc433 --- /dev/null +++ b/ui/tests/components/EventConfiguration/EventConfigUploadFilesTab.test.ts @@ -0,0 +1,1161 @@ +import EventConfigFilesUploadReportDialog from '@/components/EventConfiguration/Dialog/EventConfigFilesUploadReportDialog.vue' +import UploadedFileRenameDialog from '@/components/EventConfiguration/Dialog/UploadedFileRenameDialog.vue' +import EventConfigUploadFilesTab from '@/components/EventConfiguration/EventConfigUploadFilesTab.vue' +import { + isDuplicateFile, + MAX_FILES_UPLOAD, + validateEventConfigFile +} from '@/components/EventConfiguration/eventConfigXmlValidator' +import useSnackbar from '@/composables/useSnackbar' +import { uploadEventConfigFiles } from '@/services/eventConfigService' +import { useEventConfigStore } from '@/stores/eventConfigStore' +import { FeatherButton } from '@featherds/button' +import { FeatherIcon } from '@featherds/icon' +import CheckCircle from '@featherds/icon/action/CheckCircle' +import Delete from '@featherds/icon/action/Delete' +import Text from '@featherds/icon/file/Text' +import Apps from '@featherds/icon/navigation/Apps' +import Error from '@featherds/icon/notification/Error' +import Warning from '@featherds/icon/notification/Warning' +import { FeatherSpinner } from '@featherds/progress' +import { FeatherTooltip } from '@featherds/tooltip' +import { flushPromises, mount, VueWrapper } from '@vue/test-utils' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import Draggable from 'vuedraggable' + +vi.mock('@/stores/eventConfigStore') +vi.mock('@/components/EventConfiguration/eventConfigXmlValidator') +vi.mock('@/services/eventConfigService') +vi.mock('@/composables/useSnackbar') + +describe('EventConfigUploadFilesTab', () => { + let wrapper: VueWrapper + let store: ReturnType + let snackbar: ReturnType + + const mockFile = (name: string, type = 'text/xml', content = '') => { + return new File([content], name, { type }) + } + + beforeEach(() => { + store = reactive({ + uploadedSourceNames: [], + uploadedEventConfigFilesReportDialogState: { visible: false } + } as any) + vi.mocked(useEventConfigStore).mockReturnValue(store) + + snackbar = { + showSnackBar: vi.fn() + } as any + vi.mocked(useSnackbar).mockReturnValue(snackbar) + + vi.mocked(isDuplicateFile).mockReturnValue(false) + vi.mocked(validateEventConfigFile).mockResolvedValue({ isValid: true, errors: [] }) + vi.mocked(uploadEventConfigFiles).mockResolvedValue({ errors: [] as any, success: [] as any }) + + wrapper = mount(EventConfigUploadFilesTab, { + global: { + components: { + Draggable, + FeatherButton, + FeatherIcon, + FeatherSpinner, + FeatherTooltip, + EventConfigFilesUploadReportDialog, + UploadedFileRenameDialog + }, + provide: { + CheckCircle, + Delete, + Text, + Apps, + Error, + Warning + } + } + }) + }) + + afterEach(() => { + vi.clearAllMocks() + wrapper.unmount() + }) + + it('renders the component correctly', () => { + expect(wrapper.find('.upload-files-tab').exists()).toBe(true) + expect(wrapper.find('h2').text()).toBe('Upload Event Configuration Files') + expect(wrapper.find('.selected-files-section').exists()).toBe(true) + expect(wrapper.find('.upload-action-section').exists()).toBe(true) + expect(wrapper.find('.info-section').exists()).toBe(true) + }) + + it('displays "No files selected" when eventFiles is empty', () => { + expect(wrapper.find('.selected-files-section p').text()).toBe('No files selected') + }) + + it('renders file list when files are added', async () => { + const file = mockFile('test.events.xml') + vi.mocked(validateEventConfigFile).mockResolvedValue({ isValid: true, errors: [] }) + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + expect(wrapper.findAll('.file').length).toBe(1) + expect(wrapper.find('.file-icon span').text()).toContain('test.events.xml') + }) + + it('displays valid file icon for valid files', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + expect(wrapper.find('.success-icon').exists()).toBe(true) + }) + + it('displays error icon for invalid files', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: false, + errors: ['Invalid XML format'], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + expect(wrapper.find('.error-icon').exists()).toBe(true) + }) + + it('displays warning icon for duplicate files', async () => { + store.uploadedSourceNames = ['test.events.xml'] + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: true + }) + await wrapper.vm.$nextTick() + expect(wrapper.find('.warning-icon').exists()).toBe(true) + }) + + it('triggers file input click when "Choose files to upload" button is clicked', async () => { + const input = wrapper.find('input[type="file"]') + const spy = vi.spyOn(input.element as HTMLElement, 'click') + await wrapper.findComponent(FeatherButton).trigger('click') + expect(spy).toHaveBeenCalled() + }) + + it('disables upload button when no files are selected', () => { + expect(wrapper.find('[data-test="upload-button"]').attributes('aria-disabled')).toBe('true') + }) + + it('disables upload button when files are invalid', async () => { + await wrapper.vm.eventFiles.push({ + file: mockFile('test.events.xml'), + isValid: false, + errors: ['Invalid XML'], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + expect(wrapper.find('[data-test="upload-button"]').attributes('aria-disabled')).toBeDefined() + }) + + it('disables upload button when files are duplicates', async () => { + await wrapper.vm.eventFiles.push({ + file: mockFile('test.events.xml'), + isValid: true, + errors: [], + isDuplicate: true + }) + await wrapper.vm.$nextTick() + expect(wrapper.find('[data-test="upload-button"]').attributes('aria-disabled')).toBeDefined() + }) + + it('enables upload button when all files are valid and not duplicates', async () => { + await wrapper.vm.eventFiles.push({ + file: mockFile('test.events.xml'), + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + expect(wrapper.find('[data-test="upload-button"]').attributes('aria-disabled')).toBeUndefined() + }) + + it('handles file upload correctly', async () => { + const files = [mockFile('test1.events.xml'), mockFile('test2.events.xml')] + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: files, + writable: true + }) + await input.trigger('change') + expect(wrapper.vm.eventFiles.length).toBe(2) + expect(snackbar.showSnackBar).not.toHaveBeenCalled() + }) + + it('shows snackbar when max files limit is reached', async () => { + vi.mocked(validateEventConfigFile).mockClear().mockResolvedValue({ isValid: true, errors: [] }) + vi.mocked(isDuplicateFile).mockClear().mockReturnValue(false) + + expect(wrapper.vm.eventFiles.length).toBe(0) + const files = [ + mockFile('test1.events.xml'), + mockFile('test2.events.xml'), + mockFile('test3.events.xml'), + mockFile('test4.events.xml'), + mockFile('test5.events.xml'), + mockFile('test6.events.xml'), + mockFile('test7.events.xml'), + mockFile('test8.events.xml'), + mockFile('test9.events.xml'), + mockFile('test10.events.xml'), + mockFile('test11.events.xml') + ] + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: files, + writable: true + }) + await input.trigger('change') + await flushPromises() + + expect(wrapper.vm.eventFiles.length).toBe(MAX_FILES_UPLOAD) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: `You can upload a maximum of ${MAX_FILES_UPLOAD} files at a time.`, + error: true + }) + // Verify no unexpected error snackbars were shown + expect(snackbar.showSnackBar).not.toHaveBeenCalledWith( + expect.objectContaining({ msg: expect.stringContaining('Error processing file') }) + ) + }) + + it('removes file when remove button is clicked', async () => { + await wrapper.vm.eventFiles.push({ + file: mockFile('test.events.xml'), + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + await wrapper.find('[data-test="remove-files-button"]').trigger('click') + expect(wrapper.vm.eventFiles.length).toBe(0) + }) + + it('opens rename dialog when warning icon is clicked', async () => { + await wrapper.vm.eventFiles.push({ + file: mockFile('test.events.xml'), + isValid: true, + errors: [], + isDuplicate: true + }) + await wrapper.vm.$nextTick() + await wrapper.find('.warning-icon').trigger('click') + expect(wrapper.vm.displayRenameDialog).toBe(true) + }) + + it('handles file rename correctly', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: true + }) + wrapper.vm.selectedIndex = 0 + wrapper.vm.displayRenameDialog = true + await wrapper.vm.renameFile('newname.events.xml') + expect(wrapper.vm.eventFiles[0].file.name).toBe('newname.events.xml') + expect(wrapper.vm.displayRenameDialog).toBe(false) + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(false) + expect(snackbar.showSnackBar).not.toHaveBeenCalled() + expect(wrapper.vm.selectedIndex).toBe(null) + }) + + it('handles file overwrite correctly', async () => { + await wrapper.vm.eventFiles.push({ + file: mockFile('test.events.xml'), + isValid: true, + errors: [], + isDuplicate: true + }) + wrapper.vm.selectedIndex = 0 + wrapper.vm.displayRenameDialog = true + await wrapper.vm.overwriteFile() + expect(wrapper.vm.displayRenameDialog).toBe(false) + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(false) + expect(wrapper.vm.displayRenameDialog).toBe(false) + expect(snackbar.showSnackBar).not.toHaveBeenCalled() + expect(wrapper.vm.selectedIndex).toBe(null) + }) + + it('uploads valid files and clears the list', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.find('[data-test="upload-button"]').trigger('click') + expect(uploadEventConfigFiles).toHaveBeenCalledWith([file]) + expect(wrapper.vm.eventFiles.length).toBe(0) + expect(store.uploadedEventConfigFilesReportDialogState.visible).toBe(true) + }) + + it('shows spinner when uploading', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: false + }) + wrapper.vm.isLoading = true + await wrapper.vm.$nextTick() + expect(wrapper.findComponent(FeatherSpinner).exists()).toBe(true) + }) + + it('displays error snackbar on upload failure', async () => { + // Clear and set mock to reject + vi.mocked(uploadEventConfigFiles).mockClear() + vi.mocked(uploadEventConfigFiles).mockRejectedValue({ message: 'Upload failed' }) + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + await wrapper.find('[data-test="upload-button"]').trigger('click') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.isLoading).toBe(false) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error uploading files', + error: true + }) + }) + + it('resets file input after upload', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.find('[data-test="upload-button"]').trigger('click') + expect(wrapper.vm.eventConfFileInput.value).toBe('') + }) + + it('ellipsifies long file names', () => { + const longName = 'a'.repeat(50) + '.events.xml' + const result = wrapper.vm.ellipsify(longName, 39) + expect(result.length).toBeLessThanOrEqual(39) + expect(result).toContain('\u2026') + }) + + it('prevents upload if files are not .events.xml', async () => { + const file = mockFile('test.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.find('[data-test="upload-button"]').trigger('click') + expect(uploadEventConfigFiles).not.toHaveBeenCalled() + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'All files must be XML files with .events.xml extension', + error: true + }) + }) + + it('handles mixed valid, invalid, and duplicate files during upload', async () => { + store.uploadedSourceNames = ['duplicate.events.xml'] + vi.mocked(validateEventConfigFile).mockImplementation(async (file) => { + if (file.name.includes('invalid')) { + return { isValid: false, errors: ['Invalid XML schema'] } + } + return { isValid: true, errors: [] } + }) + vi.mocked(isDuplicateFile).mockImplementation((name) => name === 'duplicate.events.xml') + + const files = [ + mockFile('valid1.events.xml'), + mockFile('invalid.events.xml'), + mockFile('duplicate.events.xml'), + mockFile('valid2.events.xml') + ] + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: files, + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(3) + expect(wrapper.vm.eventFiles).toEqual([ + expect.objectContaining({ + file: expect.objectContaining({ name: 'valid1.events.xml' }), + isValid: true, + isDuplicate: false + }), + expect.objectContaining({ + file: expect.objectContaining({ name: 'invalid.events.xml' }), + isValid: false, + errors: ['Invalid XML schema'] + }), + expect.objectContaining({ + file: expect.objectContaining({ name: 'valid2.events.xml' }), + isValid: true, + isDuplicate: false + }) + ]) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file invalid.events.xml.', + error: true + }) + expect(wrapper.find('[data-test="upload-button"]').attributes('aria-disabled')).toBeDefined() + }) + + it('handles invalid XML syntax during file upload', async () => { + const file = mockFile('invalid.events.xml', 'text/xml', 'invalid xml root element', async () => { + const file = mockFile('noevents.events.xml', 'text/xml', '') + vi.mocked(validateEventConfigFile).mockResolvedValue({ + isValid: false, + errors: ['Missing root element'] + }) + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: [file], + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0]).toEqual( + expect.objectContaining({ + file: expect.objectContaining({ name: 'noevents.events.xml' }), + isValid: false, + errors: ['Missing root element'], + isDuplicate: false + }) + ) + expect(wrapper.find('.error-icon').exists()).toBe(true) + expect(wrapper.findComponent(FeatherTooltip).vm.title).toContain('Missing root element') + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file noevents.events.xml.', + error: true + }) + }) + + it('handles invalid OpenNMS namespace', async () => { + const file = mockFile('wrongns.events.xml', 'text/xml', '') + vi.mocked(validateEventConfigFile).mockResolvedValue({ + isValid: false, + errors: ['Missing or invalid OpenNMS namespace in element'] + }) + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: [file], + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0]).toEqual( + expect.objectContaining({ + file: expect.objectContaining({ name: 'wrongns.events.xml' }), + isValid: false, + errors: ['Missing or invalid OpenNMS namespace in element'], + isDuplicate: false + }) + ) + expect(wrapper.find('.error-icon').exists()).toBe(true) + expect(wrapper.findComponent(FeatherTooltip).vm.title).toContain('Missing or invalid OpenNMS namespace') + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file wrongns.events.xml.', + error: true + }) + }) + + it('handles missing elements with other content', async () => { + const file = mockFile( + 'noevent.events.xml', + 'text/xml', + '' + ) + vi.mocked(validateEventConfigFile).mockResolvedValue({ + isValid: false, + errors: [ + 'No entries found within element', + ' element contains but no elements' + ] + }) + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: [file], + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0]).toEqual( + expect.objectContaining({ + file: expect.objectContaining({ name: 'noevent.events.xml' }), + isValid: false, + errors: [ + 'No entries found within element', + ' element contains but no elements' + ], + isDuplicate: false + }) + ) + expect(wrapper.find('.error-icon').exists()).toBe(true) + expect(wrapper.findComponent(FeatherTooltip).vm.title).toContain('No entries found') + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file noevent.events.xml.', + error: true + }) + }) + + it('handles element with missing required fields', async () => { + const file = mockFile( + 'badevent.events.xml', + 'text/xml', + 'uei.opennms.org/test' + ) + vi.mocked(validateEventConfigFile).mockResolvedValue({ + isValid: false, + errors: ['Event 1: missing , missing '] + }) + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: [file], + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0]).toEqual( + expect.objectContaining({ + file: expect.objectContaining({ name: 'badevent.events.xml' }), + isValid: false, + errors: ['Event 1: missing , missing '], + isDuplicate: false + }) + ) + expect(wrapper.find('.error-icon').exists()).toBe(true) + expect(wrapper.findComponent(FeatherTooltip).vm.title).toContain( + 'Event 1: missing , missing ' + ) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file badevent.events.xml.', + error: true + }) + }) + + it('handles case-insensitive duplicate files', async () => { + vi.mocked(isDuplicateFile).mockImplementation((name, existingFiles) => + existingFiles.some((f) => f.file.name.toLowerCase() === name.toLowerCase()) + ) + const files = [mockFile('test.events.xml'), mockFile('TEST.events.xml'), mockFile('test.EVENTS.XML')] + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: files, + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0].file.name).toBe('test.events.xml') + expect(snackbar.showSnackBar).not.toHaveBeenCalled() + }) + + it('handles file reading error during validation', async () => { + vi.mocked(validateEventConfigFile).mockRejectedValue({ message: 'Failed to read file' }) + const file = mockFile('unreadable.events.xml') + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: [file], + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(0) + expect(wrapper.find('.error-icon').exists()).toBe(false) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file unreadable.events.xml.', + error: true + }) + }) + + it('handles large file list with mixed validation outcomes', async () => { + store.uploadedSourceNames = ['duplicate.events.xml'] + vi.mocked(validateEventConfigFile).mockImplementation(async (file) => { + if (file.name.includes('invalid')) { + return { isValid: false, errors: ['Invalid XML schema'] } + } + if (file.name.includes('badevent')) { + return { isValid: false, errors: ['Event 1: missing '] } + } + return { isValid: true, errors: [] } + }) + vi.mocked(isDuplicateFile).mockImplementation((name, existingFiles) => + existingFiles.some((element) => element.file.name.toLowerCase() === name.toLowerCase()) + ) + + const files = [ + mockFile('valid1.events.xml'), // Valid + mockFile('invalid.events.xml'), // Invalid (triggers snackbar) + mockFile('duplicate.events.xml'), // Duplicate (skipped) + mockFile('badevent.events.xml'), // Invalid (triggers snackbar) + mockFile('valid2.events.xml'), // Valid + ...Array.from({ length: 7 }, (_, i) => mockFile(`valid${i + 3}.events.xml`)) // 7 more valid files + ] + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: files, + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(MAX_FILES_UPLOAD) + expect(wrapper.vm.eventFiles).toContainEqual( + expect.objectContaining({ file: expect.objectContaining({ name: 'invalid.events.xml' }), isValid: false }) + ) + expect(wrapper.vm.eventFiles).toContainEqual( + expect.objectContaining({ file: expect.objectContaining({ name: 'badevent.events.xml' }), isValid: false }) + ) + expect(snackbar.showSnackBar).toHaveBeenCalledTimes(3) // invalid, badevent, max files + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file invalid.events.xml.', + error: true + }) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file badevent.events.xml.', + error: true + }) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: `You can upload a maximum of ${MAX_FILES_UPLOAD} files at a time.`, + error: true + }) + }) + + it('handles rapid file uploads with validation and rename', async () => { + store.uploadedSourceNames = ['test.events.xml'] + vi.mocked(validateEventConfigFile).mockImplementation(async (file) => ({ + isValid: !file.name.includes('invalid'), + errors: file.name.includes('invalid') ? ['Invalid XML'] : [] + })) + vi.mocked(isDuplicateFile).mockImplementation((name, existingFiles) => + existingFiles.some((element) => element.file.name.toLowerCase() === name.toLowerCase()) + ) + + const firstBatch = [mockFile('test.events.xml'), mockFile('invalid.events.xml')] + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: firstBatch, + writable: true + }) + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(2) + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(true) + expect(wrapper.vm.eventFiles[1].isValid).toBe(false) + + // Rename duplicate file + wrapper.vm.selectedIndex = 0 + wrapper.vm.displayRenameDialog = true + await wrapper.vm.renameFile('renamed.events.xml') + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles[0].file.name).toBe('renamed.events.xml') + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(false) + + // Upload second batch + const secondBatch = [mockFile('new.events.xml')] + Object.defineProperty(input.element, 'files', { + value: secondBatch, + writable: true + }) + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(3) + expect(wrapper.vm.eventFiles.map((f: any) => f.file.name)).toEqual([ + 'renamed.events.xml', + 'invalid.events.xml', + 'new.events.xml' + ]) + }) + + it('handles upload with mixed file types and validation', async () => { + const files = [ + mockFile( + 'valid.events.xml', + 'text/xml', + 'uei.opennms.org/testTestMinor' + ), + mockFile('invalid.txt', 'text/plain', 'not xml'), + mockFile('noevent.xml', 'text/xml', '') + ] + vi.mocked(validateEventConfigFile).mockImplementation(async (file) => { + if (file.name.endsWith('.txt')) { + return { + isValid: false, + errors: ['File does not appear to be an event configuration file (expected .events.xml extension)'] + } + } + if (file.name.includes('noevent')) { + return { + isValid: false, + errors: ['No entries found within element', 'Empty element - no content found'] + } + } + return { isValid: true, errors: [] } + }) + + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { + value: files, + writable: true + }) + + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + + expect(wrapper.vm.eventFiles.length).toBe(3) + expect(wrapper.vm.eventFiles).toEqual([ + expect.objectContaining({ file: expect.objectContaining({ name: 'valid.events.xml' }), isValid: true }), + expect.objectContaining({ file: expect.objectContaining({ name: 'invalid.txt' }), isValid: false }), + expect.objectContaining({ file: expect.objectContaining({ name: 'noevent.xml' }), isValid: false }) + ]) + expect(snackbar.showSnackBar).toHaveBeenCalledTimes(2) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file invalid.txt.', + error: true + }) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file noevent.xml.', + error: true + }) + expect(wrapper.findAll('.error-icon').length).toBe(2) + }) + + it('reorders files when dragged', async () => { + // Add files to eventFiles + const file1 = { file: mockFile('file1.events.xml'), isValid: true, errors: [], isDuplicate: false } + const file2 = { file: mockFile('file2.events.xml'), isValid: true, errors: [], isDuplicate: false } + await wrapper.vm.eventFiles.push(file1, file2) + await wrapper.vm.$nextTick() + + // Find the Draggable component + const draggable = wrapper.findComponent(Draggable) + + // Emit update:modelValue event with reversed order + draggable.vm.$emit('update:modelValue', [file2, file1]) + await wrapper.vm.$nextTick() + + // Verify the new order + expect(wrapper.vm.eventFiles.map((f: any) => f.file.name)).toEqual(['file2.events.xml', 'file1.events.xml']) + }) + + it('handles empty file content', async () => { + const file = mockFile('empty.events.xml', 'text/xml', '') + vi.mocked(validateEventConfigFile).mockResolvedValue({ + isValid: false, + errors: ['File is empty'] + }) + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { value: [file], writable: true }) + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + expect(wrapper.vm.eventFiles[0]).toEqual( + expect.objectContaining({ + file: expect.objectContaining({ name: 'empty.events.xml' }), + isValid: false, + errors: ['File is empty'] + }) + ) + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file empty.events.xml.', + error: true + }) + }) + + it('allows re-uploading the same file after selection', async () => { + const file = mockFile('test.events.xml') + const input = wrapper.find('input[type="file"]') + + // First file selection + Object.defineProperty(input.element, 'files', { value: [file], writable: true }) + await input.trigger('change') + await flushPromises() + + // Verify file was added + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0].file.name).toBe('test.events.xml') + + // Second file selection (same file) + Object.defineProperty(input.element, 'files', { value: [file], writable: true }) + await input.trigger('change') + await flushPromises() + + // Verify file was added again (proves reset worked) + expect(wrapper.vm.eventFiles.length).toBe(2) + expect(wrapper.vm.eventFiles[1].file.name).toBe('test.events.xml') + }) + + it('resets file input after selection', async () => { + const file = mockFile('test.events.xml') + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { value: [file], writable: true }) + await input.trigger('change') + await flushPromises() + expect((input.element as HTMLInputElement).files).toBeNull() + }) + + it('displays multiple errors in tooltip for invalid file', async () => { + const file = mockFile('badevent.events.xml', 'text/xml', '') + vi.mocked(validateEventConfigFile).mockResolvedValue({ + isValid: false, + errors: ['Event 1: missing ', 'Event 1: missing ', 'Event 1: missing '] + }) + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { value: [file], writable: true }) + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + const tooltip = wrapper.findComponent(FeatherTooltip) + expect(tooltip.vm.title).toContain( + 'Event 1: missing . \nEvent 1: missing . \nEvent 1: missing . ' + ) + }) + + it('handles large file validation', async () => { + const largeContent = + '' + + 'uei.opennms.org/testTestMinor'.repeat( + 1000 + ) + + '' + const file = mockFile('large.events.xml', 'text/xml', largeContent) + vi.mocked(validateEventConfigFile).mockResolvedValue({ isValid: true, errors: [] }) + const input = wrapper.find('input[type="file"]') + Object.defineProperty(input.element, 'files', { value: [file], writable: true }) + await input.trigger('change') + await flushPromises() + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0].isValid).toBe(true) + expect(snackbar.showSnackBar).not.toHaveBeenCalled() + }) + + it('prevents concurrent uploads', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ file, isValid: true, errors: [], isDuplicate: false }) + wrapper.vm.isLoading = true + await wrapper.vm.$nextTick() + expect(wrapper.find('[data-test="upload-button"]').attributes('aria-disabled')).toBe('true') + await wrapper.find('[data-test="upload-button"]').trigger('click') + expect(uploadEventConfigFiles).not.toHaveBeenCalled() + }) + + it('updates duplicate status when store.uploadedSourceNames changes', async () => { + // Add a file + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ file, isValid: true, errors: [], isDuplicate: false }) + await wrapper.vm.$nextTick() + + // Update the reactive store + store.uploadedSourceNames = ['test.events.xml'] + await wrapper.vm.$nextTick() + + // Verify isDuplicate and UI + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(true) + expect(wrapper.find('.warning-icon').exists()).toBe(true) + }) + + it('closes rename dialog without changes', async () => { + await wrapper.vm.eventFiles.push({ + file: mockFile('test.events.xml'), + isValid: true, + errors: [], + isDuplicate: true + }) + wrapper.vm.selectedIndex = 0 + wrapper.vm.displayRenameDialog = true + await wrapper.vm.closeRenameDialog() + expect(wrapper.vm.displayRenameDialog).toBe(false) + expect(wrapper.vm.selectedIndex).toBe(null) + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(true) + }) + + it('does not log warnings when clicking disabled upload button', async () => { + const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + await wrapper.find('[data-test="upload-button"]').trigger('click') + expect(consoleWarnSpy).not.toHaveBeenCalled() + expect(consoleErrorSpy).not.toHaveBeenCalled() + consoleWarnSpy.mockRestore() + consoleErrorSpy.mockRestore() + }) + + it('logs console error for non-.events.xml files on upload attempt', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + await wrapper.vm.eventFiles.push({ + file: mockFile('test.xml'), + isValid: true, + errors: [], + isDuplicate: false + }) + await wrapper.vm.$nextTick() + await wrapper.find('[data-test="upload-button"]').trigger('click') + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'All files must be XML files with .events.xml extension', + error: true + }) + consoleErrorSpy.mockRestore() + }) + + it('', async () => { + const firstFile = mockFile('test.events.xml') + const secondFile = mockFile('test.events.xml') + const input = wrapper.find('input[type="file"]') + vi.mocked(validateEventConfigFile) + .mockClear() + .mockImplementation(async (file) => { + if (file.name === 'test.events.xml' && file === firstFile) { + return { isValid: true, errors: [] } + } + if (file.name === 'test.events.xml' && file === secondFile) { + return { isValid: false, errors: ['No entries found within element'] } + } + if (file.name === 'renamed.events.xml') { + return { isValid: false, errors: ['No entries found within element'] } + } + return { isValid: true, errors: [] } + }) + Object.defineProperty(input.element, 'files', { value: [firstFile], writable: true }) + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + expect(wrapper.vm.eventFiles.length).toBe(1) + + await wrapper.find('[data-test="upload-button"]').trigger('click') + + expect(uploadEventConfigFiles).toHaveBeenCalledWith([firstFile]) + expect(wrapper.vm.eventFiles.length).toBe(0) + expect(store.uploadedEventConfigFilesReportDialogState.visible).toBe(true) + + // Simulate closing the report dialog + store.uploadedEventConfigFilesReportDialogState.visible = false + await wrapper.vm.$nextTick() + expect(store.uploadedEventConfigFilesReportDialogState.visible).toBe(false) + + store.uploadedSourceNames = ['test.events.xml'] + // Re-upload the same file + Object.defineProperty(input.element, 'files', { value: [secondFile], writable: true }) + await input.trigger('change') + await flushPromises() + await wrapper.vm.$nextTick() + expect(wrapper.vm.eventFiles.length).toBe(1) + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(true) + expect(wrapper.vm.eventFiles[0].isValid).toBe(false) + expect(wrapper.find('.warning-icon').exists()).toBe(true) + expect(wrapper.find('.error-icon').exists()).toBe(true) + expect(snackbar.showSnackBar).toHaveBeenCalled() + expect(snackbar.showSnackBar).toHaveBeenCalledWith({ + msg: 'Error processing file test.events.xml.', + error: true + }) + // There should be two tooltips - one for warning, one for error + expect(wrapper.findAllComponents(FeatherTooltip).length).toBe(2) + // The warning tooltip should show the duplicate message + expect(wrapper.findAllComponents(FeatherTooltip)[0].vm.title).toContain( + 'File is a duplicate of another file that has been already uploaded.' + ) + // The error tooltip should show the error message + expect(wrapper.findAllComponents(FeatherTooltip)[1].vm.title).toContain( + 'No entries found within element' + ) + expect(snackbar.showSnackBar).toHaveBeenCalled() + + wrapper.vm.selectedIndex = 0 + wrapper.vm.displayRenameDialog = true + await wrapper.vm.renameFile('renamed.events.xml') + await flushPromises() + await wrapper.vm.$nextTick() + expect(wrapper.vm.displayRenameDialog).toBe(false) + expect(wrapper.vm.eventFiles[0].file.name).toBe('renamed.events.xml') + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(false) + expect(wrapper.vm.eventFiles[0].isValid).toBe(false) + expect(wrapper.find('.warning-icon').exists()).toBe(false) + expect(wrapper.find('.error-icon').exists()).toBe(true) + expect(wrapper.findComponent(FeatherTooltip).vm.title).toContain('No entries found within element') + expect(snackbar.showSnackBar).toHaveBeenCalledTimes(1) // only one error + }) + + // NEW: Upload with mixed success/errors in response + it('handles upload response with partial success and errors', async () => { + const validFile = mockFile('valid.events.xml') + const invalidFile = mockFile('invalid.events.xml') // But filter skips it + await wrapper.vm.eventFiles.push( + { file: validFile, isValid: true, errors: [], isDuplicate: false }, + { file: invalidFile, isValid: false, errors: ['Invalid'], isDuplicate: false } + ) + await wrapper.vm.$nextTick() + await wrapper.find('[data-test="upload-button"]').trigger('click') + await flushPromises() + expect(uploadEventConfigFiles).not.toHaveBeenCalled() + expect(store.uploadedEventConfigFilesReportDialogState.visible).toBe(false) + }) + + it('handles drag on empty or single file list without changes', async () => { + // Empty: no drag possible + expect(wrapper.findComponent(Draggable).exists()).toBe(false) + await wrapper.vm.$nextTick() + expect(wrapper.vm.eventFiles.length).toBe(0) + + // Single: drag should no-op + const file = { file: mockFile('single.events.xml'), isValid: true, errors: [], isDuplicate: false } + await wrapper.vm.eventFiles.push(file) + await wrapper.vm.$nextTick() + const draggable = wrapper.findComponent(Draggable) + draggable.vm.$emit('update:modelValue', [file]) // Same order + await wrapper.vm.$nextTick() + expect(wrapper.vm.eventFiles).toEqual([file]) + }) + + it('re-validates renamed file with non-XML type', async () => { + const nonXmlFile = mockFile('test.txt', 'text/plain') // Bypass via manual push + await wrapper.vm.eventFiles.push({ + file: nonXmlFile, + isValid: true, // Initial mock + errors: [], + isDuplicate: true + }) + wrapper.vm.selectedIndex = 0 + wrapper.vm.displayRenameDialog = true + vi.mocked(validateEventConfigFile).mockResolvedValueOnce({ + isValid: false, + errors: ['File does not appear to be an event configuration file (expected .events.xml extension)'] + }) + await wrapper.vm.renameFile('renamed.events.xml') + await wrapper.vm.$nextTick() + expect(wrapper.vm.eventFiles[0].file.name).toBe('renamed.events.xml') + expect(wrapper.vm.eventFiles[0].file.type).toBe('text/plain') // Preserves type + expect(wrapper.vm.eventFiles[0].isValid).toBe(false) + expect(wrapper.vm.eventFiles[0].errors).toEqual(['File does not appear to be an event configuration file (expected .events.xml extension)']) + }) + + it('updates duplicates reactively during ongoing upload', async () => { + const file = mockFile('test.events.xml') + await wrapper.vm.eventFiles.push({ file, isValid: true, errors: [], isDuplicate: false }) + wrapper.vm.isLoading = true // Simulate upload start + store.uploadedSourceNames = ['test.events.xml'] // Trigger watch + await wrapper.vm.$nextTick() + expect(wrapper.vm.eventFiles[0].isDuplicate).toBe(true) // Updates even mid-upload + wrapper.vm.isLoading = false // End upload + expect(wrapper.find('[data-test="upload-button"]').attributes('aria-disabled')).toBe('true') // Still disabled due to dupe + }) + + it('shows blank tooltip for invalid file with no errors', async () => { + const file = mockFile('noerror.events.xml') + await wrapper.vm.eventFiles.push({ + file, + isValid: false, + errors: [], // Empty + isDuplicate: false + }) + await wrapper.vm.$nextTick() + expect(wrapper.find('.error-icon').exists()).toBe(true) + const tooltip = wrapper.findComponent(FeatherTooltip) + expect(tooltip.vm.title).toBe('') // Joins empty → blank; could enhance code to 'Validation failed' if needed + }) + + it('logs error on invalid index in rename/overwrite', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + wrapper.vm.selectedIndex = -1 // Invalid + wrapper.vm.displayRenameDialog = true + await wrapper.vm.renameFile('new.events.xml') + expect(consoleErrorSpy).toHaveBeenCalledWith('Invalid index for renaming file') + await wrapper.vm.overwriteFile() + expect(consoleErrorSpy).toHaveBeenCalledWith('Invalid index for overwriting file') + consoleErrorSpy.mockRestore() + }) +}) + diff --git a/ui/tests/components/EventConfiguration/eventConfigXmlValidator.test.ts b/ui/tests/components/EventConfiguration/eventConfigXmlValidator.test.ts new file mode 100644 index 000000000000..8a6eee5ed390 --- /dev/null +++ b/ui/tests/components/EventConfiguration/eventConfigXmlValidator.test.ts @@ -0,0 +1,548 @@ +import { + isDuplicateFile, + MAX_FILES_UPLOAD, + validateEventConfigFile, + validateEventElement +} from '@/components/EventConfiguration/eventConfigXmlValidator' +import { UploadEventFileType } from '@/types/eventConfig' +import { ValidationError } from 'fast-xml-parser' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +describe('eventConfigXmlValidator', () => { + let mockFile: File + + // Helper to create a mock File + const createMockFile = (name: string, content: string, type = 'text/xml') => { + return new File([content], name, { type }) + } + + beforeEach(() => { + vi.spyOn(File.prototype, 'text').mockRestore() + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + describe('MAX_FILES_UPLOAD', () => { + it('has correct value', () => { + expect(MAX_FILES_UPLOAD).toBe(10) + }) + }) + + describe('validateEventConfigFile', () => { + it('rejects empty file content', async () => { + mockFile = createMockFile('empty.events.xml', '') + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['File is empty'] + }) + }) + + it('rejects whitespace-only file content', async () => { + mockFile = createMockFile('whitespace.events.xml', ' \n\t ') + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['File is empty'] + }) + }) + + it('rejects non-.events.xml file extension without "event"', async () => { + mockFile = createMockFile('test.xml', '') + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['File does not appear to be an event configuration file (expected .events.xml extension)'] + }) + }) + + it('accepts file name with "event" but not .events.xml', async () => { + mockFile = createMockFile( + 'eventconfig.xml', + 'uei.opennms.org/testTestMinorDescription' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: true, + errors: [] + }) + }) + + it('rejects missing root element', async () => { + mockFile = createMockFile('noevents.events.xml', '') + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Missing root element'] + }) + }) + + it('rejects missing namespace', async () => { + mockFile = createMockFile('nons.events.xml', '') + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Missing or invalid OpenNMS namespace in element'] + }) + }) + + it('rejects incorrect namespace', async () => { + mockFile = createMockFile('wrongns.events.xml', '') + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Missing or invalid OpenNMS namespace in element'] + }) + }) + + it('rejects empty element', async () => { + mockFile = createMockFile( + 'noevent.events.xml', + '' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['No entries found within element'] + }) + }) + + it('rejects with non- children', async () => { + mockFile = createMockFile( + 'other.events.xml', + '' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: [' element contains but no elements'] + }) + }) + + it('rejects with multiple non- children', async () => { + mockFile = createMockFile( + 'multiple.events.xml', + '' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: [' element contains , but no elements'] + }) + }) + + it('validates file with correct structure', async () => { + mockFile = createMockFile( + 'valid.events.xml', + 'uei.opennms.org/testTestMinorDescription' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: true, + errors: [] + }) + }) + + it('rejects missing uei', async () => { + mockFile = createMockFile( + 'badevent.events.xml', + 'TestMinor' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Event 1: missing '] + }) + }) + + it('rejects missing event-label', async () => { + mockFile = createMockFile( + 'badevent.events.xml', + 'uei.opennms.org/testMinor' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Event 1: missing '] + }) + }) + + it('rejects missing severity', async () => { + mockFile = createMockFile( + 'badevent.events.xml', + 'uei.opennms.org/testTest' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Event 1: missing '] + }) + }) + + it('stops validation after first invalid event', async () => { + mockFile = createMockFile( + 'mixed.events.xml', + '' + + 'uei.opennms.org/test1Test1MinorDescription' + + 'uei.opennms.org/test2' + + '' + + '' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Event 2: missing '] + }) + }) + + it('handles file reading error', async () => { + mockFile = createMockFile('error.events.xml', '') + vi.spyOn(File.prototype, 'text').mockRejectedValue(new Error('File read error')) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Error reading file content: File read error'] + }) + }) + + it('handles large file with many events', async () => { + const eventXml = + 'uei.opennms.org/testTestMinorDescription' + const largeContent = `${eventXml.repeat(1000)}` + mockFile = createMockFile('large.events.xml', largeContent) + // Explicitly mock file.text() to ensure it works in happy-dom + vi.spyOn(mockFile, 'text').mockResolvedValue(largeContent) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: true, + errors: [] + }) + }) + + it('handles XML with comments and CDATA', async () => { + const xmlContent = + 'TestMinorDescription' + mockFile = createMockFile('comments.events.xml', xmlContent) + // Explicitly mock file.text() to ensure it works in happy-dom + vi.spyOn(mockFile, 'text').mockResolvedValue(xmlContent) + // Mock DOMParser to handle CDATA correctly + vi.spyOn(global, 'DOMParser').mockImplementation(() => { + return { + parseFromString: () => ({ + querySelector: (selector: string) => { + if (selector === 'parsererror') return null + if (selector === 'events') { + return { + getAttribute: () => 'http://xmlns.opennms.org/xsd/eventconf', + querySelectorAll: () => [ + { + querySelector: (sel: string) => { + if (sel === 'uei') return { textContent: 'uei.opennms.org/test' } + if (sel === 'event-label') return { textContent: 'Test' } + if (sel === 'severity') return { textContent: 'Minor' } + if (sel === 'descr') return { textContent: 'Description' } + return null + } + } + ], + children: [ + { + tagName: 'event' + } + ] + } + } + return null + } + }) + } as any + }) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: true, + errors: [] + }) + vi.restoreAllMocks() + }) + + it('rejects with whitespace-only fields', async () => { + mockFile = createMockFile( + 'whitespace.events.xml', + ' ' + ) + // Explicitly mock file.text() to ensure it works in happy-dom + vi.spyOn(mockFile, 'text').mockResolvedValue( + ' ' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Event 1: missing '] + }) + }) + + it('rejects with empty fields', async () => { + mockFile = createMockFile( + 'emptyfields.events.xml', + '' + ) + // Explicitly mock file.text() to ensure it works in happy-dom + vi.spyOn(mockFile, 'text').mockResolvedValue( + '' + ) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Event 1: missing '] + }) + }) + + it('rejects invalid XML syntax via DOMParser parsererror', async () => { + const invalidContent = 'unclosed' + mockFile = createMockFile('syntaxerror.events.xml', invalidContent) + vi.spyOn(mockFile, 'text').mockResolvedValue(invalidContent) + // Mock DOMParser to simulate parsererror (in real jsdom, it sets a parsererror node for malformed XML) + vi.spyOn(global, 'DOMParser').mockImplementation(() => ({ + parseFromString: () => { + // Create a minimal Document mock with querySelector for parsererror + return Object.assign(document.implementation.createDocument(null, '', null), { + querySelector: (selector: string) => { + if (selector === 'parsererror') { + // Simulate parsererror node + return document.createElement('parsererror') + } + return null + } + }) + } + })) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Invalid XML format - file contains syntax errors'] + }) + }) + + it('rejects invalid XML via XMLValidator failure without parsererror', async () => { + const invalidContent = '' // Duplicate attribute + mockFile = createMockFile('validatorfail.events.xml', invalidContent) + vi.spyOn(mockFile, 'text').mockResolvedValue(invalidContent) + // Mock DOMParser to parse without error (for coverage of line ~26), but assume XMLValidator catches duplicate attr + vi.spyOn(global, 'DOMParser').mockImplementation(() => ({ + parseFromString: () => { + // Create a minimal Document mock with querySelector for parsererror + return Object.assign(document.implementation.createDocument(null, '', null), { + querySelector: (selector: string) => { + if (selector === 'parsererror') { + // Simulate parsererror node + return document.createElement('parsererror') + } + return null + } + }) + } + })) + // Mock XMLValidator to return false for this case + const { XMLValidator } = await import('fast-xml-parser') + vi.spyOn(XMLValidator, 'validate').mockReturnValue({ err: { msg: 'Duplicate attribute' } } as ValidationError) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Invalid XML format - file contains syntax errors'] + }) + }) + + it('validates multiple events where only the last is invalid to cover full loop continuation', async () => { + const validEvent = 'uei1Label1MinorDescription' + const invalidEvent = 'uei2Minor' + const content = `${validEvent}${validEvent}${invalidEvent}` + mockFile = createMockFile('lastinvalid.events.xml', content) + vi.spyOn(mockFile, 'text').mockResolvedValue(content) + const result = await validateEventConfigFile(mockFile) + // Since it stops on first error (third event), but this covers the loop continuing through first two valid iterations + expect(result).toEqual({ + isValid: false, + errors: ['Event 3: missing '] + }) + }) + + it('handles exception during event element querySelector in loop', async () => { + // To cover potential deep errors in loop (though validateEventElement is safe, simulate query fail) + const content = + 'ueiLabelMinor' + mockFile = createMockFile('queryerror.events.xml', content) + vi.spyOn(mockFile, 'text').mockResolvedValue(content) + vi.spyOn(global, 'DOMParser').mockImplementation(() => ({ + parseFromString: () => + ({ + querySelector: (selector: string) => { + if (selector === 'parsererror') return null + if (selector === 'events') { + return { + getAttribute: () => 'http://xmlns.opennms.org/xsd/eventconf', + querySelectorAll: () => { + // Properly mock NodeListOf + const nodeList: any = [ + { + tagName: 'event', + querySelector: vi + .fn() + .mockImplementationOnce(() => ({ textContent: 'uei' })) // uei ok + .mockImplementationOnce(() => { + throw new Error('Query error') + }) // event-label throws + .mockImplementationOnce(() => ({ textContent: 'Minor' })) // severity would be next, but throws before + } + ] + ;(nodeList as any).item = (index: number) => nodeList[index] || null + ;(nodeList as any).forEach = (callback: any, thisArg?: any) => { + for (let i = 0; i < nodeList.length; i++) { + callback.call(thisArg, nodeList[i], i, nodeList) + } + } + ;(nodeList as any).length = 1 + return nodeList as NodeListOf + }, + children: [ + { + tagName: 'event' + } + ] + } + } + return null + } + }) as any + })) + const result = await validateEventConfigFile(mockFile) + expect(result).toEqual({ + isValid: false, + errors: ['Error reading file content: Query error'] + }) + }) + }) + + describe('validateEventElement', () => { + let parser: DOMParser + let mockElement: Element + + beforeEach(() => { + parser = new DOMParser() + }) + + it('validates event with all required fields', () => { + const xml = + 'uei.opennms.org/testTestMinorDescription' + mockElement = parser.parseFromString(xml, 'application/xml').querySelector('event')! + const errors = validateEventElement(mockElement, 1) + expect(errors).toBe('') + }) + + it('rejects event missing uei', () => { + const xml = 'TestMinor' + mockElement = parser.parseFromString(xml, 'application/xml').querySelector('event')! + const errors = validateEventElement(mockElement, 1) + expect(errors).toBe('Event 1: missing ') + }) + + it('rejects event missing event-label', () => { + const xml = 'uei.opennms.org/testMinor' + mockElement = parser.parseFromString(xml, 'application/xml').querySelector('event')! + const errors = validateEventElement(mockElement, 2) + expect(errors).toBe('Event 2: missing ') + }) + + it('rejects event missing severity', () => { + const xml = 'uei.opennms.org/testTest' + mockElement = parser.parseFromString(xml, 'application/xml').querySelector('event')! + const errors = validateEventElement(mockElement, 3) + expect(errors).toBe('Event 3: missing ') + }) + + it('rejects event with whitespace-only fields', () => { + const xml = ' ' + mockElement = parser.parseFromString(xml, 'application/xml').querySelector('event')! + const errors = validateEventElement(mockElement, 4) + expect(errors).toBe('Event 4: missing ') + }) + + it('rejects event with empty fields', () => { + const xml = '' + mockElement = parser.parseFromString(xml, 'application/xml').querySelector('event')! + const errors = validateEventElement(mockElement, 5) + expect(errors).toBe('Event 5: missing ') + }) + + // New tests for edge cases in validateEventElement (though 100% covered, add for robustness) + it('handles null textContent gracefully', () => { + // Simulate missing querySelector return + const mockEvent = { + querySelector: () => null + } as unknown as Element + const errors = validateEventElement(mockEvent as Element, 1) + expect(errors).toBe('Event 1: missing ') + }) + }) + + describe('isDuplicateFile', () => { + const mockFiles: UploadEventFileType[] = [ + { file: createMockFile('file1.events.xml', ''), isValid: true, errors: [], isDuplicate: false }, + { file: createMockFile('file2.events.xml', ''), isValid: true, errors: [], isDuplicate: false } + ] + + it('returns false for empty existing files', () => { + const result = isDuplicateFile('test.events.xml', []) + expect(result).toBe(false) + }) + + it('returns true for case-insensitive duplicate', () => { + const result = isDuplicateFile('FILE1.events.xml', mockFiles) + expect(result).toBe(true) + }) + + it('returns false for non-duplicate file', () => { + const result = isDuplicateFile('file3.events.xml', mockFiles) + expect(result).toBe(false) + }) + + it('handles special characters in file names', () => { + const specialFiles: UploadEventFileType[] = [ + { file: createMockFile('file-1@special.events.xml', ''), isValid: true, errors: [], isDuplicate: false } + ] + const result = isDuplicateFile('FILE-1@SPECIAL.events.xml', specialFiles) + expect(result).toBe(true) + }) + + it('handles multiple duplicates', () => { + const multiFiles: UploadEventFileType[] = [ + { file: createMockFile('file1.events.xml', ''), isValid: true, errors: [], isDuplicate: false }, + { file: createMockFile('FILE1.events.xml', ''), isValid: true, errors: [], isDuplicate: false } + ] + const result = isDuplicateFile('file1.events.xml', multiFiles) + expect(result).toBe(true) + }) + + it('handles empty file name', () => { + const result = isDuplicateFile('', mockFiles) + expect(result).toBe(false) + }) + + it('handles null or undefined existingFiles', () => { + expect(isDuplicateFile('test.events.xml', null as any)).toBe(false) + expect(isDuplicateFile('test.events.xml', undefined as any)).toBe(false) + }) + + // New test for malformed file in array (covers runtime error path, though not branched) + it('handles malformed UploadEventFileType without crashing', () => { + const badFiles: UploadEventFileType[] = [ + { file: null as any, isValid: true, errors: [], isDuplicate: false } // file.name will throw, but optional chain protects existingFiles + ] + // Since ?.some, if file null, element.file.name throws inside some, but to test, expect throw or modify code + // For coverage, run and see; here, use try-catch in test + expect(() => isDuplicateFile('test.events.xml', badFiles)).toThrow() // Covers the error path in some() + }) + }) +}) + diff --git a/ui/tests/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.test.ts b/ui/tests/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.test.ts new file mode 100644 index 000000000000..d2e7b328d57e --- /dev/null +++ b/ui/tests/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.test.ts @@ -0,0 +1,112 @@ +import { mount, VueWrapper, flushPromises } from '@vue/test-utils' +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import { FeatherDialog } from '@featherds/dialog' +import { FeatherButton } from '@featherds/button' +import ChangeEventConfigEventStatusDialog from '@/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.vue' + +describe('ChangeEventConfigEventStatusDialog.vue', () => { + let wrapper: VueWrapper + let store: ReturnType + + beforeEach(() => { + const pinia = createTestingPinia({ + createSpy: vi.fn + }) + + store = useEventConfigDetailStore(pinia) + + // mock store state + store.changeEventConfigEventStatusDialogState.visible = true + store.selectedSource = { id: 1, name: 'Test Source' } as any + store.changeEventConfigEventStatusDialogState.eventConfigEvent = { + id: 10, + eventLabel: 'High CPU Usage', + enabled: true + } as any + + wrapper = mount(ChangeEventConfigEventStatusDialog, { + global: { + plugins: [pinia], + stubs: { + FeatherDialog, + FeatherButton + } + } + }) + }) + + afterEach(() => { + wrapper.unmount() + vi.clearAllMocks() + }) + + it('renders dialog correctly with title and message', () => { + const dialog = wrapper.findComponent(FeatherDialog) + expect(dialog.exists()).toBe(true) + expect(dialog.props('labels')?.title).toBe('Change Event Configuration Event Status') + }) + + it('calls hideChangeEventConfigEventStatusDialog on Cancel click', async () => { + const cancelBtn = wrapper + .findAllComponents(FeatherButton) + .find((btn) => btn.text().toLowerCase().includes('cancel')) + + expect(cancelBtn).toBeTruthy() + await cancelBtn?.trigger('click') + + expect(store.hideChangeEventConfigEventStatusDialog).toHaveBeenCalledTimes(1) + }) + + it('calls disableEventConfigEvent when event is enabled and Save clicked', async () => { + const saveBtn = wrapper + .findAllComponents(FeatherButton) + .find((btn) => btn.text().toLowerCase().includes('save')) + + await saveBtn?.trigger('click') + await flushPromises() + + expect(store.disableEventConfigEvent).toHaveBeenCalledWith(10) + expect(store.hideChangeEventConfigEventStatusDialog).toHaveBeenCalled() + }) + + it('calls enableEventConfigEvent when event is disabled and Save clicked', async () => { + store.changeEventConfigEventStatusDialogState.eventConfigEvent = { + id: 11, + eventLabel: 'Network Down', + enabled: false + } as any + await wrapper.vm.$nextTick() + + const saveBtn = wrapper + .findAllComponents(FeatherButton) + .find((btn) => btn.text().toLowerCase().includes('save')) + + await saveBtn?.trigger('click') + await flushPromises() + + expect(store.enableEventConfigEvent).toHaveBeenCalledWith(11) + expect(store.hideChangeEventConfigEventStatusDialog).toHaveBeenCalled() + }) + + it('handles missing eventConfigEvent safely', async () => { + store.changeEventConfigEventStatusDialogState.eventConfigEvent = null as any + await wrapper.vm.$nextTick() + + const saveBtn = wrapper + .findAllComponents(FeatherButton) + .find((btn) => btn.text().toLowerCase().includes('save')) + + await saveBtn?.trigger('click') + await flushPromises() + + expect(store.disableEventConfigEvent).not.toHaveBeenCalled() + expect(store.enableEventConfigEvent).not.toHaveBeenCalled() + }) + + it('renders FeatherDialog with visible prop true', () => { + const dialog = wrapper.findComponent(FeatherDialog) + expect(dialog.props('modelValue')).toBe(true) + }) +}) diff --git a/ui/tests/components/EventConfigurationDetail/Dialog/ChangeEventConfigSourceStatusDialog.test.ts b/ui/tests/components/EventConfigurationDetail/Dialog/ChangeEventConfigSourceStatusDialog.test.ts new file mode 100644 index 000000000000..0c3e47c2735c --- /dev/null +++ b/ui/tests/components/EventConfigurationDetail/Dialog/ChangeEventConfigSourceStatusDialog.test.ts @@ -0,0 +1,130 @@ +import { mount, VueWrapper, flushPromises } from '@vue/test-utils' +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import { FeatherDialog } from '@featherds/dialog' +import { FeatherButton } from '@featherds/button' +import ChangeEventConfigSourceStatusDialog from '@/components/EventConfigurationDetail/Dialog/ChangeEventConfigSourceStatusDialog.vue' + +// mock feather components so we can actually render the buttons +vi.mock('@featherds/button', () => ({ + FeatherButton: { + template: '' + } +})) + +vi.mock('@featherds/dialog', () => ({ + FeatherDialog: { + props: ['modelValue', 'labels', 'hideClose'], + emits: ['update:modelValue', 'hidden'], + template: ` +
+ + +
+ ` + } +})) + +describe('ChangeEventConfigSourceStatusDialog.vue', () => { + let wrapper: VueWrapper + let store: ReturnType + + beforeEach(() => { + const pinia = createTestingPinia({ + createSpy: vi.fn + }) + + store = useEventConfigDetailStore(pinia) + + // define spies manually for required store methods + store.hideChangeEventConfigSourceStatusDialog = vi.fn() + store.disableEventConfigSource = vi.fn().mockResolvedValue(true) + store.enableEventConfigSource = vi.fn().mockResolvedValue(true) + + store.changeEventConfigSourceStatusDialogState.visible = true + store.changeEventConfigSourceStatusDialogState.eventConfigSource = { + id: 1, + name: 'Test Source', + enabled: true + } as any + + wrapper = mount(ChangeEventConfigSourceStatusDialog, { + global: { + plugins: [pinia] + } + }) + }) + + afterEach(() => { + wrapper.unmount() + vi.clearAllMocks() + }) + + + it('renders dialog correctly with title and message', () => { + const dialog = wrapper.findComponent(FeatherDialog) + expect(dialog.exists()).toBe(true) + expect(dialog.props('labels')?.title).toBe('Change Event Configuration Source Status') + }) + + it('calls hideChangeEventConfigSourceStatusDialog on Cancel click', async () => { + const cancelBtn = wrapper.findAllComponents(FeatherButton).find((btn) => btn.text().toLowerCase() === 'cancel') + expect(cancelBtn).toBeTruthy() + await cancelBtn!.trigger('click') + expect(store.hideChangeEventConfigSourceStatusDialog).toHaveBeenCalledTimes(2) + }) + + it('calls disableEventConfigSource when source is enabled and Save clicked', async () => { + const saveBtn = wrapper.findAll('button').find((btn) => + btn.text().toLowerCase().includes('save') + ) + expect(saveBtn).toBeTruthy() + + await saveBtn!.trigger('click') + await flushPromises() + + expect(store.disableEventConfigSource).toHaveBeenCalledWith(1) + expect(store.hideChangeEventConfigSourceStatusDialog).toHaveBeenCalled() + }) + + it('calls enableEventConfigSource when source is disabled and Save clicked', async () => { + store.changeEventConfigSourceStatusDialogState.eventConfigSource = { + id: 2, + name: 'Another Source', + enabled: false + } as any + await wrapper.vm.$nextTick() + + const saveBtn = wrapper.findAll('button').find((btn) => + btn.text().toLowerCase().includes('save') + ) + expect(saveBtn).toBeTruthy() + + await saveBtn!.trigger('click') + await flushPromises() + + expect(store.enableEventConfigSource).toHaveBeenCalledWith(2) + expect(store.hideChangeEventConfigSourceStatusDialog).toHaveBeenCalled() + }) + + it('handles missing eventConfigSource safely', async () => { + store.changeEventConfigSourceStatusDialogState.eventConfigSource = null as any + await wrapper.vm.$nextTick() + + const saveBtn = wrapper.findAll('button').find((btn) => + btn.text().toLowerCase().includes('save') + ) + + await saveBtn!.trigger('click') + await flushPromises() + + expect(store.disableEventConfigSource).not.toHaveBeenCalled() + expect(store.enableEventConfigSource).not.toHaveBeenCalled() + }) + + it('renders dialog visible = true', async () => { + const stateVisible = store.changeEventConfigSourceStatusDialogState.visible + expect(stateVisible).toBe(true) + }) +}) diff --git a/ui/tests/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.test.ts b/ui/tests/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.test.ts new file mode 100644 index 000000000000..32129bae2fb7 --- /dev/null +++ b/ui/tests/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.test.ts @@ -0,0 +1,122 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { mount, flushPromises } from '@vue/test-utils' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import * as eventConfigService from '@/services/eventConfigService' +import { FeatherButton } from '@featherds/button' +import { FeatherDialog } from '@featherds/dialog' +import DeleteEventConfigEventDialog from '@/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.vue' +import type { EventConfigSource } from '@/types/eventConfig' + +vi.mock('@featherds/dialog', () => ({ + FeatherDialog: { + name: 'FeatherDialog', + template: '
', + props: ['labels', 'modelValue'] + } +})) + +vi.mock('@/composables/useSnackbar', () => ({ + default: () => ({ + showSnackBar: vi.fn() + }) +})) + +describe('DeleteEventConfigEventDialog', () => { + let wrapper: any + let store: ReturnType + + beforeEach(async () => { + const pinia = createTestingPinia({ + createSpy: vi.fn, + stubActions: false + }) + + store = useEventConfigDetailStore() + + store.$state = { + deleteEventConfigEventDialogState: { + visible: true, + eventConfigEvent: { + id: 10, + eventLabel: 'Test Event' + } + }, + selectedSource: { + id: 5, + name: 'Test Source', + vendor: 'Cisco', + description: 'Sample Source', + enabled: true, + eventCount: 3, + fileOrder: 1, + uploadedBy: 'admin', + createdTime: new Date(), + lastModified: new Date() + } as EventConfigSource, + eventsPagination: { page: 1, pageSize: 10, total: 0 }, + isLoading: false + } as any + + wrapper = mount(DeleteEventConfigEventDialog, { + global: { + plugins: [pinia], + components: { FeatherButton, FeatherDialog } + } + }) + + await flushPromises() + }) + + it('renders the dialog when visible is true', () => { + const dialog = wrapper.findComponent(FeatherDialog) + expect(dialog.exists()).toBe(true) + expect(dialog.props('labels')).toEqual({ + title: 'Delete Event Configuration Event' + }) + }) + + it('displays correct event and source names', () => { + const modalBody = wrapper.find('.modal-body') + expect(modalBody.text()).toContain('Test Event') + expect(modalBody.text()).toContain('Test Source') + }) + + it('calls hideDeleteEventConfigEventDialog when Cancel is clicked', async () => { + const cancelButton = wrapper.findAllComponents(FeatherButton).at(0) + expect(cancelButton.exists()).toBe(true) + await cancelButton.trigger('click') + expect(store.hideDeleteEventConfigEventDialog).toHaveBeenCalled() + }) + + it('calls deleteEventConfigEventBySourceId and handles success', async () => { + vi.spyOn(eventConfigService, 'deleteEventConfigEventBySourceId').mockResolvedValue(true) + + const deleteButton = wrapper.findAllComponents(FeatherButton).at(1) + await deleteButton.trigger('click') + await flushPromises() + + expect(eventConfigService.deleteEventConfigEventBySourceId).toHaveBeenCalledWith(5, [10]) + expect(store.hideDeleteEventConfigEventDialog).toHaveBeenCalled() + expect(store.resetEventsPagination).toHaveBeenCalled() + expect(store.fetchEventsBySourceId).toHaveBeenCalled() + }) + + it('shows snackbar error if IDs are missing', async () => { + store.$state.selectedSource = null as any + await wrapper.vm.$nextTick() + + const spy = vi.spyOn(eventConfigService, 'deleteEventConfigEventBySourceId') + const deleteButton = wrapper.findAllComponents(FeatherButton).at(1) + await deleteButton.trigger('click') + await flushPromises() + + expect(spy).not.toHaveBeenCalled() + }) + + it('hides the dialog when visible is false', async () => { + store.$state.deleteEventConfigEventDialogState.visible = false + await wrapper.vm.$nextTick() + expect(wrapper.findComponent(FeatherDialog).props('modelValue')).toBe(false) + }) +}) diff --git a/ui/tests/components/EventConfigurationDetail/Dialog/DeleteEventConfigSourceDialog.test.ts b/ui/tests/components/EventConfigurationDetail/Dialog/DeleteEventConfigSourceDialog.test.ts new file mode 100644 index 000000000000..1cb6de5a6d0c --- /dev/null +++ b/ui/tests/components/EventConfigurationDetail/Dialog/DeleteEventConfigSourceDialog.test.ts @@ -0,0 +1,121 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { mount, flushPromises } from '@vue/test-utils' +import { createTestingPinia } from '@pinia/testing' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import * as eventConfigService from '@/services/eventConfigService' +import { FeatherButton } from '@featherds/button' +import { FeatherDialog } from '@featherds/dialog' +import DeleteEventConfigSourceDialog from '@/components/EventConfigurationDetail/Dialog/DeleteEventConfigSourceDialog.vue' + +vi.mock('@featherds/dialog', () => ({ + FeatherDialog: { + name: 'FeatherDialog', + template: '
', + props: ['labels', 'modelValue'] + } +})) + +const push = vi.fn() +vi.mock('vue-router', () => ({ + useRouter: () => ({ push }) +})) + +describe('DeleteEventConfigSourceDialog.vue', () => { + let wrapper: any + let store: ReturnType + + beforeEach(async () => { + const pinia = createTestingPinia({ + createSpy: vi.fn, + stubActions: false + }) + + store = useEventConfigDetailStore() + + store.$state.deleteEventConfigSourceDialogState = { + visible: true, + eventConfigSource: { + id: 1, + name: 'Test Source', + vendor: 'Cisco', + description: 'Mock description', + enabled: true, + eventCount: 5, + fileOrder: 1, + uploadedBy: 'Admin', + createdTime: new Date(), + lastModified: new Date() + } + } + + wrapper = mount(DeleteEventConfigSourceDialog, { + global: { + plugins: [pinia], + components: { FeatherButton, FeatherDialog } + } + }) + + await flushPromises() + }) + + it('renders dialog when visible is true', () => { + expect(wrapper.findComponent(FeatherDialog).exists()).toBe(true) + expect(wrapper.findComponent(FeatherDialog).props('labels')).toEqual({ + title: 'Delete Event Configuration Source' + }) + }) + + it('renders the dialog when visible is true', () => { + expect(wrapper.findComponent(FeatherDialog).exists()).toBe(true) + expect(wrapper.findComponent(FeatherDialog).props('labels')).toEqual({ + title: 'Delete Event Configuration Source' + }) + }) + + it('calls hideDeleteEventConfigSourceDialog when Cancel is clicked', async () => { + const spyHide = vi.spyOn(store, 'hideDeleteEventConfigSourceDialog') + const cancelBtn = wrapper.findAllComponents(FeatherButton).at(0) + expect(cancelBtn.exists()).toBe(true) + await cancelBtn.trigger('click') + expect(spyHide).toHaveBeenCalled() + }) + + it('calls hideDeleteEventConfigSourceDialog when Delete button is clicked', async () => { + const deleteButton = wrapper.findAllComponents(FeatherButton).at(0) + expect(deleteButton.exists()).toBe(true) + await deleteButton.trigger('click') + expect(store.hideDeleteEventConfigSourceDialog).toHaveBeenCalled() + }) + + it('shows snackbar and logs error on failed deletion', async () => { + const mockDelete = vi.spyOn(eventConfigService, 'deleteEventConfigSourceById').mockRejectedValue(new Error('fail')) + const spyConsole = vi.spyOn(console, 'error').mockImplementation(() => {}) + + const deleteBtn = wrapper.findAllComponents(FeatherButton).at(1) + await deleteBtn.trigger('click') + await flushPromises() + + expect(mockDelete).toHaveBeenCalledWith(1) + expect(spyConsole).toHaveBeenCalled() + }) + + it('does not call delete if eventConfigSource is null', async () => { + store.deleteEventConfigSourceDialogState.eventConfigSource = null + await wrapper.vm.$nextTick() + + const mockDelete = vi.spyOn(eventConfigService, 'deleteEventConfigSourceById').mockResolvedValue(true) + const deleteBtn = wrapper.findAllComponents(FeatherButton).at(1) + expect(deleteBtn.exists()).toBe(true) + await deleteBtn.trigger('click') + await flushPromises() + + expect(mockDelete).not.toHaveBeenCalled() + }) + + it('reflects dialog visibility when visible is false', async () => { + store.deleteEventConfigSourceDialogState.visible = false + await wrapper.vm.$nextTick() + expect(wrapper.findComponent(FeatherDialog).props('modelValue')).toBe(false) + }) +}) + diff --git a/ui/tests/components/EventConfigurationDetail/EventConfigEventTable.test.ts b/ui/tests/components/EventConfigurationDetail/EventConfigEventTable.test.ts new file mode 100644 index 000000000000..a88b45222a42 --- /dev/null +++ b/ui/tests/components/EventConfigurationDetail/EventConfigEventTable.test.ts @@ -0,0 +1,791 @@ +import EmptyList from '@/components/Common/EmptyList.vue' +import ChangeEventConfigEventStatusDialog from '@/components/EventConfigurationDetail/Dialog/ChangeEventConfigEventStatusDialog.vue' +import DeleteEventConfigEventDialog from '@/components/EventConfigurationDetail/Dialog/DeleteEventConfigEventDialog.vue' +import EventConfigEventTable from '@/components/EventConfigurationDetail/EventConfigEventTable.vue' +import { VENDOR_OPENNMS } from '@/lib/utils' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import { useEventModificationStore } from '@/stores/eventModificationStore' +import { CreateEditMode } from '@/types' +import { EventConfigSource } from '@/types/eventConfig' +import { FeatherButton } from '@featherds/button' +import { FeatherChip } from '@featherds/chips' +import { FeatherDropdown, FeatherDropdownItem } from '@featherds/dropdown' +import { FeatherIcon } from '@featherds/icon' +import { FeatherInput } from '@featherds/input' +import { FeatherPagination } from '@featherds/pagination' +import { FeatherSortHeader, SORT } from '@featherds/table' +import { createTestingPinia } from '@pinia/testing' +import { flushPromises, mount, VueWrapper } from '@vue/test-utils' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +const mockPush = vi.fn() +vi.mock('vue-router', () => ({ + useRouter: () => ({ + push: mockPush + }) +})) + +const mockSource: EventConfigSource = { + id: 1, + vendor: 'opennms', + name: 'Test Source', + description: 'A test event config source', + enabled: true, + createdTime: new Date(), + lastModified: new Date(), + eventCount: 0, + fileOrder: 0, + uploadedBy: '' +} + +describe('EventConfigEventTable.vue', () => { + let wrapper: VueWrapper + let store: ReturnType + let modificationStore: ReturnType + + beforeEach(async () => { + vi.clearAllMocks() + vi.useFakeTimers() + + const pinia = createTestingPinia({ + createSpy: vi.fn, + stubActions: false + }) + + store = useEventConfigDetailStore(pinia) + modificationStore = useEventModificationStore(pinia) + + // Reset store state + store.$reset() + store.events = [] + store.eventsSearchTerm = '' + store.eventsPagination = { page: 1, pageSize: 10, total: 0 } + store.selectedSource = mockSource + + // Mock store methods + store.fetchEventsBySourceId = vi.fn().mockResolvedValue(undefined) + store.refreshEventConfigEvents = vi.fn().mockResolvedValue(undefined) + store.onChangeEventsSearchTerm = vi.fn().mockResolvedValue(undefined) + store.onEventsPageChange = vi.fn().mockResolvedValue(undefined) + store.onEventsPageSizeChange = vi.fn().mockResolvedValue(undefined) + store.onEventsSortChange = vi.fn().mockResolvedValue(undefined) + store.showDeleteEventConfigEventDialog = vi.fn() + store.showChangeEventConfigEventStatusDialog = vi.fn() + + modificationStore.setSelectedEventConfigSource = vi.fn() + + wrapper = mount(EventConfigEventTable, { + global: { + plugins: [pinia], + components: { + FeatherButton, + FeatherChip, + FeatherDropdown, + FeatherDropdownItem, + FeatherIcon, + FeatherSortHeader, + FeatherPagination, + FeatherInput + } + } + }) + + await flushPromises() + await nextTick() + }) + + afterEach(() => { + vi.restoreAllMocks() + vi.useRealTimers() + }) + + it('mounts', () => { + expect(wrapper.exists()).toBe(true) + }) + + describe('Rendering', () => { + it('renders the component correctly', () => { + expect(wrapper.find('.event-config-event-table').exists()).toBe(true) + }) + + it('renders the component title correctly', () => { + expect(wrapper.find('.title').text()).toBe('Events') + }) + + it('renders search input with correct label and hint', () => { + const searchInput = wrapper.findComponent(FeatherInput) + expect(searchInput.props('label')).toBe('Search') + expect(searchInput.props('hint')).toBe('Search by Event UEI, Event Label') + expect(wrapper.find('[data-test="search-input"]').exists()).toBe(true) + }) + + it('renders refresh button', () => { + const refreshButtons = wrapper.findAllComponents(FeatherButton) + const refreshButton = refreshButtons.find((btn) => btn.props('icon') === 'Refresh') + expect(refreshButton).toBeDefined() + }) + + it('renders table headers correctly when events exist', async () => { + store.events = [ + { + id: 1, + uei: 'uei1', + eventLabel: 'Label1', + severity: 'High', + enabled: true, + description: 'Desc1', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + const headers = wrapper.findAllComponents(FeatherSortHeader) + expect(headers.length).toBe(2) + expect(wrapper.find('thead tr').text()).toContain('Event UEI') + expect(wrapper.find('thead tr').text()).toContain('Event Label') + expect(wrapper.find('thead tr').text()).toContain('Severity') + expect(wrapper.find('thead tr').text()).toContain('Status') + expect(wrapper.find('thead tr').text()).toContain('Actions') + }) + + it('renders empty list when no events', () => { + expect(wrapper.findComponent(EmptyList).exists()).toBe(true) + expect(wrapper.find('[data-test="empty-list"]').exists()).toBe(true) + }) + + it('renders pagination when events exist', async () => { + store.events = new Array(15).fill(0).map((_, i) => ({ + id: i, + uei: `uei${i}`, + eventLabel: `Label${i}`, + severity: 'High', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + })) + store.eventsPagination.total = 15 + await nextTick() + expect(wrapper.findComponent(FeatherPagination).exists()).toBe(true) + expect(wrapper.find('[data-test="FeatherPagination"]').exists()).toBe(true) + }) + + it('renders dialogs', () => { + expect(wrapper.findComponent(DeleteEventConfigEventDialog).exists()).toBe(true) + expect(wrapper.findComponent(ChangeEventConfigEventStatusDialog).exists()).toBe(true) + }) + }) + + describe('Search Functionality', () => { + it('updates search term on input and debounces call to store', async () => { + const searchInput = wrapper.findComponent(FeatherInput) + await searchInput.vm.$emit('update:modelValue', 'test search') + await nextTick() + + // Advance timers for debounce + vi.advanceTimersByTime(500) + await flushPromises() + + expect(store.eventsSearchTerm).toBe('test search') + expect(store.onChangeEventsSearchTerm).toHaveBeenCalledWith('test search') + }) + + it('trims search term on update', async () => { + const searchInput = wrapper.findComponent(FeatherInput) + await searchInput.vm.$emit('update:modelValue', ' trimmed ') + await nextTick() + vi.advanceTimersByTime(500) + await flushPromises() + expect(store.eventsSearchTerm).toBe('trimmed') + expect(store.onChangeEventsSearchTerm).toHaveBeenCalledWith('trimmed') + }) + + it('does not call store immediately on input (debounce)', async () => { + const searchInput = wrapper.findComponent(FeatherInput) + await searchInput.vm.$emit('update:modelValue', 'test') + await nextTick() + // Before debounce time + expect(store.onChangeEventsSearchTerm).not.toHaveBeenCalled() + }) + + it('calls store on empty search after debounce', async () => { + const searchInput = wrapper.findComponent(FeatherInput) + await searchInput.vm.$emit('update:modelValue', '') + await nextTick() + vi.advanceTimersByTime(500) + await flushPromises() + expect(store.onChangeEventsSearchTerm).toHaveBeenCalledWith('') + }) + }) + + describe('Refresh Button', () => { + it('calls store refresh on button click', async () => { + const refreshButton = wrapper.findAllComponents(FeatherButton).find((btn) => btn.props('icon') === 'Refresh') + await refreshButton?.trigger('click') + await nextTick() + expect(store.refreshEventConfigEvents).toHaveBeenCalled() + }) + }) + + describe('Sorting', () => { + beforeEach(async () => { + store.events = [ + { + id: 1, + uei: 'uei1', + eventLabel: 'Label1', + severity: 'High', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + }) + + it('calls sort-changed on header and updates store', async () => { + const ueiHeader = wrapper.findAllComponents(FeatherSortHeader)[0] + await ueiHeader.vm.$emit('sort-changed', { property: 'uei', value: SORT.ASCENDING }) + await nextTick() + expect(store.onEventsSortChange).toHaveBeenCalledWith('uei', SORT.ASCENDING) + }) + + it('resets other sort states to NONE when sorting a column', async () => { + const ueiHeader = wrapper.findAllComponents(FeatherSortHeader)[0] + await ueiHeader.vm.$emit('sort-changed', { property: 'uei', value: SORT.ASCENDING }) + await nextTick() + // Access via wrapper.vm + expect(wrapper.vm.sort.uei).toBe(SORT.ASCENDING) + expect(wrapper.vm.sort.eventLabel).toBe(SORT.NONE) + }) + + it('defaults to createdTime desc when sort value is NONE', async () => { + const ueiHeader = wrapper.findAllComponents(FeatherSortHeader)[0] + await ueiHeader.vm.$emit('sort-changed', { property: 'uei', value: SORT.NONE }) + await nextTick() + expect(store.onEventsSortChange).toHaveBeenCalledWith('createdTime', 'desc') + }) + + it('handles desc sort correctly', async () => { + const eventLabelHeader = wrapper.findAllComponents(FeatherSortHeader)[1] + await eventLabelHeader.vm.$emit('sort-changed', { property: 'eventLabel', value: SORT.DESCENDING }) + await nextTick() + expect(store.onEventsSortChange).toHaveBeenCalledWith('eventLabel', SORT.DESCENDING) + expect(wrapper.vm.sort.eventLabel).toBe(SORT.DESCENDING) + expect(wrapper.vm.sort.uei).toBe(SORT.NONE) + }) + }) + + describe('Table Rows', () => { + beforeEach(async () => { + store.events = [ + { + id: 1, + uei: 'UEI-1', + eventLabel: 'Event 1', + severity: 'Critical', + enabled: true, + description: '

HTML desc

', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + }) + + it('displays event data in table cells', () => { + const tds = wrapper.findAll('td') + expect(tds[0].text()).toContain('UEI-1') + expect(tds[1].text()).toContain('Event 1') + expect(tds[3].text()).toContain('Enabled') + }) + + it('renders severity chip with correct text and class', () => { + const chip = wrapper.findComponent(FeatherChip) + expect(chip.text()).toBe('Critical') + const chipElement = chip.element as Element + expect(chipElement.classList.contains('critical-color')).toBe(true) + expect(chipElement.classList.contains('severity')).toBe(true) + }) + + it('toggles status text based on enabled flag', async () => { + store.events[0].enabled = false + await nextTick() + expect(wrapper.findAll('td')[3].text()).toContain('Disabled') + }) + + it('renders description with HTML in expanded row', async () => { + const expandButton = wrapper + .find('table') + .findAllComponents(FeatherButton) + .filter((btn: any) => btn.props('primary'))[0] + expect(expandButton).toBeDefined() + await expandButton.trigger('click') + await nextTick() + const expandedRow = wrapper.find('.expanded-content') + expect(expandedRow.exists()).toBe(true) + expect(expandedRow.text()).toContain('Description:') + // v-html should render desc as bold, but in test, check innerHTML + expect(expandedRow.find('p.description').html()).toContain('desc') + }) + }) + + describe('Actions', () => { + beforeEach(async () => { + store.events = [ + { + id: 1, + uei: 'UEI-1', + eventLabel: 'Event 1', + severity: 'Critical', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + store.selectedSource = mockSource + store.selectedSource.vendor = 'SomeVendor' + await nextTick() + }) + + it('renders edit button and calls onEditEvent on click', async () => { + const editButton = wrapper.find('[data-test="edit-button"]').findComponent(FeatherButton) + await editButton.trigger('click') + await nextTick() + expect(modificationStore.setSelectedEventConfigSource).toHaveBeenCalledWith( + store.selectedSource, + CreateEditMode.Edit, + store.events[0] + ) + expect(mockPush).toHaveBeenCalledWith({ name: 'Event Configuration New' }) + }) + + it('renders dropdown only if vendor is not OpenNMS', () => { + expect(wrapper.findComponent(FeatherDropdown).exists()).toBe(true) + }) + + it('renders dropdown for non-OpenNMS vendor with correct enable/disable text', async () => { + store.selectedSource = { + id: 1, + vendor: VENDOR_OPENNMS, + name: 'Test Source', + description: 'A test event config source', + enabled: true, + eventCount: 0, + fileOrder: 0, + uploadedBy: '', + createdTime: new Date(), + lastModified: new Date() + } + await nextTick() + + const row = wrapper.find('transition-group-stub tr') + expect(row.exists()).toBe(true) + expect(row.findAll('button')).toHaveLength(3) + + expect(row.findAllComponents(FeatherDropdown)).toHaveLength(1) + + row.findAllComponents(FeatherDropdown)[0].findAll('button')[0].trigger('click') + await wrapper.vm.$nextTick() + + expect(row.findAllComponents(FeatherDropdownItem)).toHaveLength(1) + expect(row.findAllComponents(FeatherDropdownItem)[0].text()).toBe('Disable Event') + }) + + it('calls showChangeEventConfigEventStatusDialog on dropdown item click', async () => { + const spy = vi.spyOn(store, 'showChangeEventConfigEventStatusDialog') + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + + // Find the more options button (trigger) + const moreButton = buttons1[1] + expect(moreButton).toBeDefined() + + await moreButton.trigger('click') + await wrapper.vm.$nextTick() + + // Now find the dropdown items in the whole wrapper + const dropdownItems = wrapper.findAllComponents(FeatherDropdownItem) + expect(dropdownItems).toHaveLength(2) + expect(dropdownItems[0].text()).toBe('Disable Event') + expect(dropdownItems[1].text()).toBe('Delete Event') + const statusItem = dropdownItems[0].find('a') + await statusItem.trigger('click') + await wrapper.vm.$nextTick() + + expect(spy).toHaveBeenCalledWith(store.events[0]) + }) + + it('updates dropdown item text based on enabled status', async () => { + store.events[0].enabled = false + const spy = vi.spyOn(store, 'showChangeEventConfigEventStatusDialog') + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + + // Find the more options button (trigger) + const moreButton = buttons1[1] + expect(moreButton).toBeDefined() + + await moreButton.trigger('click') + await wrapper.vm.$nextTick() + + // Now find the dropdown items in the whole wrapper + const dropdownItems = wrapper.findAllComponents(FeatherDropdownItem) + expect(dropdownItems).toHaveLength(2) + expect(dropdownItems[0].text()).toBe('Enable Event') + expect(dropdownItems[1].text()).toBe('Delete Event') + const statusItem = dropdownItems[0].find('a') + await statusItem.trigger('click') + await wrapper.vm.$nextTick() + + expect(spy).toHaveBeenCalledWith(store.events[0]) + }) + + it('calls showDeleteEventConfigEventDialog on dropdown item click', async () => { + const spy = vi.spyOn(store, 'showDeleteEventConfigEventDialog') + + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + + // Find the more options button (trigger) + const moreButton = buttons1[1] + expect(moreButton).toBeDefined() + + await moreButton.trigger('click') + await wrapper.vm.$nextTick() + + // Now find the dropdown items in the whole wrapper + const dropdownItems = wrapper.findAllComponents(FeatherDropdownItem) + expect(dropdownItems).toHaveLength(2) + expect(dropdownItems[0].text()).toBe('Disable Event') + expect(dropdownItems[1].text()).toBe('Delete Event') + const statusItem = dropdownItems[1].find('a') + await statusItem.trigger('click') + await wrapper.vm.$nextTick() + + expect(spy).toHaveBeenCalledWith(store.events[0]) + }) + + it('toggles expand/collapse on button click', async () => { + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + expect(wrapper.vm.expandedRows).toEqual([]) + + const expandButton = buttons1[2] + await expandButton?.trigger('click') + await nextTick() + expect(wrapper.vm.expandedRows).toEqual([1]) + // Icon should change, but since prop, check if triggered + await expandButton?.trigger('click') + await nextTick() + expect(wrapper.vm.expandedRows).toEqual([]) + }) + + it('handles multiple expanded rows', async () => { + store.events.push({ + id: 2, + uei: 'UEI-2', + eventLabel: 'Test Event 2', + severity: 'Critical', + enabled: true, + description: 'A test event 2', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: 'opennms', + fileOrder: 0 + }) + await nextTick() + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(2) + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + const buttons2 = rows[1].findAll('button') + expect(buttons2.length).toBe(3) + + expect(wrapper.vm.expandedRows).toEqual([]) + + const expandButton1 = buttons1[2] + await expandButton1?.trigger('click') + + const expandButton2 = buttons2[2] + await expandButton2?.trigger('click') + await nextTick() + expect(wrapper.vm.expandedRows).toEqual([1, 2]) + }) + }) + + describe('Pagination', () => { + beforeEach(async () => { + store.events = new Array(15).fill(0).map((_, i) => ({ + id: i, + uei: `uei${i}`, + eventLabel: `Label${i}`, + severity: 'High', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + })) + store.eventsPagination.total = 15 + await nextTick() + }) + + it('updates page on pagination change', async () => { + const pagination = wrapper.findComponent(FeatherPagination) + await pagination.vm.$emit('update:modelValue', 2) + await nextTick() + expect(store.onEventsPageChange).toHaveBeenCalledWith(2) + }) + + it('updates page size on pagination change', async () => { + const pagination = wrapper.findComponent(FeatherPagination) + await pagination.vm.$emit('update:pageSize', 20) + await nextTick() + expect(store.onEventsPageSizeChange).toHaveBeenCalledWith(20) + }) + + it('initially sets correct pagination props', () => { + const pagination = wrapper.findComponent(FeatherPagination) + expect(pagination.props('modelValue')).toBe(1) + expect(pagination.props('pageSize')).toBe(10) + expect(pagination.props('total')).toBe(15) + }) + }) + + describe('Edge Cases', () => { + it('handles empty events array (no table, shows empty list)', async () => { + store.events = [] + await nextTick() + expect(wrapper.find('table').exists()).toBe(false) + expect(wrapper.findComponent(EmptyList).exists()).toBe(true) + }) + + it('handles events with empty description (no crash on expand)', async () => { + store.events = [ + { + id: 1, + uei: 'UEI-1', + eventLabel: 'Event 1', + severity: 'High', + enabled: true, + description: '', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + expect(wrapper.vm.expandedRows).toEqual([]) + + const expandButton = buttons1[2] + await expandButton?.trigger('click') + await nextTick() + + expect(wrapper.find('.expanded-content p.description').exists()).toBe(true) + expect(wrapper.find('.expanded-content p.description').text()).toBe('') + }) + + it('handles HTML in description without issues (v-html renders safely)', async () => { + store.events = [ + { + id: 1, + uei: 'UEI-1', + eventLabel: 'Event 1', + severity: 'High', + enabled: true, + description: 'Bold', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + const rows = wrapper.findAll('transition-group-stub tr') + expect(rows).toHaveLength(1) + + const buttons1 = rows[0].findAll('button') + expect(buttons1.length).toBe(3) + expect(wrapper.vm.expandedRows).toEqual([]) + + const expandButton = buttons1[2] + await expandButton?.trigger('click') + await nextTick() + // Script doesn't execute in test, but HTML renders + expect(wrapper.find('.expanded-content').text()).toContain('Bold') + }) + + it('handles no selectedSource (edit does nothing)', async () => { + store.selectedSource = null + store.events = [ + { + id: 1, + uei: 'UEI-1', + eventLabel: 'Event 1', + severity: 'High', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + const editButton = wrapper.find('[data-test="edit-button"]').findComponent(FeatherButton) + await editButton.trigger('click') + await nextTick() + expect(modificationStore.setSelectedEventConfigSource).not.toHaveBeenCalled() + expect(mockPush).not.toHaveBeenCalled() + }) + + it('handles duplicate event IDs in expandedRows (no crash)', async () => { + wrapper.vm.expandedRows.push(1) + wrapper.vm.expandedRows.push(1) // Duplicate + store.events = [ + { + id: 1, + uei: 'UEI-1', + eventLabel: 'Event 1', + severity: 'High', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + expect(wrapper.find('.expanded-content').exists()).toBe(true) // Renders once due to v-if + }) + + it('handles large number of events (renders without crash)', async () => { + store.events = new Array(1000).fill(0).map((_, i) => ({ + id: i, + uei: `uei${i}`, + eventLabel: `Label${i}`, + severity: 'High', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + })) + await nextTick() + expect(wrapper.findAll('tr').length).toBeGreaterThan(1) + }) + + it('sort with no events (no crash)', async () => { + store.events = [] + await nextTick() + // Simulate emit + wrapper.vm.sortChanged({ property: 'uei', value: SORT.ASCENDING }) + expect(store.onEventsSortChange).toHaveBeenCalledWith('uei', SORT.ASCENDING) + }) + + it('search with special characters (trims and calls store)', async () => { + const searchInput = wrapper.findComponent(FeatherInput) + await searchInput.vm.$emit('update:modelValue', ' test ') + await nextTick() + vi.advanceTimersByTime(500) + await flushPromises() + expect(store.eventsSearchTerm).toBe(' test') + expect(store.onChangeEventsSearchTerm).toHaveBeenCalledWith(' test') + }) + + it('handles missing event properties gracefully', async () => { + store.events = [ + { + id: 1, + uei: undefined as any, + eventLabel: undefined as any, + severity: 'Major', + enabled: true, + description: 'Desc', + xmlContent: '', + createdTime: new Date(), + lastModified: new Date(), + modifiedBy: '', + sourceName: '', + vendor: '', + fileOrder: 0 + } + ] + await nextTick() + expect(wrapper.find('td').text()).toContain('') // Or empty, but no crash + }) + }) +}) + diff --git a/ui/tests/containers/EventConfiguration.test.ts b/ui/tests/containers/EventConfiguration.test.ts new file mode 100644 index 000000000000..f4ad6755487c --- /dev/null +++ b/ui/tests/containers/EventConfiguration.test.ts @@ -0,0 +1,21 @@ +import { mount } from '@vue/test-utils' +import { describe, it, expect } from 'vitest' +import EventConfigTabContainer from '@/components/EventConfiguration/EventConfigTabContainer.vue' +import EventConfiguration from '@/containers/EventConfiguration.vue' + +describe('EventConfig.vue', () => { + it('renders heading text', () => { + const wrapper = mount(EventConfiguration, { + global: { + stubs: { + EventConfigTabContainer: true + } + } + }) + + expect(wrapper.find('h1').text()).toBe('Event Configuration') + + expect(wrapper.findComponent(EventConfigTabContainer).exists()).toBe(true) + }) +}) + diff --git a/ui/tests/containers/EventConfigurationDetail.test.ts b/ui/tests/containers/EventConfigurationDetail.test.ts new file mode 100644 index 000000000000..4a059d8b1c66 --- /dev/null +++ b/ui/tests/containers/EventConfigurationDetail.test.ts @@ -0,0 +1,310 @@ +import EventConfigurationDetail from '@/containers/EventConfigurationDetail.vue' +import { VENDOR_OPENNMS } from '@/lib/utils' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import { useEventModificationStore } from '@/stores/eventModificationStore' +import { CreateEditMode } from '@/types' +import { EventConfigSource } from '@/types/eventConfig' +import { mount, VueWrapper } from '@vue/test-utils' +import { createPinia, setActivePinia } from 'pinia' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +vi.mock('@/lib/utils', () => ({ + VENDOR_OPENNMS: 'OpenNMS' +})) + +vi.mock('vue3-ace-editor', () => ({ + VAceEditor: { + template: '
Ace Editor
', + props: ['value', 'lang', 'theme', 'options'] + } +})) + +vi.mock('ace-builds/src-noconflict/ext-language_tools', () => ({})) +vi.mock('ace-builds/src-noconflict/mode-xml', () => ({})) +vi.mock('ace-builds/src-noconflict/theme-chrome', () => ({})) + +vi.mock('vkbeautify', () => ({ + default: { + xml: vi.fn((xml) => xml) + } +})) + +vi.mock('fast-xml-parser', () => ({ + XMLValidator: { + validate: vi.fn(() => true) + } +})) + +const mockPush = vi.fn() +vi.mock('vue-router', () => ({ + useRoute: vi.fn(() => ({ + params: { id: '1' } + })), + useRouter: vi.fn(() => ({ + push: mockPush + })) +})) + +describe('EventConfigurationDetail.vue', () => { + let wrapper: VueWrapper + let store: ReturnType + let modificationStore: ReturnType + + const mockConfig: EventConfigSource = { + id: 1, + name: 'Test Config', + description: 'Test Description', + vendor: 'Test Vendor', + enabled: true, + eventCount: 5, + fileOrder: 1, + uploadedBy: 'test-user', + createdTime: new Date(), + lastModified: new Date() + } + + beforeEach(() => { + setActivePinia(createPinia()) + store = useEventConfigDetailStore() + modificationStore = useEventModificationStore() + vi.clearAllMocks() + }) + + const createWrapper = (selectedSource: EventConfigSource | null = mockConfig) => { + store.selectedSource = selectedSource + store.fetchEventsBySourceId = vi.fn() + + return mount(EventConfigurationDetail, { + global: { + stubs: { + FeatherBackButton: true, + FeatherButton: true, + EventConfigEventTable: true, + DeleteEventConfigSourceDialog: true, + ChangeEventConfigSourceStatusDialog: true + } + } + }) + } + + it('should render the component with config data', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + expect(wrapper.find('.event-config-container').exists()).toBe(true) + expect(wrapper.find('h1').text()).toBe('Event Configuration Details') + }) + + it('should display config details correctly', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + const configBox = wrapper.find('.config-details-box') + expect(configBox.text()).toContain('Test Config') + expect(configBox.text()).toContain('Test Description') + expect(configBox.text()).toContain('Test Vendor') + expect(configBox.text()).toContain('Enabled') + expect(configBox.text()).toContain('5') + }) + + it('should call setSelectedEventConfigSource when "Add Event" button is clicked', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + modificationStore.setSelectedEventConfigSource = vi.fn() + const addEventButton = wrapper.get('[data-test="add-event"]') + await addEventButton.trigger('click') + + expect(modificationStore.setSelectedEventConfigSource).toHaveBeenCalledTimes(1) + expect(modificationStore.setSelectedEventConfigSource).toHaveBeenCalledWith( + store.selectedSource, + CreateEditMode.Create, + expect.any(Object) + ) + }) + + it('should display "Disabled" status when config is disabled', async () => { + const disabledConfig = { ...mockConfig, enabled: false } + wrapper = createWrapper(disabledConfig) + await wrapper.vm.$nextTick() + + expect(wrapper.text()).toContain('Disabled') + }) + + it('should show "No event configuration found" when config is null', async () => { + wrapper = createWrapper(null) + await wrapper.vm.$nextTick() + + expect(wrapper.find('.not-found-container').exists()).toBe(true) + expect(wrapper.text()).toContain('No event configuration found.') + }) + + it('should display action buttons for non-OpenNMS vendors', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + const buttons = wrapper.findAll('.action-container button') + expect(buttons.length).equal(3) + }) + + it('should display action buttons for OpenNMS vendor with only Disable Source button and Add Event button', async () => { + const openNmsConfig = { ...mockConfig, vendor: VENDOR_OPENNMS } + wrapper = createWrapper(openNmsConfig) + await wrapper.vm.$nextTick() + + expect(wrapper.find('.action-container').exists()).toBe(true) + + const buttons = wrapper.findAll('.action-container button') + expect(buttons.length).equal(2) + + expect(buttons[0].text()).toContain('Add Event') + expect(buttons[1].text()).toContain('Disable Source') + }) + + it('should show "Disable Source" button when source is enabled', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + expect(wrapper.text()).toContain('Disable Source') + }) + + it('should show "Enable Source" button when source is disabled', async () => { + const disabledConfig = { ...mockConfig, enabled: false } + wrapper = createWrapper(disabledConfig) + await wrapper.vm.$nextTick() + + expect(wrapper.text()).toContain('Enable Source') + }) + + it('should navigate back when Go Back button is clicked', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + const backButton = wrapper.get('[data-test="back-button"]') + await backButton.trigger('click') + + expect(mockPush).toHaveBeenCalledWith({ name: 'Event Configuration' }) + }) + + it('should navigate back from not found page', async () => { + wrapper = createWrapper(null) + await wrapper.vm.$nextTick() + + const goBackButton = wrapper.find('.not-found-container button') + await goBackButton.trigger('click') + + expect(mockPush).toHaveBeenCalledWith({ name: 'Event Configuration' }) + }) + + it('should open event modification drawer when Add Event is clicked', async () => { + modificationStore.setSelectedEventConfigSource = vi.fn() + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + const addButton = wrapper.findAll('button').find((btn) => btn.text().includes('Add Event')) + await addButton?.trigger('click') + + expect(modificationStore.setSelectedEventConfigSource).toHaveBeenCalledWith( + store.selectedSource, + CreateEditMode.Create, + expect.objectContaining({ + uei: '', + eventLabel: '', + description: '' + }) + ) + expect(mockPush).toHaveBeenCalledWith({ name: 'Event Configuration New' }) + }) + + it('should show change status dialog when Disable/Enable Source is clicked', async () => { + store.showChangeEventConfigSourceStatusDialog = vi.fn() + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + const statusButton = wrapper.findAll('button').find((btn) => btn.text().includes('Disable Source')) + await statusButton?.trigger('click') + + expect(store.showChangeEventConfigSourceStatusDialog).toHaveBeenCalledWith(mockConfig) + }) + + it('should show delete dialog when Delete Source is clicked', async () => { + store.showDeleteEventConfigSourceDialog = vi.fn() + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + const deleteButton = wrapper.findAll('button').find((btn) => btn.text().includes('Delete Source')) + await deleteButton?.trigger('click') + + expect(store.showDeleteEventConfigSourceDialog).toHaveBeenCalledWith(mockConfig) + }) + + it('should fetch events on mount when route id matches selected source', async () => { + store.fetchEventsBySourceId = vi.fn() + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + expect(store.fetchEventsBySourceId).toHaveBeenCalled() + }) + + it('should not fetch events when route id does not match', async () => { + const differentConfig = { ...mockConfig, id: 999 } + store.selectedSource = differentConfig + store.fetchEventsBySourceId = vi.fn() + wrapper = mount(EventConfigurationDetail, { + global: { + stubs: { + FeatherBackButton: true, + FeatherButton: true, + EventConfigEventTable: true, + DeleteEventConfigSourceDialog: true, + ChangeEventConfigSourceStatusDialog: true + } + } + }) + await wrapper.vm.$nextTick() + expect(store.fetchEventsBySourceId).toHaveBeenCalledTimes(1) + expect(store.fetchEventsBySourceId).toHaveBeenCalledWith() + }) + + it('should render EventConfigEventTable component', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + expect(wrapper.findComponent({ name: 'EventConfigEventTable' }).exists()).toBe(true) + }) + + it('should render DeleteEventConfigSourceDialog component', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + expect(wrapper.findComponent({ name: 'DeleteEventConfigSourceDialog' }).exists()).toBe(true) + }) + + it('should render ChangeEventConfigSourceStatusDialog component', async () => { + wrapper = createWrapper() + await wrapper.vm.$nextTick() + + expect(wrapper.findComponent({ name: 'ChangeEventConfigSourceStatusDialog' }).exists()).toBe(true) + }) + + it('should handle missing config properties gracefully', async () => { + const incompleteConfig = { + id: 1, + name: 'Test', + enabled: true + } as EventConfigSource + + wrapper = createWrapper(incompleteConfig) + await wrapper.vm.$nextTick() + + expect(wrapper.find('.event-config-container').exists()).toBe(true) + }) + + it('should handle zero event count', async () => { + const zeroEventConfig = { ...mockConfig, eventCount: 0 } + wrapper = createWrapper(zeroEventConfig) + await wrapper.vm.$nextTick() + + expect(wrapper.text()).toContain('0') + }) +}) + diff --git a/ui/tests/lib/utils.test.ts b/ui/tests/lib/utils.test.ts index aa00b8dccaae..4c8522fd4048 100644 --- a/ui/tests/lib/utils.test.ts +++ b/ui/tests/lib/utils.test.ts @@ -76,8 +76,8 @@ describe('lib/utils test', () => { expect(ellipsify('', 1)).toBe('') expect(ellipsify('', 4)).toBe('') expect(ellipsify('abc', 4)).toBe('abc') - expect(ellipsify('abcdef', 4)).toBe('abcd...') - expect(ellipsify('Lorem ipsum dolor sit amet', 20)).toBe('Lorem ipsum dolor si...') + expect(ellipsify('abcdef', 4)).toBe(`abc${'\u2026'}`) + expect(ellipsify('Lorem ipsum dolor sit amet', 20)).toBe(`Lorem ipsum dolor s${'\u2026'}`) }) test('test hasNonEmptyProperty', async () => { diff --git a/ui/tests/stores/eventConfigDetailStore.test.ts b/ui/tests/stores/eventConfigDetailStore.test.ts new file mode 100644 index 000000000000..b7078b91cd39 --- /dev/null +++ b/ui/tests/stores/eventConfigDetailStore.test.ts @@ -0,0 +1,546 @@ +import { Severity } from '@/components/EventConfigEventCreate/constants' +import { + changeEventConfigEventStatus, + changeEventConfigSourceStatus, + filterEventConfigEvents +} from '@/services/eventConfigService' +import { useEventConfigDetailStore } from '@/stores/eventConfigDetailStore' +import { EventConfigEvent, EventConfigSource } from '@/types/eventConfig' +import { createPinia, setActivePinia } from 'pinia' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +vi.mock('@/services/eventConfigService', () => ({ + changeEventConfigEventStatus: vi.fn(), + changeEventConfigSourceStatus: vi.fn(), + filterEventConfigEvents: vi.fn() +})) + +describe('useEventConfigDetailStore', () => { + let store: ReturnType + + const mockSource: EventConfigSource = { + id: 1, + name: 'Test Source', + vendor: 'Test Vendor', + description: 'Test Description', + enabled: true, + eventCount: 10, + fileOrder: 1, + uploadedBy: 'testuser', + createdTime: new Date('2024-01-01'), + lastModified: new Date('2024-01-02') + } + + const mockEvents: EventConfigEvent[] = [ + { + id: 1, + uei: 'uei.test.event1', + eventLabel: 'Test Event 1', + description: 'Description 1', + severity: Severity.Major, + enabled: true, + xmlContent: 'content1', + createdTime: new Date('2024-01-01'), + lastModified: new Date('2024-01-02'), + modifiedBy: 'user1', + sourceName: 'Test Source', + vendor: 'Test Vendor', + fileOrder: 1 + }, + { + id: 2, + uei: 'uei.test.event2', + eventLabel: 'Test Event 2', + description: 'Description 2', + severity: Severity.Minor, + enabled: false, + xmlContent: 'content2', + createdTime: new Date('2024-01-03'), + lastModified: new Date('2024-01-04'), + modifiedBy: 'user2', + sourceName: 'Test Source', + vendor: 'Test Vendor', + fileOrder: 2 + } + ] + + const mockFilterResponse = { + events: mockEvents, + totalRecords: 2 + } + + beforeEach(() => { + setActivePinia(createPinia()) + store = useEventConfigDetailStore() + vi.clearAllMocks() + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('should have correct initial state', () => { + expect(store.events).toEqual([]) + expect(store.eventsPagination).toEqual({ + page: 1, + pageSize: 10, + total: 0 + }) + expect(store.eventsSearchTerm).toBe('') + expect(store.eventsSorting).toEqual({ + sortOrder: 'desc', + sortKey: 'createdTime' + }) + expect(store.selectedSource).toBeNull() + expect(store.isLoading).toBe(false) + expect(store.deleteEventConfigEventDialogState).toEqual({ + visible: false, + eventConfigEvent: null + }) + expect(store.changeEventConfigEventStatusDialogState).toEqual({ + visible: false, + eventConfigEvent: null + }) + expect(store.deleteEventConfigSourceDialogState).toEqual({ + visible: false, + eventConfigSource: null + }) + expect(store.changeEventConfigSourceStatusDialogState).toEqual({ + visible: false, + eventConfigSource: null + }) + }) + + it('should fetch events successfully when source is selected', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + await store.fetchEventsBySourceId() + + expect(filterEventConfigEvents).toHaveBeenCalledWith(1, 0, 10, '', 'createdTime', 'desc') + expect(store.events).toEqual(mockEvents) + expect(store.eventsPagination.total).toBe(2) + expect(store.isLoading).toBe(false) + }) + + it('should not fetch when no source is selected', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + store.selectedSource = null + + await store.fetchEventsBySourceId() + + expect(filterEventConfigEvents).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + consoleErrorSpy.mockRestore() + }) + + it('should fetch with correct pagination parameters', async () => { + store.selectedSource = mockSource + store.eventsPagination.page = 3 + store.eventsPagination.pageSize = 20 + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + await store.fetchEventsBySourceId() + + expect(filterEventConfigEvents).toHaveBeenCalledWith(1, 40, 20, '', 'createdTime', 'desc') + }) + + it('should fetch with search term', async () => { + store.selectedSource = mockSource + store.eventsSearchTerm = 'test search' + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + await store.fetchEventsBySourceId() + + expect(filterEventConfigEvents).toHaveBeenCalledWith(1, 0, 10, 'test search', 'createdTime', 'desc') + }) + + it('should handle errors when fetching events', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + const error = new Error('Failed to fetch events') + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockRejectedValue(error) + + await store.fetchEventsBySourceId() + + expect(consoleErrorSpy).toHaveBeenCalledWith('Error fetching events for source ID:', 1, error) + expect(store.isLoading).toBe(false) + consoleErrorSpy.mockRestore() + }) + + it('should set loading state correctly during fetch', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockImplementation( + () => + new Promise((resolve) => { + expect(store.isLoading).toBe(true) + resolve(mockFilterResponse) + }) + ) + + await store.fetchEventsBySourceId() + expect(store.isLoading).toBe(false) + }) + + it('should set selected source', () => { + store.setSelectedEventConfigSource(mockSource) + + expect(store.selectedSource).toEqual(mockSource) + }) + + it('should update selected source', () => { + store.selectedSource = mockSource + const newSource = { ...mockSource, id: 2, name: 'New Source' } + + store.setSelectedEventConfigSource(newSource) + + expect(store.selectedSource).toEqual(newSource) + }) + + it('should handle page change', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + await store.onEventsPageChange(3) + + expect(store.eventsPagination.page).toBe(3) + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should handle page size change and reset page to 1', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + store.eventsPagination.page = 5 + + await store.onEventsPageSizeChange(25) + + expect(store.eventsPagination.page).toBe(1) + expect(store.eventsPagination.pageSize).toBe(25) + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should handle search term change and reset page', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + store.eventsPagination.page = 3 + + await store.onChangeEventsSearchTerm('new search') + + expect(store.eventsSearchTerm).toBe('new search') + expect(store.eventsPagination.page).toBe(1) + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should handle sort change', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + await store.onEventsSortChange('uei', 'asc') + + expect(store.eventsSorting.sortKey).toBe('uei') + expect(store.eventsSorting.sortOrder).toBe('asc') + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should refresh event config events with all defaults', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + store.eventsPagination = { page: 5, pageSize: 25, total: 100 } + store.eventsSearchTerm = 'search term' + store.eventsSorting = { sortKey: 'uei', sortOrder: 'asc' } + + await store.refreshEventConfigEvents() + + expect(store.eventsPagination.page).toBe(1) + expect(store.eventsPagination.pageSize).toBe(10) + expect(store.eventsPagination.total).toBe(2) + expect(store.eventsSearchTerm).toBe('') + expect(store.eventsSorting).toEqual({ + sortKey: 'createdTime', + sortOrder: 'desc' + }) + expect(filterEventConfigEvents).toHaveBeenCalledWith(1, 0, 10, '', 'createdTime', 'desc') + }) + + it('should show delete event dialog', () => { + const mockEvent = mockEvents[0] + + store.showDeleteEventConfigEventDialog(mockEvent) + + expect(store.deleteEventConfigEventDialogState.visible).toBe(true) + expect(store.deleteEventConfigEventDialogState.eventConfigEvent).toEqual(mockEvent) + }) + + it('should hide delete event dialog', () => { + const mockEvent = mockEvents[0] + store.deleteEventConfigEventDialogState = { + visible: true, + eventConfigEvent: mockEvent + } + + store.hideDeleteEventConfigEventDialog() + + expect(store.deleteEventConfigEventDialogState.visible).toBe(false) + expect(store.deleteEventConfigEventDialogState.eventConfigEvent).toBeNull() + }) + + it('should show change event status dialog', () => { + const mockEvent = mockEvents[0] + + store.showChangeEventConfigEventStatusDialog(mockEvent) + + expect(store.changeEventConfigEventStatusDialogState.visible).toBe(true) + expect(store.changeEventConfigEventStatusDialogState.eventConfigEvent).toEqual(mockEvent) + }) + + it('should hide change event status dialog and fetch events', async () => { + const mockEvent = mockEvents[0] + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + store.changeEventConfigEventStatusDialogState = { + visible: true, + eventConfigEvent: mockEvent + } + + await store.hideChangeEventConfigEventStatusDialog() + + expect(store.changeEventConfigEventStatusDialogState.visible).toBe(false) + expect(store.changeEventConfigEventStatusDialogState.eventConfigEvent).toBeNull() + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should show delete source dialog', () => { + store.showDeleteEventConfigSourceDialog(mockSource) + + expect(store.deleteEventConfigSourceDialogState.visible).toBe(true) + expect(store.deleteEventConfigSourceDialogState.eventConfigSource).toEqual(mockSource) + }) + + it('should hide delete source dialog', async () => { + store.deleteEventConfigSourceDialogState = { + visible: true, + eventConfigSource: mockSource + } + + await store.hideDeleteEventConfigSourceDialog() + + expect(store.deleteEventConfigSourceDialogState.visible).toBe(false) + expect(store.deleteEventConfigSourceDialogState.eventConfigSource).toBeNull() + }) + + it('should show change source status dialog', () => { + store.showChangeEventConfigSourceStatusDialog(mockSource) + + expect(store.changeEventConfigSourceStatusDialogState.visible).toBe(true) + expect(store.changeEventConfigSourceStatusDialogState.eventConfigSource).toEqual(mockSource) + }) + + it('should hide change source status dialog', () => { + store.changeEventConfigSourceStatusDialogState = { + visible: true, + eventConfigSource: mockSource + } + + store.hideChangeEventConfigSourceStatusDialog() + + expect(store.changeEventConfigSourceStatusDialogState.visible).toBe(false) + expect(store.changeEventConfigSourceStatusDialogState.eventConfigSource).toBeNull() + }) + + it('should disable event successfully', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + vi.mocked(changeEventConfigEventStatus).mockResolvedValue(true) + + await store.disableEventConfigEvent(1) + + expect(changeEventConfigEventStatus).toHaveBeenCalledWith(1, 1, false) + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should enable event successfully', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + vi.mocked(changeEventConfigEventStatus).mockResolvedValue(true) + + await store.enableEventConfigEvent(1) + + expect(changeEventConfigEventStatus).toHaveBeenCalledWith(1, 1, true) + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should not fetch events if disable fails', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + vi.mocked(changeEventConfigEventStatus).mockResolvedValue(false) + + await store.disableEventConfigEvent(1) + + expect(changeEventConfigEventStatus).toHaveBeenCalledWith(1, 1, false) + expect(filterEventConfigEvents).not.toHaveBeenCalled() + }) + + it('should not fetch events if enable fails', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + vi.mocked(changeEventConfigEventStatus).mockResolvedValue(false) + + await store.enableEventConfigEvent(1) + + expect(changeEventConfigEventStatus).toHaveBeenCalledWith(1, 1, true) + expect(filterEventConfigEvents).not.toHaveBeenCalled() + }) + + it('should log error when disabling event with no source', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + store.selectedSource = null + + await store.disableEventConfigEvent(1) + + expect(changeEventConfigEventStatus).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + consoleErrorSpy.mockRestore() + }) + + it('should disable source successfully', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(true) + + await store.disableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, false) + expect(store.selectedSource?.enabled).toBe(false) + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should enable source successfully', async () => { + store.selectedSource = { ...mockSource, enabled: false } + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(true) + + await store.enableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, true) + expect(store.selectedSource?.enabled).toBe(true) + expect(filterEventConfigEvents).toHaveBeenCalled() + }) + + it('should not update source if disable fails', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + const originalEnabled = store.selectedSource!.enabled + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(false) + + await store.disableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, false) + expect(store.selectedSource?.enabled).toBe(originalEnabled) + expect(filterEventConfigEvents).not.toHaveBeenCalled() + }) + + it('should not update source if enable fails', async () => { + store.selectedSource = { ...mockSource, enabled: false } + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + const originalEnabled = store.selectedSource.enabled + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(false) + + await store.enableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, true) + expect(store.selectedSource?.enabled).toBe(originalEnabled) + expect(filterEventConfigEvents).not.toHaveBeenCalled() + }) + + it('should log error when disabling source with no source id', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + await expect(store.disableEventConfigSource(0)).rejects.toThrow('No source selected') + + expect(changeEventConfigSourceStatus).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + + consoleErrorSpy.mockRestore() + }) + + it('should log error when disabling with no selected source', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + store.selectedSource = null + + await expect(store.disableEventConfigSource(1)).rejects.toThrow('No source selected') + + expect(changeEventConfigSourceStatus).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + consoleErrorSpy.mockRestore() + }) + + it('should log error when enabling source with no source id', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + await expect(store.enableEventConfigSource(0)).rejects.toThrow('No source selected') + + expect(changeEventConfigSourceStatus).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + consoleErrorSpy.mockRestore() + }) + + it('should log error when enabling with no selected source', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + store.selectedSource = null + + await expect(store.enableEventConfigSource(1)).rejects.toThrow('No source selected') + + expect(changeEventConfigSourceStatus).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + consoleErrorSpy.mockRestore() + }) + + it('should handle multiple consecutive fetches correctly', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + await store.fetchEventsBySourceId() + await store.onEventsPageChange(2) + await store.onChangeEventsSearchTerm('test') + + expect(filterEventConfigEvents).toHaveBeenCalledTimes(3) + }) + + it('should maintain state consistency after failed operations', async () => { + store.selectedSource = mockSource + const error = new Error('Network error') + vi.mocked(filterEventConfigEvents).mockRejectedValue(error) + vi.spyOn(console, 'error').mockImplementation(() => {}) + + const initialEvents = [...store.events] + const initialPagination = { ...store.eventsPagination } + + await store.fetchEventsBySourceId() + + expect(store.events).toEqual(initialEvents) + expect(store.eventsPagination).toEqual(initialPagination) + expect(store.isLoading).toBe(false) + }) + + it('should handle changing source and fetching events', async () => { + store.setSelectedEventConfigSource(mockSource) + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + await store.fetchEventsBySourceId() + + expect(store.selectedSource).toEqual(mockSource) + expect(store.events).toEqual(mockEvents) + }) + + it('should handle reset filter', async () => { + store.selectedSource = mockSource + vi.mocked(filterEventConfigEvents).mockResolvedValue(mockFilterResponse) + + store.resetFilters() + + expect(store.eventsSorting).toEqual({ sortKey: 'createdTime', sortOrder: 'desc' }) + expect(store.eventsSearchTerm).toBe('') + expect(store.eventsPagination).toEqual({ page: 1, pageSize: 10, total: 0 }) + }) + +}) diff --git a/ui/tests/stores/eventConfigStore.test.ts b/ui/tests/stores/eventConfigStore.test.ts new file mode 100644 index 000000000000..8644700aeb4a --- /dev/null +++ b/ui/tests/stores/eventConfigStore.test.ts @@ -0,0 +1,410 @@ +import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest' +import { setActivePinia, createPinia } from 'pinia' +import { useEventConfigStore } from '@/stores/eventConfigStore' +import { + changeEventConfigSourceStatus, + filterEventConfigSources, + getAllSourceNames +} from '@/services/eventConfigService' +import { EventConfigSource } from '@/types/eventConfig' + +vi.mock('@/services/eventConfigService', () => ({ + changeEventConfigSourceStatus: vi.fn(), + filterEventConfigSources: vi.fn(), + getAllSourceNames: vi.fn() +})) + +describe('useEventConfigStore', () => { + let store: ReturnType + + const mockSourceNames = ['Source1', 'Source2', 'Source3'] + + const mockSources: EventConfigSource[] = [ + { + id: 1, + name: 'Test Source 1', + vendor: 'Vendor A', + description: 'Description 1', + enabled: true, + eventCount: 5, + fileOrder: 1, + uploadedBy: 'user1', + createdTime: new Date('2024-01-01'), + lastModified: new Date('2024-01-02') + }, + { + id: 2, + name: 'Test Source 2', + vendor: 'Vendor B', + description: 'Description 2', + enabled: false, + eventCount: 10, + fileOrder: 2, + uploadedBy: 'user2', + createdTime: new Date('2024-01-03'), + lastModified: new Date('2024-01-04') + } + ] + + const mockFilterResponse = { + sources: mockSources, + totalRecords: 2 + } + + beforeEach(() => { + setActivePinia(createPinia()) + store = useEventConfigStore() + vi.clearAllMocks() + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('should have correct initial state', () => { + expect(store.sources).toEqual([]) + expect(store.sourcesPagination).toEqual({ + page: 1, + pageSize: 10, + total: 0 + }) + expect(store.sourcesSearchTerm).toBe('') + expect(store.sourcesSorting).toEqual({ + sortOrder: 'desc', + sortKey: 'createdTime' + }) + expect(store.isLoading).toBe(false) + expect(store.activeTab).toBe(0) + expect(store.uploadedSourceNames).toEqual([]) + expect(store.uploadedEventConfigFilesReportDialogState.visible).toBe(false) + expect(store.deleteEventConfigSourceDialogState).toEqual({ + visible: false, + eventConfigSource: null + }) + expect(store.changeEventConfigSourceStatusDialogState).toEqual({ + visible: false, + eventConfigSource: null + }) + }) + + it('should fetch all source names successfully', async () => { + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + await store.fetchAllSourcesNames() + + expect(getAllSourceNames).toHaveBeenCalledTimes(1) + expect(store.uploadedSourceNames).toEqual(mockSourceNames) + expect(store.isLoading).toBe(false) + }) + + it('should handle errors when fetching source names', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + const error = new Error('Failed to fetch source names') + vi.mocked(getAllSourceNames).mockRejectedValue(error) + + await store.fetchAllSourcesNames() + + expect(consoleErrorSpy).toHaveBeenCalledWith('Error fetching all event configuration source names:', error) + expect(store.isLoading).toBe(false) + consoleErrorSpy.mockRestore() + }) + + it('should set loading state correctly during fetch', async () => { + vi.mocked(getAllSourceNames).mockImplementation( + () => + new Promise((resolve) => { + expect(store.isLoading).toBe(true) + resolve(mockSourceNames) + }) + ) + + await store.fetchAllSourcesNames() + expect(store.isLoading).toBe(false) + }) + + it('should fetch event configs successfully', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + await store.fetchEventConfigs() + + expect(filterEventConfigSources).toHaveBeenCalledWith(0, 10, '', 'createdTime', 'desc') + expect(getAllSourceNames).toHaveBeenCalledTimes(1) + expect(store.sources).toEqual(mockSources) + expect(store.sourcesPagination.total).toBe(2) + expect(store.uploadedSourceNames).toEqual(mockSourceNames) + expect(store.isLoading).toBe(false) + }) + + it('should fetch with correct pagination parameters', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + store.sourcesPagination.page = 3 + store.sourcesPagination.pageSize = 20 + + await store.fetchEventConfigs() + + expect(filterEventConfigSources).toHaveBeenCalledWith(40, 20, '', 'createdTime', 'desc') + }) + + it('should fetch with search term', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + store.sourcesSearchTerm = 'test search' + + await store.fetchEventConfigs() + + expect(filterEventConfigSources).toHaveBeenCalledWith(0, 10, 'test search', 'createdTime', 'desc') + }) + + it('should fetch with custom sorting', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + store.sourcesSorting = { sortKey: 'name', sortOrder: 'asc' } + + await store.fetchEventConfigs() + + expect(filterEventConfigSources).toHaveBeenCalledWith(0, 10, '', 'name', 'asc') + }) + + it('should handle errors when fetching event configs', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + const error = new Error('Failed to fetch event configs') + vi.mocked(filterEventConfigSources).mockRejectedValue(error) + + await store.fetchEventConfigs() + + expect(consoleErrorSpy).toHaveBeenCalledWith('Error fetching event configurations:', error) + expect(store.isLoading).toBe(false) + consoleErrorSpy.mockRestore() + }) + + it('should handle page change', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + await store.onSourcePageChange(3) + + expect(store.sourcesPagination.page).toBe(3) + expect(filterEventConfigSources).toHaveBeenCalled() + }) + + it('should handle page size change and reset page to 1', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + store.sourcesPagination.page = 5 + + await store.onSourcePageSizeChange(25) + + expect(store.sourcesPagination.page).toBe(1) + expect(store.sourcesPagination.pageSize).toBe(25) + expect(filterEventConfigSources).toHaveBeenCalled() + }) + + it('should reset pagination', () => { + store.sourcesPagination = { page: 5, pageSize: 25, total: 100 } + + store.resetSourcesPagination() + + expect(store.sourcesPagination).toEqual({ + page: 1, + pageSize: 10, + total: 0 + }) + }) + + it('should handle search term change and reset page', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + store.sourcesPagination.page = 3 + + await store.onChangeSourcesSearchTerm('new search') + + expect(store.sourcesSearchTerm).toBe('new search') + expect(store.sourcesPagination.page).toBe(1) + expect(filterEventConfigSources).toHaveBeenCalled() + }) + + it('should handle null search term', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + await store.onChangeSourcesSearchTerm(null as any) + + expect(store.sourcesSearchTerm).toBe('') + }) + + it('should handle sort change', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + await store.onSourcesSortChange('vendor', 'asc') + + expect(store.sourcesSorting.sortKey).toBe('vendor') + expect(store.sourcesSorting.sortOrder).toBe('asc') + expect(filterEventConfigSources).toHaveBeenCalled() + }) + + const mockSource = mockSources[0] + + it('should show delete dialog', () => { + store.showDeleteEventConfigSourceModal(mockSource) + + expect(store.deleteEventConfigSourceDialogState.visible).toBe(true) + expect(store.deleteEventConfigSourceDialogState.eventConfigSource).toEqual(mockSource) + }) + + it('should hide delete dialog', () => { + store.deleteEventConfigSourceDialogState = { + visible: true, + eventConfigSource: mockSource + } + + store.hideDeleteEventConfigSourceModal() + + expect(store.deleteEventConfigSourceDialogState.visible).toBe(false) + expect(store.deleteEventConfigSourceDialogState.eventConfigSource).toBeNull() + }) + + it('should show change status dialog', () => { + store.showChangeEventConfigSourceStatusDialog(mockSource) + + expect(store.changeEventConfigSourceStatusDialogState.visible).toBe(true) + expect(store.changeEventConfigSourceStatusDialogState.eventConfigSource).toEqual(mockSource) + }) + + it('should hide change status dialog', () => { + store.changeEventConfigSourceStatusDialogState = { + visible: true, + eventConfigSource: mockSource + } + + store.hideChangeEventConfigSourceStatusDialog() + + expect(store.changeEventConfigSourceStatusDialogState.visible).toBe(false) + expect(store.changeEventConfigSourceStatusDialogState.eventConfigSource).toBeNull() + }) + beforeEach(() => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + }) + + it('should disable event config source successfully', async () => { + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(true) + + await store.disableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, false) + expect(filterEventConfigSources).toHaveBeenCalled() + }) + + it('should enable event config source successfully', async () => { + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(true) + + await store.enableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, true) + expect(filterEventConfigSources).toHaveBeenCalled() + }) + + it('should not fetch configs if disable fails', async () => { + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(false) + + await store.disableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, false) + expect(filterEventConfigSources).not.toHaveBeenCalled() + }) + + it('should not fetch configs if enable fails', async () => { + vi.mocked(changeEventConfigSourceStatus).mockResolvedValue(false) + + await store.enableEventConfigSource(1) + + expect(changeEventConfigSourceStatus).toHaveBeenCalledWith(1, true) + expect(filterEventConfigSources).not.toHaveBeenCalled() + }) + + it('should log error when disabling with no source id', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + await expect(store.disableEventConfigSource(0)).rejects.toThrow('No source selected') + + expect(changeEventConfigSourceStatus).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + + consoleErrorSpy.mockRestore() + }) + + it('should log error when enabling with no source id', async () => { + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + await expect(store.disableEventConfigSource(0)).rejects.toThrow('No source selected') + + expect(changeEventConfigSourceStatus).not.toHaveBeenCalled() + expect(consoleErrorSpy).toHaveBeenCalledWith('No source selected') + + consoleErrorSpy.mockRestore() + }) + + it('should reset active tab', () => { + store.activeTab = 5 + + store.resetActiveTab() + + expect(store.activeTab).toBe(0) + }) + + it('should refresh events sources with all defaults', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + store.sourcesPagination = { page: 5, pageSize: 25, total: 100 } + store.sourcesSearchTerm = 'search term' + store.sourcesSorting = { sortKey: 'vendor', sortOrder: 'asc' } + + await store.refreshEventsSources() + + expect(store.sourcesPagination.page).toBe(1) + expect(store.sourcesPagination.pageSize).toBe(10) + expect(store.sourcesPagination.total).toBe(2) + expect(store.sourcesSearchTerm).toBe('') + expect(store.sourcesSorting).toEqual({ + sortKey: 'createdTime', + sortOrder: 'desc' + }) + expect(filterEventConfigSources).toHaveBeenCalledWith(0, 10, '', 'createdTime', 'desc') + }) + + it('should handle multiple consecutive fetches correctly', async () => { + vi.mocked(filterEventConfigSources).mockResolvedValue(mockFilterResponse) + vi.mocked(getAllSourceNames).mockResolvedValue(mockSourceNames) + + await store.fetchEventConfigs() + await store.onSourcePageChange(2) + await store.onChangeSourcesSearchTerm('test') + + expect(filterEventConfigSources).toHaveBeenCalledTimes(3) + expect(getAllSourceNames).toHaveBeenCalledTimes(3) + }) + + it('should maintain state consistency after failed operations', async () => { + const error = new Error('Network error') + vi.mocked(filterEventConfigSources).mockRejectedValue(error) + vi.spyOn(console, 'error').mockImplementation(() => {}) + + const initialSources = [...store.sources] + const initialPagination = { ...store.sourcesPagination } + + await store.fetchEventConfigs() + + expect(store.sources).toEqual(initialSources) + expect(store.sourcesPagination).toEqual(initialPagination) + expect(store.isLoading).toBe(false) + }) +}) + diff --git a/ui/yarn.lock b/ui/yarn.lock index 74e10f3b3395..8e7892c9c372 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -56,245 +56,245 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== -"@esbuild/aix-ppc64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz#ee6b7163a13528e099ecf562b972f2bcebe0aa97" - integrity sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw== +"@esbuild/aix-ppc64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz#2ae33300598132cc4cf580dbbb28d30fed3c5c49" + integrity sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg== "@esbuild/android-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== -"@esbuild/android-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz#115fc76631e82dd06811bfaf2db0d4979c16e2cb" - integrity sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg== +"@esbuild/android-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz#927708b3db5d739d6cb7709136924cc81bec9b03" + integrity sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ== "@esbuild/android-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== -"@esbuild/android-arm@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.10.tgz#8d5811912da77f615398611e5bbc1333fe321aa9" - integrity sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w== +"@esbuild/android-arm@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.11.tgz#571f94e7f4068957ec4c2cfb907deae3d01b55ae" + integrity sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg== "@esbuild/android-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== -"@esbuild/android-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.10.tgz#e3e96516b2d50d74105bb92594c473e30ddc16b1" - integrity sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg== +"@esbuild/android-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.11.tgz#8a3bf5cae6c560c7ececa3150b2bde76e0fb81e6" + integrity sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g== "@esbuild/darwin-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== -"@esbuild/darwin-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz#6af6bb1d05887dac515de1b162b59dc71212ed76" - integrity sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA== +"@esbuild/darwin-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz#0a678c4ac4bf8717e67481e1a797e6c152f93c84" + integrity sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w== "@esbuild/darwin-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== -"@esbuild/darwin-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz#99ae82347fbd336fc2d28ffd4f05694e6e5b723d" - integrity sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg== +"@esbuild/darwin-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz#70f5e925a30c8309f1294d407a5e5e002e0315fe" + integrity sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ== "@esbuild/freebsd-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== -"@esbuild/freebsd-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz#0c6d5558a6322b0bdb17f7025c19bd7d2359437d" - integrity sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg== +"@esbuild/freebsd-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz#4ec1db687c5b2b78b44148025da9632397553e8a" + integrity sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA== "@esbuild/freebsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== -"@esbuild/freebsd-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz#8c35873fab8c0857a75300a3dcce4324ca0b9844" - integrity sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA== +"@esbuild/freebsd-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz#4c81abd1b142f1e9acfef8c5153d438ca53f44bb" + integrity sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw== "@esbuild/linux-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== -"@esbuild/linux-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz#3edc2f87b889a15b4cedaf65f498c2bed7b16b90" - integrity sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ== +"@esbuild/linux-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz#69517a111acfc2b93aa0fb5eaeb834c0202ccda5" + integrity sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA== "@esbuild/linux-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== -"@esbuild/linux-arm@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz#86501cfdfb3d110176d80c41b27ed4611471cde7" - integrity sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg== +"@esbuild/linux-arm@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz#58dac26eae2dba0fac5405052b9002dac088d38f" + integrity sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw== "@esbuild/linux-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== -"@esbuild/linux-ia32@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz#e6589877876142537c6864680cd5d26a622b9d97" - integrity sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ== +"@esbuild/linux-ia32@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz#b89d4efe9bdad46ba944f0f3b8ddd40834268c2b" + integrity sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw== "@esbuild/linux-loong64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== -"@esbuild/linux-loong64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz#11119e18781f136d8083ea10eb6be73db7532de8" - integrity sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg== +"@esbuild/linux-loong64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz#11f603cb60ad14392c3f5c94d64b3cc8b630fbeb" + integrity sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw== "@esbuild/linux-mips64el@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== -"@esbuild/linux-mips64el@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz#3052f5436b0c0c67a25658d5fc87f045e7def9e6" - integrity sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA== +"@esbuild/linux-mips64el@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz#b7d447ff0676b8ab247d69dac40a5cf08e5eeaf5" + integrity sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ== "@esbuild/linux-ppc64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== -"@esbuild/linux-ppc64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz#2f098920ee5be2ce799f35e367b28709925a8744" - integrity sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA== +"@esbuild/linux-ppc64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz#b3a28ed7cc252a61b07ff7c8fd8a984ffd3a2f74" + integrity sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw== "@esbuild/linux-riscv64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== -"@esbuild/linux-riscv64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz#fa51d7fd0a22a62b51b4b94b405a3198cf7405dd" - integrity sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA== +"@esbuild/linux-riscv64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz#ce75b08f7d871a75edcf4d2125f50b21dc9dc273" + integrity sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww== "@esbuild/linux-s390x@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== -"@esbuild/linux-s390x@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz#a27642e36fc282748fdb38954bd3ef4f85791e8a" - integrity sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew== +"@esbuild/linux-s390x@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz#cd08f6c73b6b6ff9ccdaabbd3ff6ad3dca99c263" + integrity sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw== "@esbuild/linux-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== -"@esbuild/linux-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz#9d9b09c0033d17529570ced6d813f98315dfe4e9" - integrity sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA== +"@esbuild/linux-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz#3c3718af31a95d8946ebd3c32bb1e699bdf74910" + integrity sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ== -"@esbuild/netbsd-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz#25c09a659c97e8af19e3f2afd1c9190435802151" - integrity sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A== +"@esbuild/netbsd-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz#b4c767082401e3a4e8595fe53c47cd7f097c8077" + integrity sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg== "@esbuild/netbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== -"@esbuild/netbsd-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz#7fa5f6ffc19be3a0f6f5fd32c90df3dc2506937a" - integrity sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig== +"@esbuild/netbsd-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz#f2a930458ed2941d1f11ebc34b9c7d61f7a4d034" + integrity sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A== -"@esbuild/openbsd-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz#8faa6aa1afca0c6d024398321d6cb1c18e72a1c3" - integrity sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw== +"@esbuild/openbsd-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz#b4ae93c75aec48bc1e8a0154957a05f0641f2dad" + integrity sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg== "@esbuild/openbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== -"@esbuild/openbsd-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz#a42979b016f29559a8453d32440d3c8cd420af5e" - integrity sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw== +"@esbuild/openbsd-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz#b42863959c8dcf9b01581522e40012d2c70045e2" + integrity sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw== -"@esbuild/openharmony-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz#fd87bfeadd7eeb3aa384bbba907459ffa3197cb1" - integrity sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag== +"@esbuild/openharmony-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz#b2e717141c8fdf6bddd4010f0912e6b39e1640f1" + integrity sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ== "@esbuild/sunos-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== -"@esbuild/sunos-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz#3a18f590e36cb78ae7397976b760b2b8c74407f4" - integrity sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ== +"@esbuild/sunos-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz#9fbea1febe8778927804828883ec0f6dd80eb244" + integrity sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA== "@esbuild/win32-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== -"@esbuild/win32-arm64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz#e71741a251e3fd971408827a529d2325551f530c" - integrity sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw== +"@esbuild/win32-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz#501539cedb24468336073383989a7323005a8935" + integrity sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q== "@esbuild/win32-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== -"@esbuild/win32-ia32@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz#c6f010b5d3b943d8901a0c87ea55f93b8b54bf94" - integrity sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw== +"@esbuild/win32-ia32@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz#8ac7229aa82cef8f16ffb58f1176a973a7a15343" + integrity sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA== "@esbuild/win32-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== -"@esbuild/win32-x64@0.25.10": - version "0.25.10" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz#e4b3e255a1b4aea84f6e1d2ae0b73f826c3785bd" - integrity sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw== +"@esbuild/win32-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz#5ecda6f3fe138b7e456f4e429edde33c823f392f" + integrity sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.9.0" @@ -383,6 +383,17 @@ "@featherds/utils" "^0.12.42" vue "^3.1.0-0" +"@featherds/back-button@^0.12.42": + version "0.12.42" + resolved "https://registry.yarnpkg.com/@featherds/back-button/-/back-button-0.12.42.tgz#96d968e92a76c0795977898ec471f70e1f2315fa" + integrity sha512-Lzo5/ITYRP3NKxP/raGku7csEzBJPSMjynY8yOjtsWUZ0pogJM6AuLwGK7az5CMNj5uN3r/b5hTFcAv0jIDYSg== + dependencies: + "@featherds/icon" "^0.12.42" + "@featherds/ripple" "^0.12.42" + "@featherds/styles" "^0.12.42" + "@featherds/utils" "^0.12.42" + vue "^3.1.0-0" + "@featherds/button@^0.12.42": version "0.12.42" resolved "https://registry.yarnpkg.com/@featherds/button/-/button-0.12.42.tgz#687b5c14e4b1644b776b02160f0b70f30f665b0e" @@ -702,6 +713,15 @@ "@featherds/utils" "^0.12.42" vue "^3.1.0" +"@featherds/toggle-button@^0.12.42": + version "0.12.42" + resolved "https://registry.yarnpkg.com/@featherds/toggle-button/-/toggle-button-0.12.42.tgz#2c55733d2912e831b4ddd725808827359112befd" + integrity sha512-jwIrvyrVma+756srQzrDyKukWwWLNwNFoWqAYM2vzP6h2NgD1+uINx0qdBWLCVkug8XcJqF9nrInrKK9MXfQRg== + dependencies: + "@featherds/ripple" "^0.12.42" + "@featherds/styles" "^0.12.42" + vue "^3.1.0-0" + "@featherds/tooltip@0.12.42": version "0.12.42" resolved "https://registry.yarnpkg.com/@featherds/tooltip/-/tooltip-0.12.42.tgz#ee11d755cf8665a637b75e3e153416cbf722aafc" @@ -902,141 +922,141 @@ estree-walker "^2.0.2" picomatch "^4.0.2" -"@rollup/rollup-android-arm-eabi@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz#7050c2acdc1214a730058e21f613ab0e1fe1ced9" - integrity sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw== - -"@rollup/rollup-android-arm64@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz#3f5b2afbfcbe9021649701cf6ff0d54b1fb7e4a5" - integrity sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw== - -"@rollup/rollup-darwin-arm64@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz#70a1679fb4393ba7bafb730ee56a5278cbcdafb0" - integrity sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg== - -"@rollup/rollup-darwin-x64@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz#ae75aec88fa72069de9bca3a3ec22bf4e6a962bf" - integrity sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A== - -"@rollup/rollup-freebsd-arm64@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz#8a2bda997faa1d7e335ce1961ce71d1a76ac6288" - integrity sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ== - -"@rollup/rollup-freebsd-x64@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz#fc287bcc39b9a9c0df97336d68fd5f4458f87977" - integrity sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A== - -"@rollup/rollup-linux-arm-gnueabihf@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz#5b5a2a55dffaa64d7c7a231e80e491219e33d4f3" - integrity sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA== - -"@rollup/rollup-linux-arm-musleabihf@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz#979eab95003c21837ea0fdd8a721aa3e69fa4aa3" - integrity sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA== - -"@rollup/rollup-linux-arm64-gnu@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz#53b89f1289cbeca5ed9b6ca1602a6fe1a29dd4e2" - integrity sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ== - -"@rollup/rollup-linux-arm64-musl@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz#3bbcf5e13c09d0c4c55bd9c75ec6a7aeee56fe28" - integrity sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw== - -"@rollup/rollup-linux-loong64-gnu@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz#1cc71838465a8297f92ccc5cc9c29756b71f6e73" - integrity sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg== - -"@rollup/rollup-linux-ppc64-gnu@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz#fe3fdf2ef57dc2d58fedd4f1e0678660772c843a" - integrity sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw== - -"@rollup/rollup-linux-riscv64-gnu@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz#eebc99e75832891d58532501879ca749b1592f93" - integrity sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg== - -"@rollup/rollup-linux-riscv64-musl@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz#9a2df234d61763a44601eba17c36844a18f20539" - integrity sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg== - -"@rollup/rollup-linux-s390x-gnu@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz#f0e45ea7e41ee473c85458b1ec8fab9572cc1834" - integrity sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg== - -"@rollup/rollup-linux-x64-gnu@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz#ed63dec576799fa5571eee5b2040f65faa82b49b" - integrity sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA== - -"@rollup/rollup-linux-x64-musl@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz#755c56ac79b17fbdf0359bce7e2293a11de30ad0" - integrity sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw== - -"@rollup/rollup-openharmony-arm64@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz#84b4170fe28c2b41e406add6ccf8513bf91195ea" - integrity sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA== - -"@rollup/rollup-win32-arm64-msvc@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz#4fb0cd004183da819bec804eba70f1ef6936ccbf" - integrity sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA== - -"@rollup/rollup-win32-ia32-msvc@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz#1788ba80313477a31e6214390906201604ee38eb" - integrity sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g== - -"@rollup/rollup-win32-x64-gnu@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz#867222f288a9557487900c7836998123ebbadc9d" - integrity sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ== - -"@rollup/rollup-win32-x64-msvc@4.52.3": - version "4.52.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz#3f55b6e8fe809a7d29959d6bc686cce1804581f0" - integrity sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA== +"@rollup/rollup-android-arm-eabi@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz#59e7478d310f7e6a7c72453978f562483828112f" + integrity sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA== + +"@rollup/rollup-android-arm64@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz#a825192a0b1b2f27a5c950c439e7e37a33c5d056" + integrity sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w== + +"@rollup/rollup-darwin-arm64@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz#4ee37078bccd725ae3c5f30ef92efc8e1bf886f3" + integrity sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg== + +"@rollup/rollup-darwin-x64@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz#43cc08bd05bf9f388f125e7210a544e62d368d90" + integrity sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw== + +"@rollup/rollup-freebsd-arm64@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz#bc8e640e28abe52450baf3fc80d9b26d9bb6587d" + integrity sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ== + +"@rollup/rollup-freebsd-x64@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz#e981a22e057cc8c65bb523019d344d3a66b15bbc" + integrity sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw== + +"@rollup/rollup-linux-arm-gnueabihf@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz#4036b68904f392a20f3499d63b33e055b67eb274" + integrity sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ== + +"@rollup/rollup-linux-arm-musleabihf@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz#d3b1b9589606e0ff916801c855b1ace9e733427a" + integrity sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q== + +"@rollup/rollup-linux-arm64-gnu@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz#cbf0943c477e3b96340136dd3448eaf144378cf2" + integrity sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg== + +"@rollup/rollup-linux-arm64-musl@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz#837f5a428020d5dce1c3b4cc049876075402cf78" + integrity sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g== + +"@rollup/rollup-linux-loong64-gnu@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz#532c214ababb32ab4bc21b4054278b9a8979e516" + integrity sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ== + +"@rollup/rollup-linux-ppc64-gnu@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz#93900163b61b49cee666d10ee38257a8b1dd161a" + integrity sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g== + +"@rollup/rollup-linux-riscv64-gnu@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz#f0ffdcc7066ca04bc972370c74289f35c7a7dc42" + integrity sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg== + +"@rollup/rollup-linux-riscv64-musl@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz#361695c39dbe96773509745d77a870a32a9f8e48" + integrity sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA== + +"@rollup/rollup-linux-s390x-gnu@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz#09fc6cc2e266a2324e366486ae5d1bca48c43a6a" + integrity sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA== + +"@rollup/rollup-linux-x64-gnu@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz#aa9d5b307c08f05d3454225bb0a2b4cc87eeb2e1" + integrity sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg== + +"@rollup/rollup-linux-x64-musl@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz#26949e5b4645502a61daba2f7a8416bd17cb5382" + integrity sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw== + +"@rollup/rollup-openharmony-arm64@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz#ef493c072f9dac7e0edb6c72d63366846b6ffcd9" + integrity sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA== + +"@rollup/rollup-win32-arm64-msvc@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz#56e1aaa6a630d2202ee7ec0adddd05cf384ffd44" + integrity sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ== + +"@rollup/rollup-win32-ia32-msvc@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz#0a44bbf933a9651c7da2b8569fa448dec0de7480" + integrity sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw== + +"@rollup/rollup-win32-x64-gnu@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz#730e12f0b60b234a7c02d5d3179ca3ec7972033d" + integrity sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ== + +"@rollup/rollup-win32-x64-msvc@4.52.4": + version "4.52.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz#5b2dd648a960b8fa00d76f2cc4eea2f03daa80f4" + integrity sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w== "@scarf/scarf@=1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.4.0.tgz#3bbb984085dbd6d982494538b523be1ce6562972" integrity sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ== -"@swagger-api/apidom-ast@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-beta.50.tgz#9e0f4132ea54dd4fca0f31f919a0c5aad12d93c1" - integrity sha512-uUBUm6J6KlyKppyfS7DIW37De6oyMVIpHYmaNV3YAaDMuRMov5KHHWXKbqWlI+l493OljOcXEqDIPeLzm6B5PQ== +"@swagger-api/apidom-ast@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-beta.51.tgz#14ab3c9a111f7a14c7095db381e51d92065a1282" + integrity sha512-Rv65OTHMUdrKpRuyX4J4kSlrd8VownsGYGaA2Ytp9RCeOZkSQKeK38QO5x9XZZZyQAaDIccPI80MdIO7qqlbKQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-error" "^1.0.0-beta.50" + "@swagger-api/apidom-error" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" unraw "^3.0.0" -"@swagger-api/apidom-core@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-core@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.50.tgz#d9ed6821d1b38b66ed8cd0b8d8bf5de997354178" - integrity sha512-9N7ySdyzx/3kUnprAi63GQNt+Kq8VUvErwDgPcMRAsZX8jUhk9KLJ9N0fup4mWm6+xGs0JH35wxBxnanS6aiqw== +"@swagger-api/apidom-core@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-core@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.51.tgz#57c8f0c67fab3bc82c9f73016e36e71de7f692c2" + integrity sha512-vDtp1bUWm91S3Pn2Ry2ksZOfZPDiOQIhdkpB/Q0Jy6cRJCIz/IPiLWTfUaypmPCRcxcnyOXEUCSPWd+jKHKRMw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" + "@swagger-api/apidom-ast" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" minim "~0.23.8" ramda "~0.30.0" @@ -1044,263 +1064,263 @@ short-unique-id "^5.3.2" ts-mixer "^6.0.3" -"@swagger-api/apidom-error@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-error@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.50.tgz#4354c4ade0482824ec7b17667390057f87838ddd" - integrity sha512-vdpi2nRVcxXLGc68JPNwTcKrCKl8PnOEPuykZSxeNbDKnZY80APbsoLDX+1gdRgafK/7k5XdsBkpDQscsTkDng== +"@swagger-api/apidom-error@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-error@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.51.tgz#6599d7ee2fe25b29217823c5eca2620394ffb710" + integrity sha512-8Q1ghVuN83si6v6y/hiUYAXCDsSQEiWYHyyD1IzlDBb/f+lGu78nqaBC3cduvv/rMS1nLv8gvhMd2Gs//eDAhg== dependencies: "@babel/runtime-corejs3" "^7.20.7" -"@swagger-api/apidom-json-pointer@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.50.tgz#8d2c4129c0d59cf059df3f0e40703114a5c3b49a" - integrity sha512-2TgFKHlZ/SlnTZzY7EwE8xx5Pr2BYePX52xZJFqWnueSAIcCcsrqZeazWIAaDe/gXd47CDqU95nDChMECERspA== +"@swagger-api/apidom-json-pointer@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.51.tgz#e0ebb19cd29f24891e4b8adf07a08c30d8786067" + integrity sha512-GiVTAFr5GwmJY+80w2E9cMuQikPm3bvrlab/6m01N1mR9m/w/kmVD+3CQKAvPN5mIzapLgHZxOLiz2upf0cemw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" "@swaggerexpert/json-pointer" "^2.10.1" -"@swagger-api/apidom-ns-api-design-systems@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-beta.50.tgz#3c0017b124792de457a95a6d0c31b9a4804dd39c" - integrity sha512-VsJLgBHYEBx0tyqUVrOhK4YSknn2mSbxigy92hV0Xn0oXuGibY1NW+2yIE9wwgjutCgtmo0Ovl9pe+cagzSh4w== +"@swagger-api/apidom-ns-api-design-systems@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-beta.51.tgz#cb467747c60443efc56feb4047ac3d09e0fc1014" + integrity sha512-Ldp1kgowyoMTL42zp4kbdiwyv/Vw5eqlXlh0PYxzRPtOr/FEeqyQ5G6n4we99gOWiuQuwCC3uuXARx1rNhspww== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-3-1" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-3-1" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-arazzo-1@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-arazzo-1@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.0.0-beta.50.tgz#bfb4f1a9089c8c88a0bfc93d6ff29246769092f3" - integrity sha512-DsKi4um67e5RMVgEzbiYMa4Z5VcwFncrLF1blxU0Gzc29LB49vc/5NDXgJaJZ7F7rYWNWJ+EqIsbVjEKAiehHg== +"@swagger-api/apidom-ns-arazzo-1@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-arazzo-1@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.0.0-beta.51.tgz#b800053750e8690458464d30e7a45fef73f97958" + integrity sha512-AM80F1f6ii/is6GOCd7RGpeTPoxA1dwy8YCLzAUJqCeEJqtCo3cjuoBqkxNRhipt/0+euauxdHyItiGGlybiBw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-2020-12" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-2020-12" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-asyncapi-2@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-asyncapi-2@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-beta.50.tgz#8ee67e641a84f0b40b2cc742d14b90426d3c6947" - integrity sha512-+iIGnyvdsAlqIIuKzWSXsgwva+g7QkxZ2AkB3jBVIMqLp1AANhHaJz2nBTlgg3PYpcMpek3EutcJWiSTdaaQEQ== +"@swagger-api/apidom-ns-asyncapi-2@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-asyncapi-2@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-beta.51.tgz#b1092aee8402954e27bfa3298f0dd7a7ddb941e4" + integrity sha512-iSkd1NaTG3Dd5cmFpZPirjc3xev66Rx30/G3ETyb2k/kuJQqpYpVv8ctCAZmRsaaY175jqk6OwQd06EyAvPgMg== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-draft-7" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-draft-7" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-json-schema-2019-09@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.0.0-beta.50.tgz#83c0eae65b2c4563c5233acdfbccb66c07065e93" - integrity sha512-QP6DuthV8ZWQnthYbPEVikK5rTN4T5lhnAnmO1v6zOCS9B1heKCFcIYgBhcqCnuZ0Tt8kGOfLyqGMb57lPkCdw== +"@swagger-api/apidom-ns-json-schema-2019-09@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.0.0-beta.51.tgz#6c1dc37935febe7ddd81e69758fdce38729113ea" + integrity sha512-pG9OkKSSpM4fXsrMipOKAvMB0jz4HJ2rvFN/YXwz18/YpTlvGHjwxPjgpRRCRkGQEEKjX7QdswjdeZgLQrVEIQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-draft-7" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-draft-7" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-2020-12@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.0.0-beta.50.tgz#0310fc351efd42695227c012b1407728e1400e92" - integrity sha512-ZaqrtZEXUx35x66ND8sc5vf1sIuWPERA15EdRHeca56E09RnjZMUHkiDvdx78165h31QmM67YLi04zEBYhQS0g== +"@swagger-api/apidom-ns-json-schema-2020-12@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.0.0-beta.51.tgz#41ddfde6d6ce8b7b888649a93134a4bbb1258730" + integrity sha512-1zLSzosZLUuLp3Bb/8NLV/uTMtVY2jGDazUl9bzumIK1rrROsH87HtwHc0LIvQVjoCa1/FSNJWApHm6tNwiKig== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-2019-09" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-2019-09" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-draft-4@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.50.tgz#43b0e37d135b805ab3ea7efce0c5fc5678e95abc" - integrity sha512-aqCwW+iuN7RokH10vDp/eEwlrT4LAlHGy1pLzAS9aFVJyUutfm0I4fxLfddOKD2yd04z858zhLwOVSo4BjrLHg== +"@swagger-api/apidom-ns-json-schema-draft-4@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.51.tgz#38959f9373b43a88013c23d7ff90c1db7ff0abf7" + integrity sha512-KRaipRy2ZI1+8Z2OiXBSOSRO/RFyC7lNiXk8h9Yg1W5DDD5H9/AL4Jq6PWJaeAdKaXV/Thgon9fjK4YGPRTlQA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.0.0-beta.50" - "@swagger-api/apidom-core" "^1.0.0-beta.50" + "@swagger-api/apidom-ast" "^1.0.0-beta.51" + "@swagger-api/apidom-core" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-draft-6@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.50.tgz#a311488627a12953a4a331d3b4231c20311aed9c" - integrity sha512-trF1TZZ79WJOjQw3C1Y7wcqNMxxgHMZtJW2/tP5MwII1hqsExGzmGyUuNlVuSC9k9v/9sCj85hQlJ4TW6HFciQ== +"@swagger-api/apidom-ns-json-schema-draft-6@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.51.tgz#46a82b4c217b23b69a307df3d303022ed10cbc74" + integrity sha512-vY7zupA/KS1UUxeM4O0Y4rcb/4df5t77FNj/GVFhbvL62CV+dco5iPsCP6M2jXaPO2OS0wODfC3bIxMbzf5Mig== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-draft-7@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.50.tgz#eb99fdecf9746905331f281578e924082659aef0" - integrity sha512-g9VscnMwjPUYCfR6UxUwsLiIKnyXy2W28J+zN0rbijoSEtUdakcrxwdPhqwgJZHPci8NHNE8574zaocqKBiqSg== +"@swagger-api/apidom-ns-json-schema-draft-7@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.51.tgz#1dea1328484f8656047112bfd6fb750f6284b082" + integrity sha512-VKox5Kb55lH3Ys3ROajw9pOq8FJhU0gTZOACMYVCFHq/ROr6HETDspT6DrAampAUVDqm37x9LVhblopy8v94hA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-draft-6" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-draft-6" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-openapi-2@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-2@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-beta.50.tgz#a51171bfd36c74671e5753e3a1d8d602d2152d3f" - integrity sha512-1kp1BlLFcv6If+hLbJ1wbrRQUpiRHEBwrdNjgflSgK8IIFH9/Q3LWMFsms8lmzQtpOUvPuXBlmMAmpQ1cAljZQ== +"@swagger-api/apidom-ns-openapi-2@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-2@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-beta.51.tgz#212fb54c22571e808e60f6adf301e13a5fa879eb" + integrity sha512-Pv2rPjywIhs0kl8nkWhy5UXbqthHihcXVdNdVJF1aHDBt5VVh49VIWvM+8ngDeCad/xTPQYjeyiURX986kv/ww== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-openapi-3-0@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-0@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-beta.50.tgz#1d9631c0c7504a8985671f2f8e5ca435235b1a54" - integrity sha512-I4GHyNILNxDsYKYeG1+ZA3rnfU1RAYtNp3dA+G8LCX5AB/2N7dT2VPK8HS4cj9m3ZVz7dl1o+X6tpaJIN5kDsA== +"@swagger-api/apidom-ns-openapi-3-0@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-0@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-beta.51.tgz#a174dadd8c6ca8374ec13c1f7c5449b68a556fdd" + integrity sha512-noFmJAQEdrS+Dm662PiJ0fzxzylz/2WzY3ZHdhbs+pVk6RY8pQsfZMIaWSzs6OTZ7BTKzxW1DvTauFRbtPxIeA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-openapi-3-1@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.50.tgz#8b9a0c97849cc107228e66dd746bed858b78c50d" - integrity sha512-kxwuaFl1kQddk/RBS5Mz3rE/6v5mXggqhzVwDBObGjgkRmDRVF5nUalziBRNg6A3NcpYbsjNMU/OCA1JihFkrg== +"@swagger-api/apidom-ns-openapi-3-1@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.51.tgz#6cbdcf5c32bc4b7f16dff2ebe75216310c9e7177" + integrity sha512-CKFZxo8sNd4SPwEmn5z+WzUBPENPMznQ64PDws/CAdJo++YwXuzeI+A6Ut1WPtB3A6n30cmYBBcasZQyuHFe8Q== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.0.0-beta.50" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-json-pointer" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-json-schema-2020-12" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-3-0" "^1.0.0-beta.50" + "@swagger-api/apidom-ast" "^1.0.0-beta.51" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-json-pointer" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-json-schema-2020-12" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-3-0" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" "@swagger-api/apidom-parser-adapter-api-design-systems-json@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-beta.50.tgz#e619b43a750fd0aa31f1e5ed893aeef9821c6755" - integrity sha512-CGH2/BXLR8bSXUXUgVt5az9HSQanvU5YpKke2R9laDnO+9b4w02LhkUHiLtPMX6A+mk9Cax+ktTh6mlSKzq7pA== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-beta.51.tgz#7f8b546256fbe0a36f0c14017de38226aa0e27de" + integrity sha512-5MkROexCuCNGUc1ymznFIIO0F54HAx7mkoJs/0fpYaQWVyjgQT6OKI9ft76Vl8cmGOKA6D7Jp0j8aoVdrjayIw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-api-design-systems" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-api-design-systems" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-api-design-systems-yaml@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-beta.50.tgz#c178588e7868e63ee2ba4ee44fdbe7557c4d1190" - integrity sha512-fcw5FLKgvaPNVhkS1H6mg0uqPO8+R8jR+eFBSZRqm8IQAlzyxE/I5tUCNpMwqQQPShV3H014EHPJjfnihfZQKw== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-beta.51.tgz#214ac8f71e64289caccb3986993b050d2cf35504" + integrity sha512-9drxT6AZzO2HQcGu97x1xAN8VdS6YPZL9K9Hr5fz8RkAR8SBUNblfUm796YNjJESN+Jk4DAiVoGdeI0cf6dsUA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-api-design-systems" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-api-design-systems" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-arazzo-json-1@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.0.0-beta.50.tgz#b5f63f197b99dceaf964ce90116527578c496c75" - integrity sha512-cZWT5Ch0aPxc3uneuAc2lmGt29PTD9SYgkSYrL7EY+ooJetwjSqeLIVw6oBJHjUWtJqyKGdryyylpqNFsHV6qw== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.0.0-beta.51.tgz#44aa8d348b367d75aa666bce4eb632bce08a70c0" + integrity sha512-EEDBI3Z4xWzhsIpFUW94n9H0cuF4lKFczhauKe5ORG2MFwaJ16MNtpnoYvpY5Ad5YZmEEn8QqaBCAgQIi8qsGA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-arazzo-1" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-arazzo-1" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-arazzo-yaml-1@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.0.0-beta.50.tgz#b1dc78ff1669656a2380c4eb003811e4b006a475" - integrity sha512-wnwuzOzB3z141+6XYFs/1R1BKwEFmQjmITEvXHF3r0QzH3ayS+mOkp2NfYN4skDBLOoBCXw5ezr8v9qthW9Ojg== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.0.0-beta.51.tgz#27c45ec110bc90968486d0861109365e32ce4902" + integrity sha512-kUMyMf6KjDIvcfw1ukekVBf/21NA6b1ZmVEtqZK5Kmr8bnUTzrxXdXAksBGuIVhWXduuQsE8kvWigUOoMiFD3A== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-arazzo-1" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-arazzo-1" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-asyncapi-json-2@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-beta.50.tgz#6a9360291d8fef12156f5b8192405a568076cc97" - integrity sha512-mXgT9K+cATsRJulOHveQwZJ3VlqQ11Ashme4Xk1XdUSmavEkKsnmokkz5oo57KwyqaFCQnuI0MtpMkwWZK7zVA== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-beta.51.tgz#36103c91894f749d91bdc9736b8aa6201555dedb" + integrity sha512-bDRE4a67V/GyuKov/ox9nEEhZxKd6kwf+VQxatzm75b+U9PPb2l+105r5mJbi7nGHETt46GCT/ahZcs737wgEw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-asyncapi-2" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-asyncapi-2" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-beta.50.tgz#ebd085661d43b61ed77a23edbd29dc9e84864690" - integrity sha512-N48sPvIqBqlpgENjCun0/inWhFeRG+zK7JVU3lbVrDmSG1xh8cNk3OjKlSisuSwruWACL0z6cL5zdiBXc3FrNQ== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-beta.51.tgz#74d93f11c20dd0ab009b56997b445452c330752c" + integrity sha512-eDZfzv+1lPWZWAk6zaDk8u8FmbvHD4i3WL3AVm5tNG8MkWAEcVzdaXiVb/GMsdmyeZ3qSIG9MPgKCdCUFkjfNw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-asyncapi-2" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-asyncapi-2" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-json@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-parser-adapter-json@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-beta.50.tgz#0f1b581c9653b28766d1a557f32577ded09bbd9d" - integrity sha512-0gqtphuHO0tPnj4rV0x8VSyvDiCTkFY0vb5ILhVk9j5EW+31nxYVwDV8TBnEU5nJmnOvgvmdXhyl/2BvTjT87Q== +"@swagger-api/apidom-parser-adapter-json@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-parser-adapter-json@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-beta.51.tgz#d6d0f48d61707ff4443b137e9bcf696f272d4c6c" + integrity sha512-dkVx3YBoGdbTXtMEdu3i7eQ7R3yYCf9uEGsF2iDQgx7lq5HBmr+JAbWgKbf4hYQRGtSHvm+tpGgkzBPSZAqoRg== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.0.0-beta.50" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" + "@swagger-api/apidom-ast" "^1.0.0-beta.51" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" @@ -1309,92 +1329,92 @@ web-tree-sitter "=0.24.5" "@swagger-api/apidom-parser-adapter-openapi-json-2@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-beta.50.tgz#6da3766866a4479e2d36f95aea907e4558e93190" - integrity sha512-PF9sHWmfWeLIAX3QXKpEOHfSqzvOHK4uDMqF1BgEldqA20rdDH7p3Yedp8Q2EI9EhHvs6o2XqNtgQYHItTXBZg== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-beta.51.tgz#53dd81996ac8c548ae0330d8ec84f0f8445661d7" + integrity sha512-SuNoICSgmP2ZcwRgxJNez2c+iVN59OCuPlYlej4WqJP6EjXJgOwSwpNVKPc7U3XrJX1jRcSWYbI6vKRDFo6dZQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-2" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-2" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-openapi-json-3-0@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-beta.50.tgz#b037e2de1c54d3927bc2a4b0fa3a735cd79aa7b3" - integrity sha512-3/ORyJvETf4Xp8F7PyoKYa5655ndpZX4jxbodbh9JFN8Ruu6yj1parzmLpaL7VoTKbGlozc2TanpHlScBM4zrg== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-beta.51.tgz#ec2edd5dbbc0b7f2c3989940eb8d65e6e6cd0316" + integrity sha512-VnG+7Yi/c4jOaXU0KHyKDzTpiW4fDTvWDq09i3EuEbrWIjDwFBp8RbvVL0zQu3rwiPH0rja+fZscINmHdL+eNA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-3-0" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-3-0" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-openapi-json-3-1@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-beta.50.tgz#84163b81cd945339ba23067125383e4025f31257" - integrity sha512-W3sam19jtnj7A+HS1qbOa23ow/Nb1YwOXhAWUrqt4nGmwdOIfhqRcgKu3jMzGTQWn1dUq7EmmqIsxdI515dHVg== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-beta.51.tgz#45dad0061c580f9c2eb9a0dc602cd01c4598eea2" + integrity sha512-UXgdwLENW3dclCy5JJjiEznmQhtoN2kQV0YfeAYMgVvb/7flR9neq4zKWfmUjjyjsUre2WXowr52qMgQ1LDnCw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-3-1" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-3-1" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-json" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-openapi-yaml-2@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-beta.50.tgz#2f1e4f569cc45e3343a89532c2f0a47135166b25" - integrity sha512-9lWKmFpz/OdQG1PKIwQp+Xr70On45ycu1ioe0Awj9XPhcEGjvFoWysoYMQ9JfSaksj2esdhxpuNe/OUvwGLP9A== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-beta.51.tgz#95c75da4dd3b4b38a3188dfa8cf86e19aa8bbe63" + integrity sha512-tbY48w31+X6qvEVadKIKFOGqpw+y2S7VTb5xPWBn8yQGt+KjaDj2ni+9KiAen8Ulnzuhk3f9KkIV2NJziig8Mw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-2" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-2" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-beta.50.tgz#17c90285ccdd824c31a7e2ad8a684d5b79df1d80" - integrity sha512-VsyYjWdv3Gy48OZKmeOkwGVIaeVBj/TT51mrVF75cH0OyJf9j0st5f2vfQbW98zkleX6vV6G8+ypPjV/gbzneQ== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-beta.51.tgz#5b1fd6feb0ac4bed7f680bacc6a79a36385eee85" + integrity sha512-TEk1d4XsZokhY1k8O1ueZpKo78++o9IIzmM7oI/d5tU9wQ4dxOr2n47zZx5xFWRjjz5g6q3QBzDhTe5COdSRSw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-3-0" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-3-0" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@^1.0.0-beta.40 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-beta.50.tgz#723491ca90bac3cbccd30e4e5cbde2e3219b5d6a" - integrity sha512-Un6K5upQveKG9BTMriRTzDkaE81bfnMOtiXdxrlReOwoVmmXDmpIIqoHRWxGj+Aa0Z700TGk+rlxdAEykdnRTw== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-beta.51.tgz#a1a60da467f0829b951dae464d063696d1e99f29" + integrity sha512-rg5QMNHwdXSJWRQl6Xk61YWu7Echt50zRkvARvEwBE7h0EdDpjdjBMs3ZQwTPjMgtrEuUyNwOKFrAhdpAGvQEA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-ns-openapi-3-1" "^1.0.0-beta.50" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-ns-openapi-3-1" "^1.0.0-beta.51" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-yaml-1-2@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-parser-adapter-yaml-1-2@^1.0.0-beta.50": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-beta.50.tgz#306a94225628e73315623e9b515db4bd1a18a81e" - integrity sha512-EPT4ArNGqRmsiS+dMQY5jTVvBZnBuVv7YvxG6vb3PTuGMG5rkrNIR4MiRQyNVrLdNvn8GxqqW+FJw6vZ/cB/ZA== +"@swagger-api/apidom-parser-adapter-yaml-1-2@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-parser-adapter-yaml-1-2@^1.0.0-beta.51": + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-beta.51.tgz#9d9388ce1121e62badf3c1930538c9b3821bb202" + integrity sha512-mURkw1jK7rVjfyjmcT3nMjl6tZlI2rdIabX4h7PpytM95Rhl885Djy1ee+p1GExVnHNo3G8RtVZLYqHC2AXZNQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.0.0-beta.50" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" + "@swagger-api/apidom-ast" "^1.0.0-beta.51" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" "@tree-sitter-grammars/tree-sitter-yaml" "=0.7.1" "@types/ramda" "~0.30.0" ramda "~0.30.0" @@ -1403,13 +1423,13 @@ web-tree-sitter "=0.24.5" "@swagger-api/apidom-reference@>=1.0.0-beta.50 <1.0.0-rc.0": - version "1.0.0-beta.50" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.50.tgz#d03f5506327e92dff81a4fac6460edcd2bf3989e" - integrity sha512-aD7gTWPgkJb9oYaC4jZPvxb7YbQKG9pWDYZigAkVGqOAbeYxUXeI00XyCLj/cH8l7KwyhTZNX70F7VnfxOkq7w== + version "1.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.51.tgz#0ee0f51a06c8967f51226091ef145d9e54ab0cee" + integrity sha512-JjK5VXyIZtp4teIDIFcwIOmuBOQNc7CpD0wjIruMkNkOEzAWL4Mt+OZ9F2tZaOsNUQjWERM1NDCmb3PfuznVew== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.0.0-beta.50" - "@swagger-api/apidom-error" "^1.0.0-beta.50" + "@swagger-api/apidom-core" "^1.0.0-beta.51" + "@swagger-api/apidom-error" "^1.0.0-beta.51" "@types/ramda" "~0.30.0" axios "^1.12.2" minimatch "^7.4.3" @@ -1708,9 +1728,9 @@ "@types/leaflet" "^1.9" "@types/leaflet@^1.9", "@types/leaflet@^1.9.11": - version "1.9.20" - resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.9.20.tgz#a7feef4b0a4b36335dfc98456e76c0a86ab8462c" - integrity sha512-rooalPMlk61LCaLOvBF2VIf9M47HgMQqi5xQ9QRi7c8PkdIe0WrIi5IxXUXQjAdL0c+vcQ01mYWbthzmp9GHWw== + version "1.9.21" + resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.9.21.tgz#542e8f91250bc444f8a1416d472f5b518d83e979" + integrity sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w== dependencies: "@types/geojson" "*" @@ -1725,11 +1745,11 @@ integrity sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w== "@types/node@>=20": - version "24.6.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.6.1.tgz#29cd365beb4419b3b8271c7464f1a563446d7481" - integrity sha512-ljvjjs3DNXummeIaooB4cLBKg2U6SPI6Hjra/9rRIy7CpM0HpLtG9HptkMKAb4HYWy5S7HUvJEuWgr/y0U8SHw== + version "24.7.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.7.2.tgz#5adf66b6e2ac5cab1d10a2ad3682e359cb652f4a" + integrity sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA== dependencies: - undici-types "~7.13.0" + undici-types "~7.14.0" "@types/ramda@~0.30.0": version "0.30.2" @@ -1760,6 +1780,11 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d" integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== +"@types/vkbeautify@^0.99.4": + version "0.99.4" + resolved "https://registry.yarnpkg.com/@types/vkbeautify/-/vkbeautify-0.99.4.tgz#485911b787e55aaa5a238b4038833f43c3f13f4b" + integrity sha512-IB/vC9R2BPQJDbKaBwG6B8nnBKeu/RMYKVgVBoSiMjj3CmePsRqHaFNLiYov7sBn+CiGe6eqY9UslPv+TEyjvA== + "@types/web-bluetooth@^0.0.14": version "0.0.14" resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.14.tgz#94e175b53623384bff1f354cdb3197a8d63cdbe5" @@ -2420,9 +2445,9 @@ convert-hrtime@^5.0.0: integrity sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg== core-js-pure@^3.43.0: - version "3.45.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.45.1.tgz#b129d86a5f7f8380378577c7eaee83608570a05a" - integrity sha512-OHnWFKgTUshEU8MK+lOs1H8kC8GkTi9Z1tvNkxrCcw9wl3MJIO7q2ld77wjWn4/xuGrVu2X+nME1iIIPBSdyEQ== + version "3.46.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.46.0.tgz#9bb80248584c6334bb54cd381b0f41c619ef1b43" + integrity sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw== cronstrue@^2.11.0: version "2.61.0" @@ -2957,36 +2982,36 @@ esbuild@^0.21.3: "@esbuild/win32-x64" "0.21.5" esbuild@^0.25.0: - version "0.25.10" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.10.tgz#37f5aa5cd14500f141be121c01b096ca83ac34a9" - integrity sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ== + version "0.25.11" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.11.tgz#0f31b82f335652580f75ef6897bba81962d9ae3d" + integrity sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q== optionalDependencies: - "@esbuild/aix-ppc64" "0.25.10" - "@esbuild/android-arm" "0.25.10" - "@esbuild/android-arm64" "0.25.10" - "@esbuild/android-x64" "0.25.10" - "@esbuild/darwin-arm64" "0.25.10" - "@esbuild/darwin-x64" "0.25.10" - "@esbuild/freebsd-arm64" "0.25.10" - "@esbuild/freebsd-x64" "0.25.10" - "@esbuild/linux-arm" "0.25.10" - "@esbuild/linux-arm64" "0.25.10" - "@esbuild/linux-ia32" "0.25.10" - "@esbuild/linux-loong64" "0.25.10" - "@esbuild/linux-mips64el" "0.25.10" - "@esbuild/linux-ppc64" "0.25.10" - "@esbuild/linux-riscv64" "0.25.10" - "@esbuild/linux-s390x" "0.25.10" - "@esbuild/linux-x64" "0.25.10" - "@esbuild/netbsd-arm64" "0.25.10" - "@esbuild/netbsd-x64" "0.25.10" - "@esbuild/openbsd-arm64" "0.25.10" - "@esbuild/openbsd-x64" "0.25.10" - "@esbuild/openharmony-arm64" "0.25.10" - "@esbuild/sunos-x64" "0.25.10" - "@esbuild/win32-arm64" "0.25.10" - "@esbuild/win32-ia32" "0.25.10" - "@esbuild/win32-x64" "0.25.10" + "@esbuild/aix-ppc64" "0.25.11" + "@esbuild/android-arm" "0.25.11" + "@esbuild/android-arm64" "0.25.11" + "@esbuild/android-x64" "0.25.11" + "@esbuild/darwin-arm64" "0.25.11" + "@esbuild/darwin-x64" "0.25.11" + "@esbuild/freebsd-arm64" "0.25.11" + "@esbuild/freebsd-x64" "0.25.11" + "@esbuild/linux-arm" "0.25.11" + "@esbuild/linux-arm64" "0.25.11" + "@esbuild/linux-ia32" "0.25.11" + "@esbuild/linux-loong64" "0.25.11" + "@esbuild/linux-mips64el" "0.25.11" + "@esbuild/linux-ppc64" "0.25.11" + "@esbuild/linux-riscv64" "0.25.11" + "@esbuild/linux-s390x" "0.25.11" + "@esbuild/linux-x64" "0.25.11" + "@esbuild/netbsd-arm64" "0.25.11" + "@esbuild/netbsd-x64" "0.25.11" + "@esbuild/openbsd-arm64" "0.25.11" + "@esbuild/openbsd-x64" "0.25.11" + "@esbuild/openharmony-arm64" "0.25.11" + "@esbuild/sunos-x64" "0.25.11" + "@esbuild/win32-arm64" "0.25.11" + "@esbuild/win32-ia32" "0.25.11" + "@esbuild/win32-x64" "0.25.11" escape-string-regexp@^4.0.0: version "4.0.0" @@ -3160,6 +3185,13 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-xml-parser@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.3.0.tgz#ae388d5a0f6ed31c8ce9e413c1ac89c8e57e7b07" + integrity sha512-gkWGshjYcQCF+6qtlrqBqELqNqnt4CxruY6UVAWWnqb3DQ6qaNFEIKqzYep1XzHLM/QtrHVCxyPOtTk4LTQ7Aw== + dependencies: + strnum "^2.1.0" + fastq@^1.6.0: version "1.19.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5" @@ -3412,9 +3444,9 @@ ignore@^5.2.0, ignore@^5.2.4: integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== immutable@^5.0.2: - version "5.1.3" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.3.tgz#e6486694c8b76c37c063cca92399fa64098634d4" - integrity sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg== + version "5.1.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.4.tgz#e3f8c1fe7b567d56cf26698f31918c241dae8c1f" + integrity sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA== import-fresh@^3.2.1: version "3.3.1" @@ -4181,34 +4213,34 @@ robust-predicates@^3.0.2: integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== rollup@^4.20.0, rollup@^4.34.9: - version "4.52.3" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.52.3.tgz#cc5c28d772b022ce48b235a97b347ccd9d88c1a3" - integrity sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A== + version "4.52.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.52.4.tgz#71e64cce96a865fcbaa6bb62c6e82807f4e378a1" + integrity sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ== dependencies: "@types/estree" "1.0.8" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.52.3" - "@rollup/rollup-android-arm64" "4.52.3" - "@rollup/rollup-darwin-arm64" "4.52.3" - "@rollup/rollup-darwin-x64" "4.52.3" - "@rollup/rollup-freebsd-arm64" "4.52.3" - "@rollup/rollup-freebsd-x64" "4.52.3" - "@rollup/rollup-linux-arm-gnueabihf" "4.52.3" - "@rollup/rollup-linux-arm-musleabihf" "4.52.3" - "@rollup/rollup-linux-arm64-gnu" "4.52.3" - "@rollup/rollup-linux-arm64-musl" "4.52.3" - "@rollup/rollup-linux-loong64-gnu" "4.52.3" - "@rollup/rollup-linux-ppc64-gnu" "4.52.3" - "@rollup/rollup-linux-riscv64-gnu" "4.52.3" - "@rollup/rollup-linux-riscv64-musl" "4.52.3" - "@rollup/rollup-linux-s390x-gnu" "4.52.3" - "@rollup/rollup-linux-x64-gnu" "4.52.3" - "@rollup/rollup-linux-x64-musl" "4.52.3" - "@rollup/rollup-openharmony-arm64" "4.52.3" - "@rollup/rollup-win32-arm64-msvc" "4.52.3" - "@rollup/rollup-win32-ia32-msvc" "4.52.3" - "@rollup/rollup-win32-x64-gnu" "4.52.3" - "@rollup/rollup-win32-x64-msvc" "4.52.3" + "@rollup/rollup-android-arm-eabi" "4.52.4" + "@rollup/rollup-android-arm64" "4.52.4" + "@rollup/rollup-darwin-arm64" "4.52.4" + "@rollup/rollup-darwin-x64" "4.52.4" + "@rollup/rollup-freebsd-arm64" "4.52.4" + "@rollup/rollup-freebsd-x64" "4.52.4" + "@rollup/rollup-linux-arm-gnueabihf" "4.52.4" + "@rollup/rollup-linux-arm-musleabihf" "4.52.4" + "@rollup/rollup-linux-arm64-gnu" "4.52.4" + "@rollup/rollup-linux-arm64-musl" "4.52.4" + "@rollup/rollup-linux-loong64-gnu" "4.52.4" + "@rollup/rollup-linux-ppc64-gnu" "4.52.4" + "@rollup/rollup-linux-riscv64-gnu" "4.52.4" + "@rollup/rollup-linux-riscv64-musl" "4.52.4" + "@rollup/rollup-linux-s390x-gnu" "4.52.4" + "@rollup/rollup-linux-x64-gnu" "4.52.4" + "@rollup/rollup-linux-x64-musl" "4.52.4" + "@rollup/rollup-openharmony-arm64" "4.52.4" + "@rollup/rollup-win32-arm64-msvc" "4.52.4" + "@rollup/rollup-win32-ia32-msvc" "4.52.4" + "@rollup/rollup-win32-x64-gnu" "4.52.4" + "@rollup/rollup-win32-x64-msvc" "4.52.4" fsevents "~2.3.2" run-parallel@^1.1.9: @@ -4252,9 +4284,9 @@ scule@^1.3.0: integrity sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g== semver@^7.3.6, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3: - version "7.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + version "7.7.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== shebang-command@^2.0.0: version "2.0.0" @@ -4314,9 +4346,9 @@ stackback@0.0.2: integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== std-env@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1" - integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw== + version "3.10.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.10.0.tgz#d810b27e3a073047b2b5e40034881f5ea6f9c83b" + integrity sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg== "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" @@ -4378,6 +4410,11 @@ strip-literal@^2.1.1: dependencies: js-tokens "^9.0.1" +strnum@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-2.1.1.tgz#cf2a6e0cf903728b8b2c4b971b7e36b4e82d46ab" + integrity sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw== + super-regex@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/super-regex/-/super-regex-0.2.0.tgz#dc1e071e55cdcf56930eb6271f73653a655b2642" @@ -4561,10 +4598,10 @@ ufo@^1.6.1: resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== -undici-types@~7.13.0: - version "7.13.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.13.0.tgz#a20ba7c0a2be0c97bd55c308069d29d167466bff" - integrity sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ== +undici-types@~7.14.0: + version "7.14.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.14.0.tgz#4c037b32ca4d7d62fae042174604341588bc0840" + integrity sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA== undici@5.28.4: version "5.28.4" @@ -4684,9 +4721,9 @@ vite@^5.0.0: fsevents "~2.3.3" vite@^6.3.5: - version "6.3.6" - resolved "https://registry.yarnpkg.com/vite/-/vite-6.3.6.tgz#69a976b64930750d40219fbc68c5200874d315c1" - integrity sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA== + version "6.4.0" + resolved "https://registry.yarnpkg.com/vite/-/vite-6.4.0.tgz#cc26fce6fc4bb423b3a5e7bbeada7b3cf2d3ac9c" + integrity sha512-oLnWs9Hak/LOlKjeSpOwD6JMks8BeICEdYMJBf6P4Lac/pO9tKiv/XhXnAM7nNfSkZahjlCZu9sS50zL8fSnsw== dependencies: esbuild "^0.25.0" fdir "^6.4.4" @@ -4730,6 +4767,11 @@ vitest@^2.1.9: vite-node "2.1.9" why-is-node-running "^2.3.0" +vkbeautify@^0.99.3: + version "0.99.3" + resolved "https://registry.yarnpkg.com/vkbeautify/-/vkbeautify-0.99.3.tgz#4769b3238c5d772c6ea967545dd1df5582f23297" + integrity sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q== + vue-component-type-helpers@^2.0.0: version "2.2.12" resolved "https://registry.yarnpkg.com/vue-component-type-helpers/-/vue-component-type-helpers-2.2.12.tgz#5014787aad185a22f460ad469cc51f14524308bc" @@ -4763,9 +4805,9 @@ vue-eslint-parser@^9.3.1, vue-eslint-parser@^9.4.3: semver "^7.3.6" vue-router@^4.2.4: - version "4.5.1" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.5.1.tgz#47bffe2d3a5479d2886a9a244547a853aa0abf69" - integrity sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw== + version "4.6.2" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.6.2.tgz#88dc6f9f5b4cd4264ea34a6733298cd00fef38a5" + integrity sha512-my83mxQKXyCms9EegBXZldehOihxBjgSjZqrZwgg4vBacNGl0oBCO+xT//wgOYpLV1RW93ZfqxrjTozd+82nbA== dependencies: "@vue/devtools-api" "^6.6.4"