[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.exception.StrolchException;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -287,7 +288,7 @@ public class ComponentContainerImpl implements ComponentContainer {
|
|||
for (String realmName : getRealmNames()) {
|
||||
getComponent(OperationsLog.class).addMessage(new LogMessage(realmName, SYSTEM_USER_AGENT,
|
||||
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("environment", environment) //
|
||||
.value("components", "" + this.controllerMap.size()) //
|
||||
|
@ -311,7 +312,7 @@ public class ComponentContainerImpl implements ComponentContainer {
|
|||
for (String realmName : getRealmNames()) {
|
||||
getComponent(OperationsLog.class).addMessage(new LogMessage(realmName, SYSTEM_USER_AGENT,
|
||||
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("environment", environment) //
|
||||
.value("components", "" + this.controllerMap.size()));
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||
|
||||
import li.strolch.agent.api.*;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -162,7 +163,7 @@ public class DefaultObserverHandler implements ObserverHandler {
|
|||
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
||||
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), SYSTEM_USER_AGENT,
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import li.strolch.agent.api.*;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -193,7 +194,7 @@ public class EventCollectingObserverHandler implements ObserverHandler {
|
|||
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
||||
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), SYSTEM_USER_AGENT,
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package li.strolch.handler.operationslog;
|
|||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
|
@ -11,32 +12,36 @@ import li.strolch.model.Locator;
|
|||
import li.strolch.model.Tags.Json;
|
||||
import li.strolch.utils.I18nMessage;
|
||||
import li.strolch.utils.helper.ExceptionHelper;
|
||||
import li.strolch.utils.iso8601.ISO8601;
|
||||
|
||||
public class LogMessage extends I18nMessage {
|
||||
|
||||
private final String id;
|
||||
private final String username;
|
||||
private ZonedDateTime zonedDateTime;
|
||||
private final ZonedDateTime zonedDateTime;
|
||||
private final String realm;
|
||||
private final Locator locator;
|
||||
private final LogSeverity severity;
|
||||
private LogMessageState state;
|
||||
private String stackTrace;
|
||||
|
||||
public LogMessage(String realm, String username, Locator locator, LogSeverity severity, ResourceBundle bundle,
|
||||
String key) {
|
||||
public LogMessage(String realm, String username, Locator locator, LogSeverity severity, LogMessageState state,
|
||||
ResourceBundle bundle, String key) {
|
||||
super(bundle, key);
|
||||
this.id = StrolchAgent.getUniqueId();
|
||||
this.zonedDateTime = ZonedDateTime.now();
|
||||
// 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.username = username;
|
||||
this.locator = locator;
|
||||
this.severity = severity;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
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);
|
||||
this.id = id;
|
||||
this.zonedDateTime = zonedDateTime;
|
||||
|
@ -44,6 +49,7 @@ public class LogMessage extends I18nMessage {
|
|||
this.username = username;
|
||||
this.locator = locator;
|
||||
this.severity = severity;
|
||||
this.state = state;
|
||||
this.stackTrace = stackTrace;
|
||||
}
|
||||
|
||||
|
@ -71,6 +77,14 @@ public class LogMessage extends I18nMessage {
|
|||
return this.severity;
|
||||
}
|
||||
|
||||
public LogMessageState getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public void setState(LogMessageState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public LogMessage withException(Throwable t) {
|
||||
this.stackTrace = ExceptionHelper.formatException(t);
|
||||
return this;
|
||||
|
@ -100,10 +114,12 @@ public class LogMessage extends I18nMessage {
|
|||
jsonObject.addProperty(Json.KEY, getKey());
|
||||
jsonObject.addProperty(Json.MESSAGE, formatMessage());
|
||||
jsonObject.addProperty(Json.SEVERITY, this.severity.name());
|
||||
jsonObject.addProperty(Json.STATE, this.state.name());
|
||||
jsonObject.addProperty(Json.USERNAME, this.username);
|
||||
jsonObject.addProperty(Json.REALM, this.realm);
|
||||
jsonObject.addProperty(Json.LOCATOR, this.locator.toString());
|
||||
jsonObject.addProperty(Json.EXCEPTION, this.stackTrace);
|
||||
if (this.stackTrace != null)
|
||||
jsonObject.addProperty(Json.EXCEPTION, this.stackTrace);
|
||||
JsonObject values = new JsonObject();
|
||||
for (String key : getValues().stringPropertyNames()) {
|
||||
values.addProperty(key, getValues().getProperty(key));
|
||||
|
@ -113,37 +129,48 @@ public class LogMessage extends I18nMessage {
|
|||
return jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((this.locator == null) ? 0 : this.locator.hashCode());
|
||||
result = prime * result + ((this.realm == null) ? 0 : this.realm.hashCode());
|
||||
result = prime * result + ((this.severity == null) ? 0 : this.severity.hashCode());
|
||||
return result;
|
||||
public static LogMessage fromJson(JsonObject messageJ) {
|
||||
|
||||
String id = messageJ.get(Json.ID).getAsString();
|
||||
ZonedDateTime zonedDateTime = ISO8601.parseToZdt(messageJ.get(Json.DATE).getAsString());
|
||||
String realm = messageJ.get(Json.REALM).getAsString();
|
||||
String username = messageJ.get(Json.USERNAME).getAsString();
|
||||
Locator locator = Locator.valueOf(messageJ.get(Json.LOCATOR).getAsString());
|
||||
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
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
if (!super.equals(o))
|
||||
return false;
|
||||
LogMessage other = (LogMessage) obj;
|
||||
if (this.locator == null) {
|
||||
if (other.locator != null)
|
||||
return false;
|
||||
} else if (!this.locator.equals(other.locator))
|
||||
return false;
|
||||
if (this.realm == null) {
|
||||
if (other.realm != null)
|
||||
return false;
|
||||
} else if (!this.realm.equals(other.realm))
|
||||
return false;
|
||||
if (this.severity != other.severity)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
LogMessage that = (LogMessage) o;
|
||||
return Objects.equals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + (id != null ? id.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.concurrent.ExecutorService;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.agent.api.StrolchAgent;
|
||||
|
@ -94,6 +95,72 @@ public class OperationsLog extends StrolchComponent {
|
|||
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) {
|
||||
if (logMessages.size() < this.maxMessages)
|
||||
return Collections.emptyList();
|
||||
|
@ -124,7 +191,8 @@ public class OperationsLog extends StrolchComponent {
|
|||
LogMessageDao logMessageDao = tx.getPersistenceHandler().getLogMessageDao(tx);
|
||||
if (messagesToRemove != null && !messagesToRemove.isEmpty())
|
||||
logMessageDao.removeAll(messagesToRemove);
|
||||
logMessageDao.save(logMessage);
|
||||
if (logMessage != null)
|
||||
logMessageDao.save(logMessage);
|
||||
tx.commitOnClose();
|
||||
}
|
||||
});
|
||||
|
@ -134,7 +202,31 @@ public class OperationsLog extends StrolchComponent {
|
|||
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,
|
||||
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()) //
|
||||
.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.StrolchRealm;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -266,7 +267,7 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
|||
operationsLog.addMessage(
|
||||
new LogMessage(this.realmName == null ? StrolchConstants.DEFAULT_REALM : this.realmName,
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import li.strolch.exception.StrolchAccessDeniedException;
|
|||
import li.strolch.exception.StrolchException;
|
||||
import li.strolch.exception.StrolchModelException;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.*;
|
||||
|
@ -1692,7 +1693,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
OperationsLog operationsLog = container.getComponent(OperationsLog.class);
|
||||
operationsLog.addMessage(new LogMessage(this.realm.getRealm(), this.certificate.getUsername(),
|
||||
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$
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
*/
|
||||
package li.strolch.persistence.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
|
||||
|
@ -31,6 +31,10 @@ public interface LogMessageDao {
|
|||
|
||||
void saveAll(List<LogMessage> logMessages);
|
||||
|
||||
void updateState(LogMessage logMessage);
|
||||
|
||||
void updateStates(Collection<LogMessage> logMessages);
|
||||
|
||||
void remove(LogMessage logMessage);
|
||||
|
||||
void removeAll(List<LogMessage> logMessages);
|
||||
|
|
|
@ -28,6 +28,7 @@ import li.strolch.agent.api.StrolchComponent;
|
|||
import li.strolch.exception.StrolchAccessDeniedException;
|
||||
import li.strolch.exception.StrolchException;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -219,11 +220,11 @@ public class DefaultServiceHandler extends StrolchComponent implements ServiceHa
|
|||
ResourceBundle bundle = ResourceBundle.getBundle("strolch-agent");
|
||||
if (throwable == null) {
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +1,34 @@
|
|||
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 li.strolch.model.Tags;
|
||||
import li.strolch.utils.I18nMessage;
|
||||
|
||||
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());
|
||||
// json.addProperty("message", message.getMessage());
|
||||
//
|
||||
// Properties values = message.getValues();
|
||||
// if (!values.isEmpty()) {
|
||||
// JsonObject valuesJ = new JsonObject();
|
||||
// values.stringPropertyNames().forEach(key -> valuesJ.addProperty(key, values.getProperty(key)));
|
||||
// json.add("values", valuesJ);
|
||||
// }
|
||||
Properties properties = new Properties();
|
||||
if (messageJ.has(Tags.Json.VALUES)) {
|
||||
JsonArray valuesJ = messageJ.getAsJsonArray(Tags.Json.VALUES);
|
||||
for (JsonElement jsonElement : valuesJ) {
|
||||
JsonObject valueJ = jsonElement.getAsJsonObject();
|
||||
|
||||
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 com.google.gson.JsonObject;
|
||||
import li.strolch.model.Tags;
|
||||
import li.strolch.utils.I18nMessage;
|
||||
import li.strolch.utils.I18nMessageVisitor;
|
||||
|
||||
|
@ -12,14 +13,14 @@ public class I18nMessageToJsonVisitor implements I18nMessageVisitor<JsonObject>
|
|||
public JsonObject visit(I18nMessage message) {
|
||||
JsonObject json = new JsonObject();
|
||||
|
||||
json.addProperty("key", message.getKey());
|
||||
json.addProperty("message", message.getMessage());
|
||||
json.addProperty(Tags.Json.KEY, message.getKey());
|
||||
json.addProperty(Tags.Json.MESSAGE, message.getMessage());
|
||||
|
||||
Properties values = message.getValues();
|
||||
if (!values.isEmpty()) {
|
||||
JsonObject valuesJ = new JsonObject();
|
||||
values.stringPropertyNames().forEach(key -> valuesJ.addProperty(key, values.getProperty(key)));
|
||||
json.add("values", valuesJ);
|
||||
json.add(Tags.Json.VALUES, valuesJ);
|
||||
}
|
||||
|
||||
return json;
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.time.ZonedDateTime;
|
|||
import java.util.*;
|
||||
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.model.Locator;
|
||||
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 MESSAGE = "message";
|
||||
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,
|
||||
STACK_TRACE);
|
||||
private static final String FIELDS = commaSeparated(ID, REALM, DATE_TIME, USERNAME, SEVERITY, STATE, LOCATOR, KEY,
|
||||
MESSAGE, STACK_TRACE);
|
||||
|
||||
private static final String queryByRealmMaxSql =
|
||||
"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 insertLogMessageSql =
|
||||
"insert into operations_log (" + FIELDS + ") values (?, ?, ?, ?, ?::log_severity_type, ?, ?, ?, ?)";
|
||||
private static final String insertLogMessageSql = "insert into operations_log (" + FIELDS
|
||||
+ ") 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 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 removeValuesSql = "delete from operations_log_values where id = ?";
|
||||
|
||||
|
@ -106,11 +110,36 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
|||
|
||||
@Override
|
||||
public void saveAll(List<LogMessage> logMessages) {
|
||||
for (LogMessage logMessage : logMessages) {
|
||||
save(logMessage);
|
||||
logMessages.forEach(this::save);
|
||||
}
|
||||
|
||||
@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
|
||||
public void remove(LogMessage logMessage) {
|
||||
try (PreparedStatement removeStatement = this.tx.getConnection().prepareStatement(removeSql);
|
||||
|
@ -237,10 +266,11 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
|||
// 3 dateTime = ?,
|
||||
// 4 username = ?,
|
||||
// 5 severity = ?,
|
||||
// 6 locator = ?,
|
||||
// 7 key = ?,
|
||||
// 8 message = ?,
|
||||
// 9 stacktrace = ?,
|
||||
// 6 state = ?
|
||||
// 7 locator = ?,
|
||||
// 8 key = ?,
|
||||
// 9 message = ?,
|
||||
// 10 stacktrace = ?,
|
||||
|
||||
ps.setString(1, logMessage.getId());
|
||||
ps.setString(2, logMessage.getRealm());
|
||||
|
@ -248,10 +278,11 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
|||
Calendar.getInstance());
|
||||
ps.setString(4, logMessage.getUsername());
|
||||
ps.setString(5, logMessage.getSeverity().name());
|
||||
ps.setString(6, logMessage.getLocator().toString());
|
||||
ps.setString(7, logMessage.getKey());
|
||||
ps.setString(8, logMessage.getMessage());
|
||||
ps.setString(9, logMessage.getStackTrace());
|
||||
ps.setString(6, logMessage.getState().name());
|
||||
ps.setString(7, logMessage.getLocator().toString());
|
||||
ps.setString(8, logMessage.getKey());
|
||||
ps.setString(9, logMessage.getMessage());
|
||||
ps.setString(10, logMessage.getStackTrace());
|
||||
}
|
||||
|
||||
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());
|
||||
String username = resultSet.getString(4);
|
||||
LogSeverity severity = LogSeverity.valueOf(resultSet.getString(5));
|
||||
Locator locator = Locator.valueOf(resultSet.getString(6));
|
||||
String key = resultSet.getString(7);
|
||||
String message = resultSet.getString(8);
|
||||
String exception = resultSet.getString(9);
|
||||
LogMessageState state = LogMessageState.valueOf(resultSet.getString(6));
|
||||
Locator locator = Locator.valueOf(resultSet.getString(7));
|
||||
String key = resultSet.getString(8);
|
||||
String message = resultSet.getString(9);
|
||||
String exception = resultSet.getString(10);
|
||||
|
||||
Properties properties = new Properties();
|
||||
while (valuesResult.next()) {
|
||||
|
@ -273,6 +305,7 @@ public class PostgreSqlLogMessageDao implements LogMessageDao {
|
|||
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
|
||||
db_version=0.8.0
|
||||
db_version=0.9.0
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package li.strolch.persistence.xml;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
|
@ -38,6 +39,16 @@ public class XmlLogMessageDao implements LogMessageDao {
|
|||
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
|
||||
public void remove(LogMessage logMessage) {
|
||||
this.tx.getObjectDao().remove(logMessage);
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Properties;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.model.Locator;
|
||||
import li.strolch.model.Tags;
|
||||
|
@ -42,6 +43,7 @@ public class LogMessageSaxReader extends DefaultHandler {
|
|||
private String username;
|
||||
private Locator locator;
|
||||
private LogSeverity severity;
|
||||
private LogMessageState state;
|
||||
private String key;
|
||||
private Properties properties;
|
||||
private String message;
|
||||
|
@ -70,6 +72,7 @@ public class LogMessageSaxReader extends DefaultHandler {
|
|||
case Tags.KEY:
|
||||
case Tags.MESSAGE:
|
||||
case Tags.EXCEPTION:
|
||||
case Tags.STATE:
|
||||
|
||||
this.sb = new StringBuilder();
|
||||
break;
|
||||
|
@ -96,8 +99,11 @@ public class LogMessageSaxReader extends DefaultHandler {
|
|||
switch (qName) {
|
||||
|
||||
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,
|
||||
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);
|
||||
break;
|
||||
|
||||
|
@ -116,6 +122,11 @@ public class LogMessageSaxReader extends DefaultHandler {
|
|||
this.sb = null;
|
||||
break;
|
||||
|
||||
case Tags.STATE:
|
||||
this.state = LogMessageState.valueOf(this.sb.toString());
|
||||
this.sb = null;
|
||||
break;
|
||||
|
||||
case Tags.KEY:
|
||||
this.key = this.sb.toString();
|
||||
this.sb = null;
|
||||
|
|
|
@ -44,6 +44,7 @@ public class LogMessageToSaxWriterVisitor {
|
|||
|
||||
writeElem(Tags.MESSAGE, logMessage.getMessage());
|
||||
writeElem(Tags.SEVERITY, logMessage.getSeverity().name());
|
||||
writeElem(Tags.STATE, logMessage.getState().name());
|
||||
writeElem(Tags.USERNAME, logMessage.getUsername());
|
||||
writeElem(Tags.LOCATOR, logMessage.getLocator().toString());
|
||||
writeElem(Tags.KEY, logMessage.getKey());
|
||||
|
|
|
@ -13,6 +13,7 @@ import li.strolch.agent.api.StrolchRealm;
|
|||
import li.strolch.execution.command.*;
|
||||
import li.strolch.execution.policy.ExecutionPolicy;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -300,7 +301,7 @@ public class Controller {
|
|||
if (this.container.hasComponent(OperationsLog.class)) {
|
||||
this.container.getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +324,7 @@ public class Controller {
|
|||
if (this.container.hasComponent(OperationsLog.class)) {
|
||||
this.container.getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import li.strolch.agent.api.StrolchRealm;
|
|||
import li.strolch.execution.command.ArchiveActivityCommand;
|
||||
import li.strolch.execution.policy.ExecutionPolicy;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.*;
|
||||
|
@ -293,7 +294,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||
getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +316,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||
getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +338,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||
getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -359,7 +360,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||
getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +382,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||
getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -407,7 +408,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||
getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -88,7 +89,7 @@ public class SimpleDurationExecutionTimer implements DelayedExecutionTimer {
|
|||
if (this.agent.getContainer().hasComponent(OperationsLog.class)) {
|
||||
this.agent.getContainer().getComponent(OperationsLog.class).addMessage(
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import static li.strolch.runtime.StrolchConstants.PolicyConstants.TYPE_RESERVE;
|
|||
import java.util.ResourceBundle;
|
||||
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.model.State;
|
||||
import li.strolch.model.activity.Action;
|
||||
|
@ -42,7 +43,7 @@ public class ToErrorReservationExecution extends ReservationExecution {
|
|||
if (action.getType().equals(TYPE_RESERVE) && isReserved(tx(), action)) {
|
||||
setActionState(action, State.EXECUTION);
|
||||
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")
|
||||
.value("resourceLoc", action.getResourceLocator().toString()));
|
||||
} else {
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Map.Entry;
|
|||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -140,7 +141,7 @@ public class Migrations {
|
|||
List<Version> list = migrationsRan.getList(realm);
|
||||
for (Version version : list) {
|
||||
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")
|
||||
.value("version", version.toString());
|
||||
operationsLog.addMessage(logMessage);
|
||||
|
|
|
@ -28,6 +28,7 @@ import li.strolch.agent.api.ComponentContainer;
|
|||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.agent.api.StrolchComponent;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Tags;
|
||||
|
@ -204,7 +205,7 @@ public class MigrationsHandler extends StrolchComponent {
|
|||
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||
getComponent(OperationsLog.class).addMessage(new LogMessage(Tags.AGENT, SYSTEM_USER_AGENT,
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@ package li.strolch.testbase.runtime;
|
|||
import static java.util.stream.Collectors.toList;
|
||||
import static li.strolch.model.Tags.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.ResourceBundle;
|
||||
|
||||
|
@ -12,6 +13,7 @@ import li.strolch.agent.api.ComponentContainer;
|
|||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.agent.api.StrolchRealm;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogMessageState;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
|
@ -45,7 +47,7 @@ public class LogMessagesTestRunner {
|
|||
ResourceBundle bundle = ResourceBundle.getBundle("li-strolch-testbase");
|
||||
LogMessage logMessage = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
||||
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);
|
||||
|
||||
// default is async persisting...
|
||||
|
@ -83,7 +85,7 @@ public class LogMessagesTestRunner {
|
|||
for (int i = 0; i < MAX_MESSAGES * 2; i++) {
|
||||
LogMessage m = new LogMessage(this.realmName, SYSTEM_USER_AGENT,
|
||||
Locator.valueOf(AGENT, "li.strolch.testbase", StrolchAgent.getUniqueId()),
|
||||
LogSeverity.Exception, bundle, "test-message");
|
||||
LogSeverity.Exception, LogMessageState.Information, bundle, "test-message");
|
||||
this.operationsLog.addMessage(m);
|
||||
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) {
|
||||
throw new IllegalStateException("Interrupted!");
|
||||
}
|
||||
|
|
|
@ -15,17 +15,17 @@ public class I18nMessage {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(I18nMessage.class);
|
||||
|
||||
private ResourceBundle bundle;
|
||||
private String key;
|
||||
private Properties values;
|
||||
private final String key;
|
||||
private final Properties values;
|
||||
private final ResourceBundle bundle;
|
||||
private String message;
|
||||
|
||||
public I18nMessage(ResourceBundle bundle, String key) {
|
||||
DBC.INTERIM.assertNotNull("bundle must be set!", bundle);
|
||||
DBC.INTERIM.assertNotEmpty("key must be set!", key);
|
||||
this.bundle = bundle;
|
||||
this.key = key;
|
||||
this.values = new Properties();
|
||||
this.bundle = bundle;
|
||||
}
|
||||
|
||||
public I18nMessage(String key, Properties values, String message) {
|
||||
|
@ -34,6 +34,7 @@ public class I18nMessage {
|
|||
this.key = key;
|
||||
this.values = values == null ? new Properties() : values;
|
||||
this.message = message;
|
||||
this.bundle = null;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
|
@ -62,6 +63,11 @@ public class I18nMessage {
|
|||
if (this.message != null)
|
||||
return this.message;
|
||||
|
||||
if (this.bundle == null) {
|
||||
this.message = this.key;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
try {
|
||||
String string = this.bundle.getString(this.key);
|
||||
this.message = StringHelper.replacePropertiesIn(this.values, EMPTY, string);
|
||||
|
|
Loading…
Reference in New Issue