From f4d4335b1e53d4c489f951c518c050a7654b99b6 Mon Sep 17 00:00:00 2001 From: "GARCIA, JOSE" Date: Tue, 24 Sep 2024 16:17:29 -0700 Subject: [PATCH] feat(notifications/cdEvents): added support for customData at pipeline notification config level. --- .../echo/cdevents/CDEventsBuilderService.java | 18 ++-- .../CDEventsNotificationAgentSpec.groovy | 90 ++++++++++++++++--- 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/echo-notifications/src/main/groovy/com/netflix/spinnaker/echo/cdevents/CDEventsBuilderService.java b/echo-notifications/src/main/groovy/com/netflix/spinnaker/echo/cdevents/CDEventsBuilderService.java index c23fc713a..87de8169f 100644 --- a/echo-notifications/src/main/groovy/com/netflix/spinnaker/echo/cdevents/CDEventsBuilderService.java +++ b/echo-notifications/src/main/groovy/com/netflix/spinnaker/echo/cdevents/CDEventsBuilderService.java @@ -21,6 +21,7 @@ import dev.cdevents.constants.CDEventConstants.CDEventTypes; import dev.cdevents.exception.CDEventsException; import io.cloudevents.CloudEvent; +import java.util.Collections; import java.util.Map; import java.util.Optional; import lombok.extern.slf4j.Slf4j; @@ -72,11 +73,18 @@ public CloudEvent createCDEvent( .map(p -> (String) p.get("cdEventsType")) .orElseThrow(() -> new FieldNotFoundException("notifications.cdEventsType")); - Object customData = - Optional.ofNullable(event.content) - .map(e -> (Map) e.get("context")) - .map(e -> e.get("customData")) - .orElse(new Object()); + // Grab customData object from notification level as higher order precedence. Needed for when + // setting pipeline + // level notifications. + Map customData = + Optional.ofNullable(preference) + .map(p -> (Map) p.get("customData")) + .orElseGet( + () -> + Optional.ofNullable(event.content) + .map(e -> (Map) e.get("context")) + .map(ctx -> (Map) ctx.get("customData")) + .orElseGet(Collections::emptyMap)); log.info("Event type {} received to create CDEvent.", cdEventsType); // This map will be updated to add more event types that Spinnaker needs to send diff --git a/echo-notifications/src/test/groovy/com/netflix/spinnaker/echo/notification/CDEventsNotificationAgentSpec.groovy b/echo-notifications/src/test/groovy/com/netflix/spinnaker/echo/notification/CDEventsNotificationAgentSpec.groovy index 9728ea39b..bbefc8ca6 100644 --- a/echo-notifications/src/test/groovy/com/netflix/spinnaker/echo/notification/CDEventsNotificationAgentSpec.groovy +++ b/echo-notifications/src/test/groovy/com/netflix/spinnaker/echo/notification/CDEventsNotificationAgentSpec.groovy @@ -53,12 +53,12 @@ class CDEventsNotificationAgentSpec extends Specification { cdevent.get().getType() ==~ expectedType where: - cdEventsType || expectedType || status - "dev.cdevents.pipelinerun.queued" || /dev.cdevents.pipelinerun.queued.0.1.1/ || /starting/ - "dev.cdevents.pipelinerun.started" || /dev.cdevents.pipelinerun.started.0.1.1/ || /started/ + cdEventsType || expectedType || status + "dev.cdevents.pipelinerun.queued" || /dev.cdevents.pipelinerun.queued.0.1.1/ || /starting/ + "dev.cdevents.pipelinerun.started" || /dev.cdevents.pipelinerun.started.0.1.1/ || /started/ "dev.cdevents.pipelinerun.finished" || /dev.cdevents.pipelinerun.finished.0.1.1/ || /complete/ - "dev.cdevents.taskrun.started" || /dev.cdevents.taskrun.started.0.1.1/ || /started/ - "dev.cdevents.taskrun.finished" || /dev.cdevents.taskrun.finished.0.1.1/ || /complete/ + "dev.cdevents.taskrun.started" || /dev.cdevents.taskrun.started.0.1.1/ || /started/ + "dev.cdevents.taskrun.finished" || /dev.cdevents.taskrun.finished.0.1.1/ || /complete/ brokerURL = "http://dev.cdevents.server/default/events-broker" @@ -70,7 +70,7 @@ class CDEventsNotificationAgentSpec extends Specification { } @Unroll - def "sends cdEvent with customData #customData"() { + def "sends cdEvent with customData #customData when set at event.context level"() { given: def cdevent = new BlockingVariable() @@ -86,19 +86,85 @@ class CDEventsNotificationAgentSpec extends Specification { cdevent.get().getType() ==~ expectedType where: - cdEventsType || expectedType || status || customData - "dev.cdevents.pipelinerun.queued" || /dev.cdevents.pipelinerun.queued.0.1.1/ || /starting/ || [foo: "pipelinerun.queued"] - "dev.cdevents.pipelinerun.started" || /dev.cdevents.pipelinerun.started.0.1.1/ || /started/ || [foo: "pipelinerun.started"] + cdEventsType || expectedType || status || customData + "dev.cdevents.pipelinerun.queued" || /dev.cdevents.pipelinerun.queued.0.1.1/ || /starting/ || [foo: "pipelinerun.queued"] + "dev.cdevents.pipelinerun.started" || /dev.cdevents.pipelinerun.started.0.1.1/ || /started/ || [foo: "pipelinerun.started"] "dev.cdevents.pipelinerun.finished" || /dev.cdevents.pipelinerun.finished.0.1.1/ || /complete/ || [foo: "pipelinerun.finished"] - "dev.cdevents.taskrun.started" || /dev.cdevents.taskrun.started.0.1.1/ || /started/ || [foo: "taskrun.started"] - "dev.cdevents.taskrun.finished" || /dev.cdevents.taskrun.finished.0.1.1/ || /complete/ || [foo: "taskrun.finished"] + "dev.cdevents.taskrun.started" || /dev.cdevents.taskrun.started.0.1.1/ || /started/ || [foo: "taskrun.started"] + "dev.cdevents.taskrun.finished" || /dev.cdevents.taskrun.finished.0.1.1/ || /complete/ || [foo: "taskrun.finished"] + brokerURL = "http://dev.cdevents.server/default/events-broker" + application = "whatever" + event = new Event(content: [ + execution: [id: "1", name: "foo-pipeline"], + context : [customData: customData] + ]) + type = "pipeline" + } + + @Unroll + def "sends cdEvent with customData #customData when set at notification preference level"() { + + given: + def cdevent = new BlockingVariable() + cdeventsSender.sendCDEvent(*_) >> { ceToSend, eventsBrokerURL -> + cdevent.set(ceToSend) + } + + when: + agent.sendNotifications([address: brokerURL, cdEventsType: cdEventsType, customData: customData], application, event, [type: type, link: "link"], status) + + then: + def m = convertToMap(cdevent.get().getData().toBytes()) + convertToMap(cdevent.get().getData().toBytes()).customData == customData + cdevent.get().getType() ==~ expectedType + + where: + cdEventsType || expectedType || status || customData + "dev.cdevents.pipelinerun.queued" || /dev.cdevents.pipelinerun.queued.0.1.1/ || /starting/ || [foo: "pipelinerun.queued"] + "dev.cdevents.pipelinerun.started" || /dev.cdevents.pipelinerun.started.0.1.1/ || /started/ || [foo: "pipelinerun.started"] + "dev.cdevents.pipelinerun.finished" || /dev.cdevents.pipelinerun.finished.0.1.1/ || /complete/ || [foo: "pipelinerun.finished"] + "dev.cdevents.taskrun.started" || /dev.cdevents.taskrun.started.0.1.1/ || /started/ || [foo: "taskrun.started"] + "dev.cdevents.taskrun.finished" || /dev.cdevents.taskrun.finished.0.1.1/ || /complete/ || [foo: "taskrun.finished"] + + brokerURL = "http://dev.cdevents.server/default/events-broker" + application = "whatever" + event = new Event(content: [ + execution: [id: "1", name: "foo-pipeline"] + ]) + type = "pipeline" + } + + @Unroll + def "sends cdEvent with customData #customData when set at notification preference level and event.context level"() { + + given: + def cdevent = new BlockingVariable() + cdeventsSender.sendCDEvent(*_) >> { ceToSend, eventsBrokerURL -> + cdevent.set(ceToSend) + } + + when: + agent.sendNotifications([address: brokerURL, cdEventsType: cdEventsType, customData: preferenceCustomData], application, event, [type: type, link: "link"], status) + + then: + //Preference level should take higher order precedence + convertToMap(cdevent.get().getData().toBytes()).customData == preferenceCustomData + cdevent.get().getType() ==~ expectedType + + where: + cdEventsType || expectedType || status || customData || preferenceCustomData + "dev.cdevents.pipelinerun.queued" || /dev.cdevents.pipelinerun.queued.0.1.1/ || /starting/ || [foo: "pipelinerun.queued"] || [zoo: "pipelinerun.queued"] + "dev.cdevents.pipelinerun.started" || /dev.cdevents.pipelinerun.started.0.1.1/ || /started/ || [foo: "pipelinerun.started"] || [zoo: "pipelinerun.started"] + "dev.cdevents.pipelinerun.finished" || /dev.cdevents.pipelinerun.finished.0.1.1/ || /complete/ || [foo: "pipelinerun.finished"] || [zoo: "pipelinerun.finished"] + "dev.cdevents.taskrun.started" || /dev.cdevents.taskrun.started.0.1.1/ || /started/ || [foo: "taskrun.started"] || [zoo: "taskrun.started"] + "dev.cdevents.taskrun.finished" || /dev.cdevents.taskrun.finished.0.1.1/ || /complete/ || [foo: "taskrun.finished"] || [zoo: "taskrun.finished"] brokerURL = "http://dev.cdevents.server/default/events-broker" application = "whatever" event = new Event(content: [ execution: [id: "1", name: "foo-pipeline"], - context: [customData: customData] + context : [customData: customData] ]) type = "pipeline" }