io.hyperfoil.tools.horreum.svc.NotificationServiceImpl Maven / Gradle / Ivy
The newest version!
package io.hyperfoil.tools.horreum.svc;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.security.PermitAll;
import jakarta.annotation.security.RolesAllowed;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.transaction.SystemException;
import jakarta.transaction.TransactionManager;
import jakarta.transaction.Transactional;
import org.hibernate.Session;
import org.jboss.logging.Logger;
import io.hyperfoil.tools.horreum.api.alerting.NotificationSettings;
import io.hyperfoil.tools.horreum.api.internal.services.NotificationService;
import io.hyperfoil.tools.horreum.entity.alerting.NotificationSettingsDAO;
import io.hyperfoil.tools.horreum.entity.data.DatasetDAO;
import io.hyperfoil.tools.horreum.entity.data.TestDAO;
import io.hyperfoil.tools.horreum.entity.user.UserApiKey;
import io.hyperfoil.tools.horreum.events.DatasetChanges;
import io.hyperfoil.tools.horreum.mapper.NotificationSettingsMapper;
import io.hyperfoil.tools.horreum.notification.Notification;
import io.hyperfoil.tools.horreum.notification.NotificationPlugin;
import io.hyperfoil.tools.horreum.server.WithRoles;
import io.quarkus.runtime.Startup;
@ApplicationScoped
@Startup
public class NotificationServiceImpl implements NotificationService {
private static final Logger log = Logger.getLogger(NotificationServiceImpl.class);
//@formatter:off
private static final String GET_NOTIFICATIONS = """
WITH ens AS (
SELECT ns.*, watch_id FROM notificationsettings ns
JOIN watch_users wu ON NOT ns.isteam AND ns.name = wu.users
UNION
SELECT ns.*, watch_id FROM notificationsettings ns
JOIN watch_teams wt ON ns.isteam AND ns.name = wt.teams
UNION
SELECT ns.*, watch_id FROM notificationsettings ns
JOIN team t ON NOT ns.isteam
AND ns.name = t.team_name
JOIN watch_teams wt ON wt.teams = t.team_name
)
SELECT method, data, name
FROM ens
JOIN watch ON ens.watch_id = watch.id
WHERE testid = ?
AND name NOT IN (SELECT optout FROM watch_optout WHERE ens.watch_id = watch_optout.watch_id)
""";
//@formatter:on
public final Map plugins = new HashMap<>();
@Inject
EntityManager em;
@Inject
Instance notificationPlugins;
@Inject
TransactionManager tm;
@PostConstruct
public void init() {
notificationPlugins.forEach(plugin -> plugins.put(plugin.method(), plugin));
}
@WithRoles(extras = Roles.HORREUM_SYSTEM)
@Transactional
public void onNewChanges(DatasetChanges event) {
if (!event.isNotify()) {
log.debug("Notification skipped");
return;
}
log.debugf("Received new changes in test %d (%s), dataset %d/%d (fingerprint: %s)",
event.dataset.testId, event.testName, event.dataset.runId, event.dataset.ordinal, event.fingerprint);
notifyAll(event.dataset.testId, n -> n.notifyChanges(event));
}
@WithRoles(extras = Roles.HORREUM_SYSTEM)
@Transactional
public void onMissingValues(MissingValuesEvent event) {
if (!event.notify) {
log.debugf("Skipping notification for missing run values on test %d, run %d", event.dataset.testId,
event.dataset.id);
return;
}
// TODO: breaks storage/alerting separation!
TestDAO test = TestDAO.findById(event.dataset.testId);
String testName = test == null ? "unknown" : test.name;
log.debugf("Received missing values event in test %d (%s), run %d, variables %s", event.dataset.testId, testName,
event.dataset.id, event.variables);
String fingerprint = em.getReference(DatasetDAO.class, event.dataset.id).getFingerprint();
notifyAll(event.dataset.testId, n -> n.notifyMissingValues(testName, fingerprint, event));
}
private void notifyAll(int testId, Consumer consumer) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy