Skip to content
Snippets Groups Projects
Commit 8dfb50bb authored by René Schöne's avatar René Schöne
Browse files

working on forwarding using implicit NTAs

- use local version of jastadd with fixed flush-inc-attr event
- use changed jastadd to check params of that event (the index of the NTA in this case)
- fixed cleanup of ragconnect-observer
- disconnect now is successful, if one sub-publisher removed the given token
- still todo: finish test, check "check" method
- use packaged jastadd version once it incorporates local changes
parent 790e3f51
No related branches found
No related tags found
1 merge request!24Resolve "Feature: Send enpoint for non-terminal using implicit NTA"
Pipeline #12253 failed
This commit is part of merge request !24. Comments created here will be created in the context of that merge request.
Showing with 127 additions and 44 deletions
No preview for this file type
...@@ -22,7 +22,10 @@ mainClassName = 'org.jastadd.ragconnect.compiler.Compiler' ...@@ -22,7 +22,10 @@ mainClassName = 'org.jastadd.ragconnect.compiler.Compiler'
repositories { repositories {
mavenCentral() mavenCentral()
jcenter() maven {
name "gitlab-maven"
url "https://git-st.inf.tu-dresden.de/api/v4/groups/jastadd/-/packages/maven"
}
} }
tasks.compileJava { tasks.compileJava {
options.release.set(11) options.release.set(11)
...@@ -31,8 +34,8 @@ tasks.compileJava { ...@@ -31,8 +34,8 @@ tasks.compileJava {
dependencies { dependencies {
implementation project(':relast-preprocessor') implementation project(':relast-preprocessor')
implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "${mustache_java_version}" implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "${mustache_java_version}"
// runtimeOnly group: 'org.jastadd', name: 'jastadd', version: '2.3.5' runtimeOnly group: 'org.jastadd', name: 'jastadd2', version: '2.3.5-dresden'
runtimeOnly fileTree(include: ['jastadd2.jar'], dir: '../libs') // runtimeOnly fileTree(include: ['jastadd2.jar'], dir: '../libs')
api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
} }
......
...@@ -4,6 +4,10 @@ Design considerations ...@@ -4,6 +4,10 @@ Design considerations
- no complete intermediate structure, but instead single nodes where applicable/needed - no complete intermediate structure, but instead single nodes where applicable/needed
*/ */
aspect NewStuff { aspect NewStuff {
// unsorted
syn String RagConnect.observerInstanceFieldName() = internalRagConnectPrefix() + "ObserverInstance";
syn String RagConnect.observerInstanceSingletonMethodName() = internalRagConnectPrefix() + "Observer";
syn String RagConnect.observerInstanceResetMethodName() = internalRagConnectPrefix() + "resetObserver";
// send.mustache // send.mustache
syn boolean EndpointDefinition.needForwardingNTA() = getEndpointTarget().needForwardingNTA(); syn boolean EndpointDefinition.needForwardingNTA() = getEndpointTarget().needForwardingNTA();
syn String EndpointDefinition.forwardingNTA_Name() = getEndpointTarget().forwardingNTA_Name(); syn String EndpointDefinition.forwardingNTA_Name() = getEndpointTarget().forwardingNTA_Name();
......
...@@ -13,6 +13,8 @@ aspect RagConnectHandler { ...@@ -13,6 +13,8 @@ aspect RagConnectHandler {
{{#Handlers}} {{#Handlers}}
{{#InUse}}{{fieldName}}.close();{{/InUse}} {{#InUse}}{{fieldName}}.close();{{/InUse}}
{{/Handlers}} {{/Handlers}}
trace().setReceiver({{observerInstanceSingletonMethodName}}().oldReceiver);
{{observerInstanceResetMethodName}}();
} }
{{#mqttHandler}} {{#mqttHandler}}
...@@ -73,20 +75,33 @@ aspect RagConnectHandler { ...@@ -73,20 +75,33 @@ aspect RagConnectHandler {
} }
boolean remove(RagConnectToken token) { boolean remove(RagConnectToken token) {
if (tokenToSender == null) { String errorMessage = internal_remove(token);
System.err.println("Removing sender before first addition for " + token.entityName + " at " + token.uri); if (errorMessage == null) {
return true;
} else {
System.err.println(errorMessage);
return false; return false;
} }
}
/**
* (internal) Removes the token, returning an error message if there is one.
* @param token the token to be removed
* @return an error message (upon error), or null (upon success)
*/
String internal_remove(RagConnectToken token) {
if (tokenToSender == null) {
return "Removing sender before first addition for " + token.entityName + " at " + token.uri;
}
Runnable sender = tokenToSender.remove(token); Runnable sender = tokenToSender.remove(token);
if (sender == null) { if (sender == null) {
System.err.println("Could not find connected sender for " + token.entityName + " at " + token.uri); return "Could not find connected sender for " + token.entityName + " at " + token.uri;
return false;
} }
boolean success = senders.remove(sender); boolean success = senders.remove(sender);
if (senders.isEmpty()) { if (senders.isEmpty()) {
lastValue = null; lastValue = null;
} }
return success; return success ? null : "Could not remove sender for " + token.entityName + " at " + token.uri;
} }
void run() { void run() {
...@@ -111,9 +126,22 @@ aspect RagConnectHandler { ...@@ -111,9 +126,22 @@ aspect RagConnectHandler {
boolean remove(RagConnectToken token) { boolean remove(RagConnectToken token) {
// publishers.forEach((index, publisher) -> publisher.remove(token)); // publishers.forEach((index, publisher) -> publisher.remove(token));
return publishers.values().stream() // remove token from each publisher, at least one has to successfully remove the token to make this call a success
.map(publisher -> publisher.remove(token)) boolean result = false;
.reduce(true, (result, success) -> result && success); java.util.List<String> errorMessages = new java.util.ArrayList<>();
for (RagConnectPublisher publisher : publishers.values()) {
String errorMessage = publisher.internal_remove(token);
if (errorMessage == null) {
result = true;
} else {
errorMessages.add(errorMessage);
}
}
if (!result) {
// only print error message, if all publishers failed to remove the token
errorMessages.stream().forEachOrdered(System.err::println);
}
return result;
} }
void run(int index) { void run(int index) {
......
...@@ -57,12 +57,17 @@ aspect RagConnectObserver { ...@@ -57,12 +57,17 @@ aspect RagConnectObserver {
final RagConnectToken connectToken; final RagConnectToken connectToken;
final ASTNode node; final ASTNode node;
final String attributeString; final String attributeString;
final boolean compareParams;
final Object params;
final Runnable attributeCall; final Runnable attributeCall;
RagConnectObserverEntry(RagConnectToken connectToken, ASTNode node, String attributeString, Runnable attributeCall) { RagConnectObserverEntry(RagConnectToken connectToken, ASTNode node, String attributeString,
boolean compareParams, Object params, Runnable attributeCall) {
this.connectToken = connectToken; this.connectToken = connectToken;
this.node = node; this.node = node;
this.attributeString = attributeString; this.attributeString = attributeString;
this.compareParams = compareParams;
this.params = params;
this.attributeCall = attributeCall; this.attributeCall = attributeCall;
} }
} }
...@@ -96,11 +101,21 @@ aspect RagConnectObserver { ...@@ -96,11 +101,21 @@ aspect RagConnectObserver {
} }
void add(RagConnectToken connectToken, ASTNode node, String attributeString, Runnable attributeCall) { void add(RagConnectToken connectToken, ASTNode node, String attributeString, Runnable attributeCall) {
internal_add(connectToken, node, attributeString, false, null, attributeCall);
}
void add(RagConnectToken connectToken, ASTNode node, String attributeString, Object params, Runnable attributeCall) {
internal_add(connectToken, node, attributeString, true, params, attributeCall);
}
private void internal_add(RagConnectToken connectToken, ASTNode node, String attributeString,
boolean compareParams, Object params, Runnable attributeCall) {
{{#configLoggingEnabledForIncremental}} {{#configLoggingEnabledForIncremental}}
System.out.println("** observer add: " + node + " on " + attributeString); System.out.println("** observer add: " + node + " on " + attributeString + (compareParams ? " (parameterized)" : ""));
{{/configLoggingEnabledForIncremental}} {{/configLoggingEnabledForIncremental}}
observedNodes.add(new RagConnectObserverEntry(connectToken, node, attributeString, attributeCall)); observedNodes.add(new RagConnectObserverEntry(connectToken, node, attributeString,
compareParams, params, attributeCall));
} }
void remove(RagConnectToken connectToken) { void remove(RagConnectToken connectToken) {
observedNodes.removeIf(entry -> entry.connectToken.equals(connectToken)); observedNodes.removeIf(entry -> entry.connectToken.equals(connectToken));
} }
...@@ -127,7 +142,7 @@ aspect RagConnectObserver { ...@@ -127,7 +142,7 @@ aspect RagConnectObserver {
entryQueue.clear(); entryQueue.clear();
startEntry = null; startEntry = null;
{{#configLoggingEnabledForIncremental}} {{#configLoggingEnabledForIncremental}}
System.out.println("** observer process (" + entriesToProcess.length + "): " + node + " on " + attribute); System.out.println("** observer process (entries: " + entriesToProcess.length + "): " + node + " on " + attribute);
{{/configLoggingEnabledForIncremental}} {{/configLoggingEnabledForIncremental}}
for (RagConnectObserverEntry entry : entriesToProcess) { for (RagConnectObserverEntry entry : entriesToProcess) {
entry.attributeCall.run(); entry.attributeCall.run();
...@@ -146,7 +161,7 @@ aspect RagConnectObserver { ...@@ -146,7 +161,7 @@ aspect RagConnectObserver {
{{/configLoggingEnabledForIncremental}} {{/configLoggingEnabledForIncremental}}
// iterate through list, if matching pair. could maybe be more efficient. // iterate through list, if matching pair. could maybe be more efficient.
for (RagConnectObserverEntry entry : observedNodes) { for (RagConnectObserverEntry entry : observedNodes) {
if (entry.node.equals(node) && entry.attributeString.equals(attribute)) { if (entry.node.equals(node) && entry.attributeString.equals(attribute) && (!entry.compareParams || java.util.Objects.equals(entry.params, params))) {
// hit. call the attribute/nta-token // hit. call the attribute/nta-token
{{#configLoggingEnabledForIncremental}} {{#configLoggingEnabledForIncremental}}
System.out.println("** observer hit: " + entry.node + " on " + entry.attributeString); System.out.println("** observer hit: " + entry.node + " on " + entry.attributeString);
...@@ -162,13 +177,16 @@ aspect RagConnectObserver { ...@@ -162,13 +177,16 @@ aspect RagConnectObserver {
} }
} }
private static RagConnectObserver ASTNode.{{internalRagConnectPrefix}}ObserverInstance; private static RagConnectObserver ASTNode.{{observerInstanceFieldName}};
RagConnectObserver ASTNode.{{internalRagConnectPrefix}}Observer() { RagConnectObserver ASTNode.{{observerInstanceSingletonMethodName}}() {
if ({{internalRagConnectPrefix}}ObserverInstance == null) { if ({{observerInstanceFieldName}} == null) {
// does not matter, which node is used to create the observer as ASTState/tracing is also static // does not matter, which node is used to create the observer as ASTState/tracing is also static
{{internalRagConnectPrefix}}ObserverInstance = new RagConnectObserver(this); {{observerInstanceFieldName}} = new RagConnectObserver(this);
}
return {{observerInstanceFieldName}};
} }
return {{internalRagConnectPrefix}}ObserverInstance; void ASTNode.{{observerInstanceResetMethodName}}() {
{{observerInstanceFieldName}} = null;
} }
} }
{{/configIncrementalOptionActive}} {{/configIncrementalOptionActive}}
...@@ -42,11 +42,17 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete ...@@ -42,11 +42,17 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
connectTokenMap.add(this, false, connectToken); connectTokenMap.add(this, false, connectToken);
{{#configIncrementalOptionActive}} {{#configIncrementalOptionActive}}
{{!todo maybe getterMethodName needs to be change for indexed send}} {{!todo maybe getterMethodName needs to be change for indexed send}}
{{internalRagConnectPrefix}}Observer().add(connectToken, this, "{{getterMethodName}}", () -> { {{observerInstanceSingletonMethodName}}().add(
connectToken,
this,
"{{getterMethodName}}{{#IndexBasedListAccess}}_int{{/IndexBasedListAccess}}",
{{#IndexBasedListAccess}}index,{{/IndexBasedListAccess}}
() -> {
if (this.{{updateMethodName}}({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}})) { if (this.{{updateMethodName}}({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}})) {
this.{{writeMethodName}}({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}}); this.{{writeMethodName}}({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}});
} }
}); }
);
{{/configIncrementalOptionActive}} {{/configIncrementalOptionActive}}
} }
return success; return success;
...@@ -61,7 +67,7 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam ...@@ -61,7 +67,7 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
return false; return false;
} }
{{#configIncrementalOptionActive}} {{#configIncrementalOptionActive}}
connectTokens.forEach(token -> {{internalRagConnectPrefix}}Observer().remove(token)); connectTokens.forEach(token -> {{observerInstanceSingletonMethodName}}().remove(token));
{{/configIncrementalOptionActive}} {{/configIncrementalOptionActive}}
RagConnectDisconnectHandlerMethod disconnectingMethod; RagConnectDisconnectHandlerMethod disconnectingMethod;
switch (scheme) { switch (scheme) {
......
...@@ -31,6 +31,10 @@ group = 'de.tudresden.inf.st' ...@@ -31,6 +31,10 @@ group = 'de.tudresden.inf.st'
repositories { repositories {
mavenCentral() mavenCentral()
maven {
name "gitlab-maven"
url "https://git-st.inf.tu-dresden.de/api/v4/groups/jastadd/-/packages/maven"
}
} }
tasks.compileTestJava { tasks.compileTestJava {
options.release.set(11) options.release.set(11)
...@@ -39,8 +43,8 @@ tasks.compileTestJava { ...@@ -39,8 +43,8 @@ tasks.compileTestJava {
dependencies { dependencies {
implementation project(':ragconnect.base') implementation project(':ragconnect.base')
runtimeOnly group: 'org.jastadd', name: 'jastadd', version: '2.3.5-dresden' // runtimeOnly group: 'org.jastadd', name: 'jastadd', version: '2.3.5-dresden'
// runtimeOnly fileTree(include: ['jastadd2.jar'], dir: '../libs') runtimeOnly fileTree(include: ['jastadd2.jar'], dir: '../libs')
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0' testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0'
......
...@@ -12,3 +12,12 @@ aspect MakeCodeWork { ...@@ -12,3 +12,12 @@ aspect MakeCodeWork {
return tree; return tree;
} }
} }
aspect NameResolution {
// overriding customID guarantees to produce the same JSON representation for equal lists
// otherwise, the value for id is different each time
@Override
protected String A.customID() {
return getClass().getSimpleName() + getValue();
}
}
package org.jastadd.ragconnect.tests; package org.jastadd.ragconnect.tests;
import defaultOnlyRead.ast.MqttHandler; import defaultOnlyRead.ast.MqttHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import java.io.IOException; import java.io.IOException;
...@@ -16,9 +18,10 @@ public abstract class AbstractMqttTest { ...@@ -16,9 +18,10 @@ public abstract class AbstractMqttTest {
private static boolean checkDone = false; private static boolean checkDone = false;
protected static MqttHandler publisher; protected static MqttHandler publisher;
protected Logger logger = LogManager.getLogger(getClass());
@BeforeAll @BeforeAll
public static void createPublishAndOnceCheckMqttConnection() { public static void createPublisherAndCheckMqttConnectionOnce() {
boolean checkResult; boolean checkResult;
try { try {
publisher = new MqttHandler("Publisher") publisher = new MqttHandler("Publisher")
...@@ -45,9 +48,11 @@ public abstract class AbstractMqttTest { ...@@ -45,9 +48,11 @@ public abstract class AbstractMqttTest {
@Tag("mqtt") @Tag("mqtt")
@Test @Test
public final void testCommunicateSendInitialValue() throws IOException, InterruptedException { public final void testCommunicateSendInitialValue() throws IOException, InterruptedException {
logger.debug("Start testCommunicateSendInitialValue");
createModel(); createModel();
setupReceiverAndConnect(true); setupReceiverAndConnect(true);
logger.debug("Calling communicateSendInitialValue");
communicateSendInitialValue(); communicateSendInitialValue();
} }
...@@ -60,9 +65,11 @@ public abstract class AbstractMqttTest { ...@@ -60,9 +65,11 @@ public abstract class AbstractMqttTest {
@Tag("mqtt") @Tag("mqtt")
@Test @Test
public final void testCommunicateOnlyUpdatedValue() throws IOException, InterruptedException { public final void testCommunicateOnlyUpdatedValue() throws IOException, InterruptedException {
logger.debug("Start testCommunicateOnlyUpdatedValue");
createModel(); createModel();
setupReceiverAndConnect(false); setupReceiverAndConnect(false);
logger.debug("Calling communicateOnlyUpdatedValue");
communicateOnlyUpdatedValue(); communicateOnlyUpdatedValue();
} }
...@@ -80,10 +87,12 @@ public abstract class AbstractMqttTest { ...@@ -80,10 +87,12 @@ public abstract class AbstractMqttTest {
/** /**
* Begin with this snippet * Begin with this snippet
* <pre> * <pre>
* {@code
* model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); * model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
* *
* handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost()); * handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
* assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS)); * assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
* }
* </pre> * </pre>
* *
* And then add dependencies, initialise receiver, add connections to those receivers, * And then add dependencies, initialise receiver, add connections to those receivers,
...@@ -94,18 +103,21 @@ public abstract class AbstractMqttTest { ...@@ -94,18 +103,21 @@ public abstract class AbstractMqttTest {
@AfterEach @AfterEach
public void alwaysCloseConnections() { public void alwaysCloseConnections() {
logger.debug("Closing connections");
closeConnections(); closeConnections();
} }
/** /**
* Write the following snippet (using your correct handler and model): * Write the following snippet (using your correct handler and model):
* <pre> * <pre>
* {@code
* if (handler != null) { * if (handler != null) {
* handler.close(); * handler.close();
* } * }
* if (model != null) { * if (model != null) {
* model.ragconnectCloseConnections(); * model.ragconnectCloseConnections();
* } * }
* }
* </pre> * </pre>
*/ */
protected abstract void closeConnections(); protected abstract void closeConnections();
......
...@@ -15,7 +15,8 @@ import static org.assertj.core.groups.Tuple.tuple; ...@@ -15,7 +15,8 @@ import static org.assertj.core.groups.Tuple.tuple;
import static org.awaitility.Awaitility.await; import static org.awaitility.Awaitility.await;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.jastadd.ragconnect.tests.TestUtils.waitForMqtt; import static org.jastadd.ragconnect.tests.TestUtils.waitForMqtt;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* Test case "forwarding". * Test case "forwarding".
...@@ -38,6 +39,7 @@ public class IndexedSendTest extends AbstractMqttTest { ...@@ -38,6 +39,7 @@ public class IndexedSendTest extends AbstractMqttTest {
/** Use initially created members as values in {@link #check} todo link correct method */ /** Use initially created members as values in {@link #check} todo link correct method */
private static final String INITIAL_VALUE = "initial" + rand.nextInt(100); private static final String INITIAL_VALUE = "initial" + rand.nextInt(100);
private static final Logger logger = LogManager.getLogger(IndexedSendTest.class);
private MqttHandler handler; private MqttHandler handler;
private ReceiverData data; private ReceiverData data;
...@@ -101,7 +103,6 @@ public class IndexedSendTest extends AbstractMqttTest { ...@@ -101,7 +103,6 @@ public class IndexedSendTest extends AbstractMqttTest {
@Override @Override
protected void communicateSendInitialValue() throws IOException, InterruptedException { protected void communicateSendInitialValue() throws IOException, InterruptedException {
// TODO check
// Sink.ManyA <-- Root.MultipleA // Sink.ManyA <-- Root.MultipleA
// Sink.ManyAWithSuffix <-- Root.MultipleAWithSuffix // Sink.ManyAWithSuffix <-- Root.MultipleAWithSuffix
checkNoWait(4, tuple("am0", "am1"), tuple("am0post", "am1post")); checkNoWait(4, tuple("am0", "am1"), tuple("am0post", "am1post"));
...@@ -140,7 +141,6 @@ public class IndexedSendTest extends AbstractMqttTest { ...@@ -140,7 +141,6 @@ public class IndexedSendTest extends AbstractMqttTest {
// TODO check // TODO check
assertEquals(listA0.getValue(), senderRoot._ragconnect_MultipleA(0).getValue()); assertEquals(listA0.getValue(), senderRoot._ragconnect_MultipleA(0).getValue());
System.out.println("before changing value");
listA0.setValue("changedValue"); listA0.setValue("changedValue");
assertEquals(listA0.getValue(), senderRoot._ragconnect_MultipleA(0).getValue()); assertEquals(listA0.getValue(), senderRoot._ragconnect_MultipleA(0).getValue());
check(1, tuple("changedValue"), tuple()); check(1, tuple("changedValue"), tuple());
...@@ -244,16 +244,15 @@ public class IndexedSendTest extends AbstractMqttTest { ...@@ -244,16 +244,15 @@ public class IndexedSendTest extends AbstractMqttTest {
private static class ReceiverData { private static class ReceiverData {
int numberOfValues = 0; int numberOfValues = 0;
} }
}
static class PrintingReceiver implements ASTState.Trace.Receiver {
class PrintingReceiver implements ASTState.Trace.Receiver {
static Logger logger = LogManager.getLogger(PrintingReceiver.class); static Logger logger = LogManager.getLogger(PrintingReceiver.class);
@Override @Override
public void accept(ASTState.Trace.Event event, ASTNode node, String attribute, Object params, Object value) { public void accept(ASTState.Trace.Event event, @SuppressWarnings("rawtypes") ASTNode node, String attribute, Object params, Object value) {
logger.info("event: {}, node: {}, attribute: {}, params: {}, value: {}", logger.info("event: {}, node: {}, attribute: {}, params: {}, value: {}",
event, node, attribute, params, value); event, node, attribute, params, value);
} }
} }
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<Configuration status="INFO"> <Configuration status="INFO">
<Appenders> <Appenders>
<Console name="Console" target="SYSTEM_OUT"> <Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level [%t] %logger{20} - %msg%n"/> <PatternLayout pattern="%highlight{%d{HH:mm:ss.SSS} %-5level [%t] %logger{20} - %msg%n}" disableAnsi="false"/>
</Console> </Console>
</Appenders> </Appenders>
<Loggers> <Loggers>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment