first try to generate messages from events

todo:

- add subject function to Event interface
- implement interface on derived event classes
- make events translatable

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-01-13 00:23:46 +01:00
parent 674a80ef09
commit ce5bff6a17
8 changed files with 63 additions and 32 deletions

View File

@@ -3,7 +3,7 @@ default: devel
build: image build: image
podman run --name svelte-build \ podman run --name svelte-build \
--rm \ --rm \
-v ../frontend:/home/svelte/frontend \ -v ../frontend:/home/svelte/frontend:U \
-ti svelte /opt/svelte-build -ti svelte /opt/svelte-build
image: image:
podman build --build-arg UID=$$(id -u) --build-arg GID=$$(id -g) -t svelte . podman build --build-arg UID=$$(id -u) --build-arg GID=$$(id -g) -t svelte .
@@ -11,6 +11,6 @@ image:
devel: image devel: image
-podman rm -f svelte -podman rm -f svelte
podman run --name svelte \ podman run --name svelte \
-v ../frontend:/home/svelte/frontend \ -v ../frontend:/home/svelte/frontend:U \
-p 5173:5173 \ -p 5173:5173 \
-ti svelte /opt/svelte-init -ti svelte /opt/svelte-init

View File

@@ -7,6 +7,7 @@ import static java.util.Optional.*;
import de.srsoftware.tools.Diff; import de.srsoftware.tools.Diff;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@@ -43,6 +44,8 @@ public abstract class Event<Payload extends Mappable> {
this.oldData = oldData; this.oldData = oldData;
} }
public abstract Collection<UmbrellaUser> audience();
public abstract String describe(); public abstract String describe();
private Map<String, Object> dropMarkdown(Map<String, Object> map) { private Map<String, Object> dropMarkdown(Map<String, Object> map) {
@@ -60,11 +63,13 @@ public abstract class Event<Payload extends Mappable> {
} }
public String eventType(){ public EventType eventType(){
return eventType.toString(); return eventType;
} }
public abstract boolean isIntendedFor(UmbrellaUser user); public boolean isIntendedFor(UmbrellaUser user){
return audience().contains(user);
}
public UmbrellaUser initiator(){ public UmbrellaUser initiator(){
return initiator; return initiator;

View File

@@ -3,8 +3,12 @@ package de.srsoftware.umbrella.messagebus.events;
import static de.srsoftware.umbrella.core.Constants.PROJECT; import static de.srsoftware.umbrella.core.Constants.PROJECT;
import de.srsoftware.umbrella.core.model.Member;
import de.srsoftware.umbrella.core.model.Project; import de.srsoftware.umbrella.core.model.Project;
import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
@@ -18,15 +22,12 @@ public class ProjectEvent extends Event<Project>{
} }
@Override @Override
public String describe() { public Collection<UmbrellaUser> audience() {
return diff().orElse("[TODO: ProjectEvent.describe]"); return payload().members().values().stream().map(Member::user).toList();
} }
@Override @Override
public boolean isIntendedFor(UmbrellaUser user) { public String describe() {
for (var member : payload().members().values()){ return diff().orElse("[TODO: ProjectEvent.describe]");
if (member.user().equals(user)) return true;
}
return false;
} }
} }

View File

@@ -3,8 +3,12 @@ package de.srsoftware.umbrella.messagebus.events;
import static de.srsoftware.umbrella.core.Constants.TASK; import static de.srsoftware.umbrella.core.Constants.TASK;
import de.srsoftware.umbrella.core.model.Member;
import de.srsoftware.umbrella.core.model.Task; import de.srsoftware.umbrella.core.model.Task;
import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
@@ -18,15 +22,12 @@ public class TaskEvent extends Event<Task>{
} }
@Override @Override
public String describe() { public Collection<UmbrellaUser> audience() {
return diff().orElse("[TODO: TaskEvent.describe()]"); return payload().members().values().stream().map(Member::user).toList();
} }
@Override @Override
public boolean isIntendedFor(UmbrellaUser user) { public String describe() {
for (var member : payload().members().values()){ return diff().orElse("[TODO: TaskEvent.describe()]");
if (member.user().equals(user)) return true;
}
return false;
} }
} }

View File

@@ -3,8 +3,12 @@ package de.srsoftware.umbrella.messagebus.events;
import static de.srsoftware.umbrella.core.Constants.WIKI; import static de.srsoftware.umbrella.core.Constants.WIKI;
import de.srsoftware.umbrella.core.model.Member;
import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.core.model.WikiPage; import de.srsoftware.umbrella.core.model.WikiPage;
import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
@@ -18,15 +22,12 @@ public class WikiEvent extends Event<WikiPage>{
} }
@Override @Override
public String describe() { public Collection<UmbrellaUser> audience() {
return diff().orElse("[TODO: WikiEvent.describe()]"); return payload().members().values().stream().map(Member::user).toList();
} }
@Override @Override
public boolean isIntendedFor(UmbrellaUser user) { public String describe() {
for (var member : payload().members().values()){ return diff().orElse("[TODO: WikiEvent.describe()]");
if (member.user().equals(user)) return true;
}
return false;
} }
} }

