working on journal module

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-01-09 08:47:20 +01:00
parent 6668e29923
commit 81dc30359d
10 changed files with 75 additions and 12 deletions

View File

@@ -65,7 +65,7 @@ public class Application {
var server = HttpServer.create(new InetSocketAddress(port), 0); var server = HttpServer.create(new InetSocketAddress(port), 0);
try { try {
new Translations().bindPath("/api/translations").on(server); new Translations().bindPath("/api/translations").on(server);
new JournalModule().bindPath("/api/journal").on(server); new JournalModule(config).bindPath("/api/journal").on(server);
new MessageApi().bindPath("/api/bus").on(server); new MessageApi().bindPath("/api/bus").on(server);
new MessageSystem(config); new MessageSystem(config);
new UserModule(config).bindPath("/api/user").on(server); new UserModule(config).bindPath("/api/user").on(server);

View File

@@ -18,22 +18,28 @@ public abstract class Event<Payload extends Mappable> {
} }
private UmbrellaUser initiator; private UmbrellaUser initiator;
private String realm; private String module;
private Payload payload; private Payload payload;
private EventType eventType; private EventType eventType;
public Event(UmbrellaUser initiator, String realm, Payload payload, EventType type){ public Event(UmbrellaUser initiator, String module, Payload payload, EventType type){
this.initiator = initiator; this.initiator = initiator;
this.realm = realm; this.module = module;
this.payload = payload; this.payload = payload;
this.eventType = type; this.eventType = type;
} }
public abstract String describe();
public String eventType(){ public String eventType(){
return eventType.toString(); return eventType.toString();
} }
public abstract boolean isIntendedFor(UmbrellaUser user); public abstract boolean isIntendedFor(UmbrellaUser user);
public UmbrellaUser initiator(){
return initiator;
}
public String json(){ public String json(){
Class<?> clazz = payload.getClass(); Class<?> clazz = payload.getClass();
{ // get the highest superclass that is not object { // get the highest superclass that is not object
@@ -48,6 +54,10 @@ public abstract class Event<Payload extends Mappable> {
return new JSONObject(map).toString(); return new JSONObject(map).toString();
} }
public String module(){
return module;
}
public Payload payload(){ public Payload payload(){
return payload; return payload;
} }

View File

@@ -12,6 +12,11 @@ public class ProjectEvent extends Event<Project>{
super(initiator, PROJECT, project, type); super(initiator, PROJECT, project, type);
} }
@Override
public String describe() {
return "[TODO: ProjectEvent.describe]";
}
@Override @Override
public boolean isIntendedFor(UmbrellaUser user) { public boolean isIntendedFor(UmbrellaUser user) {
for (var member : payload().members().values()){ for (var member : payload().members().values()){

View File

@@ -12,6 +12,11 @@ public class TaskEvent extends Event<Task>{
super(initiator, TASK, task, type); super(initiator, TASK, task, type);
} }
@Override
public String describe() {
return "[TODO: TaskEvent.describe()]";
}
@Override @Override
public boolean isIntendedFor(UmbrellaUser user) { public boolean isIntendedFor(UmbrellaUser user) {
for (var member : payload().members().values()){ for (var member : payload().members().values()){

View File

@@ -75,5 +75,4 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
} }

View File

@@ -8,10 +8,7 @@ public class Constants {
private Constants(){} private Constants(){}
public static final String ACTION = "action";
public static final String ADDRESS = "address"; public static final String ADDRESS = "address";
public static final String ALLOWED_STATES = "allowed_states"; public static final String ALLOWED_STATES = "allowed_states";
public static final String ATTACHMENTS = "attachments"; public static final String ATTACHMENTS = "attachments";

View File

@@ -3,4 +3,7 @@ package de.srsoftware.umbrella.journal;
public class Constants { public class Constants {
public static final String CONFIG_DATABASE = "umbrella.modules.journal.database"; public static final String CONFIG_DATABASE = "umbrella.modules.journal.database";
public static final String ERROR_WRITE_EVENT = "Failed to write {0} event of {1} to journal!";
public static final String TABLE_JOURNAL = "journal";
} }

View File

@@ -1,4 +1,7 @@
package de.srsoftware.umbrella.journal; package de.srsoftware.umbrella.journal;
import de.srsoftware.umbrella.messagebus.events.Event;
public interface JournalDb { public interface JournalDb {
void logEvent(Event event);
} }

View File

@@ -13,17 +13,18 @@ import static de.srsoftware.umbrella.journal.Constants.CONFIG_DATABASE;
public class JournalModule extends BaseHandler implements EventListener { public class JournalModule extends BaseHandler implements EventListener {
private final SqliteDb journalDb; private final JournalDb journalDb;
public JournalModule(Configuration config){ public JournalModule(Configuration config){
super(); super();
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE)) var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
journalDb = new SqliteDb(connect(dbFile)); journalDb = new SqliteDb(connect(dbFile));
ModuleRegistry.add(this); ModuleRegistry.add(this);
} }
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
LOG.log(System.Logger.Level.DEBUG,"{0} @ {1} ({2})",event.eventType(),event.module(),event.initiator());
journalDb.logEvent(event);
} }
} }

View File

@@ -1,8 +1,19 @@
package de.srsoftware.umbrella.journal; package de.srsoftware.umbrella.journal;
import de.srsoftware.tools.jdbc.Query;
import de.srsoftware.umbrella.core.BaseDb; import de.srsoftware.umbrella.core.BaseDb;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.messagebus.events.Event;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException;
import static de.srsoftware.tools.jdbc.Query.insertInto;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
import static de.srsoftware.umbrella.journal.Constants.ERROR_WRITE_EVENT;
import static de.srsoftware.umbrella.journal.Constants.TABLE_JOURNAL;
import static java.text.MessageFormat.format;
public class SqliteDb extends BaseDb implements JournalDb{ public class SqliteDb extends BaseDb implements JournalDb{
public SqliteDb(Connection connection) { public SqliteDb(Connection connection) {
@@ -18,4 +29,33 @@ public class SqliteDb extends BaseDb implements JournalDb{
return setCurrentVersion(1); return setCurrentVersion(1);
} }
private void createJournalTable() {
var sql = """
CREATE TABLE {0} (
{1} INT PRIMARY KEY,
{2} INT,
{3} VARCHAR(255) NOT NULL,
{4} VARCHAR(16) NUT NULL,
{5} TEXT
);
""";
sql = format(sql,TABLE_JOURNAL,ID,USER_ID,MODULE,ACTION,DESCRIPTION);
try {
db.prepareStatement(sql).execute();
} catch (SQLException e) {
throw databaseException(ERROR_FAILED_CREATE_TABLE,TABLE_JOURNAL);
}
}
@Override
public void logEvent(Event event) {
try {
insertInto(TABLE_JOURNAL,USER_ID,MODULE,ACTION,DESCRIPTION)
.values(event.initiator().id(), event.module(), event.eventType(), event.describe())
.execute(db).close();
} catch (SQLException e) {
throw databaseException(ERROR_WRITE_EVENT,event.eventType(),event.initiator().name());
}
}
} }