use of org.graylog2.notifications.Notification in project graylog2-server by Graylog2.
the class EventNotificationExecutionJob method execute.
@Override
public JobTriggerUpdate execute(JobExecutionContext ctx) throws JobExecutionException {
Optional<EventDefinitionDto> optionalEventDefinition;
long gracePeriodInMS = 0;
final JobTriggerDto trigger = ctx.trigger();
final Optional<Data> optionalData = trigger.data().map(d -> (Data) d);
if (!optionalData.isPresent()) {
throw new JobExecutionException("Missing notification job data for notification <" + jobConfig.notificationId() + ">, unable to execute notification: " + ctx.definition().title(), trigger, JobTriggerUpdate.withoutNextTime());
}
final Data data = optionalData.get();
final EventDto eventDto = data.eventDto();
final NotificationDto notification = notificationService.get(jobConfig.notificationId()).orElseThrow(() -> new JobExecutionException("Couldn't find notification <" + jobConfig.notificationId() + ">", trigger, JobTriggerUpdate.withError(trigger)));
final EventNotification.Factory eventNotificationFactory = eventNotificationFactories.get(notification.config().type());
if (eventNotificationFactory == null) {
throw new JobExecutionException("Couldn't find factory for notification type <" + notification.config().type() + ">", trigger, ctx.jobTriggerUpdates().scheduleNextExecution());
}
final EventNotification eventNotification = eventNotificationFactory.create();
metrics.registerEventNotification(eventNotification, notification);
try {
optionalEventDefinition = Optional.ofNullable(getEventDefinition(eventDto));
if (optionalEventDefinition.isPresent()) {
gracePeriodInMS = optionalEventDefinition.get().notificationSettings().gracePeriodMs();
}
} catch (NotFoundException e) {
LOG.error("Couldn't find event definition with ID <{}>.", eventDto.eventDefinitionId());
optionalEventDefinition = Optional.empty();
}
EventNotificationContext notificationContext = EventNotificationContext.builder().notificationId(notification.id()).notificationConfig(notification.config()).event(eventDto).eventDefinition(optionalEventDefinition.get()).jobTrigger(trigger).build();
updateTriggerStatus(eventDto, gracePeriodInMS);
if (inGrace(eventDto, gracePeriodInMS)) {
LOG.debug("Notification <{}> triggered but it's in grace period.", jobConfig.notificationId());
metrics.markInGrace(eventNotification, notification);
return ctx.jobTriggerUpdates().scheduleNextExecution();
}
try {
metrics.markExecution(eventNotification, notification);
eventNotification.execute(notificationContext);
metrics.markSuccess(eventNotification, notification);
} catch (TemporaryEventNotificationException e) {
metrics.markFailedTemporarily(eventNotification, notification);
final long retryPeriod = configurationProvider.get().eventNotificationsRetry();
throw new JobExecutionException(String.format(Locale.ROOT, "Failed to execute notification, retrying in %d minutes - <%s/%s/%s>", TimeUnit.MILLISECONDS.toMinutes(retryPeriod), notification.id(), notification.title(), notification.config().type()), trigger, ctx.jobTriggerUpdates().retryIn(retryPeriod, TimeUnit.MILLISECONDS), e);
} catch (PermanentEventNotificationException e) {
metrics.markFailedPermanently(eventNotification, notification);
throw new JobExecutionException(String.format(Locale.ROOT, "Failed permanently to execute notification, giving up - <%s/%s/%s>", notification.id(), notification.title(), notification.config().type()), trigger, ctx.jobTriggerUpdates().scheduleNextExecution(), e);
} catch (EventNotificationException e) {
metrics.markFailed(eventNotification, notification);
throw new JobExecutionException(String.format(Locale.ROOT, "Notification failed to execute - <%s/%s/%s>", notification.id(), notification.title(), notification.config().type()), trigger, ctx.jobTriggerUpdates().scheduleNextExecution(), e);
}
updateNotifiedStatus(eventDto, gracePeriodInMS);
return ctx.jobTriggerUpdates().scheduleNextExecution();
}
use of org.graylog2.notifications.Notification in project graylog2-server by Graylog2.
the class NotificationResourceHandler method delete.
/**
* Deletes an existing notification definition and its corresponding scheduler job definition and trigger.
*
* @param dtoId the notification definition to delete
* @return true if the notification definition got deleted, false otherwise
*/
public boolean delete(String dtoId) {
final Optional<NotificationDto> dto = notificationService.get(dtoId);
if (!dto.isPresent()) {
return false;
}
jobDefinitionService.getByConfigField(EventNotificationConfig.FIELD_NOTIFICATION_ID, dtoId).ifPresent(jobDefinition -> {
LOG.debug("Deleting job definition <{}/{}> for notification <{}/{}>", jobDefinition.id(), jobDefinition.title(), dto.get().id(), dto.get().title());
jobDefinitionService.delete(jobDefinition.id());
});
// Delete notification from existing events
eventDefinitionService.getByNotificationId(dtoId).forEach(eventDefinition -> {
LOG.debug("Removing notification <{}/{}> from event definition <{}/{}>", dto.get().id(), dto.get().title(), eventDefinition.id(), eventDefinition.title());
final ImmutableList<EventNotificationHandler.Config> notifications = eventDefinition.notifications().stream().filter(entry -> !entry.notificationId().equals(dtoId)).collect(ImmutableList.toImmutableList());
EventDefinitionDto updatedEventDto = eventDefinition.toBuilder().notifications(notifications).build();
eventDefinitionService.save(updatedEventDto);
});
LOG.debug("Deleting notification definition <{}/{}>", dto.get().id(), dto.get().title());
return notificationService.delete(dtoId) > 0;
}
use of org.graylog2.notifications.Notification in project graylog2-server by Graylog2.
the class EmailEventNotification method execute.
@Override
public void execute(EventNotificationContext ctx) throws TemporaryEventNotificationException, PermanentEventNotificationException {
final EmailEventNotificationConfig config = (EmailEventNotificationConfig) ctx.notificationConfig();
try {
ImmutableList<MessageSummary> backlog = notificationCallbackService.getBacklogForEvent(ctx);
emailSender.sendEmails(config, ctx, backlog);
} catch (EmailSender.ConfigurationError e) {
throw new TemporaryEventNotificationException(e.getMessage());
} catch (TransportConfigurationException e) {
Notification systemNotification = notificationService.buildNow().addNode(nodeId.toString()).addType(Notification.Type.EMAIL_TRANSPORT_CONFIGURATION_INVALID).addSeverity(Notification.Severity.NORMAL).addDetail("exception", e.getMessage());
notificationService.publishIfFirst(systemNotification);
throw new TemporaryEventNotificationException("Notification has email recipients and is triggered, but email transport is not configured. " + e.getMessage());
} catch (Exception e) {
String exceptionDetail = e.toString();
if (e.getCause() != null) {
exceptionDetail += " (" + e.getCause() + ")";
}
final Notification systemNotification = notificationService.buildNow().addNode(nodeId.toString()).addType(Notification.Type.EMAIL_TRANSPORT_FAILED).addSeverity(Notification.Severity.NORMAL).addDetail("exception", exceptionDetail);
notificationService.publishIfFirst(systemNotification);
throw new PermanentEventNotificationException("Notification has email recipients and is triggered, but sending emails failed. " + e.getMessage());
}
LOG.debug("Sending email to addresses <{}> and users <{}> using notification <{}>", Strings.join(config.emailRecipients(), ','), Strings.join(config.userRecipients(), ','), ctx.notificationId());
}
use of org.graylog2.notifications.Notification in project graylog2-server by Graylog2.
the class NotificationTestData method getDummyContext.
public static EventNotificationContext getDummyContext(NotificationDto notificationDto, String userName) {
final EventDto eventDto = EventDto.builder().alert(true).eventDefinitionId("EventDefinitionTestId").eventDefinitionType("notification-test-v1").eventTimestamp(Tools.nowUTC()).processingTimestamp(Tools.nowUTC()).id("TEST_NOTIFICATION_ID").streams(ImmutableSet.of(Stream.DEFAULT_EVENTS_STREAM_ID)).message("Notification test message triggered from user <" + userName + ">").source(Stream.DEFAULT_STREAM_ID).keyTuple(ImmutableList.of("testkey")).key("testkey").originContext(EventOriginContext.elasticsearchMessage("testIndex_42", "b5e53442-12bb-4374-90ed-0deadbeefbaz")).priority(2).fields(ImmutableMap.of("field1", "value1", "field2", "value2")).build();
final EventDefinitionDto eventDefinitionDto = EventDefinitionDto.builder().alert(true).id(TEST_NOTIFICATION_ID).title("Event Definition Test Title").description("Event Definition Test Description").config(new EventProcessorConfig() {
@Override
public String type() {
return "test-dummy-v1";
}
@Override
public ValidationResult validate() {
return null;
}
@Override
public EventProcessorConfigEntity toContentPackEntity(EntityDescriptorIds entityDescriptorIds) {
return null;
}
}).fieldSpec(ImmutableMap.of()).priority(2).keySpec(ImmutableList.of()).notificationSettings(new EventNotificationSettings() {
@Override
public long gracePeriodMs() {
return 0;
}
@Override
public // disable to avoid errors in getBacklogForEvent()
long backlogSize() {
return 0;
}
@Override
public Builder toBuilder() {
return null;
}
}).build();
return EventNotificationContext.builder().notificationId(TEST_NOTIFICATION_ID).notificationConfig(notificationDto.config()).event(eventDto).eventDefinition(eventDefinitionDto).build();
}
use of org.graylog2.notifications.Notification in project graylog2-server by Graylog2.
the class StreamFacade method decode.
private NativeEntity<Stream> decode(EntityV1 entity, Map<String, ValueReference> parameters, Map<EntityDescriptor, Object> nativeEntities, User user) {
final StreamEntity streamEntity = objectMapper.convertValue(entity.data(), StreamEntity.class);
final CreateStreamRequest createStreamRequest = CreateStreamRequest.create(streamEntity.title().asString(parameters), streamEntity.description().asString(parameters), // ignored
null, null, streamEntity.matchingType().asString(parameters), streamEntity.removeMatches().asBoolean(parameters), indexSetService.getDefault().id());
final Stream stream = streamService.create(createStreamRequest, user.getName());
final List<StreamRule> streamRules = streamEntity.streamRules().stream().map(streamRuleEntity -> createStreamRuleRequest(streamRuleEntity, parameters)).map(request -> streamRuleService.create(DUMMY_STREAM_ID, request)).collect(Collectors.toList());
// TODO: The creation of legacy alert conditions should be avoided and a new event definition should be created instead
final List<AlertCondition> alertConditions = streamEntity.alertConditions().stream().map(alertCondition -> createStreamAlertConditionRequest(alertCondition, parameters)).map(request -> {
try {
return streamAlertService.fromRequest(request, stream, user.getName());
} catch (ConfigurationException e) {
throw new ContentPackException("Couldn't create entity " + entity.toEntityDescriptor(), e);
}
}).collect(Collectors.toList());
// TODO: The creation of legacy alarm callback should be avoided and a new event notification should be created instead
final List<AlarmCallbackConfiguration> alarmCallbacks = streamEntity.alarmCallbacks().stream().map(alarmCallback -> createStreamAlarmCallbackRequest(alarmCallback, parameters)).map(request -> alarmCallbackConfigurationService.create(stream.getId(), request, user.getName())).collect(Collectors.toList());
final String savedStreamId;
try {
savedStreamId = streamService.saveWithRulesAndOwnership(stream, streamRules, user);
for (final AlertCondition alertCondition : alertConditions) {
streamService.addAlertCondition(stream, alertCondition);
}
for (final AlarmCallbackConfiguration alarmCallback : alarmCallbacks) {
alarmCallbackConfigurationService.save(alarmCallback);
}
} catch (ValidationException e) {
throw new ContentPackException("Couldn't create entity " + entity.toEntityDescriptor(), e);
}
final Set<ObjectId> outputIds = streamEntity.outputs().stream().map(valueReference -> valueReference.asString(parameters)).map(ModelId::of).map(modelId -> EntityDescriptor.create(modelId, ModelTypes.OUTPUT_V1)).map(descriptor -> findOutput(descriptor, nativeEntities)).map(Output::getId).map(ObjectId::new).collect(Collectors.toSet());
streamService.addOutputs(new ObjectId(savedStreamId), outputIds);
if (!alertConditions.isEmpty() || !alarmCallbacks.isEmpty()) {
// TODO: Remove migration call once we updated the above code to directly create event definitions and notifications
try {
legacyAlertsMigration.upgrade();
} catch (Exception e) {
LOG.error("Couldn't run migration for newly created legacy alert conditions and/or alarm callbacks", e);
}
}
return NativeEntity.create(entity.id(), savedStreamId, TYPE_V1, stream.getTitle(), stream);
}
Aggregations