View File

@@ -153,6 +153,11 @@ public class WikiPage implements Mappable {
); );
} }
@Override
public String toString() {
return title;
}
public int version(){ public int version(){
return version; return version;
} }

View File

@@ -1,6 +1,7 @@
description = "Umbrella : Message subsystem" description = "Umbrella : Message subsystem"
dependencies{ dependencies{
implementation(project(":bus"))
implementation(project(":core")) implementation(project(":core"))
implementation("com.sun.mail:jakarta.mail:2.0.1") implementation("com.sun.mail:jakarta.mail:2.0.1")
implementation("org.bitbucket.b_c:jose4j:0.9.6") implementation("org.bitbucket.b_c:jose4j:0.9.6")

View File

@@ -6,7 +6,9 @@ import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingConfigException; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingConfigException;
import static de.srsoftware.umbrella.message.Constants.*; import static de.srsoftware.umbrella.message.Constants.*;
import static de.srsoftware.umbrella.messagebus.MessageBus.messageBus;
import static java.lang.System.Logger.Level.*; import static java.lang.System.Logger.Level.*;
import static java.text.MessageFormat.format;
import de.srsoftware.configuration.Configuration; import de.srsoftware.configuration.Configuration;
import de.srsoftware.umbrella.core.ModuleRegistry; import de.srsoftware.umbrella.core.ModuleRegistry;
@@ -16,6 +18,8 @@ import de.srsoftware.umbrella.core.model.Envelope;
import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.core.model.User; import de.srsoftware.umbrella.core.model.User;
import de.srsoftware.umbrella.message.model.CombinedMessage; import de.srsoftware.umbrella.message.model.CombinedMessage;
import de.srsoftware.umbrella.messagebus.EventListener;
import de.srsoftware.umbrella.messagebus.events.Event;
import jakarta.activation.DataHandler; import jakarta.activation.DataHandler;
import jakarta.mail.Message; import jakarta.mail.Message;
import jakarta.mail.MessagingException; import jakarta.mail.MessagingException;
@@ -29,7 +33,7 @@ import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public class MessageSystem implements PostBox { public class MessageSystem implements PostBox, EventListener {
public static final System.Logger LOG = System.getLogger(MessageSystem.class.getSimpleName()); public static final System.Logger LOG = System.getLogger(MessageSystem.class.getSimpleName());
private final Timer timer = new Timer(); private final Timer timer = new Timer();
@@ -59,9 +63,6 @@ public class MessageSystem implements PostBox {
timer.schedule(this,date.getTime()); timer.schedule(this,date.getTime());
LOG.log(INFO,"Scheduled {0} at {1}",getClass().getSimpleName(),date.getTime()); LOG.log(INFO,"Scheduled {0} at {1}",getClass().getSimpleName(),date.getTime());
} }
} }
private final String from,host,user,pass; private final String from,host,user,pass;
private final int port; private final int port;
@@ -88,8 +89,26 @@ public class MessageSystem implements PostBox {
new SubmissionTask(16).schedule(); new SubmissionTask(16).schedule();
new SubmissionTask(18).schedule(); new SubmissionTask(18).schedule();
new SubmissionTask(20).schedule(); new SubmissionTask(20).schedule();
messageBus().register(this);
} }
@Override
public void onEvent(Event<?> event) {
for (var user : event.audience()){
if (!"s.richter@srsoftware.de".equals(user.email().toString())) continue;
var verb = switch (event.eventType()){
case UPDATE -> "updated";
case CREATE -> "created";
case DELETE -> "deleted";
};
var title = format("{0} {1} {2} {3}",event.initiator().name(),verb,event.module(), event.payload());
var message = new de.srsoftware.umbrella.core.model.Message(event.initiator(),title,event.describe(),null,null);
var envelope = new Envelope(message,user);
send(envelope);
}
}
@Override @Override
public void send(Envelope envelope) { public void send(Envelope envelope) {
queue.add(envelope); queue.add(envelope);
@@ -187,8 +206,6 @@ public class MessageSystem implements PostBox {
} }
} }
LOG.log(TRACE, "Message to {0} is ready…", receiver); LOG.log(TRACE, "Message to {0} is ready…", receiver);
Transport.send(msg,user,pass); Transport.send(msg,user,pass);
LOG.log(DEBUG, "Sent message to {0}.", receiver); LOG.log(DEBUG, "Sent message to {0}.", receiver);