diff --git a/.circleci/config.yml b/.circleci/config.yml index 0b06430d..98c0e754 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -160,7 +160,6 @@ jobs: mkdir -p ~/dist/ cp assembly/opennms-rpm/target/rpm/opennms-alec-plugin/RPMS/noarch/* ~/dist/ cp assembly/sentinel-rpm/target/rpm/sentinel-alec-plugin/RPMS/noarch/* ~/dist/ - cp assembly/kar/target/opennms-alec-plugin.kar ~/dist/ when: always - store_artifacts: @@ -171,7 +170,6 @@ jobs: root: ~/ paths: - project - - dist/*.kar build-debian: executor: build-debian-executor @@ -239,12 +237,6 @@ jobs: keys: - v1-docker-{{ checksum "smoke-test/src/main/resources/docker_fixed_images" }} - - run: - name: Make the kar available - command: | - mkdir -p ~/assembly/kar/target/ - ln -s ~/dist/opennms-oce-plugin.kar ~/assembly/kar/target/opennms-oce-plugin.kar - - run: name: Import docker images command: | diff --git a/.gitignore b/.gitignore index 10f2cc42..689dd7fb 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,4 @@ java/bin/ dependency-reduced-pom.xml # Ignore any copied KAR files produced for the smoke tests -smoke-test/src/main/resources/sentinel-overlay/deploy/*.kar +*.kar diff --git a/assembly/opennms-deb/pom.xml b/assembly/opennms-deb/pom.xml index 4dd994ae..43924ac8 100644 --- a/assembly/opennms-deb/pom.xml +++ b/assembly/opennms-deb/pom.xml @@ -78,7 +78,7 @@ - ${project.build.directory}/releases/${project.artifactId}-${project.version}/oce/org.opennms.alec.assembly.kar-${project.version}.kar + ${project.build.directory}/releases/${project.artifactId}-${project.version}/alec/org.opennms.alec.assembly.kar-${project.version}.kar ${project.build.directory}/deb/usr/share/opennms/deploy/opennms-alec-plugin.kar diff --git a/assembly/opennms-deb/src/main/assemblies/plugin.xml b/assembly/opennms-deb/src/main/assemblies/plugin.xml index 26cb42cb..486565cf 100644 --- a/assembly/opennms-deb/src/main/assemblies/plugin.xml +++ b/assembly/opennms-deb/src/main/assemblies/plugin.xml @@ -7,7 +7,7 @@ false - /oce/ + /alec/ false true diff --git a/assembly/sentinel-deb/pom.xml b/assembly/sentinel-deb/pom.xml index 15e2c9c8..b6a8f100 100644 --- a/assembly/sentinel-deb/pom.xml +++ b/assembly/sentinel-deb/pom.xml @@ -78,7 +78,7 @@ - ${project.build.directory}/releases/${project.artifactId}-${project.version}/oce/org.opennms.alec.assembly.kar-${project.version}.kar + ${project.build.directory}/releases/${project.artifactId}-${project.version}/alec/org.opennms.alec.assembly.kar-${project.version}.kar ${project.build.directory}/deb/var/lib/sentinel/deploy/opennms-alec-plugin.kar diff --git a/assembly/sentinel-deb/src/main/assemblies/plugin.xml b/assembly/sentinel-deb/src/main/assemblies/plugin.xml index 26cb42cb..486565cf 100644 --- a/assembly/sentinel-deb/src/main/assemblies/plugin.xml +++ b/assembly/sentinel-deb/src/main/assemblies/plugin.xml @@ -7,7 +7,7 @@ false - /oce/ + /alec/ false true diff --git a/datasource/jaxb/src/main/resources/OSGI-INF/blueprint.disabled/blueprint.xml b/datasource/jaxb/src/main/resources/OSGI-INF/blueprint.disabled/blueprint.xml index 77d03539..580bac45 100644 --- a/datasource/jaxb/src/main/resources/OSGI-INF/blueprint.disabled/blueprint.xml +++ b/datasource/jaxb/src/main/resources/OSGI-INF/blueprint.disabled/blueprint.xml @@ -3,7 +3,7 @@ xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"> - + diff --git a/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/ApiMapper.java b/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/ApiMapper.java index faee49f6..e84fa679 100644 --- a/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/ApiMapper.java +++ b/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/ApiMapper.java @@ -123,7 +123,7 @@ private Optional getSituationIdFromAlarm(org.opennms.integration.api.v1. public InMemoryEvent toEvent(Situation situation) { final ImmutableInMemoryEvent.Builder eventBuilder = ImmutableInMemoryEvent.newBuilder(); - eventBuilder.setUei(SITUATION_UEI).setSource("oce"); + eventBuilder.setUei(SITUATION_UEI).setSource("alec"); // Use the max severity as the situation severity final Severity maxSeverity = Severity.fromValue(situation.getAlarms().stream() @@ -145,7 +145,7 @@ public InMemoryEvent toEvent(Situation situation) { String description = earliestAlarm.getDescription(); if (situation.getDiagnosticText() != null) { - description += "\n

OCE Diagnostic: " + situation.getDiagnosticText() + "

"; + description += "\n

ALEC Diagnostic: " + situation.getDiagnosticText() + "

"; } eventBuilder.addParameter(ImmutableEventParameter.newInstance("situationDescr", description)); } diff --git a/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectAlarmFeedbackDatasource.java b/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectAlarmFeedbackDatasource.java index 6f6a1c9c..780c1f74 100644 --- a/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectAlarmFeedbackDatasource.java +++ b/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectAlarmFeedbackDatasource.java @@ -84,7 +84,7 @@ public class DirectAlarmFeedbackDatasource implements AlarmFeedbackListener, Ala /** * @param alarmFeedbackDao used to retrieve the current feedback - * @param mapper used to Map between API and OCE types + * @param mapper used to Map between API and ALEC types */ public DirectAlarmFeedbackDatasource(AlarmFeedbackDao alarmFeedbackDao, ApiMapper mapper) { this.feedbackDao = Objects.requireNonNull(alarmFeedbackDao); diff --git a/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectInventoryDatasource.java b/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectInventoryDatasource.java index 98c45d66..4593f29e 100644 --- a/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectInventoryDatasource.java +++ b/datasource/opennms-direct/src/main/java/org/opennms/alec/datasource/opennms/jvm/DirectInventoryDatasource.java @@ -141,7 +141,7 @@ public class DirectInventoryDatasource implements InventoryDatasource, AlarmLife * @param nodeDao used to retrieve the current inventory * @param alarmDao used to retrieve the current inventory * @param edgeDao used to retrieve the current inventory - * @param mapper used to Map between API and OCE types + * @param mapper used to Map between API and ALEC types */ public DirectInventoryDatasource(NodeDao nodeDao, AlarmDao alarmDao, EdgeDao edgeDao, ApiMapper mapper) { this.nodeDao = Objects.requireNonNull(nodeDao); diff --git a/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/OpennmsMapper.java b/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/OpennmsMapper.java index 7571e71c..0b60728f 100644 --- a/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/OpennmsMapper.java +++ b/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/OpennmsMapper.java @@ -58,12 +58,20 @@ public static Alarm toAlarm(OpennmsModelProtos.Alarm alarm) { alarmBuilder.setNodeId(alarm.getNodeCriteria().getId()); } + // Type and instance may be empty strings and in that case we don't want to set them on the alarm we are + // creating + if(!Strings.isNullOrEmpty(alarm.getManagedObjectType())) { + alarmBuilder.setInventoryObjectType(alarm.getManagedObjectType()); + } + + if(!Strings.isNullOrEmpty(alarm.getManagedObjectInstance())) { + alarmBuilder.setInventoryObjectId(alarm.getManagedObjectInstance()); + } + return alarmBuilder .setId(alarm.getReductionKey()) .setTime(alarm.getLastEventTime()) .setSeverity(toSeverity(alarm.getSeverity())) - .setInventoryObjectType(alarm.getManagedObjectType()) - .setInventoryObjectId(alarm.getManagedObjectInstance()) .setSummary(alarm.getLogMessage()) .setDescription(alarm.getDescription()) .build(); diff --git a/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/SituationToEvent.java b/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/SituationToEvent.java index adc82ce5..386c8693 100644 --- a/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/SituationToEvent.java +++ b/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/SituationToEvent.java @@ -64,7 +64,7 @@ public static Event toEvent(Situation situation) { String description = alarmForDescr.getDescription(); if (situation.getDiagnosticText() != null) { - description += "\n

OCE Diagnostic: " + situation.getDiagnosticText() + "

"; + description += "\n

ALEC Diagnostic: " + situation.getDiagnosticText() + "

"; } e.addParam("situationDescr", description); diff --git a/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/events/Event.java b/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/events/Event.java index d387cf94..ba7bb31f 100644 --- a/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/events/Event.java +++ b/datasource/opennms-kafka/src/main/java/org/opennms/alec/datasource/opennms/events/Event.java @@ -58,7 +58,7 @@ protected synchronized DateFormat initialValue() { private String uei; @XmlElement(name="source") - private String source = "oce"; + private String source = "alec"; @XmlElement(name="parms") private Parameters parameters = new Parameters(); diff --git a/datasource/opennms-kafka/src/main/resources/inventory.groovy b/datasource/opennms-kafka/src/main/resources/inventory.groovy index 0446007e..863c6476 100644 --- a/datasource/opennms-kafka/src/main/resources/inventory.groovy +++ b/datasource/opennms-kafka/src/main/resources/inventory.groovy @@ -26,15 +26,11 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.oce.datasource.opennms +package org.opennms.alec.datasource.opennms import com.google.common.base.Strings import groovy.util.logging.Slf4j -import org.opennms.alec.datasource.common.inventory.Edge -import org.opennms.alec.datasource.common.inventory.ManagedObjectType -import org.opennms.alec.datasource.common.inventory.Port -import org.opennms.alec.datasource.common.inventory.Segment -import org.opennms.alec.datasource.common.inventory.TypeToInventory +import org.opennms.alec.datasource.common.inventory.* import org.opennms.alec.datasource.opennms.EnrichedAlarm import org.opennms.alec.datasource.opennms.InventoryFromAlarm import org.opennms.alec.datasource.opennms.OpennmsMapper diff --git a/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/OpennmsDatasourceIT.java b/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/OpennmsDatasourceIT.java index 3e84ec05..249fd4a0 100644 --- a/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/OpennmsDatasourceIT.java +++ b/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/OpennmsDatasourceIT.java @@ -57,7 +57,7 @@ public abstract class OpennmsDatasourceIT { @Rule public KafkaEmbedded embeddedKafka = new KafkaEmbedded(2, true, 2, - "alarms", "alarmFeedback", "nodes", "oce-inventory", "edges"); + "alarms", "alarmFeedback", "nodes", "alec-inventory", "edges"); @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); diff --git a/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/events/EventMarshalTest.java b/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/events/EventMarshalTest.java index ee5c50c7..0f49813c 100644 --- a/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/events/EventMarshalTest.java +++ b/datasource/opennms-kafka/src/test/java/org/opennms/alec/datasource/opennms/events/EventMarshalTest.java @@ -52,7 +52,7 @@ public void canMarshalAndUnmarshal() { assertThat(JaxbUtils.toXml(e, Event.class), isSimilarTo("\n" + "\n" + " someuei\n" + - " oce\n" + + " alec\n" + " \n" + " \n" + " k1\n" + @@ -75,7 +75,7 @@ public void canMarshalAndUnmarshal() { " \n" + " \n" + " someuei\n" + - " oce\n" + + " alec\n" + " \n" + " \n" + " k1\n" + diff --git a/docs/modules/architecture/pages/opennms_integration.adoc b/docs/modules/architecture/pages/opennms_integration.adoc index 35495dd4..55953c4d 100644 --- a/docs/modules/architecture/pages/opennms_integration.adoc +++ b/docs/modules/architecture/pages/opennms_integration.adoc @@ -11,7 +11,7 @@ These events are then sent to _eventd_ where they are processed and enriched wit _alarmd_ listens for events that contain alarm meta-data and creates or updates alarms that correspond to these. In addition to the existing alarm processing that was present in OpenNMS before 24.0.0, _alarmd_ now expose a series of link:https://github.com/OpenNMS/opennms-integration-api/blob/1f08398169d10538da7379e13eb8f4cd23933450/api/src/main/java/org/opennms/integration/api/v1/alarms/AlarmPersisterExtension.java[hooks] that can be used to alter/enrich the alarms when they are created. -OCE leverages these hooks to perform additional processing and *tag* the alarms with a managed object type and managed object instance. +ALEC leverages these hooks to perform additional processing and *tag* the alarms with a managed object type and managed object instance. See the <> section bellow for more details. OpenNMS also provides facilities to be notified when alarms are in some way modified. diff --git a/docs/modules/datasources/pages/overview.adoc b/docs/modules/datasources/pages/overview.adoc index d53c5a87..3bc319f5 100644 --- a/docs/modules/datasources/pages/overview.adoc +++ b/docs/modules/datasources/pages/overview.adoc @@ -1,9 +1,9 @@ -= OCE Datasources += ALEC Datasources :imagesdir: ../assets/images == Overview -The OCE Datasource is responsible for interacting with the monitoring system and providing a feed of alarms, inventory objects and situations. +The ALEC Datasource is responsible for interacting with the monitoring system and providing a feed of alarms, inventory objects and situations. Data sources are also responsible for creating the situations in the *monitoring system*. We provide two datasources for integrating with OpenNMS: one for the xref:direct.adoc[monolithic deployment] and one for the xref:kafka.adoc[distributed deployment]. diff --git a/docs/modules/engines/pages/deeplearning.adoc b/docs/modules/engines/pages/deeplearning.adoc index aff9ca4b..9bc26310 100644 --- a/docs/modules/engines/pages/deeplearning.adoc +++ b/docs/modules/engines/pages/deeplearning.adoc @@ -58,15 +58,15 @@ Let's take a snapshot of the current graph: opennms-alec:datasource-snapshot /tmp/snap1 ``` -Now edit `/tmp/snap1/oce.situations.xml` to reflect the desired state of situations. +Now edit `/tmp/snap1/alec.situations.xml` to reflect the desired state of situations. Build vectors from the dataset: ``` -opennms-alec:tensorflow-vectorize --alarms-in /tmp/snap1/oce.alarms.xml \ - --inventory-in /tmp/snap1/oce.inventory.xml \ - --situations-in /tmp/snap1/oce.situations.xml \ - --csv-out /tmp/snap1/oce.vector.dataset.csv +opennms-alec:tensorflow-vectorize --alarms-in /tmp/snap1/alec.alarms.xml \ + --inventory-in /tmp/snap1/alec.inventory.xml \ + --situations-in /tmp/snap1/alec.situations.xml \ + --csv-out /tmp/snap1/alec.vector.dataset.csv ``` === Train with Ludwig @@ -74,7 +74,7 @@ opennms-alec:tensorflow-vectorize --alarms-in /tmp/snap1/oce.alarms.xml \ Use Ludwig to train the model: ``` -ludwig train --data_csv /tmp/snap1/oce.vector.dataset.csv --model_definition_file model.yaml +ludwig train --data_csv /tmp/snap1/alec.vector.dataset.csv --model_definition_file model.yaml ``` NOTE: Pull `model.yaml` from the `ludwig_model.yaml` file in the source tree @@ -132,14 +132,14 @@ config:update Generate situations: ``` -opennms-alec:process-alarms --alarms-in /tmp/snap1/oce.alarms.xml \ - --inventory-in /tmp/snap1/oce.inventory.xml \ - --situations-out /tmp/snap1/oce.situations.deeplearning.trained.xml \ +opennms-alec:process-alarms --alarms-in /tmp/snap1/alec.alarms.xml \ + --inventory-in /tmp/snap1/alec.inventory.xml \ + --situations-out /tmp/snap1/alec.situations.deeplearning.trained.xml \ --engine deeplearning ``` Compare results: ``` -opennms-alec:score-situations -s peer /tmp/snap1/oce.situations.xml /tmp/snap1/oce.situations.deeplearning.trained.xml +opennms-alec:score-situations -s peer /tmp/snap1/alec.situations.xml /tmp/snap1/alec.situations.deeplearning.trained.xml ``` diff --git a/docs/modules/install/pages/common_install.adoc b/docs/modules/install/pages/common_install.adoc index 09b91d58..0af4e998 100644 --- a/docs/modules/install/pages/common_install.adoc +++ b/docs/modules/install/pages/common_install.adoc @@ -98,7 +98,7 @@ Number of active alarms stored in Elasticsearch (Alarm History) [ Success ] = === Enable Syslogd -Let's take advantage of the Syslog patterns and event definitions provided in OCE by enabling Syslogd. +Let's take advantage of the Syslog patterns and event definitions provided in ALEC by enabling Syslogd. Enable Syslogd by editing `$OPENNMS_HOME/etc/service-configuration.xml` and changing: ``` diff --git a/engine/cluster/src/main/java/org/opennms/alec/engine/cluster/GraphManager.java b/engine/cluster/src/main/java/org/opennms/alec/engine/cluster/GraphManager.java index ac3f0369..4f36b2fa 100644 --- a/engine/cluster/src/main/java/org/opennms/alec/engine/cluster/GraphManager.java +++ b/engine/cluster/src/main/java/org/opennms/alec/engine/cluster/GraphManager.java @@ -282,7 +282,7 @@ public synchronized Optional addOrUpdateAlarm(Alarm alarm) { } final ResourceKey resourceKey = getResourceKeyFor(alarm); final CEVertex vertex = resourceKeyVertexMap.computeIfAbsent(resourceKey, (key) -> { - LOG.info("No existing vertex was found with resource key: {} for alarm with id: {}. Creating a new vertex.", resourceKey, alarm.getId()); + LOG.info("No existing vertex was found with resource key: {} for alarm with id: {} and contents: {}. Creating a new vertex.", resourceKey, alarm.getId(), alarm); final CEVertex v = new CEVertex(vertexIdGenerator.getAndIncrement(), resourceKey); g.addVertex(v); didGraphChange.set(true); diff --git a/engine/deeplearning/src/main/java/org/opennms/alec/engine/deeplearning/TFModel.java b/engine/deeplearning/src/main/java/org/opennms/alec/engine/deeplearning/TFModel.java index bd3e3d3a..66fcf889 100644 --- a/engine/deeplearning/src/main/java/org/opennms/alec/engine/deeplearning/TFModel.java +++ b/engine/deeplearning/src/main/java/org/opennms/alec/engine/deeplearning/TFModel.java @@ -75,7 +75,7 @@ public TFModel(BundleContext bundleContext, String modelPath) { if (Strings.isNullOrEmpty(modelPath)) { LOG.info("No model path is set. Using default model from class-path."); try { - tempDir = Files.createTempDirectory("oce-tf"); + tempDir = Files.createTempDirectory("alec-tf"); effectiveModelPath = tempDir.toAbsolutePath().toString(); if (bundleContext != null) { // If we're given a bundle context, use it diff --git a/features/graph/common/src/main/java/org/opennms/alec/features/graph/common/GraphMLConverter.java b/features/graph/common/src/main/java/org/opennms/alec/features/graph/common/GraphMLConverter.java index f2a24e04..b20279dc 100644 --- a/features/graph/common/src/main/java/org/opennms/alec/features/graph/common/GraphMLConverter.java +++ b/features/graph/common/src/main/java/org/opennms/alec/features/graph/common/GraphMLConverter.java @@ -99,7 +99,7 @@ public class GraphMLConverter { this.situations = Objects.requireNonNull(situations); long now = new Date().getTime(); inventoryEdgeTimeNormalizer = new EdgeTimeNormalizer(now); - graph.setProperty(ONMS_GRAPHML_GRAPH_NAMESPACE, "oce"); + graph.setProperty(ONMS_GRAPHML_GRAPH_NAMESPACE, "alec"); graph.setProperty(CREATED_TIMESTAMP_KEY, now); doc.addGraph(graph); } diff --git a/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-edge.html b/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-edge.html index 13d8e7c8..88e8d7ef 100644 --- a/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-edge.html +++ b/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-edge.html @@ -1,4 +1,4 @@ -{% set visible = edge != null && edge.namespace == "oce" %} +{% set visible = edge != null && edge.namespace == "alec" %} {% set title = edge.properties.id %} diff --git a/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-vertex.html b/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-vertex.html index a03be853..74fcb48f 100644 --- a/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-vertex.html +++ b/features/graph/common/src/main/resources/overlay/etc/infopanel/oce-vertex.html @@ -1,4 +1,4 @@ -{% set visible = vertex != null && vertex.namespace == "oce" %} +{% set visible = vertex != null && vertex.namespace == "alec" %} {% set title = vertex.properties.tooltipText %} {% set garbageCollected = vertex.properties.garbage_collected != null && vertex.properties.garbage_collected == "true" %} diff --git a/features/shell/src/main/java/org/opennms/alec/features/shell/Snapshot.java b/features/shell/src/main/java/org/opennms/alec/features/shell/Snapshot.java index 8f1b7432..ba50d2fa 100644 --- a/features/shell/src/main/java/org/opennms/alec/features/shell/Snapshot.java +++ b/features/shell/src/main/java/org/opennms/alec/features/shell/Snapshot.java @@ -85,21 +85,21 @@ public Object execute() throws Exception { final Path outputPath = Paths.get(outputFolder); Files.createDirectories(outputPath); - final Path inventoryPath = outputPath.resolve("oce.inventory.xml"); + final Path inventoryPath = outputPath.resolve("alec.inventory.xml"); System.out.printf("Saving inventory to: %s\n", inventoryPath); final List ios = inventoryDatasource.getInventory(); final Inventory inventory = JaxbUtils.toInventory(ios); JaxbUtils.write(inventory, inventoryPath); System.out.printf("Done saving %d inventory objects.\n", inventory.getModelObjectEntry().size()); - final Path alarmsPath = outputPath.resolve("oce.alarms.xml"); + final Path alarmsPath = outputPath.resolve("alec.alarms.xml"); System.out.printf("Saving alarms to: %s\n", alarmsPath); final List apiAlarms = alarmDatasource.getAlarms(); final Alarms alarms = JaxbUtils.toAlarms(apiAlarms); JaxbUtils.write(alarms, alarmsPath); System.out.printf("Done saving %d alarms.\n", alarms.getAlarm().size()); - final Path situationsPath = outputPath.resolve("oce.situations.xml"); + final Path situationsPath = outputPath.resolve("alec.situations.xml"); System.out.printf("Saving situations to: %s\n", situationsPath); final List apiSituations = situationDatasource.getSituations(); final Situations situations = JaxbUtils.toSituations(apiSituations); diff --git a/processor/redundant/src/main/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessor.java b/processor/redundant/src/main/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessor.java index b00e9500..b14b26b4 100644 --- a/processor/redundant/src/main/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessor.java +++ b/processor/redundant/src/main/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessor.java @@ -64,12 +64,12 @@ public class ActiveStandbySituationProcessor implements SituationProcessor, Role /** * The redundancy domain to register with. */ - static final String OCE_DOMAIN = "oce"; + static final String ALEC_DOMAIN = "alec"; /** * The service Id to register with the redundancy domain. */ - private static final String OCE_SERVICE_ID = "oce.driver"; + private static final String ALEC_SERVICE_ID = "alec.driver"; /** * The domain manager. @@ -108,7 +108,7 @@ public class ActiveStandbySituationProcessor implements SituationProcessor, Role private ActiveStandbySituationProcessor(SituationDatasource situationDatasource, DomainManagerFactory domainManagerFactory) { this.situationDatasource = Objects.requireNonNull(situationDatasource); - domainManager = Objects.requireNonNull(domainManagerFactory).getManagerForDomain(OCE_DOMAIN); + domainManager = Objects.requireNonNull(domainManagerFactory).getManagerForDomain(ALEC_DOMAIN); } /** @@ -122,10 +122,10 @@ static ActiveStandbySituationProcessor newInstance(SituationDatasource situation DomainManagerFactory domainManagerFactory) { ActiveStandbySituationProcessor instance = new ActiveStandbySituationProcessor(situationDatasource, domainManagerFactory); - LOG.debug("Registering service {} for domain {}", OCE_SERVICE_ID, OCE_DOMAIN); + LOG.debug("Registering service {} for domain {}", ALEC_SERVICE_ID, ALEC_DOMAIN); // The domain registration has to happen after the instance has been created to prevent leaking a 'this' // reference that may be used by the domain manager before the processor has been fully constructed - instance.domainManager.register(OCE_SERVICE_ID, instance); + instance.domainManager.register(ALEC_SERVICE_ID, instance); return instance; } @@ -198,8 +198,8 @@ Role getCurrentRole() { * Deregister with the domain manager. */ void destroy() { - LOG.debug("Deregistering service {}", OCE_SERVICE_ID); - domainManager.deregister(OCE_SERVICE_ID); + LOG.debug("Deregistering service {}", ALEC_SERVICE_ID); + domainManager.deregister(ALEC_SERVICE_ID); } /** diff --git a/processor/redundant/src/test/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessorTest.java b/processor/redundant/src/test/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessorTest.java index c5f3657b..77419bd3 100644 --- a/processor/redundant/src/test/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessorTest.java +++ b/processor/redundant/src/test/java/org/opennms/alec/processor/redundant/ActiveStandbySituationProcessorTest.java @@ -91,7 +91,7 @@ public void testAcceptWhileActive() throws Exception { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Situation.class); doNothing().when(mockSituationDataSource).forwardSituation(argumentCaptor.capture()); - situationProcessor.handleRoleChange(Role.ACTIVE, ActiveStandbySituationProcessor.OCE_DOMAIN); + situationProcessor.handleRoleChange(Role.ACTIVE, ActiveStandbySituationProcessor.ALEC_DOMAIN); situationProcessor.accept(mockSituation); verify(mockSituationDataSource, times(1)).forwardSituation(mockSituation); @@ -121,7 +121,7 @@ public void testFlushOnSwitchover() throws Exception { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Situation.class); doNothing().when(mockSituationDataSource).forwardSituation(argumentCaptor.capture()); - situationProcessor.handleRoleChange(Role.ACTIVE, ActiveStandbySituationProcessor.OCE_DOMAIN); + situationProcessor.handleRoleChange(Role.ACTIVE, ActiveStandbySituationProcessor.ALEC_DOMAIN); await().atMost(10, TimeUnit.SECONDS).until(() -> situationProcessor.getUnconfirmedSituations().isEmpty()); diff --git a/smoke-test/pom.xml b/smoke-test/pom.xml index a07b0718..e9b1ed01 100644 --- a/smoke-test/pom.xml +++ b/smoke-test/pom.xml @@ -43,13 +43,31 @@ maven-resources-plugin - copy-resources + copy-resources-sentinel validate copy-resources - ${basedir}/src/main/resources/sentinel-overlay/deploy + ${basedir}/src/main/resources/overlays/sentinel-overlay/deploy + + + ${basedir}/../assembly/kar/target + + opennms-alec-plugin.kar + + + + + + + copy-resources-integrated + validate + + copy-resources + + + ${basedir}/src/main/resources/overlays/opennms-integrated-overlay/deploy ${basedir}/../assembly/kar/target @@ -68,7 +86,13 @@ - ${basedir}/src/main/resources/sentinel-overlay/deploy + ${basedir}/src/main/resources/overlays/sentinel-overlay/deploy + + opennms-alec-plugin.kar + + + + ${basedir}/src/main/resources/overlays/opennms-integrated-overlay/deploy opennms-alec-plugin.kar diff --git a/smoke-test/src/main/java/org/opennms/e2e/grafana/Grafana44SeleniumDriver.java b/smoke-test/src/main/java/org/opennms/alec/smoke/grafana/Grafana44SeleniumDriver.java similarity index 99% rename from smoke-test/src/main/java/org/opennms/e2e/grafana/Grafana44SeleniumDriver.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/grafana/Grafana44SeleniumDriver.java index ca716b34..fe293279 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/grafana/Grafana44SeleniumDriver.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/grafana/Grafana44SeleniumDriver.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.grafana; +package org.opennms.alec.smoke.grafana; import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/smoke-test/src/main/java/org/opennms/e2e/grafana/GrafanaRestClient.java b/smoke-test/src/main/java/org/opennms/alec/smoke/grafana/GrafanaRestClient.java similarity index 98% rename from smoke-test/src/main/java/org/opennms/e2e/grafana/GrafanaRestClient.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/grafana/GrafanaRestClient.java index 4fd37a7d..5a913754 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/grafana/GrafanaRestClient.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/grafana/GrafanaRestClient.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.grafana; +package org.opennms.alec.smoke.grafana; import java.io.File; import java.io.IOException; @@ -47,7 +47,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.opennms.e2e.grafana.model.DataSource; +import org.opennms.alec.smoke.grafana.model.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/smoke-test/src/main/java/org/opennms/e2e/grafana/model/DataSource.java b/smoke-test/src/main/java/org/opennms/alec/smoke/grafana/model/DataSource.java similarity index 99% rename from smoke-test/src/main/java/org/opennms/e2e/grafana/model/DataSource.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/grafana/model/DataSource.java index 3bfc7f76..a8d01ab0 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/grafana/model/DataSource.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/grafana/model/DataSource.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.grafana.model; +package org.opennms.alec.smoke.grafana.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/smoke-test/src/main/java/org/opennms/e2e/opennms/OpenNMSRestClient.java b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/OpenNMSRestClient.java similarity index 63% rename from smoke-test/src/main/java/org/opennms/e2e/opennms/OpenNMSRestClient.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/opennms/OpenNMSRestClient.java index 90c70eca..b303c5e2 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/opennms/OpenNMSRestClient.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/OpenNMSRestClient.java @@ -26,18 +26,21 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.opennms; +package org.opennms.alec.smoke.opennms; import static org.awaitility.Awaitility.await; +import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; -import java.util.Arrays; +import java.nio.file.Paths; import java.util.Base64; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -51,12 +54,13 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.opennms.e2e.opennms.model.Alarm; -import org.opennms.e2e.opennms.model.AlarmList; -import org.opennms.e2e.opennms.model.Event; +import org.opennms.alec.smoke.opennms.model.Alarm; +import org.opennms.alec.smoke.opennms.model.AlarmList; +import org.opennms.alec.smoke.opennms.model.Event; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; public class OpenNMSRestClient { @@ -96,8 +100,6 @@ public String getDisplayVersion() { return actualObj.get("displayVersion").asText(); } catch (IOException e) { throw new RuntimeException(e); - } catch (Exception e) { - throw new RuntimeException(e); } } @@ -148,23 +150,69 @@ public void waitForOutstandingSituation() { .until(this::hasActiveSituation); } - public void triggerGenericSituation() { - triggerAlarmsForCorrelation(); - sendEvent(Event.genericSituationAlarmTriggerEvent(Arrays.asList("n1", "n2", "n3"))); + public void triggerAlarmsForCorrelation(int nodeId) { + Event e1 = Event.genericAlarmEventOnNode(nodeId); + sendEvent(e1); + await().atMost(15, TimeUnit.SECONDS).until(() -> testForAlarmWithReductionKey(e1.reductionKey())); + + Event e2 = Event.genericAlarmEventOnNode(nodeId); + sendEvent(e2); + await().atMost(15, TimeUnit.SECONDS).until(() -> testForAlarmWithReductionKey(e2.reductionKey())); + + Event e3 = Event.genericAlarmEventOnNode(nodeId); + sendEvent(e3); + await().atMost(15, TimeUnit.SECONDS).until(() -> testForAlarmWithReductionKey(e3.reductionKey())); + } + + public int addTestNode() throws URISyntaxException { + // The requisition foreign source is hardcoded to "test" in the XML file + addRequisition(); + addNodeToRequisition("test"); + importRequisition("test"); + return waitForNode("test:test"); + } + + private void addRequisition() throws URISyntaxException { + final WebTarget target = getTarget().path("requisitions"); + File requisitionFile = new File(getClass().getClassLoader().getResource(Paths.get("requests", "requisition" + + ".xml").toString()).toURI()); + final Response response = getBuilder(target).post(Entity.xml(requisitionFile)); + if (!Response.Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) { + throw new IllegalArgumentException(String.format("Requisition add failed with %d: %s", response.getStatus(), + response)); + } + } + + private void addNodeToRequisition(String requisitionName) throws URISyntaxException { + final WebTarget target = getTarget().path("requisitions").path(requisitionName).path("nodes"); + File nodeFile = new File(getClass().getClassLoader().getResource(Paths.get("requests", "node" + + ".xml").toString()).toURI()); + final Response response = getBuilder(target).post(Entity.xml(nodeFile)); + if (!Response.Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) { + throw new IllegalArgumentException(String.format("Node add failed with %d: %s", response.getStatus(), + response)); + } } - public void triggerAlarmsForCorrelation() { - Event n1 = Event.genericAlarmTriggerEvent("n1"); - sendEvent(n1); - await().atMost(15, TimeUnit.SECONDS).until(() -> testForAlarmWithReductionKey(n1.reductionKey())); + private void importRequisition(String requisitionName) { + final WebTarget target = getTarget().path("requisitions").path(requisitionName).path("import"); + final Response response = getBuilder(target).put(Entity.json("")); + if (!Response.Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) { + throw new IllegalArgumentException(String.format("Requisition activation failed with %d: %s", + response.getStatus(), response)); + } + } - Event n2 = Event.genericAlarmTriggerEvent("n2"); - sendEvent(n2); - await().atMost(15, TimeUnit.SECONDS).until(() -> testForAlarmWithReductionKey(n2.reductionKey())); + int waitForNode(String criteria) { + final WebTarget target = getTarget().path("nodes").path(criteria); + await().atMost(1, TimeUnit.MINUTES) + .pollInterval(5, TimeUnit.SECONDS) + .until(() -> Response.Status.Family.SUCCESSFUL.equals(getBuilder(target).get().getStatusInfo().getFamily())); + Response response = getBuilder(target).accept(MediaType.APPLICATION_JSON_TYPE).get(); + String responseBody = response.readEntity(String.class); - Event n3 = Event.genericAlarmTriggerEvent("n3"); - sendEvent(n3); - await().atMost(15, TimeUnit.SECONDS).until(() -> testForAlarmWithReductionKey(n3.reductionKey())); + // Return the ID of the node we waited for + return Integer.parseInt((String) new Gson().fromJson(responseBody, Map.class).get("id")); } public void clearAllAlarms() { @@ -183,11 +231,6 @@ private WebTarget getTarget() { return client.target(url.toString()).path("rest"); } - private WebTarget getTargetV2() { - final Client client = ClientBuilder.newClient(); - return client.target(url.toString()).path("api").path("v2"); - } - private Invocation.Builder getBuilder(final WebTarget target) { return target.request().header("Authorization", authorizationHeader); } diff --git a/smoke-test/src/main/java/org/opennms/e2e/opennms/model/Alarm.java b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/Alarm.java similarity index 99% rename from smoke-test/src/main/java/org/opennms/e2e/opennms/model/Alarm.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/Alarm.java index 01a02091..26b2f609 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/opennms/model/Alarm.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/Alarm.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.opennms.model; +package org.opennms.alec.smoke.opennms.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/smoke-test/src/main/java/org/opennms/e2e/opennms/model/AlarmList.java b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/AlarmList.java similarity index 97% rename from smoke-test/src/main/java/org/opennms/e2e/opennms/model/AlarmList.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/AlarmList.java index 7f55515c..2bd25bee 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/opennms/model/AlarmList.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/AlarmList.java @@ -26,10 +26,9 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.opennms.model; +package org.opennms.alec.smoke.opennms.model; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; import java.util.ArrayList; import java.util.List; diff --git a/smoke-test/src/main/java/org/opennms/e2e/opennms/model/Event.java b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/Event.java similarity index 73% rename from smoke-test/src/main/java/org/opennms/e2e/opennms/model/Event.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/Event.java index 6536b5ee..15b4898c 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/opennms/model/Event.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/opennms/model/Event.java @@ -26,46 +26,28 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.opennms.model; +package org.opennms.alec.smoke.opennms.model; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.UUID; public class Event { private String uei; private String severity; + private Integer nodeid; private final List parms = new ArrayList<>(); - private static Event genericAlarmEvent(String node) { + public static Event genericAlarmEventOnNode(int nodeId) { return new Event() .setUei("uei.opennms.org/alarms/trigger") - .addParm(new Parameter("node", Objects.requireNonNull(node))); + .setNodeid(nodeId) + .setSeverity("MAJOR") + .addParm(new Parameter("node", Integer.toString(nodeId))) + .addParm(new Parameter("service", "service." + UUID.randomUUID().toString())); } - public static Event genericAlarmTriggerEvent(String node) { - return genericAlarmEvent(node) - .setSeverity("MAJOR"); - } - - private static Event createGenericSituationAlarmEvent(List nodes) { - Objects.requireNonNull(nodes); - Event event = new Event() - .setUei("uei.opennms.org/alarms/trigger") - .addParm(new Parameter("node", "situation")); - - for (int i = 0; i < nodes.size(); i++) { - event.addParm(new Parameter("related-reductionKey" + (i + 1), - "uei.opennms.org/alarms/trigger:" + nodes.get(i) + "::")); - } - - return event; - } - - public static Event genericSituationAlarmTriggerEvent(List nodes) { - return createGenericSituationAlarmEvent(nodes).setSeverity("MAJOR"); - } - public String getUei() { return uei; } @@ -81,7 +63,12 @@ public String reductionKey() { .findFirst() .get() .getValue(); - return "uei.opennms.org/alarms/trigger:" + node + "::"; + String service = parms.stream() + .filter(parm -> parm.parmName == "service") + .findFirst() + .get() + .getValue(); + return "uei.opennms.org/alarms/trigger:" + node + "::" + service; } public String getSeverity() { @@ -97,11 +84,20 @@ public Event addParm(Parameter parm) { parms.add(parm); return this; } - + public List getParms() { return parms; } + public Integer getNodeid() { + return nodeid; + } + + public Event setNodeid(Integer nodeid) { + this.nodeid = nodeid; + return this; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -109,12 +105,13 @@ public boolean equals(Object o) { Event event = (Event) o; return Objects.equals(uei, event.uei) && Objects.equals(severity, event.severity) && + Objects.equals(nodeid, event.nodeid) && Objects.equals(parms, event.parms); } @Override public int hashCode() { - return Objects.hash(uei, severity, parms); + return Objects.hash(uei, severity, nodeid, parms); } @Override @@ -122,10 +119,11 @@ public String toString() { return "Event{" + "uei='" + uei + '\'' + ", severity='" + severity + '\'' + - ", parms='" + parms + '\'' + + ", nodeid=" + nodeid + + ", parms=" + parms + '}'; } - + public static class Parameter { private final String parmName; private final String value; diff --git a/smoke-test/src/main/java/org/opennms/alec/smoke/util/Cleanup.java b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Cleanup.java new file mode 100644 index 00000000..952b376e --- /dev/null +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Cleanup.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * This file is part of OpenNMS(R). + * + * Copyright (C) 2019 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc. + * + * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. + * + * OpenNMS(R) is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * OpenNMS(R) is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with OpenNMS(R). If not, see: + * http://www.gnu.org/licenses/ + * + * For more information contact: + * OpenNMS(R) Licensing + * http://www.opennms.org/ + * http://www.opennms.com/ + *******************************************************************************/ + +package org.opennms.alec.smoke.util; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Cleanup { + private static final Logger LOG = LoggerFactory.getLogger(Cleanup.class); + + private static boolean shouldSkipCleanup() { + return Boolean.parseBoolean(Optional.ofNullable( + System.getenv("SKIP_CLEANUP_ON_FAILURE")).orElse("false")); + } + + public static void skipCleanupIfNeeded(Throwable t) { + if (shouldSkipCleanup()) { + LOG.error("Error:", t); + LOG.info("Skipping cleanup and halting tests"); + System.exit(1); + } + } +} diff --git a/smoke-test/src/main/java/org/opennms/e2e/util/DockerImageResolver.java b/smoke-test/src/main/java/org/opennms/alec/smoke/util/DockerImageResolver.java similarity index 98% rename from smoke-test/src/main/java/org/opennms/e2e/util/DockerImageResolver.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/util/DockerImageResolver.java index e6bab139..f0b6f31b 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/util/DockerImageResolver.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/util/DockerImageResolver.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.util; +package org.opennms.alec.smoke.util; import java.io.IOException; import java.util.Optional; diff --git a/smoke-test/src/main/java/org/opennms/e2e/util/Karaf.java b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Karaf.java similarity index 80% rename from smoke-test/src/main/java/org/opennms/e2e/util/Karaf.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/util/Karaf.java index 3c876a64..a9813bfc 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/util/Karaf.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Karaf.java @@ -26,17 +26,19 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.util; +package org.opennms.alec.smoke.util; import static java.util.concurrent.TimeUnit.SECONDS; import static org.awaitility.Awaitility.await; +import java.io.File; import java.io.PrintStream; import java.net.InetSocketAddress; +import java.nio.file.Path; import java.util.Arrays; import java.util.concurrent.TimeUnit; -import org.opennms.e2e.util.ssh.SshClient; +import org.opennms.alec.smoke.util.ssh.SshClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -79,4 +81,16 @@ public static void waitForBundleActive(String bundleName, InetSocketAddress serv row.contains("Active")); }); } + + public static void verifyKar(Path overlayDeployPath) { + // We expect to find exactly 1 kar file that will be overlayed onto the deploy directory of the sentinel + // container to install ALEC + File[] karFiles = overlayDeployPath.toFile().listFiles((dir, name) -> name.endsWith(".kar")); + if (karFiles == null || karFiles.length < 1) { + throw new RuntimeException("Could not find the .kar file to deploy ALEC"); + } + if (karFiles.length > 1) { + throw new RuntimeException("Found too many .kar files for deploying ALEC"); + } + } } diff --git a/smoke-test/src/main/java/org/opennms/e2e/util/Network.java b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Network.java similarity index 97% rename from smoke-test/src/main/java/org/opennms/e2e/util/Network.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/util/Network.java index 7e50488e..e69f7006 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/util/Network.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Network.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.util; +package org.opennms.alec.smoke.util; import java.net.InetSocketAddress; diff --git a/smoke-test/src/main/java/org/opennms/e2e/util/Overlay.java b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Overlay.java similarity index 79% rename from smoke-test/src/main/java/org/opennms/e2e/util/Overlay.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/util/Overlay.java index 2f7220c6..40b7ab4a 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/util/Overlay.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/util/Overlay.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.util; +package org.opennms.alec.smoke.util; import java.io.File; import java.io.IOException; @@ -39,10 +39,13 @@ import org.apache.commons.io.FileUtils; public class Overlay { - public static Path createTmpOverlayInClasspath(String fromResourceDir) throws Exception { + public static final String OVERLAY_DIR = "overlays"; + + public static Path createTmpOverlayInClasspath(String overlayDirToCopy) throws Exception { URL resourceDirURL = Thread.currentThread() .getContextClassLoader() - .getResource(Objects.requireNonNull(fromResourceDir)); + .getResource(Objects.requireNonNull(OVERLAY_DIR)); + Path tmpResourceDir = Files.createTempDirectory(Paths.get(resourceDirURL.getPath()).getParent(), "tmp" + ".overlay"); @@ -57,7 +60,13 @@ public static Path createTmpOverlayInClasspath(String fromResourceDir) throws Ex } })); } - FileUtils.copyDirectory(new File(resourceDirURL.toURI()), tmpResourceDir.toFile()); + + if (overlayDirToCopy != null) { + File toCopy = new File(Paths.get(resourceDirURL.getPath(), overlayDirToCopy).toUri()); + if (toCopy.exists()) { + FileUtils.copyDirectory(toCopy, tmpResourceDir.toFile()); + } + } if (!tmpResourceDir.toFile().setReadable(true, false)) { throw new RuntimeException(String.format("Failed to set path %s readable", tmpResourceDir)); @@ -69,4 +78,8 @@ public static Path createTmpOverlayInClasspath(String fromResourceDir) throws Ex return tmpResourceDir; } + + public static String getOverlayDir(String dir) { + return Paths.get(OVERLAY_DIR,dir).toString(); + } } diff --git a/smoke-test/src/main/java/org/opennms/e2e/util/ssh/SLF4JLogger.java b/smoke-test/src/main/java/org/opennms/alec/smoke/util/ssh/SLF4JLogger.java similarity index 98% rename from smoke-test/src/main/java/org/opennms/e2e/util/ssh/SLF4JLogger.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/util/ssh/SLF4JLogger.java index c2c769e2..09212268 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/util/ssh/SLF4JLogger.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/util/ssh/SLF4JLogger.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.util.ssh; +package org.opennms.alec.smoke.util.ssh; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/smoke-test/src/main/java/org/opennms/e2e/util/ssh/SshClient.java b/smoke-test/src/main/java/org/opennms/alec/smoke/util/ssh/SshClient.java similarity index 99% rename from smoke-test/src/main/java/org/opennms/e2e/util/ssh/SshClient.java rename to smoke-test/src/main/java/org/opennms/alec/smoke/util/ssh/SshClient.java index 2a513090..ced2b854 100644 --- a/smoke-test/src/main/java/org/opennms/e2e/util/ssh/SshClient.java +++ b/smoke-test/src/main/java/org/opennms/alec/smoke/util/ssh/SshClient.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.util.ssh; +package org.opennms.alec.smoke.util.ssh; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/smoke-test/src/main/resources/opennms-overlay/deploy/features.xml b/smoke-test/src/main/resources/opennms-overlay/deploy/features.xml deleted file mode 100644 index 98114c23..00000000 --- a/smoke-test/src/main/resources/opennms-overlay/deploy/features.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - opennms-kafka-producer - - \ No newline at end of file diff --git a/smoke-test/src/main/resources/opennms-overlay/etc/org.apache.felix.fileinstall-deploy.cfg b/smoke-test/src/main/resources/opennms-overlay/etc/org.apache.felix.fileinstall-deploy.cfg deleted file mode 100644 index 81cc8a96..00000000 --- a/smoke-test/src/main/resources/opennms-overlay/etc/org.apache.felix.fileinstall-deploy.cfg +++ /dev/null @@ -1,26 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. -# -################################################################################ - -felix.fileinstall.dir = ${karaf.base}/deploy -felix.fileinstall.tmpdir = ${karaf.data}/generated-bundles -# Use a 10 second poll time to avoid initial startup race condition when installing via deploy directory -felix.fileinstall.poll = 10000 -felix.fileinstall.start.level = 80 -felix.fileinstall.active.level = 80 -felix.fileinstall.log.level = 3 diff --git a/smoke-test/src/main/resources/overlays/opennms-distributed-overlay/etc/featuresBoot.d/kafkaProducer.boot b/smoke-test/src/main/resources/overlays/opennms-distributed-overlay/etc/featuresBoot.d/kafkaProducer.boot new file mode 100644 index 00000000..581c70f4 --- /dev/null +++ b/smoke-test/src/main/resources/overlays/opennms-distributed-overlay/etc/featuresBoot.d/kafkaProducer.boot @@ -0,0 +1 @@ +opennms-kafka-producer diff --git a/smoke-test/src/main/resources/opennms-overlay/etc/opennms.properties.d/kafka.properties b/smoke-test/src/main/resources/overlays/opennms-distributed-overlay/etc/opennms.properties.d/kafka.properties similarity index 100% rename from smoke-test/src/main/resources/opennms-overlay/etc/opennms.properties.d/kafka.properties rename to smoke-test/src/main/resources/overlays/opennms-distributed-overlay/etc/opennms.properties.d/kafka.properties diff --git a/smoke-test/src/main/resources/opennms-overlay/etc/org.opennms.features.kafka.producer.client.cfg b/smoke-test/src/main/resources/overlays/opennms-distributed-overlay/etc/org.opennms.features.kafka.producer.client.cfg similarity index 100% rename from smoke-test/src/main/resources/opennms-overlay/etc/org.opennms.features.kafka.producer.client.cfg rename to smoke-test/src/main/resources/overlays/opennms-distributed-overlay/etc/org.opennms.features.kafka.producer.client.cfg diff --git a/smoke-test/src/main/resources/sentinel-overlay-standalone/etc/featuresBoot.d/alec.boot b/smoke-test/src/main/resources/overlays/opennms-integrated-overlay/etc/featuresBoot.d/alec.boot similarity index 71% rename from smoke-test/src/main/resources/sentinel-overlay-standalone/etc/featuresBoot.d/alec.boot rename to smoke-test/src/main/resources/overlays/opennms-integrated-overlay/etc/featuresBoot.d/alec.boot index 5bfce728..6cb5b9a7 100644 --- a/smoke-test/src/main/resources/sentinel-overlay-standalone/etc/featuresBoot.d/alec.boot +++ b/smoke-test/src/main/resources/overlays/opennms-integrated-overlay/etc/featuresBoot.d/alec.boot @@ -1,4 +1,4 @@ -alec-datasource-opennms-kafka wait-for-kar=opennms-alec-plugin +alec-datasource-opennms-direct wait-for-kar=opennms-alec-plugin alec-engine-cluster wait-for-kar=opennms-alec-plugin alec-processor-standalone wait-for-kar=opennms-alec-plugin alec-driver-main wait-for-kar=opennms-alec-plugin diff --git a/smoke-test/src/main/resources/sentinel-overlay-redundant/etc/featuresBoot.d/alec.boot b/smoke-test/src/main/resources/overlays/sentinel-overlay-redundant/etc/featuresBoot.d/alec.boot similarity index 100% rename from smoke-test/src/main/resources/sentinel-overlay-redundant/etc/featuresBoot.d/alec.boot rename to smoke-test/src/main/resources/overlays/sentinel-overlay-redundant/etc/featuresBoot.d/alec.boot diff --git a/smoke-test/src/main/resources/overlays/sentinel-overlay-standalone/etc/featuresBoot.d/alec.boot b/smoke-test/src/main/resources/overlays/sentinel-overlay-standalone/etc/featuresBoot.d/alec.boot new file mode 100644 index 00000000..56786b74 --- /dev/null +++ b/smoke-test/src/main/resources/overlays/sentinel-overlay-standalone/etc/featuresBoot.d/alec.boot @@ -0,0 +1,5 @@ +alec-datasource-opennms-kafka wait-for-kar=opennms-alec-plugin +alec-engine-%ALEC_ENGINE_FEATURE% wait-for-kar=opennms-alec-plugin +alec-processor-standalone wait-for-kar=opennms-alec-plugin +alec-driver-main wait-for-kar=opennms-alec-plugin +alec-features-graph-shell wait-for-kar=opennms-alec-plugin \ No newline at end of file diff --git a/smoke-test/src/main/resources/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.producer.cfg b/smoke-test/src/main/resources/overlays/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.producer.cfg similarity index 100% rename from smoke-test/src/main/resources/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.producer.cfg rename to smoke-test/src/main/resources/overlays/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.producer.cfg diff --git a/smoke-test/src/main/resources/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.streams.cfg b/smoke-test/src/main/resources/overlays/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.streams.cfg similarity index 100% rename from smoke-test/src/main/resources/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.streams.cfg rename to smoke-test/src/main/resources/overlays/sentinel-overlay/etc/org.opennms.alec.datasource.opennms.kafka.streams.cfg diff --git a/smoke-test/src/main/resources/sentinel-overlay/etc/org.opennms.features.distributed.coordination.zookeeper.cfg b/smoke-test/src/main/resources/overlays/sentinel-overlay/etc/org.opennms.features.distributed.coordination.zookeeper.cfg similarity index 100% rename from smoke-test/src/main/resources/sentinel-overlay/etc/org.opennms.features.distributed.coordination.zookeeper.cfg rename to smoke-test/src/main/resources/overlays/sentinel-overlay/etc/org.opennms.features.distributed.coordination.zookeeper.cfg diff --git a/smoke-test/src/main/resources/requests/node.xml b/smoke-test/src/main/resources/requests/node.xml new file mode 100644 index 00000000..e5f828d5 --- /dev/null +++ b/smoke-test/src/main/resources/requests/node.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/smoke-test/src/main/resources/requests/requisition.xml b/smoke-test/src/main/resources/requests/requisition.xml new file mode 100644 index 00000000..52d46c36 --- /dev/null +++ b/smoke-test/src/main/resources/requests/requisition.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/smoke-test/src/main/resources/sentinel-overlay-redundant/deploy/features.xml b/smoke-test/src/main/resources/sentinel-overlay-redundant/deploy/features.xml deleted file mode 100644 index 6e7271a5..00000000 --- a/smoke-test/src/main/resources/sentinel-overlay-redundant/deploy/features.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - mvn:org.opennms.alec/alec-karaf-features/1.0.0-SNAPSHOT/xml/features - - - sentinel-coordination-api - sentinel-coordination-common - sentinel-coordination-zookeeper - alec-datasource-opennms-kafka - alec-engine-cluster - alec-processor-redundant - alec-driver-main - - \ No newline at end of file diff --git a/smoke-test/src/test/java/org/opennms/e2e/alec/AbstractCorrelationTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/ALECSmokeTestBase.java similarity index 58% rename from smoke-test/src/test/java/org/opennms/e2e/alec/AbstractCorrelationTest.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/ALECSmokeTestBase.java index 4b7a63a1..d28351a4 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/alec/AbstractCorrelationTest.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/ALECSmokeTestBase.java @@ -26,120 +26,120 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.alec; +package org.opennms.alec.smoke; import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertThat; -import static org.opennms.e2e.containers.OpenNMSContainer.DB_ALIAS; import static org.opennms.alec.datasource.opennms.OpennmsDatasource.DEFAULT_ALARM_FEEDBACK_TOPIC; import static org.opennms.alec.datasource.opennms.OpennmsDatasource.DEFAULT_ALARM_TOPIC; import static org.opennms.alec.datasource.opennms.OpennmsDatasource.DEFAULT_EDGES_TOPIC; import static org.opennms.alec.datasource.opennms.OpennmsDatasource.DEFAULT_INVENTORY_TOPIC; import static org.opennms.alec.datasource.opennms.OpennmsDatasource.DEFAULT_NODE_TOPIC; +import static org.opennms.alec.smoke.containers.OpenNMSContainer.DB_ALIAS; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.Properties; import java.util.concurrent.TimeUnit; -import org.apache.commons.lang3.tuple.Pair; import org.apache.kafka.clients.admin.AdminClient; import org.apache.kafka.clients.admin.AdminClientConfig; import org.apache.kafka.clients.admin.CreateTopicsResult; import org.apache.kafka.clients.admin.NewTopic; import org.junit.Rule; import org.junit.rules.RuleChain; -import org.opennms.e2e.containers.HelmContainer; -import org.opennms.e2e.containers.ALECSentinelContainer; -import org.opennms.e2e.containers.OpenNMSContainer; -import org.opennms.e2e.grafana.Grafana44SeleniumDriver; -import org.opennms.e2e.grafana.GrafanaRestClient; -import org.opennms.e2e.opennms.OpenNMSRestClient; -import org.opennms.e2e.util.DockerImageResolver; -import org.opennms.e2e.util.Network; +import org.opennms.alec.smoke.containers.BrowserWebDriverContainer; +import org.opennms.alec.smoke.containers.HelmContainer; +import org.opennms.alec.smoke.containers.KafkaContainer; +import org.opennms.alec.smoke.containers.OpenNMSContainer; +import org.opennms.alec.smoke.containers.PostgreSQLContainer; +import org.opennms.alec.smoke.grafana.GrafanaRestClient; +import org.opennms.alec.smoke.opennms.OpenNMSRestClient; +import org.opennms.alec.smoke.util.DockerImageResolver; +import org.opennms.alec.smoke.util.Network; import org.openqa.selenium.remote.DesiredCapabilities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.testcontainers.containers.BrowserWebDriverContainer; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.KafkaContainer; -import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy; import org.testcontainers.containers.wait.strategy.Wait; -public abstract class AbstractCorrelationTest { - private static final Logger LOG = LoggerFactory.getLogger(AbstractCorrelationTest.class); - private static final String PLUGIN_NAME = "opennms-helm-app"; - private static final String DATA_SOURCE_NAME = "OpenNMS-Fault-Management"; - private static final String DASHBOARD_NAME = "Helm-Dashboard"; - private static final String GENERIC_ALARM_TITLE = "Alarm: Generic Trigger"; - - GrafanaRestClient grafanaRestClient; - OpenNMSRestClient openNMSRestClient; +public abstract class ALECSmokeTestBase { + private static final Logger LOG = LoggerFactory.getLogger(ALECSmokeTestBase.class); + protected static final String PLUGIN_NAME = "opennms-helm-app"; + protected static final String DATA_SOURCE_NAME = "OpenNMS-Fault-Management"; + protected static final String DASHBOARD_NAME = "Helm-Dashboard"; + protected static final String GENERIC_ALARM_TITLE = "Alarm: Generic Trigger"; + protected GrafanaRestClient grafanaRestClient; + protected OpenNMSRestClient openNMSRestClient; // Define the containers used by all correlation tests - private final GenericContainer kafkaContainer = new KafkaContainer("4.0.0") + + protected final GenericContainer kafkaContainer = new KafkaContainer("4.0.0") .withNetwork(Network.getNetwork()) .withNetworkAliases("kafka") - .waitingFor(new WaitForKafkaTopics()); - private final GenericContainer postgreSQLContainer = new PostgreSQLContainer(DockerImageResolver.getImageAndTag( + .waitingFor(new ALECSmokeTestBase.WaitForKafkaTopics()); + + protected final GenericContainer postgreSQLContainer = new PostgreSQLContainer(DockerImageResolver.getImageAndTag( "postgres")) .withNetwork(Network.getNetwork()) .withNetworkAliases(DB_ALIAS); - private final OpenNMSContainer opennmsContainer = new OpenNMSContainer(); - private final HelmContainer helmContainer = new HelmContainer(); - private final BrowserWebDriverContainer webDriverContainer = new BrowserWebDriverContainer(DockerImageResolver. - getImageAndTag("selenium")) - .withCapabilities(DesiredCapabilities.chrome()) - .withRecordingMode(BrowserWebDriverContainer.VncRecordingMode.RECORD_FAILING, - new File(Optional.ofNullable(System.getenv("TEST_RECORDING_DIR")).orElse("/tmp"))); - - // This controls the order of startup of the containers - // + + protected final org.testcontainers.containers.BrowserWebDriverContainer webDriverContainer = + new BrowserWebDriverContainer(DockerImageResolver.getImageAndTag("selenium")) + .withCapabilities(DesiredCapabilities.chrome()) + .withRecordingMode(BrowserWebDriverContainer.VncRecordingMode.RECORD_FAILING, + new File(Optional.ofNullable(System.getenv("TEST_RECORDING_DIR")).orElse("/tmp"))); + + protected final OpenNMSContainer opennmsContainer = new OpenNMSContainer(); + + protected final HelmContainer helmContainer = new HelmContainer(); + + // The list of containers to use for tests in startup-order + private final List containers = new ArrayList<>(Arrays.asList(kafkaContainer, postgreSQLContainer, + opennmsContainer, helmContainer)); + // Future improvement could be to define a docker compose file and load that rather than individual // containers in a rule chain @Rule - public final RuleChain rc = containerStartupRuleChain(); + public RuleChain rc = containerStartupRuleChain(); private RuleChain containerStartupRuleChain() { - CorrelationSetupAndCleanupRule setupAndCleanup = new CorrelationSetupAndCleanupRule(this::setup, - this::cleanup, Boolean.parseBoolean(Optional.ofNullable( - System.getenv("SKIP_CLEANUP_ON_FAILURE")).orElse("false"))); - - return RuleChain - .outerRule(kafkaContainer) - .around(postgreSQLContainer) - .around(opennmsContainer) - .around(helmContainer) - // Let subclasses add containers - .around(addTestSpecificContainers()) - // Add the web driver container and the setup/cleanup rules last - .around(webDriverContainer) - .around(setupAndCleanup); + adjustContainersForTest(); + CorrelationSetupAndCleanupRule setupAndCleanup = + new CorrelationSetupAndCleanupRule(() -> setup(getOpennmsContainer()), this::cleanup); + Iterator containerIterator = containers.iterator(); + RuleChain rc = RuleChain.outerRule(containerIterator.next()); + + while (containerIterator.hasNext()) { + rc = rc.around(containerIterator.next()); + } + + // Add the web driver container and the setup/cleanup rules last + return rc.around(webDriverContainer).around(setupAndCleanup); } - RuleChain addTestSpecificContainers() { - // Define a single non-redundant OCE by default - // If additional containers are required this method should be overridden - try { - return RuleChain.outerRule(new ALECSentinelContainer(false)); - } catch (Exception e) { - throw new RuntimeException(e); - } + protected abstract void adjustContainersForTest(); + + protected void addContainers(List containersToAdd) { + containers.addAll(Objects.requireNonNull(containersToAdd)); + } + + protected void replaceContainer(GenericContainer existingContainer, GenericContainer newContainer) { + Objects.requireNonNull(existingContainer); + Objects.requireNonNull(newContainer); + containers.set(containers.indexOf(existingContainer), newContainer); } - void verifyGenericSituation() throws Exception { - new Grafana44SeleniumDriver(webDriverContainer.getWebDriver(), - helmContainer.getHelmUrlForWebDriver()) - .home() - .dashboard(DASHBOARD_NAME) - .verifyAnAlarmIsPresent() - .verifyRelatedAlarmLabels(Collections.singletonList(Pair.of(GENERIC_ALARM_TITLE, 3))); + protected OpenNMSContainer getOpennmsContainer() { + return opennmsContainer; } private void setupHelm(GrafanaRestClient grafanaRestClient) throws IOException { @@ -159,10 +159,10 @@ private void cleanupHelm(GrafanaRestClient grafanaRestClient) { grafanaRestClient.setPluginStatus(PLUGIN_NAME, false); } - private void setup() { + private void setup(OpenNMSContainer openNMSContainer) { LOG.info("Setting up..."); grafanaRestClient = new GrafanaRestClient(helmContainer.getHelmExternalUrl()); - openNMSRestClient = new OpenNMSRestClient(opennmsContainer.getOpenNMSUrl()); + openNMSRestClient = new OpenNMSRestClient(openNMSContainer.getOpenNMSUrl()); try { setupHelm(grafanaRestClient); } catch (IOException e) { @@ -178,7 +178,7 @@ private void cleanup() { cleanupHelm(grafanaRestClient); } - // This ensures the OCE engine can initialize, without the topics it will wait forever + // This ensures the ALEC engine can initialize, without the topics it will wait forever private static class WaitForKafkaTopics extends AbstractWaitStrategy { @Override protected void waitUntilReady() { @@ -192,7 +192,7 @@ protected void waitUntilReady() { int partitions = 8; short replication = 1; - // All of the topics that OCE requires to be present in order to initialize the Kafka datasource + // All of the topics that ALEC requires to be present in order to initialize the Kafka datasource List topics = Arrays.asList( new NewTopic(DEFAULT_ALARM_TOPIC, partitions, replication), new NewTopic(DEFAULT_ALARM_FEEDBACK_TOPIC, partitions, replication), diff --git a/smoke-test/src/test/java/org/opennms/e2e/alec/CorrelationSetupAndCleanupRule.java b/smoke-test/src/test/java/org/opennms/alec/smoke/CorrelationSetupAndCleanupRule.java similarity index 75% rename from smoke-test/src/test/java/org/opennms/e2e/alec/CorrelationSetupAndCleanupRule.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/CorrelationSetupAndCleanupRule.java index 8401586f..d45b5a93 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/alec/CorrelationSetupAndCleanupRule.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/CorrelationSetupAndCleanupRule.java @@ -26,43 +26,36 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.alec; +package org.opennms.alec.smoke; import java.util.Objects; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.opennms.alec.smoke.util.Cleanup; public class CorrelationSetupAndCleanupRule implements TestRule { - private static final Logger LOG = LoggerFactory.getLogger(CorrelationSetupAndCleanupRule.class); private final Runnable setup; private final Runnable cleanup; - private final boolean skipCleanupOnFailure; - CorrelationSetupAndCleanupRule(Runnable setup, Runnable cleanup, boolean skipCleanupOnFailure) { + CorrelationSetupAndCleanupRule(Runnable setup, Runnable cleanup) { this.setup = Objects.requireNonNull(setup); this.cleanup = Objects.requireNonNull(cleanup); - this.skipCleanupOnFailure = skipCleanupOnFailure; } @Override public Statement apply(Statement base, Description description) { return new Statement() { @Override - public void evaluate() throws Throwable { - boolean success = false; + public void evaluate() { try { setup.run(); base.evaluate(); - success = true; + } catch (Throwable t) { + Cleanup.skipCleanupIfNeeded(t); + throw new RuntimeException(t); } finally { - if (!success && skipCleanupOnFailure) { - LOG.info("Skipping cleanup and halting tests"); - System.exit(1); - } cleanup.run(); } } diff --git a/smoke-test/src/test/java/org/opennms/e2e/containers/ALECSentinelContainer.java b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/ALECSentinelContainer.java similarity index 72% rename from smoke-test/src/test/java/org/opennms/e2e/containers/ALECSentinelContainer.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/containers/ALECSentinelContainer.java index 2415ecc5..f5f87081 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/containers/ALECSentinelContainer.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/ALECSentinelContainer.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.containers; +package org.opennms.alec.smoke.containers; import static org.awaitility.Awaitility.await; @@ -37,13 +37,20 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; +import java.util.List; +import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.io.FileUtils; -import org.opennms.e2e.util.Karaf; -import org.opennms.e2e.util.Network; -import org.opennms.e2e.util.Overlay; +import org.junit.runner.Description; +import org.opennms.alec.smoke.util.Cleanup; +import org.opennms.alec.smoke.util.Karaf; +import org.opennms.alec.smoke.util.Network; +import org.opennms.alec.smoke.util.Overlay; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.containers.BindMode; @@ -60,43 +67,48 @@ public class ALECSentinelContainer extends GenericContainer { private static AtomicInteger redundantIndex = new AtomicInteger(0); private boolean isRedundant; private int redundantId; + private final Supplier engineFeatureSupplier; + private final Path overlayPath; - public ALECSentinelContainer(boolean isRedundant) throws Exception{ - super(org.opennms.e2e.util.DockerImageResolver.getImageAndTag("sentinel")); + + // Taking a Supplier since this constructor is called before the value is populated + // It will be populated by the time get() is called on the supplier + public ALECSentinelContainer(boolean isRedundant, Supplier engineFeatureSupplier) throws Exception { + super(org.opennms.alec.smoke.util.DockerImageResolver.getImageAndTag("sentinel")); this.isRedundant = isRedundant; redundantId = redundantIndex.getAndIncrement(); + overlayPath = prepareRedundantOverlay(); withExposedPorts(SENTINEL_SSH_PORT) .withEnv("KARAF_DEBUG_LOGGING", "org.opennms.alec") .withNetwork(Network.getNetwork()) .withNetworkAliases(getIndexedAlias()) .withCommand("-d") - .withClasspathResourceMapping(prepareRedundantOverlay().getFileName().toString(), "/opt/sentinel-overlay", + .withClasspathResourceMapping(overlayPath.getFileName().toString(), "/opt/sentinel-overlay", BindMode.READ_ONLY, SelinuxContext.SINGLE) .waitingFor(new WaitForALEC()); + this.engineFeatureSupplier = Objects.requireNonNull(engineFeatureSupplier); } - private void verifyKar(Path overlayDeployPath) { - // We expect to find exactly 1 kar file that will be overlayed onto the deploy directory of the sentinel - // container to install ALEC - File[] karFiles = overlayDeployPath.toFile().listFiles((dir, name) -> name.endsWith(".kar")); - if (karFiles == null || karFiles.length < 1) { - throw new RuntimeException("Could not find the .kar file to deploy ALEC"); - } - if (karFiles.length > 1) { - throw new RuntimeException("Found too many .kar files for deploying ALEC"); + @Override + public void start() { + try { + setEngineType(Paths.get(overlayPath.toString(), "etc", "featuresBoot.d", "alec.boot")); + } catch (IOException e) { + throw new RuntimeException(e); } + super.start(); } @SuppressWarnings("ResultOfMethodCallIgnored") private Path prepareRedundantOverlay() throws Exception { Path sentinelOverlayPath = Overlay.createTmpOverlayInClasspath(OVERLAY_DIR); - verifyKar(sentinelOverlayPath.resolve("deploy")); + Karaf.verifyKar(sentinelOverlayPath.resolve("deploy")); if (isRedundant) { FileUtils.copyDirectory(new File(Thread.currentThread() .getContextClassLoader() - .getResource(OVERLAY_REDUNDANT_DIR) + .getResource(Overlay.getOverlayDir(OVERLAY_REDUNDANT_DIR)) .toURI()), sentinelOverlayPath.toFile()); try { insertApplicationId(sentinelOverlayPath); @@ -106,13 +118,22 @@ private Path prepareRedundantOverlay() throws Exception { } else { FileUtils.copyDirectory(new File(Thread.currentThread() .getContextClassLoader() - .getResource(OVERLAY_STANDALONE_DIR) + .getResource(Overlay.getOverlayDir(OVERLAY_STANDALONE_DIR)) .toURI()), sentinelOverlayPath.toFile()); } return sentinelOverlayPath; } + private void setEngineType(Path path) throws IOException { + Stream lines = Files.lines(path); + String overriddenEngine = Objects.requireNonNull(engineFeatureSupplier.get()); + List newLines = lines.map(lineStr -> lineStr.replaceAll("%ALEC_ENGINE_FEATURE%", overriddenEngine)) + .collect(Collectors.toList()); + Files.write(path, newLines); + lines.close(); + } + public InetSocketAddress getSSHAddress() { return new InetSocketAddress(getContainerIpAddress(), getMappedPort(SENTINEL_SSH_PORT)); } @@ -170,4 +191,10 @@ protected void waitUntilReady() { public String toString() { return getIndexedAlias(); } + + @Override + protected void failed(Throwable e, Description description) { + Cleanup.skipCleanupIfNeeded(e); + super.failed(e, description); + } } diff --git a/smoke-test/src/test/java/org/opennms/alec/smoke/containers/BrowserWebDriverContainer.java b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/BrowserWebDriverContainer.java new file mode 100644 index 00000000..5e04e7fa --- /dev/null +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/BrowserWebDriverContainer.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * This file is part of OpenNMS(R). + * + * Copyright (C) 2019 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc. + * + * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. + * + * OpenNMS(R) is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * OpenNMS(R) is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with OpenNMS(R). If not, see: + * http://www.gnu.org/licenses/ + * + * For more information contact: + * OpenNMS(R) Licensing + * http://www.opennms.org/ + * http://www.opennms.com/ + *******************************************************************************/ + +package org.opennms.alec.smoke.containers; + +import org.junit.runner.Description; +import org.opennms.alec.smoke.util.Cleanup; + +public class BrowserWebDriverContainer extends org.testcontainers.containers.BrowserWebDriverContainer { + public BrowserWebDriverContainer(String dockerImageName) { + super(dockerImageName); + } + + @Override + protected void failed(Throwable e, Description description) { + Cleanup.skipCleanupIfNeeded(e); + super.failed(e, description); + } +} diff --git a/smoke-test/src/test/java/org/opennms/e2e/containers/HelmContainer.java b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/HelmContainer.java similarity index 89% rename from smoke-test/src/test/java/org/opennms/e2e/containers/HelmContainer.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/containers/HelmContainer.java index 6ecfbda2..1706dbf4 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/containers/HelmContainer.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/HelmContainer.java @@ -26,7 +26,7 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.containers; +package org.opennms.alec.smoke.containers; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; @@ -37,9 +37,11 @@ import java.net.MalformedURLException; import java.net.URL; -import org.opennms.e2e.grafana.GrafanaRestClient; -import org.opennms.e2e.util.DockerImageResolver; -import org.opennms.e2e.util.Network; +import org.junit.runner.Description; +import org.opennms.alec.smoke.grafana.GrafanaRestClient; +import org.opennms.alec.smoke.util.Cleanup; +import org.opennms.alec.smoke.util.DockerImageResolver; +import org.opennms.alec.smoke.util.Network; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.containers.GenericContainer; @@ -97,4 +99,10 @@ protected void waitUntilReady() { LOG.info("Helm is ready"); } } + + @Override + protected void failed(Throwable e, Description description) { + Cleanup.skipCleanupIfNeeded(e); + super.failed(e, description); + } } diff --git a/smoke-test/src/test/java/org/opennms/alec/smoke/containers/IntegratedOpenNMSALECContainer.java b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/IntegratedOpenNMSALECContainer.java new file mode 100644 index 00000000..67d9620e --- /dev/null +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/IntegratedOpenNMSALECContainer.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * This file is part of OpenNMS(R). + * + * Copyright (C) 2019 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc. + * + * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. + * + * OpenNMS(R) is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * OpenNMS(R) is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with OpenNMS(R). If not, see: + * http://www.gnu.org/licenses/ + * + * For more information contact: + * OpenNMS(R) Licensing + * http://www.opennms.org/ + * http://www.opennms.com/ + *******************************************************************************/ + +package org.opennms.alec.smoke.containers; + +import java.nio.file.Path; + +import org.junit.runner.Description; +import org.opennms.alec.smoke.util.Cleanup; +import org.opennms.alec.smoke.util.Karaf; +import org.opennms.alec.smoke.util.Network; +import org.opennms.alec.smoke.util.Overlay; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.wait.strategy.WaitStrategyTarget; + +public class IntegratedOpenNMSALECContainer extends OpenNMSContainer { + private static final Logger LOG = LoggerFactory.getLogger(IntegratedOpenNMSALECContainer.class); + + protected String getOverlayDir() { + return Overlay.getOverlayDir("opennms-integrated-overlay"); + } + + @Override + protected Path prepareOverlay() { + Path overlayPath = super.prepareOverlay(); + Karaf.verifyKar(overlayPath.resolve("deploy")); + return overlayPath; + } + + @Override + protected void waitForKarafBundles(WaitStrategyTarget waitStrategyTarget) { + LOG.info("Waiting for integrated ALEC"); + Karaf.waitForBundleActive("org.opennms.alec.driver", Network.getConnectionAddress(waitStrategyTarget, + OPENNMS_SSH_PORT)); + } + + @Override + protected void failed(Throwable e, Description description) { + Cleanup.skipCleanupIfNeeded(e); + super.failed(e, description); + } +} diff --git a/smoke-test/src/test/java/org/opennms/alec/smoke/containers/KafkaContainer.java b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/KafkaContainer.java new file mode 100644 index 00000000..d564f00e --- /dev/null +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/KafkaContainer.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * This file is part of OpenNMS(R). + * + * Copyright (C) 2019 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc. + * + * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. + * + * OpenNMS(R) is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * OpenNMS(R) is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with OpenNMS(R). If not, see: + * http://www.gnu.org/licenses/ + * + * For more information contact: + * OpenNMS(R) Licensing + * http://www.opennms.org/ + * http://www.opennms.com/ + *******************************************************************************/ + +package org.opennms.alec.smoke.containers; + +import org.junit.runner.Description; +import org.opennms.alec.smoke.util.Cleanup; + +public class KafkaContainer extends org.testcontainers.containers.KafkaContainer { + public KafkaContainer(String confluentPlatformVersion) { + super(confluentPlatformVersion); + } + + @Override + protected void failed(Throwable e, Description description) { + Cleanup.skipCleanupIfNeeded(e); + super.failed(e, description); + } +} diff --git a/smoke-test/src/test/java/org/opennms/e2e/containers/OpenNMSContainer.java b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/OpenNMSContainer.java similarity index 68% rename from smoke-test/src/test/java/org/opennms/e2e/containers/OpenNMSContainer.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/containers/OpenNMSContainer.java index e9c0659a..955fd3f3 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/containers/OpenNMSContainer.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/OpenNMSContainer.java @@ -26,34 +26,42 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.containers; +package org.opennms.alec.smoke.containers; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.notNullValue; +import java.io.File; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Path; -import org.opennms.e2e.util.DockerImageResolver; -import org.opennms.e2e.util.Karaf; -import org.opennms.e2e.util.Network; -import org.opennms.e2e.opennms.OpenNMSRestClient; +import org.apache.commons.io.FileUtils; +import org.junit.runner.Description; +import org.opennms.alec.smoke.opennms.OpenNMSRestClient; +import org.opennms.alec.smoke.util.Cleanup; +import org.opennms.alec.smoke.util.DockerImageResolver; +import org.opennms.alec.smoke.util.Karaf; +import org.opennms.alec.smoke.util.Network; +import org.opennms.alec.smoke.util.Overlay; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.SelinuxContext; +import org.testcontainers.containers.wait.strategy.WaitStrategyTarget; public class OpenNMSContainer extends GenericContainer { public static final String DB_ALIAS = "db"; private static final Logger LOG = LoggerFactory.getLogger(OpenNMSContainer.class); private static final int OPENNMS_WEB_PORT = 8980; - private static final int OPENNMS_SSH_PORT = 8101; + protected static final int OPENNMS_SSH_PORT = 8101; private static final int OPENNMS_DEBUG_PORT = 8001; static final String ALIAS = "opennms"; + protected static final String OVERLAY_DIR = "opennms-overlay"; public OpenNMSContainer() { super(DockerImageResolver.getImageAndTag("opennms")); @@ -68,7 +76,8 @@ public OpenNMSContainer() { .withEnv("OPENNMS_DBPASS", "opennms") .withEnv("KARAF_FEATURES", "producer") .withEnv("JAVA_OPTS", "-agentlib:jdwp=transport=dt_socket,server=y,address=0.0.0.0:8001,suspend=n") - .withClasspathResourceMapping("opennms-overlay", "/opt/opennms-overlay", BindMode.READ_ONLY, + .withClasspathResourceMapping(prepareOverlay().getFileName().toString(), "/opt/opennms-overlay", + BindMode.READ_ONLY, SelinuxContext.SINGLE) .withNetwork(Network.getNetwork()) .withNetworkAliases(ALIAS) @@ -85,7 +94,27 @@ public URL getOpenNMSUrl() { } } - private static class WaitForOpenNMS extends org.testcontainers.containers.wait.strategy.AbstractWaitStrategy { + protected Path prepareOverlay() { + Path opennmsOverlayPath = null; + try { + opennmsOverlayPath = Overlay.createTmpOverlayInClasspath(OVERLAY_DIR); + + FileUtils.copyDirectory(new File(Thread.currentThread() + .getContextClassLoader() + .getResource(getOverlayDir()) + .toURI()), opennmsOverlayPath.toFile()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return opennmsOverlayPath; + } + + protected String getOverlayDir() { + return Overlay.getOverlayDir("opennms-distributed-overlay"); + } + + protected class WaitForOpenNMS extends org.testcontainers.containers.wait.strategy.AbstractWaitStrategy { @Override protected void waitUntilReady() { LOG.info("Waiting for OpenNMS..."); @@ -102,9 +131,19 @@ protected void waitUntilReady() { .ignoreExceptions() .until(nmsRestClient::getDisplayVersion, notNullValue()); - Karaf.waitForBundleActive("org.opennms.features.kafka", Network.getConnectionAddress(waitStrategyTarget, - OPENNMS_SSH_PORT)); + waitForKarafBundles(waitStrategyTarget); LOG.info("OpenNMS is ready"); } } + + protected void waitForKarafBundles(WaitStrategyTarget waitStrategyTarget) { + Karaf.waitForBundleActive("org.opennms.features.kafka", Network.getConnectionAddress(waitStrategyTarget, + OPENNMS_SSH_PORT)); + } + + @Override + protected void failed(Throwable e, Description description) { + Cleanup.skipCleanupIfNeeded(e); + super.failed(e, description); + } } diff --git a/smoke-test/src/test/java/org/opennms/alec/smoke/containers/PostgreSQLContainer.java b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/PostgreSQLContainer.java new file mode 100644 index 00000000..83fad7cf --- /dev/null +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/containers/PostgreSQLContainer.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * This file is part of OpenNMS(R). + * + * Copyright (C) 2019 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc. + * + * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. + * + * OpenNMS(R) is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * OpenNMS(R) is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with OpenNMS(R). If not, see: + * http://www.gnu.org/licenses/ + * + * For more information contact: + * OpenNMS(R) Licensing + * http://www.opennms.org/ + * http://www.opennms.com/ + *******************************************************************************/ + +package org.opennms.alec.smoke.containers; + +import org.junit.runner.Description; +import org.opennms.alec.smoke.util.Cleanup; + +public class PostgreSQLContainer extends org.testcontainers.containers.PostgreSQLContainer { + public PostgreSQLContainer(String dockerImageName) { + super(dockerImageName); + } + + @Override + protected void failed(Throwable e, Description description) { + Cleanup.skipCleanupIfNeeded(e); + super.failed(e, description); + } +} diff --git a/smoke-test/src/test/java/org/opennms/e2e/alec/End2EndStandaloneCorrelationTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/CorrelationTestBase.java similarity index 55% rename from smoke-test/src/test/java/org/opennms/e2e/alec/End2EndStandaloneCorrelationTest.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/correlation/CorrelationTestBase.java index 8f02f7f1..f62c874c 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/alec/End2EndStandaloneCorrelationTest.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/CorrelationTestBase.java @@ -1,8 +1,8 @@ /******************************************************************************* * This file is part of OpenNMS(R). * - * Copyright (C) 2018 The OpenNMS Group, Inc. - * OpenNMS(R) is Copyright (C) 1999-2018 The OpenNMS Group, Inc. + * Copyright (C) 2019 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * @@ -26,22 +26,38 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.alec; +package org.opennms.alec.smoke.correlation; -import org.junit.Test; +import java.util.Collections; + +import org.apache.commons.lang3.tuple.Pair; +import org.opennms.alec.smoke.ALECSmokeTestBase; +import org.opennms.alec.smoke.grafana.Grafana44SeleniumDriver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class End2EndStandaloneCorrelationTest extends AbstractCorrelationTest { - private static final Logger LOG = LoggerFactory.getLogger(End2EndStandaloneCorrelationTest.class); +public abstract class CorrelationTestBase extends ALECSmokeTestBase { + private static final Logger LOG = LoggerFactory.getLogger(CorrelationTestBase.class); + + private void verifyGenericSituation() throws Exception { + new Grafana44SeleniumDriver(webDriverContainer.getWebDriver(), + helmContainer.getHelmUrlForWebDriver()) + .home() + .dashboard(DASHBOARD_NAME) + .verifyAnAlarmIsPresent() + .verifyRelatedAlarmLabels(Collections.singletonList(Pair.of(GENERIC_ALARM_TITLE, 3))); + } + + protected void runBasicCorrelation() throws Exception { + // Add a node + LOG.info("Adding node"); + int nodeId = openNMSRestClient.addTestNode(); - @Test - public void canCorrelateAlarms() throws Exception { // Trigger some alarms LOG.info("Triggering alarms that should end up related"); - openNMSRestClient.triggerAlarmsForCorrelation(); + openNMSRestClient.triggerAlarmsForCorrelation(nodeId); - // OCE Should now correlate them, we need to wait here for the situation alarm to show up + // ALEC Should now correlate them, we need to wait here for the situation alarm to show up LOG.info("Waiting for a situation to be received by OpenNMS..."); openNMSRestClient.waitForOutstandingSituation(); diff --git a/smoke-test/src/test/java/org/opennms/e2e/alec/End2EndRedundantCorrelationTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/DistributedRedundantCorrrelationTest.java similarity index 56% rename from smoke-test/src/test/java/org/opennms/e2e/alec/End2EndRedundantCorrelationTest.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/correlation/DistributedRedundantCorrrelationTest.java index 7b189b87..b7acd059 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/alec/End2EndRedundantCorrelationTest.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/DistributedRedundantCorrrelationTest.java @@ -26,70 +26,52 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.alec; +package org.opennms.alec.smoke.correlation; import static org.awaitility.Awaitility.await; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; -import org.junit.Ignore; import org.junit.Test; -import org.junit.rules.RuleChain; -import org.opennms.e2e.containers.ALECSentinelContainer; -import org.opennms.e2e.util.Karaf; +import org.opennms.alec.smoke.containers.ALECSentinelContainer; +import org.opennms.alec.smoke.util.Karaf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class End2EndRedundantCorrelationTest extends AbstractCorrelationTest { - private static final Logger LOG = LoggerFactory.getLogger(End2EndRedundantCorrelationTest.class); - private static final int NUM_REDUNDANT_OCE = 2; - private List redundantOCEs; +public class DistributedRedundantCorrrelationTest extends CorrelationTestBase { + private static final Logger LOG = LoggerFactory.getLogger(DistributedRedundantCorrrelationTest.class); + private static final int NUM_REDUNDANT_ALEC = 2; + private List redundantALECs; @Override - RuleChain addTestSpecificContainers() { - redundantOCEs = new ArrayList<>(); - RuleChain ruleChain = RuleChain.emptyRuleChain(); - // Define NUM_REDUNDANT_OCE redundant OCEs - for (int i = 0; i < NUM_REDUNDANT_OCE; i++) { + protected void adjustContainersForTest() { + redundantALECs = new ArrayList<>(); + // Define NUM_REDUNDANT_ALEC redundant ALECs + for (int i = 0; i < NUM_REDUNDANT_ALEC; i++) { ALECSentinelContainer alecSentinelContainer = null; try { - alecSentinelContainer = new ALECSentinelContainer(true); + alecSentinelContainer = new ALECSentinelContainer(true, () -> "oce-engine-cluster"); } catch (Exception e) { throw new RuntimeException(e); } - redundantOCEs.add(alecSentinelContainer); - // Initialize the first rule chain for the first OCE - if (redundantOCEs.size() == 1) { - ruleChain = RuleChain.outerRule(alecSentinelContainer); - } else { - ruleChain = ruleChain.around(alecSentinelContainer); - } + redundantALECs.add(alecSentinelContainer); + addContainers(Collections.singletonList(alecSentinelContainer)); } - return ruleChain; } @Test public void canCorrelateAlarmsAfterFailure() throws Exception { - waitForActiveOCE().shutdownKaraf(); - - LOG.info("Triggering alarms for correlation via API..."); - openNMSRestClient.triggerAlarmsForCorrelation(); - - // OCE Should now correlate them, we need to wait here for the situation alarm to show up - LOG.info("Waiting for a situation to be received by OpenNMS..."); - openNMSRestClient.waitForOutstandingSituation(); - - // Login, navigate to dashboard, view alarm in table, verify the related alarms - LOG.info("Situation received, verifying via Helm..."); - verifyGenericSituation(); + waitForActiveALEC().shutdownKaraf(); + runBasicCorrelation(); } private Optional getActiveOCE() throws Exception { - for (ALECSentinelContainer alecSentinelContainer : redundantOCEs) { + for (ALECSentinelContainer alecSentinelContainer : redundantALECs) { String[] output = Karaf.runKarafCommands(alecSentinelContainer.getSSHAddress(), "processor:current-role").split("\n"); @@ -101,15 +83,15 @@ private Optional getActiveOCE() throws Exception { return Optional.empty(); } - private ALECSentinelContainer waitForActiveOCE() throws Exception { - LOG.info("Waiting for an active OCE instance..."); + private ALECSentinelContainer waitForActiveALEC() throws Exception { + LOG.info("Waiting for an active ALEC instance..."); await() .atMost(2, TimeUnit.MINUTES) .pollInterval(10, TimeUnit.SECONDS) .until(() -> getActiveOCE().isPresent()); - ALECSentinelContainer activeOCE = getActiveOCE().get(); - LOG.info("OCE {} is now active", activeOCE); - return activeOCE; + ALECSentinelContainer activeALEC = getActiveOCE().get(); + LOG.info("ALEC {} is now active", activeALEC); + return activeALEC; } } diff --git a/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/DistributedStandaloneCorrelationTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/DistributedStandaloneCorrelationTest.java new file mode 100644 index 00000000..16a354ca --- /dev/null +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/DistributedStandaloneCorrelationTest.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * This file is part of OpenNMS(R). + * + * Copyright (C) 2018 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2018 The OpenNMS Group, Inc. + * + * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. + * + * OpenNMS(R) is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * OpenNMS(R) is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with OpenNMS(R). If not, see: + * http://www.gnu.org/licenses/ + * + * For more information contact: + * OpenNMS(R) Licensing + * http://www.opennms.org/ + * http://www.opennms.com/ + *******************************************************************************/ + +package org.opennms.alec.smoke.correlation; + +import static org.awaitility.Awaitility.await; + +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.opennms.alec.smoke.containers.ALECSentinelContainer; +import org.opennms.alec.smoke.util.Karaf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@RunWith(Parameterized.class) +public class DistributedStandaloneCorrelationTest extends CorrelationTestBase { + private static final Logger LOG = LoggerFactory.getLogger(DistributedStandaloneCorrelationTest.class); + private ALECSentinelContainer alecSentinelContainer; + @Parameterized.Parameter + public String engine; + + @Parameterized.Parameters + public static Object[] data() { + return new Object[]{"cluster", "dbscan", "deeplearning"}; + } + + @Override + protected void adjustContainersForTest() { + // Define a single non-redundant ALEC + try { + alecSentinelContainer = new ALECSentinelContainer(false, () -> engine); + addContainers(Collections.singletonList(alecSentinelContainer)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void canCorrelateAlarms() throws Exception { + LOG.info("Running test with engine: " + engine); + verifyCorrectEngineIsRunning(); + runBasicCorrelation(); + } + + private void verifyCorrectEngineIsRunning() { + LOG.debug("Checking for engine {}", engine); + + await() + .atMost(30, TimeUnit. + SECONDS) + .pollInterval(5, TimeUnit.SECONDS) + .ignoreExceptions() + .until(() -> { + String[] output = Karaf.runKarafCommands(alecSentinelContainer.getSSHAddress(), "opennms-alec" + + ":list-graphs").split("\n"); + + // We can't check the row startsWith the engine name since there seems to be some random characters + // prepended to output rows + return Arrays.stream(output).anyMatch(row -> row.contains(engine + ":") && + row.contains("situations") && row.contains("vertices") && row.contains("edges")); + }); + } +} diff --git a/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/IntegratedCorrelationTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/IntegratedCorrelationTest.java new file mode 100644 index 00000000..5e9e30b9 --- /dev/null +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/correlation/IntegratedCorrelationTest.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * This file is part of OpenNMS(R). + * + * Copyright (C) 2019 The OpenNMS Group, Inc. + * OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc. + * + * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. + * + * OpenNMS(R) is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * OpenNMS(R) is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with OpenNMS(R). If not, see: + * http://www.gnu.org/licenses/ + * + * For more information contact: + * OpenNMS(R) Licensing + * http://www.opennms.org/ + * http://www.opennms.com/ + *******************************************************************************/ + +package org.opennms.alec.smoke.correlation; + +import java.util.Objects; + +import org.junit.Test; +import org.opennms.alec.smoke.containers.IntegratedOpenNMSALECContainer; +import org.opennms.alec.smoke.containers.OpenNMSContainer; + +public class IntegratedCorrelationTest extends CorrelationTestBase { + private IntegratedOpenNMSALECContainer integratedContainer; + + @Override + protected void adjustContainersForTest() { + // Replace the base opennms container with an integrated one + integratedContainer = new IntegratedOpenNMSALECContainer(); + replaceContainer(opennmsContainer, integratedContainer); + } + + @Override + protected OpenNMSContainer getOpennmsContainer() { + return Objects.requireNonNull(integratedContainer); + } + + @Test + public void canCorrelateAlarms() throws Exception { + runBasicCorrelation(); + } +} diff --git a/smoke-test/src/test/java/org/opennms/e2e/grafana/model/ModelTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/grafana/model/ModelTest.java similarity index 97% rename from smoke-test/src/test/java/org/opennms/e2e/grafana/model/ModelTest.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/grafana/model/ModelTest.java index 7df22893..706784b7 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/grafana/model/ModelTest.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/grafana/model/ModelTest.java @@ -1,4 +1,4 @@ -package org.opennms.e2e.grafana.model; +package org.opennms.alec.smoke.grafana.model; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; diff --git a/smoke-test/src/test/java/org/opennms/e2e/opennms/OpenNMSRestClientTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/opennms/OpenNMSRestClientTest.java similarity index 95% rename from smoke-test/src/test/java/org/opennms/e2e/opennms/OpenNMSRestClientTest.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/opennms/OpenNMSRestClientTest.java index b61c458d..8eda2899 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/opennms/OpenNMSRestClientTest.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/opennms/OpenNMSRestClientTest.java @@ -26,12 +26,12 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.opennms; +package org.opennms.alec.smoke.opennms; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.opennms.e2e.opennms.model.Event; +import org.opennms.alec.smoke.opennms.model.Event; import java.net.InetSocketAddress; import java.net.MalformedURLException; diff --git a/smoke-test/src/test/java/org/opennms/e2e/opennms/model/ModelTest.java b/smoke-test/src/test/java/org/opennms/alec/smoke/opennms/model/ModelTest.java similarity index 98% rename from smoke-test/src/test/java/org/opennms/e2e/opennms/model/ModelTest.java rename to smoke-test/src/test/java/org/opennms/alec/smoke/opennms/model/ModelTest.java index 0d69a54b..9ce554fc 100644 --- a/smoke-test/src/test/java/org/opennms/e2e/opennms/model/ModelTest.java +++ b/smoke-test/src/test/java/org/opennms/alec/smoke/opennms/model/ModelTest.java @@ -26,11 +26,10 @@ * http://www.opennms.com/ *******************************************************************************/ -package org.opennms.e2e.opennms.model; +package org.opennms.alec.smoke.opennms.model; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; -import org.opennms.e2e.grafana.model.DataSource; import java.io.IOException;