diff --git a/roda-core/roda-core/src/main/java/org/roda/core/common/notifications/FileNotificationProcessor.java b/roda-core/roda-core/src/main/java/org/roda/core/common/notifications/FileNotificationProcessor.java new file mode 100644 index 0000000000..2bb222c9e5 --- /dev/null +++ b/roda-core/roda-core/src/main/java/org/roda/core/common/notifications/FileNotificationProcessor.java @@ -0,0 +1,86 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE file at the root of the source + * tree and available online at + * + * https://github.com/keeps/roda + */ +package org.roda.core.common.notifications; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +import org.roda.core.RodaCoreFactory; +import org.roda.core.data.common.RodaConstants; +import org.roda.core.data.exceptions.AlreadyExistsException; +import org.roda.core.data.exceptions.GenericException; +import org.roda.core.data.utils.JsonUtils; +import org.roda.core.data.v2.jobs.Job; +import org.roda.core.data.v2.notifications.Notification; +import org.roda.core.data.v2.notifications.Notification.NOTIFICATION_STATE; +import org.roda.core.model.ModelService; +import org.roda.core.storage.fs.FSUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileNotificationProcessor implements NotificationProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(FileNotificationProcessor.class); + public static final String JOB_KEY = "job"; + + private String dropPath; + private Map scope; + + public FileNotificationProcessor(String dropPath, Map scope) { + this.dropPath = dropPath; + this.scope = scope; + } + + @Override + public Notification processNotification(ModelService model, Notification notification) { + if (scope.containsKey(JOB_KEY)) { + Job job = (Job) scope.get(JOB_KEY); + String content = createNotificationContent(job); + notification.setBody(content); + if (dropPath != null && dropPath.startsWith("file:///")) { + LOGGER.debug("Sending notification via drop folder ..."); + Path trimmedDropPath = Paths.get(dropPath.substring(7)); + + if (FSUtils.isDirectory(trimmedDropPath)) { + try { + Path jobPath = FSUtils.createDirectory(trimmedDropPath, job.getId()); + + Path jobFilePath = RodaCoreFactory.getStoragePath().resolve(RodaConstants.STORAGE_CONTAINER_JOB) + .resolve(job.getId() + RodaConstants.JOB_FILE_EXTENSION); + FSUtils.copy(jobFilePath, jobPath.resolve(job.getId() + RodaConstants.JOB_FILE_EXTENSION), true); + + Path jobReportPath = RodaCoreFactory.getStoragePath().resolve(RodaConstants.STORAGE_CONTAINER_JOB_REPORT) + .resolve(job.getId()); + FSUtils.copy(jobReportPath, jobPath.resolve(RodaConstants.RODA_OBJECT_REPORTS), true); + + FSUtils.createFile(jobPath, ".ready"); + + LOGGER.debug("Notification sent"); + notification.setState(NOTIFICATION_STATE.COMPLETED); + } catch (AlreadyExistsException | GenericException | IOException e) { + LOGGER.warn("Notification not sent", e); + notification.setState(NOTIFICATION_STATE.FAILED); + } + } else { + LOGGER.warn("Drop path is not a folder, cannot send notification."); + notification.setState(NOTIFICATION_STATE.FAILED); + } + } else { + LOGGER.warn("No drop path, cannot send notification."); + notification.setState(NOTIFICATION_STATE.FAILED); + } + } + + return notification; + } + + private String createNotificationContent(Job job) { + return JsonUtils.getJsonFromObject(job); + } +} diff --git a/roda-core/roda-core/src/main/java/org/roda/core/common/notifications/HTTPNotificationProcessor.java b/roda-core/roda-core/src/main/java/org/roda/core/common/notifications/HTTPNotificationProcessor.java index 533acf7bc0..bec52decc6 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/common/notifications/HTTPNotificationProcessor.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/common/notifications/HTTPNotificationProcessor.java @@ -33,9 +33,7 @@ import org.slf4j.LoggerFactory; public class HTTPNotificationProcessor implements NotificationProcessor { - private static final Logger LOGGER = LoggerFactory.getLogger(HTTPNotificationProcessor.class); - public static final String JOB_KEY = "job"; private String endpoint; diff --git a/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java b/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java index 59199ebc58..7ab10cf57f 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java @@ -2190,23 +2190,26 @@ public RiskIncidence retrieveRiskIncidence(String incidenceId) /***************** Notification related *****************/ /**********************************************************/ - public Notification createNotification(final Notification notification, final NotificationProcessor processor) + public Notification createNotification(Notification notification, NotificationProcessor processor) throws GenericException, AuthorizationDeniedException { - notification.setId(IdUtils.createUUID()); notification.setAcknowledgeToken(IdUtils.createUUID()); - Notification processedNotification = processor.processNotification(this, notification); + + if (processor != null) { + notification = processor.processNotification(this, notification); + } try { - String notificationAsJson = JsonUtils.getJsonFromObject(processedNotification); - StoragePath notificationPath = ModelUtils.getNotificationStoragePath(processedNotification.getId()); + String notificationAsJson = JsonUtils.getJsonFromObject(notification); + StoragePath notificationPath = ModelUtils.getNotificationStoragePath(notification.getId()); storage.createBinary(notificationPath, new StringContentPayload(notificationAsJson), false); - notifyNotificationCreatedOrUpdated(processedNotification).failOnError(); + notifyNotificationCreatedOrUpdated(notification).failOnError(); } catch (NotFoundException | RequestNotValidException | AlreadyExistsException e) { LOGGER.error("Error creating notification in storage", e); throw new GenericException(e); } - return processedNotification; + + return notification; } public Notification updateNotification(Notification notification) diff --git a/roda-core/roda-core/src/main/java/org/roda/core/storage/fs/FSUtils.java b/roda-core/roda-core/src/main/java/org/roda/core/storage/fs/FSUtils.java index b884cc698e..8d4ec7cc05 100644 --- a/roda-core/roda-core/src/main/java/org/roda/core/storage/fs/FSUtils.java +++ b/roda-core/roda-core/src/main/java/org/roda/core/storage/fs/FSUtils.java @@ -777,11 +777,11 @@ public static Map generateContentDigest(Path path, String... alg return digests; } - public static Path createRandomDirectory(Path parent) throws IOException { + public static Path createDirectory(Path parent, String name) throws IOException { Path directory; do { try { - directory = Files.createDirectory(parent.resolve(IdUtils.createUUID())); + directory = Files.createDirectory(parent.resolve(name)); } catch (FileAlreadyExistsException e) { LOGGER.warn("Got colision when creating random directory", e); directory = null; @@ -791,13 +791,21 @@ public static Path createRandomDirectory(Path parent) throws IOException { return directory; } + public static Path createRandomDirectory(Path parent) throws IOException { + return createDirectory(parent, IdUtils.createUUID()); + } + public static Path createRandomFile(Path parent) throws IOException { + return createFile(parent, IdUtils.createUUID()); + } + + public static Path createFile(Path parent, String name) throws IOException { Path file; do { try { - file = Files.createFile(parent.resolve(IdUtils.createUUID())); + file = Files.createFile(parent.resolve(name)); } catch (FileAlreadyExistsException e) { - LOGGER.warn("Got colision when creating random directory", e); + LOGGER.warn("Got colision when creating random file", e); file = null; } } while (file == null);