Skip to content

Commit

Permalink
Add new TeamsEventNotificationV2 supporting Microsoft Workflows (#19983)
Browse files Browse the repository at this point in the history
* Add new TeamsEventNotificationV2 supporting Microsoft Workflows
  • Loading branch information
kingzacko1 authored Jul 29, 2024
1 parent 1edb74a commit d00a8bd
Show file tree
Hide file tree
Showing 15 changed files with 1,075 additions and 16 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/pr-19983.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type = "added"
message = "Added Microsoft Teams Notification V2 which is compatible with Microsoft Workflows."

issues = ["Graylog2/graylog-plugin-enterprise#7794"]
pulls = ["19983"]
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
import org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotification;
import org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfig;
import org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigEntity;
import org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigV2;
import org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigV2Entity;
import org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationV2;
import org.graylog.integrations.pagerduty.PagerDutyNotification;
import org.graylog.integrations.pagerduty.PagerDutyNotificationConfig;
import org.graylog.integrations.pagerduty.PagerDutyNotificationConfigEntity;
Expand Down Expand Up @@ -111,14 +114,22 @@ private void configureServerOnlyBindings() {
SlackEventNotificationConfigEntity.TYPE_NAME,
SlackEventNotificationConfigEntity.class);

// Teams Notification
// Teams Notification (deprecated with Microsoft's retiring connectors)
addNotificationType(TeamsEventNotificationConfig.TYPE_NAME,
TeamsEventNotificationConfig.class,
TeamsEventNotification.class,
TeamsEventNotification.Factory.class,
TeamsEventNotificationConfigEntity.TYPE_NAME,
TeamsEventNotificationConfigEntity.class);

// Teams Notification V2
addNotificationType(TeamsEventNotificationConfigV2.TYPE_NAME,
TeamsEventNotificationConfigV2.class,
TeamsEventNotificationV2.class,
TeamsEventNotificationV2.Factory.class,
TeamsEventNotificationConfigV2Entity.TYPE_NAME,
TeamsEventNotificationConfigV2Entity.class);

// Pager Duty Notification
addNotificationType(PagerDutyNotificationConfig.TYPE_NAME,
PagerDutyNotificationConfig.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.floreysoft.jmte.Engine;
import com.google.common.annotations.VisibleForTesting;
import jakarta.inject.Inject;
import org.graylog.events.notifications.EventNotification;
import org.graylog.events.notifications.EventNotificationContext;
import org.graylog.events.notifications.EventNotificationException;
Expand All @@ -38,8 +39,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.inject.Inject;

import java.net.URI;
import java.util.Collections;
import java.util.List;
Expand All @@ -50,6 +49,7 @@
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Objects.requireNonNull;

@Deprecated
public class TeamsEventNotification implements EventNotification {

private static final Logger LOG = LoggerFactory.getLogger(TeamsEventNotification.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.auto.value.AutoValue;
import jakarta.validation.constraints.NotBlank;
import org.graylog.events.contentpack.entities.EventNotificationConfigEntity;
import org.graylog.events.event.EventDto;
import org.graylog.events.notifications.EventNotificationConfig;
Expand All @@ -33,16 +34,14 @@
import org.joda.time.DateTimeZone;

import javax.annotation.Nullable;

import jakarta.validation.constraints.NotBlank;

import java.net.URI;
import java.util.Locale;
import java.util.regex.Pattern;

@AutoValue
@JsonTypeName(TeamsEventNotificationConfig.TYPE_NAME)
@JsonDeserialize(builder = TeamsEventNotificationConfig.Builder.class)
@Deprecated
public abstract class TeamsEventNotificationConfig implements EventNotificationConfig {

public static final String TYPE_NAME = "teams-notification-v1";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@AutoValue
@JsonTypeName(TeamsEventNotificationConfigEntity.TYPE_NAME)
@JsonDeserialize(builder = TeamsEventNotificationConfigEntity.Builder.class)
@Deprecated
public abstract class TeamsEventNotificationConfigEntity implements EventNotificationConfigEntity {

public static final String TYPE_NAME = "teams-notification-v1";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program 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
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
package org.graylog.integrations.notifications.types.microsoftteams;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.auto.value.AutoValue;
import jakarta.validation.constraints.NotBlank;
import org.graylog.events.contentpack.entities.EventNotificationConfigEntity;
import org.graylog.events.event.EventDto;
import org.graylog.events.notifications.EventNotificationConfig;
import org.graylog.events.notifications.EventNotificationExecutionJob;
import org.graylog.scheduler.JobTriggerData;
import org.graylog2.contentpacks.EntityDescriptorIds;
import org.graylog2.contentpacks.model.entities.references.ValueReference;
import org.graylog2.plugin.rest.ValidationResult;
import org.joda.time.DateTimeZone;

import java.net.URI;

@AutoValue
@JsonTypeName(TeamsEventNotificationConfigV2.TYPE_NAME)
@JsonDeserialize(builder = TeamsEventNotificationConfigV2.Builder.class)
public abstract class TeamsEventNotificationConfigV2 implements EventNotificationConfig {
public static final String TYPE_NAME = "teams-notification-v2";

public static final long DEFAULT_BACKLOG_SIZE = 0;
private static final String WEBHOOK_URL = "https://server.region.logic.azure.com:443/workflows/xxxxxxx";
private static final DateTimeZone DEFAULT_TIME_ZONE = DateTimeZone.UTC;
public static final String DEFAULT_ADAPTIVE_CARD = "{\n" +
" \"contentType\": \"application/vnd.microsoft.card.adaptive\",\n" +
" \"content\": {\n" +
" \"type\": \"AdaptiveCard\",\n" +
" \"version\": \"1.6\",\n" +
" \"body\": [\n" +
" {\n" +
" \"type\": \"TextBlock\",\n" +
" \"size\": \"Large\",\n" +
" \"weight\": \"Bolder\",\n" +
" \"text\": \"${event_definition_title} triggered\",\n" +
" \"style\": \"heading\",\n" +
" \"fontType\": \"Default\"\n" +
" },\n" +
" {\n" +
" \"type\": \"TextBlock\",\n" +
" \"text\": \"${event_definition_description}\",\n" +
" \"wrap\": true\n" +
" }\n" +
" ],\n" +
" \"$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\",\n" +
" \"rtl\": false\n" +
" }\n" +
"}";

static final String INVALID_WEBHOOK_ERROR_MESSAGE = "Specified Webhook URL is not a valid URL";
static final String INVALID_BACKLOG_ERROR_MESSAGE = "Backlog size cannot be less than zero";
static final String FIELD_WEBHOOK_URL = "webhook_url";
static final String FIELD_ADAPTIVE_CARD = "adaptive_card";
static final String FIELD_BACKLOG_SIZE = "backlog_size";
static final String FIELD_TIME_ZONE = "time_zone";

@JsonProperty(FIELD_BACKLOG_SIZE)
public abstract long backlogSize();

@JsonProperty(FIELD_WEBHOOK_URL)
@NotBlank
public abstract String webhookUrl();

@JsonProperty(FIELD_ADAPTIVE_CARD)
public abstract String adaptiveCard();

@JsonProperty(FIELD_TIME_ZONE)
public abstract DateTimeZone timeZone();

@Override
@JsonIgnore
public JobTriggerData toJobTriggerData(EventDto dto) {
return EventNotificationExecutionJob.Data.builder().eventDto(dto).build();
}

@Override
public EventNotificationConfigEntity toContentPackEntity(EntityDescriptorIds entityDescriptorIds) {
return TeamsEventNotificationConfigV2Entity.builder()
.webhookUrl(ValueReference.of(webhookUrl()))
.adaptiveCard(ValueReference.of(adaptiveCard()))
.timeZone(ValueReference.of(timeZone().getID()))
.build();
}

public static Builder builder() { return Builder.create(); }

@Override
@JsonIgnore
public ValidationResult validate() {
ValidationResult validation = new ValidationResult();

try {
new URI(webhookUrl());
} catch (Exception ex) {
validation.addError(FIELD_WEBHOOK_URL, INVALID_WEBHOOK_ERROR_MESSAGE);
}

if (backlogSize() < 0) {
validation.addError(FIELD_BACKLOG_SIZE, INVALID_BACKLOG_ERROR_MESSAGE);
}

return validation;
}

@AutoValue.Builder
public static abstract class Builder implements EventNotificationConfig.Builder<Builder> {
@JsonCreator
public static Builder create() {
return new AutoValue_TeamsEventNotificationConfigV2.Builder()
.type(TYPE_NAME)
.webhookUrl(WEBHOOK_URL)
.adaptiveCard(DEFAULT_ADAPTIVE_CARD)
.backlogSize(DEFAULT_BACKLOG_SIZE)
.timeZone(DEFAULT_TIME_ZONE);
}

@JsonProperty(FIELD_BACKLOG_SIZE)
public abstract Builder backlogSize(long backlogSize);

@JsonProperty(FIELD_WEBHOOK_URL)
public abstract Builder webhookUrl(String webhookUrl);

@JsonProperty(FIELD_ADAPTIVE_CARD)
public abstract Builder adaptiveCard(String adaptiveCard);

@JsonProperty(FIELD_TIME_ZONE)
public abstract Builder timeZone(DateTimeZone timeZone);

public abstract TeamsEventNotificationConfigV2 build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program 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
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
package org.graylog.integrations.notifications.types.microsoftteams;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.auto.value.AutoValue;
import org.graylog.events.contentpack.entities.EventNotificationConfigEntity;
import org.graylog.events.notifications.EventNotificationConfig;
import org.graylog2.contentpacks.model.entities.EntityDescriptor;
import org.graylog2.contentpacks.model.entities.references.ValueReference;
import org.joda.time.DateTimeZone;

import java.util.Map;

import static org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigV2.DEFAULT_ADAPTIVE_CARD;
import static org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigV2.DEFAULT_BACKLOG_SIZE;
import static org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigV2.FIELD_ADAPTIVE_CARD;
import static org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigV2.FIELD_TIME_ZONE;
import static org.graylog.integrations.notifications.types.microsoftteams.TeamsEventNotificationConfigV2.FIELD_WEBHOOK_URL;

@AutoValue
@JsonTypeName(TeamsEventNotificationConfigV2Entity.TYPE_NAME)
@JsonDeserialize(builder = TeamsEventNotificationConfigV2Entity.Builder.class)
public abstract class TeamsEventNotificationConfigV2Entity implements EventNotificationConfigEntity {

public static final String TYPE_NAME = "teams-notification-v2";

@JsonProperty(FIELD_WEBHOOK_URL)
public abstract ValueReference webhookUrl();

@JsonProperty(FIELD_ADAPTIVE_CARD)
public abstract ValueReference adaptiveCard();

@JsonProperty(FIELD_TIME_ZONE)
public abstract ValueReference timeZone();

public static Builder builder() {
return Builder.create();
}

public abstract Builder toBuilder();

@AutoValue.Builder
public static abstract class Builder implements EventNotificationConfigEntity.Builder<Builder> {

@JsonCreator
public static Builder create() {
return new AutoValue_TeamsEventNotificationConfigV2Entity.Builder()
.type(TYPE_NAME)
.adaptiveCard(ValueReference.of(DEFAULT_ADAPTIVE_CARD))
.timeZone(ValueReference.of("UTC"));
}

@JsonProperty(FIELD_WEBHOOK_URL)
public abstract Builder webhookUrl(ValueReference webhookUrl);

@JsonProperty(FIELD_ADAPTIVE_CARD)
public abstract Builder adaptiveCard(ValueReference customMessage);

@JsonProperty(FIELD_TIME_ZONE)
public abstract Builder timeZone(ValueReference timeZone);

public abstract TeamsEventNotificationConfigV2Entity build();
}

@Override
public EventNotificationConfig toNativeEntity(Map<String, ValueReference> parameters, Map<EntityDescriptor, Object> nativeEntities) {
return TeamsEventNotificationConfigV2.builder()
.webhookUrl(webhookUrl().asString(parameters))
.adaptiveCard(adaptiveCard().asString(parameters))
.timeZone(DateTimeZone.forID(timeZone().asString(parameters)))
.backlogSize(DEFAULT_BACKLOG_SIZE)
.build();
}
}

Loading

0 comments on commit d00a8bd

Please sign in to comment.