[Major] I18nMessage and LogMessage refactorings, added state, JSON parsers, etc.
This commit is contained in:
parent
006508ff2e
commit
76aff683ee
|
@ -29,6 +29,7 @@ import java.util.*;
|
||||||
import li.strolch.agent.api.*;
|
import li.strolch.agent.api.*;
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -287,7 +288,7 @@ public class ComponentContainerImpl implements ComponentContainer {
|
||||||
for (String realmName : getRealmNames()) {
|
for (String realmName : getRealmNames()) {
|
||||||
getComponent(OperationsLog.class).addMessage(new LogMessage(realmName, SYSTEM_USER_AGENT,
|
getComponent(OperationsLog.class).addMessage(new LogMessage(realmName, SYSTEM_USER_AGENT,
|
||||||
Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()), LogSeverity.Info,
|
Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()), LogSeverity.Info,
|
||||||
ResourceBundle.getBundle("strolch-agent"), "agent.started") //
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"), "agent.started") //
|
||||||
.value("applicationName", applicationName) //
|
.value("applicationName", applicationName) //
|
||||||
.value("environment", environment) //
|
.value("environment", environment) //
|
||||||
.value("components", "" + this.controllerMap.size()) //
|
.value("components", "" + this.controllerMap.size()) //
|
||||||
|
@ -311,7 +312,7 @@ public class ComponentContainerImpl implements ComponentContainer {
|
||||||
for (String realmName : getRealmNames()) {
|
for (String realmName : getRealmNames()) {
|
||||||
getComponent(OperationsLog.class).addMessage(new LogMessage(realmName, SYSTEM_USER_AGENT,
|
getComponent(OperationsLog.class).addMessage(new LogMessage(realmName, SYSTEM_USER_AGENT,
|
||||||
Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()), LogSeverity.Info,
|
Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()), LogSeverity.Info,
|
||||||
ResourceBundle.getBundle("strolch-agent"), "agent.stopping") //
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"), "agent.stopping") //
|
||||||
.value("applicationName", applicationName) //
|
.value("applicationName", applicationName) //
|
||||||
.value("environment", environment) //
|
.value("environment", environment) //
|
||||||
.value("components", "" + this.controllerMap.size()));
|
.value("components", "" + this.controllerMap.size()));
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
import li.strolch.agent.api.*;
|
import li.strolch.agent.api.*;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -162,7 +163,7 @@ public class DefaultObserverHandler implements ObserverHandler {
|
||||||
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
||||||
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), SYSTEM_USER_AGENT,
|
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), SYSTEM_USER_AGENT,
|
||||||
Locator.valueOf(AGENT, ObserverHandler.class.getName(), type, StrolchAgent.getUniqueId()),
|
Locator.valueOf(AGENT, ObserverHandler.class.getName(), type, StrolchAgent.getUniqueId()),
|
||||||
LogSeverity.Exception, ResourceBundle.getBundle("strolch-agent"), "agent.observers.update.failed")
|
LogSeverity.Exception, LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"), "agent.observers.update.failed")
|
||||||
.withException(e).value("type", type).value("reason", e));
|
.withException(e).value("type", type).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import li.strolch.agent.api.*;
|
import li.strolch.agent.api.*;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -193,7 +194,7 @@ public class EventCollectingObserverHandler implements ObserverHandler {
|
||||||
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
||||||
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), SYSTEM_USER_AGENT,
|
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), SYSTEM_USER_AGENT,
|
||||||
Locator.valueOf(AGENT, ObserverHandler.class.getName(), type, StrolchAgent.getUniqueId()),
|
Locator.valueOf(AGENT, ObserverHandler.class.getName(), type, StrolchAgent.getUniqueId()),
|
||||||
LogSeverity.Exception, ResourceBundle.getBundle("strolch-agent"), "agent.observers.update.failed")
|
LogSeverity.Exception, LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"), "agent.observers.update.failed")
|
||||||
.withException(e).value("type", type).value("reason", e));
|
.withException(e).value("type", type).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package li.strolch.handler.operationslog;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
@ -11,32 +12,36 @@ import li.strolch.model.Locator;
|
||||||
import li.strolch.model.Tags.Json;
|
import li.strolch.model.Tags.Json;
|
||||||
import li.strolch.utils.I18nMessage;
|
import li.strolch.utils.I18nMessage;
|
||||||
import li.strolch.utils.helper.ExceptionHelper;
|
import li.strolch.utils.helper.ExceptionHelper;
|
||||||
|
import li.strolch.utils.iso8601.ISO8601;
|
||||||
|
|
||||||
public class LogMessage extends I18nMessage {
|
public class LogMessage extends I18nMessage {
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String username;
|
private final String username;
|
||||||
private ZonedDateTime zonedDateTime;
|
private final ZonedDateTime zonedDateTime;
|
||||||
private final String realm;
|
private final String realm;
|
||||||
private final Locator locator;
|
private final Locator locator;
|
||||||
private final LogSeverity severity;
|
private final LogSeverity severity;
|
||||||
|
private LogMessageState state;
|
||||||
private String stackTrace;
|
private String stackTrace;
|
||||||
|
|
||||||
public LogMessage(String realm, String username, Locator locator, LogSeverity severity, ResourceBundle bundle,
|
public LogMessage(String realm, String username, Locator locator, LogSeverity severity, LogMessageState state,
|
||||||
String key) {
|
ResourceBundle bundle, String key) {
|
||||||
super(bundle, key);
|
super(bundle, key);
|
||||||
this.id = StrolchAgent.getUniqueId();
|
this.id = StrolchAgent.getUniqueId();
|
||||||
this.zonedDateTime = ZonedDateTime.now();
|
|
||||||
// persisting in the DB only handles millisecond precision, not nano precision
|
// persisting in the DB only handles millisecond precision, not nano precision
|
||||||
this.zonedDateTime = this.zonedDateTime.withNano((this.zonedDateTime.getNano() / 1000000) * 1000000);
|
ZonedDateTime now = ZonedDateTime.now();
|
||||||
|
this.zonedDateTime = now.withNano((now.getNano() / 1000000) * 1000000);
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.locator = locator;
|
this.locator = locator;
|
||||||
this.severity = severity;
|
this.severity = severity;
|
||||||
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LogMessage(String id, ZonedDateTime zonedDateTime, String realm, String username, Locator locator,
|
public LogMessage(String id, ZonedDateTime zonedDateTime, String realm, String username, Locator locator,
|
||||||
LogSeverity severity, String key, Properties values, String message, String stackTrace) {
|
LogSeverity severity, LogMessageState state, String key, Properties values, String message,
|
||||||
|
String stackTrace) {
|
||||||
super(key, values, message);
|
super(key, values, message);
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.zonedDateTime = zonedDateTime;
|
this.zonedDateTime = zonedDateTime;
|
||||||
|
@ -44,6 +49,7 @@ public class LogMessage extends I18nMessage {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.locator = locator;
|
this.locator = locator;
|
||||||
this.severity = severity;
|
this.severity = severity;
|
||||||
|
this.state = state;
|
||||||
this.stackTrace = stackTrace;
|
this.stackTrace = stackTrace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +77,14 @@ public class LogMessage extends I18nMessage {
|
||||||
return this.severity;
|
return this.severity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LogMessageState getState() {
|
||||||
|
return this.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(LogMessageState state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
public LogMessage withException(Throwable t) {
|
public LogMessage withException(Throwable t) {
|
||||||
this.stackTrace = ExceptionHelper.formatException(t);
|
this.stackTrace = ExceptionHelper.formatException(t);
|
||||||
return this;
|
return this;
|
||||||
|
@ -100,9 +114,11 @@ public class LogMessage extends I18nMessage {
|
||||||
jsonObject.addProperty(Json.KEY, getKey());
|
jsonObject.addProperty(Json.KEY, getKey());
|
||||||
jsonObject.addProperty(Json.MESSAGE, formatMessage());
|
jsonObject.addProperty(Json.MESSAGE, formatMessage());
|
||||||
jsonObject.addProperty(Json.SEVERITY, this.severity.name());
|
jsonObject.addProperty(Json.SEVERITY, this.severity.name());
|
||||||
|
jsonObject.addProperty(Json.STATE, this.state.name());
|
||||||
jsonObject.addProperty(Json.USERNAME, this.username);
|
jsonObject.addProperty(Json.USERNAME, this.username);
|
||||||
jsonObject.addProperty(Json.REALM, this.realm);
|
jsonObject.addProperty(Json.REALM, this.realm);
|
||||||
jsonObject.addProperty(Json.LOCATOR, this.locator.toString());
|
jsonObject.addProperty(Json.LOCATOR, this.locator.toString());
|
||||||
|
if (this.stackTrace != null)
|
||||||
jsonObject.addProperty(Json.EXCEPTION, this.stackTrace);
|
jsonObject.addProperty(Json.EXCEPTION, this.stackTrace);
|
||||||
JsonObject values = new JsonObject();
|
JsonObject values = new JsonObject();
|
||||||
for (String key : getValues().stringPropertyNames()) {
|
for (String key : getValues().stringPropertyNames()) {
|
||||||
|
@ -113,37 +129,48 @@ public class LogMessage extends I18nMessage {
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static LogMessage fromJson(JsonObject messageJ) {
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
String id = messageJ.get(Json.ID).getAsString();
|
||||||
int result = super.hashCode();
|
ZonedDateTime zonedDateTime = ISO8601.parseToZdt(messageJ.get(Json.DATE).getAsString());
|
||||||
result = prime * result + ((this.locator == null) ? 0 : this.locator.hashCode());
|
String realm = messageJ.get(Json.REALM).getAsString();
|
||||||
result = prime * result + ((this.realm == null) ? 0 : this.realm.hashCode());
|
String username = messageJ.get(Json.USERNAME).getAsString();
|
||||||
result = prime * result + ((this.severity == null) ? 0 : this.severity.hashCode());
|
Locator locator = Locator.valueOf(messageJ.get(Json.LOCATOR).getAsString());
|
||||||
return result;
|
LogSeverity severity = LogSeverity.valueOf(messageJ.get(Json.SEVERITY).getAsString());
|
||||||
|
LogMessageState state = LogMessageState.valueOf(messageJ.get(Json.STATE).getAsString());
|
||||||
|
String key = messageJ.get(Json.KEY).getAsString();
|
||||||
|
String message = messageJ.get(Json.MESSAGE).getAsString();
|
||||||
|
String stackTrace = messageJ.has(Json.EXCEPTION) ? messageJ.get(Json.EXCEPTION).getAsString() : "";
|
||||||
|
|
||||||
|
Properties properties = new Properties();
|
||||||
|
if (messageJ.has(Json.VALUES)) {
|
||||||
|
JsonObject valuesJ = messageJ.getAsJsonObject(Json.VALUES);
|
||||||
|
for (String propertyName : valuesJ.keySet()) {
|
||||||
|
properties.setProperty(propertyName, valuesJ.get(propertyName).getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LogMessage(id, zonedDateTime, realm, username, locator, severity, state, key, properties, message,
|
||||||
|
stackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object o) {
|
||||||
if (this == obj)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
if (!super.equals(obj))
|
if (o == null || getClass() != o.getClass())
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (!super.equals(o))
|
||||||
return false;
|
return false;
|
||||||
LogMessage other = (LogMessage) obj;
|
|
||||||
if (this.locator == null) {
|
LogMessage that = (LogMessage) o;
|
||||||
if (other.locator != null)
|
return Objects.equals(id, that.id);
|
||||||
return false;
|
}
|
||||||
} else if (!this.locator.equals(other.locator))
|
|
||||||
return false;
|
@Override
|
||||||
if (this.realm == null) {
|
public int hashCode() {
|
||||||
if (other.realm != null)
|
int result = super.hashCode();
|
||||||
return false;
|
result = 31 * result + (id != null ? id.hashCode() : 0);
|
||||||
} else if (!this.realm.equals(other.realm))
|
return result;
|
||||||
return false;
|
|
||||||
if (this.severity != other.severity)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package li.strolch.handler.operationslog;
|
||||||
|
|
||||||
|
public enum LogMessageState {
|
||||||
|
Active,
|
||||||
|
Inactive,
|
||||||
|
Information
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchAgent;
|
import li.strolch.agent.api.StrolchAgent;
|
||||||
|
@ -94,6 +95,72 @@ public class OperationsLog extends StrolchComponent {
|
||||||
this.executorService.submit(() -> persist(realm, logMessage, messagesToRemove));
|
this.executorService.submit(() -> persist(realm, logMessage, messagesToRemove));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeMessage(LogMessage message) {
|
||||||
|
|
||||||
|
String realmName = message.getRealm();
|
||||||
|
LinkedHashMap<Locator, LinkedHashSet<LogMessage>> byLocator = this.logMessagesByLocator.get(realmName);
|
||||||
|
if (byLocator != null)
|
||||||
|
byLocator.remove(message.getLocator());
|
||||||
|
|
||||||
|
List<LogMessage> messages = this.logMessagesByRealmAndId.get(realmName);
|
||||||
|
if (messages != null) {
|
||||||
|
messages.remove(message);
|
||||||
|
|
||||||
|
// persist changes for non-transient realms
|
||||||
|
StrolchRealm realm = getContainer().getRealm(realmName);
|
||||||
|
if (!realm.getMode().isTransient())
|
||||||
|
this.executorService.submit(() -> persist(realm, null, Collections.singletonList(message)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void removeMessages(Collection<LogMessage> logMessages) {
|
||||||
|
|
||||||
|
Map<String, List<LogMessage>> messagesByRealm = logMessages.stream()
|
||||||
|
.collect(Collectors.groupingBy(LogMessage::getRealm));
|
||||||
|
|
||||||
|
messagesByRealm.forEach((realmName, messages) -> {
|
||||||
|
|
||||||
|
LinkedHashMap<Locator, LinkedHashSet<LogMessage>> byLocator = this.logMessagesByLocator.get(realmName);
|
||||||
|
if (byLocator != null)
|
||||||
|
messages.forEach(logMessage -> byLocator.remove(logMessage.getLocator()));
|
||||||
|
|
||||||
|
List<LogMessage> byRealm = this.logMessagesByRealmAndId.get(realmName);
|
||||||
|
if (byRealm != null) {
|
||||||
|
messages.removeIf(logMessage -> !byRealm.remove(logMessage));
|
||||||
|
|
||||||
|
// persist changes for non-transient realms
|
||||||
|
StrolchRealm realm = getContainer().getRealm(realmName);
|
||||||
|
if (!realm.getMode().isTransient())
|
||||||
|
this.executorService.submit(() -> persist(realm, null, messages));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void updateState(String realmName, Locator locator, LogMessageState state) {
|
||||||
|
getMessagesFor(realmName, locator).ifPresent(logMessages -> {
|
||||||
|
logMessages.forEach(logMessage -> logMessage.setState(state));
|
||||||
|
|
||||||
|
StrolchRealm realm = getContainer().getRealm(realmName);
|
||||||
|
if (!realm.getMode().isTransient()) {
|
||||||
|
persist(realm, logMessages);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void updateState(String realmName, String id, LogMessageState state) {
|
||||||
|
List<LogMessage> logMessages = this.logMessagesByRealmAndId.get(realmName);
|
||||||
|
for (LogMessage logMessage : logMessages) {
|
||||||
|
if (logMessage.getId().equals(id)) {
|
||||||
|
logMessage.setState(state);
|
||||||
|
|
||||||
|
StrolchRealm realm = getContainer().getRealm(realmName);
|
||||||
|
if (!realm.getMode().isTransient()) {
|
||||||
|
persist(realm, logMessages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<LogMessage> pruneMessages(List<LogMessage> logMessages) {
|
private List<LogMessage> pruneMessages(List<LogMessage> logMessages) {
|
||||||
if (logMessages.size() < this.maxMessages)
|
if (logMessages.size() < this.maxMessages)
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -124,6 +191,7 @@ public class OperationsLog extends StrolchComponent {
|
||||||
LogMessageDao logMessageDao = tx.getPersistenceHandler().getLogMessageDao(tx);
|
LogMessageDao logMessageDao = tx.getPersistenceHandler().getLogMessageDao(tx);
|
||||||
if (messagesToRemove != null && !messagesToRemove.isEmpty())
|
if (messagesToRemove != null && !messagesToRemove.isEmpty())
|
||||||
logMessageDao.removeAll(messagesToRemove);
|
logMessageDao.removeAll(messagesToRemove);
|
||||||
|
if (logMessage != null)
|
||||||
logMessageDao.save(logMessage);
|
logMessageDao.save(logMessage);
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
|
@ -134,7 +202,31 @@ public class OperationsLog extends StrolchComponent {
|
||||||
this.logMessagesByRealmAndId.computeIfAbsent(realm.getRealm(), r -> new ArrayList<>())
|
this.logMessagesByRealmAndId.computeIfAbsent(realm.getRealm(), r -> new ArrayList<>())
|
||||||
.add(new LogMessage(realm.getRealm(), SYSTEM_USER_AGENT,
|
.add(new LogMessage(realm.getRealm(), SYSTEM_USER_AGENT,
|
||||||
Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()), LogSeverity.Info,
|
Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()), LogSeverity.Info,
|
||||||
ResourceBundle.getBundle("strolch-agent"), "operationsLog.persist.failed") //
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"),
|
||||||
|
"operationsLog.persist.failed") //
|
||||||
|
.value("reason", e.getMessage()) //
|
||||||
|
.withException(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void persist(StrolchRealm realm, Collection<LogMessage> logMessages) {
|
||||||
|
try {
|
||||||
|
runAsAgent(ctx -> {
|
||||||
|
try (StrolchTransaction tx = realm.openTx(ctx.getCertificate(), getClass(), false)) {
|
||||||
|
LogMessageDao logMessageDao = tx.getPersistenceHandler().getLogMessageDao(tx);
|
||||||
|
logMessageDao.updateStates(logMessages);
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to persist operations logs!", e);
|
||||||
|
synchronized (this) {
|
||||||
|
this.logMessagesByRealmAndId.computeIfAbsent(realm.getRealm(), r -> new ArrayList<>())
|
||||||
|
.add(new LogMessage(realm.getRealm(), SYSTEM_USER_AGENT,
|
||||||
|
Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()), LogSeverity.Info,
|
||||||
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"),
|
||||||
|
"operationsLog.persist.failed") //
|
||||||
.value("reason", e.getMessage()) //
|
.value("reason", e.getMessage()) //
|
||||||
.withException(e));
|
.withException(e));
|
||||||
}
|
}
|
||||||
|
@ -170,9 +262,4 @@ public class OperationsLog extends StrolchComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeMessage(String realm, LogMessage message) {
|
|
||||||
List<LogMessage> messages = this.logMessagesByRealmAndId.get(realm);
|
|
||||||
messages.remove(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import li.strolch.agent.api.StrolchAgent;
|
||||||
import li.strolch.agent.api.StrolchComponent;
|
import li.strolch.agent.api.StrolchComponent;
|
||||||
import li.strolch.agent.api.StrolchRealm;
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -266,7 +267,7 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
operationsLog.addMessage(
|
operationsLog.addMessage(
|
||||||
new LogMessage(this.realmName == null ? StrolchConstants.DEFAULT_REALM : this.realmName,
|
new LogMessage(this.realmName == null ? StrolchConstants.DEFAULT_REALM : this.realmName,
|
||||||
SYSTEM_USER_AGENT, Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()),
|
SYSTEM_USER_AGENT, Locator.valueOf(AGENT, "strolch-agent", StrolchAgent.getUniqueId()),
|
||||||
LogSeverity.Exception, ResourceBundle.getBundle("strolch-agent"), "strolchjob.failed")
|
LogSeverity.Exception, LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"), "strolchjob.failed")
|
||||||
.withException(e).value("jobName", getClass().getName()).value("reason", e));
|
.withException(e).value("jobName", getClass().getName()).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import li.strolch.exception.StrolchAccessDeniedException;
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.exception.StrolchModelException;
|
import li.strolch.exception.StrolchModelException;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.*;
|
import li.strolch.model.*;
|
||||||
|
@ -1692,7 +1693,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
||||||
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), this.certificate.getUsername(),
|
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), this.certificate.getUsername(),
|
||||||
Locator.valueOf(AGENT, "tx", this.action, getUniqueId()), LogSeverity.Exception,
|
Locator.valueOf(AGENT, "tx", this.action, getUniqueId()), LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-agent"), "agent.tx.failed").withException(e).value("reason", e));
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"), "agent.tx.failed").withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
|
|
||||||
String msg = "Strolch Transaction for realm {0} failed due to {1}\n{2}"; //$NON-NLS-1$
|
String msg = "Strolch Transaction for realm {0} failed due to {1}\n{2}"; //$NON-NLS-1$
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.persistence.api;
|
package li.strolch.persistence.api;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
|
||||||
|
@ -31,6 +31,10 @@ public interface LogMessageDao {
|
||||||
|
|
||||||
void saveAll(List<LogMessage> logMessages);
|
void saveAll(List<LogMessage> logMessages);
|
||||||
|
|
||||||
|
void updateState(LogMessage logMessage);
|
||||||
|
|
||||||
|
void updateStates(Collection<LogMessage> logMessages);
|
||||||
|
|
||||||
void remove(LogMessage logMessage);
|
void remove(LogMessage logMessage);
|
||||||
|
|
||||||
void removeAll(List<LogMessage> logMessages);
|
void removeAll(List<LogMessage> logMessages);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import li.strolch.agent.api.StrolchComponent;
|
||||||
import li.strolch.exception.StrolchAccessDeniedException;
|
import li.strolch.exception.StrolchAccessDeniedException;
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -219,11 +220,11 @@ public class DefaultServiceHandler extends StrolchComponent implements ServiceHa
|
||||||
ResourceBundle bundle = ResourceBundle.getBundle("strolch-agent");
|
ResourceBundle bundle = ResourceBundle.getBundle("strolch-agent");
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
logMessage = new LogMessage(realmName, username, Locator.valueOf(AGENT, svcName, getUniqueId()),
|
logMessage = new LogMessage(realmName, username, Locator.valueOf(AGENT, svcName, getUniqueId()),
|
||||||
LogSeverity.Exception, bundle, "agent.service.failed").value("service", svcName)
|
LogSeverity.Exception, LogMessageState.Information, bundle, "agent.service.failed").value("service", svcName)
|
||||||
.value("reason", reason);
|
.value("reason", reason);
|
||||||
} else {
|
} else {
|
||||||
logMessage = new LogMessage(realmName, username, Locator.valueOf(AGENT, svcName, getUniqueId()),
|
logMessage = new LogMessage(realmName, username, Locator.valueOf(AGENT, svcName, getUniqueId()),
|
||||||
LogSeverity.Exception, bundle, "agent.service.failed.ex").withException(throwable)
|
LogSeverity.Exception, LogMessageState.Information, bundle, "agent.service.failed.ex").withException(throwable)
|
||||||
.value("service", svcName).value("reason", reason).value("exception", throwable);
|
.value("service", svcName).value("reason", reason).value("exception", throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,34 @@
|
||||||
package li.strolch.model.i18n;
|
package li.strolch.model.i18n;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import li.strolch.model.Tags;
|
||||||
import li.strolch.utils.I18nMessage;
|
import li.strolch.utils.I18nMessage;
|
||||||
|
|
||||||
public class I18nMessageJsonParser {
|
public class I18nMessageJsonParser {
|
||||||
|
|
||||||
public static I18nMessage parse(JsonObject messageJ) {
|
public I18nMessage parse(JsonObject messageJ) {
|
||||||
|
|
||||||
// TODO
|
String key = messageJ.get(Tags.Json.KEY).getAsString();
|
||||||
|
String message = messageJ.get(Tags.Json.MESSAGE).getAsString();
|
||||||
|
|
||||||
// String key = json.addProperty("key", message.getKey());
|
Properties properties = new Properties();
|
||||||
// json.addProperty("message", message.getMessage());
|
if (messageJ.has(Tags.Json.VALUES)) {
|
||||||
//
|
JsonArray valuesJ = messageJ.getAsJsonArray(Tags.Json.VALUES);
|
||||||
// Properties values = message.getValues();
|
for (JsonElement jsonElement : valuesJ) {
|
||||||
// if (!values.isEmpty()) {
|
JsonObject valueJ = jsonElement.getAsJsonObject();
|
||||||
// JsonObject valuesJ = new JsonObject();
|
|
||||||
// values.stringPropertyNames().forEach(key -> valuesJ.addProperty(key, values.getProperty(key)));
|
|
||||||
// json.add("values", valuesJ);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return null;
|
Set<String> keys = valueJ.keySet();
|
||||||
|
for (String propertyName : keys) {
|
||||||
|
properties.setProperty(propertyName, valueJ.get(propertyName).getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new I18nMessage(key, properties, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package li.strolch.model.i18n;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import li.strolch.model.Tags;
|
||||||
import li.strolch.utils.I18nMessage;
|
import li.strolch.utils.I18nMessage;
|
||||||
import li.strolch.utils.I18nMessageVisitor;
|
import li.strolch.utils.I18nMessageVisitor;
|
||||||
|
|
||||||
|
@ -12,14 +13,14 @@ public class I18nMessageToJsonVisitor implements I18nMessageVisitor<JsonObject>
|
||||||
public JsonObject visit(I18nMessage message) {
|
public JsonObject visit(I18nMessage message) {
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
|
|
||||||
json.addProperty("key", message.getKey());
|
json.addProperty(Tags.Json.KEY, message.getKey());
|
||||||
json.addProperty("message", message.getMessage());
|
json.addProperty(Tags.Json.MESSAGE, message.getMessage());
|
||||||
|
|
||||||
Properties values = message.getValues();
|
Properties values = message.getValues();
|
||||||
if (!values.isEmpty()) {
|
if (!values.isEmpty()) {
|
||||||
JsonObject valuesJ = new JsonObject();
|
JsonObject valuesJ = new JsonObject();
|
||||||
values.stringPropertyNames().forEach(key -> valuesJ.addProperty(key, values.getProperty(key)));
|
values.stringPropertyNames().forEach(key -> valuesJ.addProperty(key, values.getProperty(key)));
|
||||||
json.add("values", valuesJ);
|
json.add(Tags.Json.VALUES, valuesJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.time.ZonedDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
import li.strolch.persistence.api.LogMessageDao;
|
import li.strolch.persistence.api.LogMessageDao;
|
||||||
|
@ -28,18 +29,21 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
||||||
private static final String KEY = "key";
|
private static final String KEY = "key";
|
||||||
private static final String MESSAGE = "message";
|
private static final String MESSAGE = "message";
|
||||||
private static final String STACK_TRACE = "stacktrace";
|
private static final String STACK_TRACE = "stacktrace";
|
||||||
|
private static final String STATE = "state";
|
||||||
|
|
||||||
private static final String FIELDS = commaSeparated(ID, REALM, DATE_TIME, USERNAME, SEVERITY, LOCATOR, KEY, MESSAGE,
|
private static final String FIELDS = commaSeparated(ID, REALM, DATE_TIME, USERNAME, SEVERITY, STATE, LOCATOR, KEY,
|
||||||
STACK_TRACE);
|
MESSAGE, STACK_TRACE);
|
||||||
|
|
||||||
private static final String queryByRealmMaxSql =
|
private static final String queryByRealmMaxSql =
|
||||||
"select " + FIELDS + " from operations_log where realm = ? order by id desc limit ?";
|
"select " + FIELDS + " from operations_log where realm = ? order by id desc limit ?";
|
||||||
private static final String queryValuesSql = "select key, value from operations_log_values where id = ?";
|
private static final String queryValuesSql = "select key, value from operations_log_values where id = ?";
|
||||||
|
|
||||||
private static final String insertLogMessageSql =
|
private static final String insertLogMessageSql = "insert into operations_log (" + FIELDS
|
||||||
"insert into operations_log (" + FIELDS + ") values (?, ?, ?, ?, ?::log_severity_type, ?, ?, ?, ?)";
|
+ ") values (?, ?, ?, ?, ?::log_severity_type, ?::log_state_type, ?, ?, ?, ?)";
|
||||||
private static final String insertValuesSql = "insert into operations_log_values (id, key, value) values (?, ?, ?)";
|
private static final String insertValuesSql = "insert into operations_log_values (id, key, value) values (?, ?, ?)";
|
||||||
|
|
||||||
|
private static final String updateLogMessageStateSql = "update operations_log set state = ?::log_state_type where id = ?";
|
||||||
|
|
||||||
private static final String removeSql = "delete from operations_log where id = ?";
|
private static final String removeSql = "delete from operations_log where id = ?";
|
||||||
private static final String removeValuesSql = "delete from operations_log_values where id = ?";
|
private static final String removeValuesSql = "delete from operations_log_values where id = ?";
|
||||||
|
|
||||||
|
@ -106,9 +110,34 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAll(List<LogMessage> logMessages) {
|
public void saveAll(List<LogMessage> logMessages) {
|
||||||
for (LogMessage logMessage : logMessages) {
|
logMessages.forEach(this::save);
|
||||||
save(logMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(LogMessage logMessage) {
|
||||||
|
try (PreparedStatement ps = this.tx.getConnection().prepareStatement(updateLogMessageStateSql)) {
|
||||||
|
|
||||||
|
// update state
|
||||||
|
ps.setString(1, logMessage.getState().name());
|
||||||
|
ps.setString(2, logMessage.getId());
|
||||||
|
|
||||||
|
int count = ps.executeUpdate();
|
||||||
|
if (count != 1) {
|
||||||
|
throw new StrolchPersistenceException(MessageFormat
|
||||||
|
.format("Expected to update 1 log_message record, but updated {0} for LogMessage {2}", count,
|
||||||
|
logMessage.getId())); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new StrolchPersistenceException(MessageFormat
|
||||||
|
.format("Failed to update LogMessage state {0} due to {1}", logMessage.getId(), //$NON-NLS-1$
|
||||||
|
e.getLocalizedMessage()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStates(Collection<LogMessage> logMessages) {
|
||||||
|
logMessages.forEach(this::updateState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -237,10 +266,11 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
||||||
// 3 dateTime = ?,
|
// 3 dateTime = ?,
|
||||||
// 4 username = ?,
|
// 4 username = ?,
|
||||||
// 5 severity = ?,
|
// 5 severity = ?,
|
||||||
// 6 locator = ?,
|
// 6 state = ?
|
||||||
// 7 key = ?,
|
// 7 locator = ?,
|
||||||
// 8 message = ?,
|
// 8 key = ?,
|
||||||
// 9 stacktrace = ?,
|
// 9 message = ?,
|
||||||
|
// 10 stacktrace = ?,
|
||||||
|
|
||||||
ps.setString(1, logMessage.getId());
|
ps.setString(1, logMessage.getId());
|
||||||
ps.setString(2, logMessage.getRealm());
|
ps.setString(2, logMessage.getRealm());
|
||||||
|
@ -248,10 +278,11 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
||||||
Calendar.getInstance());
|
Calendar.getInstance());
|
||||||
ps.setString(4, logMessage.getUsername());
|
ps.setString(4, logMessage.getUsername());
|
||||||
ps.setString(5, logMessage.getSeverity().name());
|
ps.setString(5, logMessage.getSeverity().name());
|
||||||
ps.setString(6, logMessage.getLocator().toString());
|
ps.setString(6, logMessage.getState().name());
|
||||||
ps.setString(7, logMessage.getKey());
|
ps.setString(7, logMessage.getLocator().toString());
|
||||||
ps.setString(8, logMessage.getMessage());
|
ps.setString(8, logMessage.getKey());
|
||||||
ps.setString(9, logMessage.getStackTrace());
|
ps.setString(9, logMessage.getMessage());
|
||||||
|
ps.setString(10, logMessage.getStackTrace());
|
||||||
}
|
}
|
||||||
|
|
||||||
private LogMessage logMessageFrom(ResultSet resultSet, ResultSet valuesResult) throws SQLException {
|
private LogMessage logMessageFrom(ResultSet resultSet, ResultSet valuesResult) throws SQLException {
|
||||||
|
@ -261,10 +292,11 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
||||||
ZonedDateTime dateTime = ZonedDateTime.ofInstant(resultSet.getTimestamp(3).toInstant(), ZoneId.systemDefault());
|
ZonedDateTime dateTime = ZonedDateTime.ofInstant(resultSet.getTimestamp(3).toInstant(), ZoneId.systemDefault());
|
||||||
String username = resultSet.getString(4);
|
String username = resultSet.getString(4);
|
||||||
LogSeverity severity = LogSeverity.valueOf(resultSet.getString(5));
|
LogSeverity severity = LogSeverity.valueOf(resultSet.getString(5));
|
||||||
Locator locator = Locator.valueOf(resultSet.getString(6));
|
LogMessageState state = LogMessageState.valueOf(resultSet.getString(6));
|
||||||
String key = resultSet.getString(7);
|
Locator locator = Locator.valueOf(resultSet.getString(7));
|
||||||
String message = resultSet.getString(8);
|
String key = resultSet.getString(8);
|
||||||
String exception = resultSet.getString(9);
|
String message = resultSet.getString(9);
|
||||||
|
String exception = resultSet.getString(10);
|
||||||
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
while (valuesResult.next()) {
|
while (valuesResult.next()) {
|
||||||
|
@ -273,6 +305,7 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
||||||
properties.setProperty(valueK, valueV);
|
properties.setProperty(valueK, valueV);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LogMessage(id, dateTime, realm, username, locator, severity, key, properties, message, exception);
|
return new LogMessage(id, dateTime, realm, username, locator, severity, state, key, properties, message,
|
||||||
|
exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS resources;
|
||||||
|
DROP TABLE IF EXISTS orders;
|
||||||
|
DROP TABLE IF EXISTS activities;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS audits;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS operations_log;
|
||||||
|
DROP TABLE IF EXISTS operations_log_values;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS db_version;
|
||||||
|
|
||||||
|
DROP TYPE IF EXISTS order_state;
|
||||||
|
DROP TYPE IF EXISTS access_type;
|
||||||
|
DROP TYPE IF EXISTS log_severity_type;
|
||||||
|
DROP TYPE IF EXISTS log_state_type;
|
|
@ -0,0 +1,207 @@
|
||||||
|
|
||||||
|
-- DB_VERSION
|
||||||
|
CREATE TABLE IF NOT EXISTS db_version (
|
||||||
|
id serial primary key not null,
|
||||||
|
app varchar(255) not null,
|
||||||
|
version varchar(255) not null,
|
||||||
|
description varchar(255) not null,
|
||||||
|
created timestamp with time zone not null
|
||||||
|
);
|
||||||
|
|
||||||
|
-- RESOURCES
|
||||||
|
CREATE TABLE IF NOT EXISTS resources (
|
||||||
|
id varchar(255) not null,
|
||||||
|
version integer not null,
|
||||||
|
created_by varchar(255) not null,
|
||||||
|
created_at timestamp with time zone not null,
|
||||||
|
updated_at timestamp with time zone not null,
|
||||||
|
deleted boolean not null,
|
||||||
|
latest boolean not null,
|
||||||
|
name varchar(255) not null,
|
||||||
|
type varchar(255) not null,
|
||||||
|
asxml xml,
|
||||||
|
asjson json,
|
||||||
|
|
||||||
|
PRIMARY KEY (id, version)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ORDERS
|
||||||
|
CREATE TYPE order_state AS ENUM ('CREATED', 'PLANNING', 'PLANNED', 'EXECUTION', 'STOPPED', 'WARNING', 'ERROR', 'EXECUTED', 'CLOSED');
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS orders (
|
||||||
|
id varchar(255) not null,
|
||||||
|
version integer not null,
|
||||||
|
created_by varchar(255) not null,
|
||||||
|
created_at timestamp with time zone not null,
|
||||||
|
updated_at timestamp with time zone not null,
|
||||||
|
deleted boolean,
|
||||||
|
latest boolean not null,
|
||||||
|
name varchar(255),
|
||||||
|
type varchar(255),
|
||||||
|
state order_state,
|
||||||
|
date timestamp with time zone,
|
||||||
|
asxml xml,
|
||||||
|
asjson json,
|
||||||
|
|
||||||
|
PRIMARY KEY (id, version)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ACTIVITIES
|
||||||
|
CREATE TABLE IF NOT EXISTS activities (
|
||||||
|
id varchar(255) not null,
|
||||||
|
version integer not null,
|
||||||
|
created_by varchar(255) not null,
|
||||||
|
created_at timestamp with time zone not null,
|
||||||
|
updated_at timestamp with time zone not null,
|
||||||
|
deleted boolean not null,
|
||||||
|
latest boolean not null,
|
||||||
|
name varchar(255) not null,
|
||||||
|
type varchar(255) not null,
|
||||||
|
state order_state,
|
||||||
|
asxml xml,
|
||||||
|
asjson json,
|
||||||
|
|
||||||
|
PRIMARY KEY (id, version)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AUDITS
|
||||||
|
CREATE TYPE access_type AS ENUM ('READ', 'CREATE', 'UPDATE', 'DELETE');
|
||||||
|
CREATE TABLE IF NOT EXISTS audits (
|
||||||
|
id bigint PRIMARY KEY,
|
||||||
|
username varchar(255) NOT NULL,
|
||||||
|
firstname varchar(255) NOT NULL,
|
||||||
|
lastname varchar(255) NOT NULL,
|
||||||
|
date timestamp with time zone NOT NULL,
|
||||||
|
|
||||||
|
element_type varchar(255) NOT NULL,
|
||||||
|
element_sub_type varchar(255) NOT NULL,
|
||||||
|
element_accessed varchar(255) NOT NULL,
|
||||||
|
new_version timestamp with time zone,
|
||||||
|
|
||||||
|
action varchar(255) NOT NULL,
|
||||||
|
access_type access_type NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Operations Log
|
||||||
|
CREATE TYPE log_severity_type AS ENUM ('Info', 'Notification', 'Warning', 'Error', 'Exception');
|
||||||
|
CREATE TYPE log_state_type AS ENUM ('Active', 'Inactive', 'Information');
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS operations_log (
|
||||||
|
id varchar(255) PRIMARY KEY,
|
||||||
|
realm varchar(255),
|
||||||
|
dateTime timestamp with time zone,
|
||||||
|
username varchar(255),
|
||||||
|
severity log_severity_type,
|
||||||
|
state log_state_type,
|
||||||
|
locator varchar(1024),
|
||||||
|
key varchar(255),
|
||||||
|
message text,
|
||||||
|
stacktrace text
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS operations_log_values (
|
||||||
|
id varchar(255),
|
||||||
|
key varchar(255),
|
||||||
|
value text
|
||||||
|
);
|
||||||
|
|
||||||
|
-- set version
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.1.0',
|
||||||
|
'strolch',
|
||||||
|
'Initial schema version',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.2.0',
|
||||||
|
'strolch',
|
||||||
|
'Added new table for audits',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.2.1',
|
||||||
|
'strolch',
|
||||||
|
'Added new column app to table table version',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.3.0',
|
||||||
|
'strolch',
|
||||||
|
'Added new column element_sub_type to table audits',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.4.0',
|
||||||
|
'strolch',
|
||||||
|
'Added new table activities',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.5.0',
|
||||||
|
'strolch',
|
||||||
|
'Added versioning to root elements',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.5.1',
|
||||||
|
'strolch',
|
||||||
|
'Added state column to activity, and added new states',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.6.0',
|
||||||
|
'strolch',
|
||||||
|
'Added json column to all tables',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.7.0',
|
||||||
|
'strolch',
|
||||||
|
'Added persisting of operations log',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.8.0',
|
||||||
|
'strolch',
|
||||||
|
'Added updated_at column to all tables',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.9.0',
|
||||||
|
'strolch',
|
||||||
|
'Added log_state column to operations_log',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
-- add new type
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'log_state_type') THEN
|
||||||
|
CREATE TYPE log_state_type AS ENUM ('Active', 'Inactive', 'Information');
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
-- add version columns
|
||||||
|
ALTER TABLE operations_log ADD COLUMN state log_state_type;
|
||||||
|
|
||||||
|
-- set initial values for new columns
|
||||||
|
UPDATE operations_log SET state = 'Information' where state IS NULL;
|
||||||
|
|
||||||
|
-- make columns not null
|
||||||
|
ALTER TABLE operations_log ALTER COLUMN state SET NOT NULL;
|
||||||
|
|
||||||
|
INSERT INTO db_version
|
||||||
|
(version, app, description, created)
|
||||||
|
values(
|
||||||
|
'0.9.0',
|
||||||
|
'strolch',
|
||||||
|
'Added log_state column to operations_log',
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
|
@ -1,2 +1,2 @@
|
||||||
# Property file defining what the currently expected version is supposed to be
|
# Property file defining what the currently expected version is supposed to be
|
||||||
db_version=0.8.0
|
db_version=0.9.0
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package li.strolch.persistence.xml;
|
package li.strolch.persistence.xml;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
@ -38,6 +39,16 @@ public class XmlLogMessageDao implements LogMessageDao {
|
||||||
this.tx.getObjectDao().addAll(logMessages);
|
this.tx.getObjectDao().addAll(logMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(LogMessage logMessage) {
|
||||||
|
this.tx.getObjectDao().update(logMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStates(Collection<LogMessage> logMessages) {
|
||||||
|
logMessages.forEach(logMessage -> this.tx.getObjectDao().update(logMessage));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(LogMessage logMessage) {
|
public void remove(LogMessage logMessage) {
|
||||||
this.tx.getObjectDao().remove(logMessage);
|
this.tx.getObjectDao().remove(logMessage);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Properties;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
import li.strolch.model.Tags;
|
import li.strolch.model.Tags;
|
||||||
|
@ -42,6 +43,7 @@ public class LogMessageSaxReader extends DefaultHandler {
|
||||||
private String username;
|
private String username;
|
||||||
private Locator locator;
|
private Locator locator;
|
||||||
private LogSeverity severity;
|
private LogSeverity severity;
|
||||||
|
private LogMessageState state;
|
||||||
private String key;
|
private String key;
|
||||||
private Properties properties;
|
private Properties properties;
|
||||||
private String message;
|
private String message;
|
||||||
|
@ -70,6 +72,7 @@ public class LogMessageSaxReader extends DefaultHandler {
|
||||||
case Tags.KEY:
|
case Tags.KEY:
|
||||||
case Tags.MESSAGE:
|
case Tags.MESSAGE:
|
||||||
case Tags.EXCEPTION:
|
case Tags.EXCEPTION:
|
||||||
|
case Tags.STATE:
|
||||||
|
|
||||||
this.sb = new StringBuilder();
|
this.sb = new StringBuilder();
|
||||||
break;
|
break;
|
||||||
|
@ -96,8 +99,11 @@ public class LogMessageSaxReader extends DefaultHandler {
|
||||||
switch (qName) {
|
switch (qName) {
|
||||||
|
|
||||||
case Tags.LOG_MESSAGE:
|
case Tags.LOG_MESSAGE:
|
||||||
|
if (this.state == null)
|
||||||
|
this.state = LogMessageState.Information;
|
||||||
|
|
||||||
LogMessage logMessage = new LogMessage(this.id, this.dateTime, this.realm, this.username, this.locator,
|
LogMessage logMessage = new LogMessage(this.id, this.dateTime, this.realm, this.username, this.locator,
|
||||||
this.severity, this.key, this.properties, this.message, this.exception);
|
this.severity, this.state, this.key, this.properties, this.message, this.exception);
|
||||||
this.logMessageConsumer.accept(logMessage);
|
this.logMessageConsumer.accept(logMessage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -116,6 +122,11 @@ public class LogMessageSaxReader extends DefaultHandler {
|
||||||
this.sb = null;
|
this.sb = null;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Tags.STATE:
|
||||||
|
this.state = LogMessageState.valueOf(this.sb.toString());
|
||||||
|
this.sb = null;
|
||||||
|
break;
|
||||||
|
|
||||||
case Tags.KEY:
|
case Tags.KEY:
|
||||||
this.key = this.sb.toString();
|
this.key = this.sb.toString();
|
||||||
this.sb = null;
|
this.sb = null;
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class LogMessageToSaxWriterVisitor {
|
||||||
|
|
||||||
writeElem(Tags.MESSAGE, logMessage.getMessage());
|
writeElem(Tags.MESSAGE, logMessage.getMessage());
|
||||||
writeElem(Tags.SEVERITY, logMessage.getSeverity().name());
|
writeElem(Tags.SEVERITY, logMessage.getSeverity().name());
|
||||||
|
writeElem(Tags.STATE, logMessage.getState().name());
|
||||||
writeElem(Tags.USERNAME, logMessage.getUsername());
|
writeElem(Tags.USERNAME, logMessage.getUsername());
|
||||||
writeElem(Tags.LOCATOR, logMessage.getLocator().toString());
|
writeElem(Tags.LOCATOR, logMessage.getLocator().toString());
|
||||||
writeElem(Tags.KEY, logMessage.getKey());
|
writeElem(Tags.KEY, logMessage.getKey());
|
||||||
|
|
|
@ -13,6 +13,7 @@ import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.execution.command.*;
|
import li.strolch.execution.command.*;
|
||||||
import li.strolch.execution.policy.ExecutionPolicy;
|
import li.strolch.execution.policy.ExecutionPolicy;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -300,7 +301,7 @@ public class Controller {
|
||||||
if (this.container.hasComponent(OperationsLog.class)) {
|
if (this.container.hasComponent(OperationsLog.class)) {
|
||||||
this.container.getComponent(OperationsLog.class).addMessage(
|
this.container.getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.error")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.error")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +324,7 @@ public class Controller {
|
||||||
if (this.container.hasComponent(OperationsLog.class)) {
|
if (this.container.hasComponent(OperationsLog.class)) {
|
||||||
this.container.getComponent(OperationsLog.class).addMessage(
|
this.container.getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.warning")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.warning")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.execution.command.ArchiveActivityCommand;
|
import li.strolch.execution.command.ArchiveActivityCommand;
|
||||||
import li.strolch.execution.policy.ExecutionPolicy;
|
import li.strolch.execution.policy.ExecutionPolicy;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.*;
|
import li.strolch.model.*;
|
||||||
|
@ -293,7 +294,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, controller.getLocator(), LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, controller.getLocator(), LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.execution")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.execution")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,7 +316,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.executed")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.executed")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,7 +338,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.stopped")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.stopped")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,7 +360,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.error")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.error")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,7 +382,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.warning")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.warning")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,7 +408,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, activity.getLocator(), LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, activity.getLocator(), LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.archive")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.archive")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchAgent;
|
import li.strolch.agent.api.StrolchAgent;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -88,7 +89,7 @@ public class SimpleDurationExecutionTimer implements DelayedExecutionTimer {
|
||||||
if (this.agent.getContainer().hasComponent(OperationsLog.class)) {
|
if (this.agent.getContainer().hasComponent(OperationsLog.class)) {
|
||||||
this.agent.getContainer().getComponent(OperationsLog.class).addMessage(
|
this.agent.getContainer().getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.executed")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.executed")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import static li.strolch.runtime.StrolchConstants.PolicyConstants.TYPE_RESERVE;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
|
@ -42,7 +43,7 @@ public class ToErrorReservationExecution extends ReservationExecution {
|
||||||
if (action.getType().equals(TYPE_RESERVE) && isReserved(tx(), action)) {
|
if (action.getType().equals(TYPE_RESERVE) && isReserved(tx(), action)) {
|
||||||
setActionState(action, State.EXECUTION);
|
setActionState(action, State.EXECUTION);
|
||||||
toError(new LogMessage(tx().getRealmName(), tx().getCertificate().getUsername(), action.getLocator(),
|
toError(new LogMessage(tx().getRealmName(), tx().getCertificate().getUsername(), action.getLocator(),
|
||||||
LogSeverity.Error, ResourceBundle.getBundle("strolch-service"),
|
LogSeverity.Error, LogMessageState.Information, ResourceBundle.getBundle("strolch-service"),
|
||||||
"execution.policy.reservation.alreadyReserved")
|
"execution.policy.reservation.alreadyReserved")
|
||||||
.value("resourceLoc", action.getResourceLocator().toString()));
|
.value("resourceLoc", action.getResourceLocator().toString()));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Map.Entry;
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchAgent;
|
import li.strolch.agent.api.StrolchAgent;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -140,7 +141,7 @@ public class Migrations {
|
||||||
List<Version> list = migrationsRan.getList(realm);
|
List<Version> list = migrationsRan.getList(realm);
|
||||||
for (Version version : list) {
|
for (Version version : list) {
|
||||||
LogMessage logMessage = new LogMessage(realm, SYSTEM_USER_AGENT,
|
LogMessage logMessage = new LogMessage(realm, SYSTEM_USER_AGENT,
|
||||||
locator.append(StrolchAgent.getUniqueId()), LogSeverity.Info,
|
locator.append(StrolchAgent.getUniqueId()), LogSeverity.Info, LogMessageState.Information,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.migrations.version")
|
ResourceBundle.getBundle("strolch-service"), "execution.handler.migrations.version")
|
||||||
.value("version", version.toString());
|
.value("version", version.toString());
|
||||||
operationsLog.addMessage(logMessage);
|
operationsLog.addMessage(logMessage);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchAgent;
|
import li.strolch.agent.api.StrolchAgent;
|
||||||
import li.strolch.agent.api.StrolchComponent;
|
import li.strolch.agent.api.StrolchComponent;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Tags;
|
import li.strolch.model.Tags;
|
||||||
|
@ -204,7 +205,7 @@ public class MigrationsHandler extends StrolchComponent {
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(new LogMessage(Tags.AGENT, SYSTEM_USER_AGENT,
|
getComponent(OperationsLog.class).addMessage(new LogMessage(Tags.AGENT, SYSTEM_USER_AGENT,
|
||||||
getLocator().append(StrolchAgent.getUniqueId()), LogSeverity.Exception,
|
getLocator().append(StrolchAgent.getUniqueId()), LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.executed")
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.executed")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@ package li.strolch.testbase.runtime;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static li.strolch.model.Tags.AGENT;
|
import static li.strolch.model.Tags.AGENT;
|
||||||
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchAgent;
|
import li.strolch.agent.api.StrolchAgent;
|
||||||
import li.strolch.agent.api.StrolchRealm;
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
|
import li.strolch.handler.operationslog.LogMessageState;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
import li.strolch.handler.operationslog.OperationsLog;
|
import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
@ -45,7 +47,7 @@ public class LogMessagesTestRunner {
|
||||||
ResourceBundle bundle = ResourceBundle.getBundle("li-strolch-testbase");
|
ResourceBundle bundle = ResourceBundle.getBundle("li-strolch-testbase");
|
||||||
LogMessage logMessage = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
LogMessage logMessage = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
||||||
Locator.valueOf(AGENT, "li.strolch.testbase", StrolchAgent.getUniqueId()), LogSeverity.Exception,
|
Locator.valueOf(AGENT, "li.strolch.testbase", StrolchAgent.getUniqueId()), LogSeverity.Exception,
|
||||||
bundle, "test-message").withException(ex).value("reason", ex);
|
LogMessageState.Information, bundle, "test-message").withException(ex).value("reason", ex);
|
||||||
this.operationsLog.addMessage(logMessage);
|
this.operationsLog.addMessage(logMessage);
|
||||||
|
|
||||||
// default is async persisting...
|
// default is async persisting...
|
||||||
|
@ -83,7 +85,7 @@ public class LogMessagesTestRunner {
|
||||||
for (int i = 0; i < MAX_MESSAGES * 2; i++) {
|
for (int i = 0; i < MAX_MESSAGES * 2; i++) {
|
||||||
LogMessage m = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
LogMessage m = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
||||||
Locator.valueOf(AGENT, "li.strolch.testbase", StrolchAgent.getUniqueId()),
|
Locator.valueOf(AGENT, "li.strolch.testbase", StrolchAgent.getUniqueId()),
|
||||||
LogSeverity.Exception, bundle, "test-message");
|
LogSeverity.Exception, LogMessageState.Information, bundle, "test-message");
|
||||||
this.operationsLog.addMessage(m);
|
this.operationsLog.addMessage(m);
|
||||||
ids.add(m.getId());
|
ids.add(m.getId());
|
||||||
}
|
}
|
||||||
|
@ -108,6 +110,49 @@ public class LogMessagesTestRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add a few more messages
|
||||||
|
LogMessage logMessage1 = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
||||||
|
Locator.valueOf(AGENT, "test", "@1"), LogSeverity.Error, LogMessageState.Active, bundle,
|
||||||
|
"test-message");
|
||||||
|
LogMessage logMessage2 = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
||||||
|
Locator.valueOf(AGENT, "test", "@2"), LogSeverity.Error, LogMessageState.Active, bundle,
|
||||||
|
"test-message");
|
||||||
|
LogMessage logMessage3 = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
||||||
|
Locator.valueOf(AGENT, "test", "@3"), LogSeverity.Error, LogMessageState.Active, bundle,
|
||||||
|
"test-message");
|
||||||
|
|
||||||
|
this.operationsLog.addMessage(logMessage1);
|
||||||
|
this.operationsLog.addMessage(logMessage2);
|
||||||
|
this.operationsLog.addMessage(logMessage3);
|
||||||
|
|
||||||
|
// update state of element
|
||||||
|
this.operationsLog.updateState(this.realmName, logMessage1.getLocator(), LogMessageState.Inactive);
|
||||||
|
assertEquals(LogMessageState.Inactive, logMessage1.getState());
|
||||||
|
|
||||||
|
this.operationsLog.updateState(this.realmName, logMessage1.getId(), LogMessageState.Active);
|
||||||
|
assertEquals(LogMessageState.Active, logMessage1.getState());
|
||||||
|
|
||||||
|
// now try and remove a single element
|
||||||
|
this.operationsLog.removeMessage(logMessage1);
|
||||||
|
assertFalse(this.operationsLog.getMessagesFor(this.realmName, logMessage1.getLocator()).isPresent());
|
||||||
|
|
||||||
|
// now remove bulk
|
||||||
|
List<LogMessage> toRemove = Arrays.asList(logMessage2, logMessage3);
|
||||||
|
this.operationsLog.removeMessages(toRemove);
|
||||||
|
|
||||||
|
// default is async persisting...
|
||||||
|
Thread.sleep(300L);
|
||||||
|
|
||||||
|
// assert all are removed
|
||||||
|
try (StrolchTransaction tx = realm.openTx(this.certificate, "test", true)) {
|
||||||
|
LogMessageDao logMessageDao = tx.getPersistenceHandler().getLogMessageDao(tx);
|
||||||
|
List<String> logMessageIds = logMessageDao.queryLatest(this.realmName, Integer.MAX_VALUE).stream()
|
||||||
|
.map(LogMessage::getId).sorted().collect(toList());
|
||||||
|
assertFalse(logMessageIds.contains(logMessage1.getId()));
|
||||||
|
assertFalse(logMessageIds.contains(logMessage2.getId()));
|
||||||
|
assertFalse(logMessageIds.contains(logMessage3.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new IllegalStateException("Interrupted!");
|
throw new IllegalStateException("Interrupted!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,17 @@ public class I18nMessage {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(I18nMessage.class);
|
private static final Logger logger = LoggerFactory.getLogger(I18nMessage.class);
|
||||||
|
|
||||||
private ResourceBundle bundle;
|
private final String key;
|
||||||
private String key;
|
private final Properties values;
|
||||||
private Properties values;
|
private final ResourceBundle bundle;
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public I18nMessage(ResourceBundle bundle, String key) {
|
public I18nMessage(ResourceBundle bundle, String key) {
|
||||||
DBC.INTERIM.assertNotNull("bundle must be set!", bundle);
|
DBC.INTERIM.assertNotNull("bundle must be set!", bundle);
|
||||||
DBC.INTERIM.assertNotEmpty("key must be set!", key);
|
DBC.INTERIM.assertNotEmpty("key must be set!", key);
|
||||||
this.bundle = bundle;
|
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.values = new Properties();
|
this.values = new Properties();
|
||||||
|
this.bundle = bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public I18nMessage(String key, Properties values, String message) {
|
public I18nMessage(String key, Properties values, String message) {
|
||||||
|
@ -34,6 +34,7 @@ public class I18nMessage {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.values = values == null ? new Properties() : values;
|
this.values = values == null ? new Properties() : values;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
|
this.bundle = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
|
@ -62,6 +63,11 @@ public class I18nMessage {
|
||||||
if (this.message != null)
|
if (this.message != null)
|
||||||
return this.message;
|
return this.message;
|
||||||
|
|
||||||
|
if (this.bundle == null) {
|
||||||
|
this.message = this.key;
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String string = this.bundle.getString(this.key);
|
String string = this.bundle.getString(this.key);
|
||||||
this.message = StringHelper.replacePropertiesIn(this.values, EMPTY, string);
|
this.message = StringHelper.replacePropertiesIn(this.values, EMPTY, string);
|
||||||
|
|
Loading…
Reference in New Issue