Skip to content

Commit 5c8e5c3

Browse files
committed
fix scanning for included files to be created later, issues/1021
Signed-off-by: ceki <[email protected]>
1 parent edcc7e8 commit 5c8e5c3

5 files changed

Lines changed: 111 additions & 43 deletions

File tree

logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigurationDoneListener.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,32 @@
1818
import ch.qos.logback.core.spi.ConfigurationEvent;
1919
import ch.qos.logback.core.spi.ConfigurationEventListener;
2020

21+
import java.util.Objects;
2122
import java.util.concurrent.CountDownLatch;
2223

2324
class ReconfigurationDoneListener implements ConfigurationEventListener {
2425
CountDownLatch countDownLatch;
2526

26-
ReconfigureOnChangeTask roct;
27+
//ReconfigureOnChangeTask roct;
2728

28-
ReconfigurationDoneListener(CountDownLatch countDownLatch, ReconfigureOnChangeTask aRoct) {
29+
ReconfigurationDoneListener(CountDownLatch countDownLatch) {
2930
this.countDownLatch = countDownLatch;
30-
this.roct = aRoct;
31+
//this.roct = aRoct;
3132
}
3233

3334
@Override
3435
public void listen(ConfigurationEvent configurationEvent) {
35-
switch (configurationEvent.getEventType()) {
36-
case CONFIGURATION_ENDED_SUCCESSFULLY:
37-
if(roct == null) {
38-
countDownLatch.countDown();
39-
} else {
40-
Object data = configurationEvent.getData();
41-
if(data instanceof ReconfigureOnChangeTask && roct == data) {
42-
countDownLatch.countDown();
43-
}
44-
}
45-
break;
46-
default:
36+
if (configurationEvent.getEventType() == ConfigurationEvent.EventType.CONFIGURATION_ENDED_SUCCESSFULLY) {
37+
countDownLatch.countDown();
38+
39+
// if (roct == null) {
40+
// countDownLatch.countDown();
41+
// } else {
42+
// Object data = configurationEvent.getData();
43+
// if (data instanceof ReconfigureOnChangeTask && roct == data) {
44+
// countDownLatch.countDown();
45+
// }
46+
// }
4747
}
4848

4949
}

logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigurationTaskRegisteredConfigEventListener.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,31 @@
1818
import ch.qos.logback.core.spi.ConfigurationEvent;
1919
import ch.qos.logback.core.spi.ConfigurationEventListener;
2020

21+
import java.util.Objects;
22+
23+
/**
24+
* A listener implementation that processes configuration events related to
25+
* the registration of a reconfiguration task.
26+
*
27+
* This class listens to configuration events and identifies if a
28+
* "CHANGE_DETECTOR_REGISTERED" event has occurred. When such an event is detected,
29+
* it captures and stores the associated {@link ReconfigureOnChangeTask} instance
30+
* from the event data if it exists.
31+
*
32+
* Implements the {@link ConfigurationEventListener} interface.
33+
*/
2134
public class ReconfigurationTaskRegisteredConfigEventListener implements ConfigurationEventListener {
2235

2336
boolean changeDetectorRegisteredEventOccurred = false;
2437
ReconfigureOnChangeTask reconfigureOnChangeTask;
38+
2539
@Override
2640
public void listen(ConfigurationEvent configurationEvent) {
27-
switch (configurationEvent.getEventType()) {
28-
case CHANGE_DETECTOR_REGISTERED:
41+
if (configurationEvent.getEventType() == ConfigurationEvent.EventType.CHANGE_DETECTOR_REGISTERED) {
2942
changeDetectorRegisteredEventOccurred = true;
3043
Object data = configurationEvent.getData();
31-
if(data instanceof ReconfigureOnChangeTask)
44+
if (data instanceof ReconfigureOnChangeTask)
3245
reconfigureOnChangeTask = (ReconfigureOnChangeTask) data;
33-
break;
34-
default:
3546
}
3647
}
3748
}

logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureOnChangeTaskTest.java

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@
3333
import ch.qos.logback.core.testUtil.CoreTestConstants;
3434
import ch.qos.logback.core.testUtil.FileTestUtil;
3535
import ch.qos.logback.core.testUtil.RandomUtil;
36-
import ch.qos.logback.core.util.StatusPrinter;
36+
import ch.qos.logback.core.util.Loader;
3737
import ch.qos.logback.core.util.StatusPrinter2;
3838
import org.junit.jupiter.api.*;
3939

4040
import java.io.*;
41+
import java.net.URL;
4142
import java.util.List;
4243
import java.util.concurrent.CountDownLatch;
4344
import java.util.concurrent.ExecutionException;
@@ -70,6 +71,8 @@ public class ReconfigureOnChangeTaskTest extends ReconfigureTaskTestSupport {
7071

7172
private static final String SCAN_PERIOD_DEFAULT_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan_period_default.xml";
7273

74+
private static final String TOP_FILE_WITH_INCLUSION = "asResource/topWithFileInclusion.xml";
75+
7376
Logger logger = loggerContext.getLogger(this.getClass());
7477
StatusChecker statusChecker = new StatusChecker(loggerContext);
7578
StatusPrinter2 statusPrinter2 = new StatusPrinter2();
@@ -91,6 +94,14 @@ void configure(File file) throws JoranException {
9194
jc.doConfigure(file);
9295
}
9396

97+
void configureAsResource(String filename) throws JoranException {
98+
URL url = Loader.getResource(filename, this.getClass().getClassLoader());
99+
assertNotNull(url);
100+
JoranConfigurator jc = new JoranConfigurator();
101+
jc.setContext(loggerContext);
102+
jc.doConfigure(url);
103+
}
104+
94105
@Test
95106
@Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS)
96107
public void checkBasicLifecyle() throws JoranException, IOException, InterruptedException {
@@ -130,6 +141,7 @@ public void scanWithFileInclusion() throws JoranException, IOException, Interrup
130141
checkThatTaskCanBeStopped();
131142
}
132143

144+
133145
@Test
134146
@Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS)
135147
public void scanWithResourceInclusion() throws JoranException, IOException, InterruptedException {
@@ -256,7 +268,7 @@ public void fallbackToSafe_FollowedByRecovery() throws IOException, JoranExcepti
256268

257269
private void addResetResistantOnConsoleStatusListener() {
258270
// enable when debugging
259-
if(1==1)
271+
if(1!=1)
260272
return;
261273
OnConsoleStatusListener ocs = new OnConsoleStatusListener();
262274
ocs.setContext(loggerContext);
@@ -265,6 +277,43 @@ private void addResetResistantOnConsoleStatusListener() {
265277
loggerContext.getStatusManager().add(ocs);
266278
}
267279

280+
@Test
281+
@Timeout(value = 2, unit = TimeUnit.SECONDS)
282+
public void XXXscanWithIncludedFileCreatedLater() throws IOException, JoranException, InterruptedException {
283+
ReconfigurationTaskRegisteredConfigEventListener roctRegisteredListener = new ReconfigurationTaskRegisteredConfigEventListener();
284+
loggerContext.addConfigurationEventListener(roctRegisteredListener);
285+
addResetResistantOnConsoleStatusListener();
286+
String innerFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "scanWithIncludedFileCreatedLater-" + diff + ".xml";
287+
System.setProperty("fileCreatedLater", innerFileAsStr);
288+
configureAsResource(TOP_FILE_WITH_INCLUSION);
289+
290+
File innerFile = new File(innerFileAsStr);
291+
292+
List<File> fileList = getConfigurationWatchList(loggerContext);
293+
assertThatListContainsFile(fileList, innerFile);
294+
295+
// capture reference to ReconfigureOnChangeTask
296+
//ReconfigureOnChangeTask roct = roctRegisteredListener.reconfigureOnChangeTask;
297+
//assertNotNull(roct);
298+
299+
CountDownLatch changeDetectedLatch = registerChangeDetectedListener();
300+
CountDownLatch configurationDoneLatch = registerNewReconfigurationDoneSuccessfullyListener();
301+
302+
303+
writeToFile(innerFile, "<included><root level=\"ERROR\"/></included> ");
304+
changeDetectedLatch.await();
305+
configurationDoneLatch.await();
306+
307+
//Thread.sleep(1000);
308+
//waitForReconfigureOnChangeTaskToRun();
309+
310+
//statusPrinter2.print(loggerContext);
311+
Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
312+
assertEquals(Level.ERROR, root.getLevel());
313+
314+
}
315+
316+
268317
@Test
269318
@Timeout(value = TIMEOUT_LONG, unit = TimeUnit.SECONDS)
270319
public void fallbackToSafeWithIncludedFile_FollowedByRecovery() throws IOException, JoranException, InterruptedException, ExecutionException {
@@ -278,16 +327,11 @@ public void fallbackToSafeWithIncludedFile_FollowedByRecovery() throws IOExcepti
278327
writeToFile(innerFile, "<included><root level=\"ERROR\"/></included> ");
279328
addResetResistantOnConsoleStatusListener();
280329

281-
ReconfigurationTaskRegisteredConfigEventListener roctRegisteredListener = new ReconfigurationTaskRegisteredConfigEventListener();
282-
loggerContext.addConfigurationEventListener(roctRegisteredListener);
283-
284330
configure(topLevelFile);
285331

286-
ReconfigureOnChangeTask roct = roctRegisteredListener.reconfigureOnChangeTask;
287-
288332

289333
CountDownLatch changeDetectedLatch = registerChangeDetectedListener();
290-
CountDownLatch configurationDoneLatch = registerNewReconfigurationDoneSuccessfullyListener(roct);
334+
CountDownLatch configurationDoneLatch = registerNewReconfigurationDoneSuccessfullyListener();
291335

292336
writeToFile(innerFile, "<included>\n<root>\n</included>");
293337
changeDetectedLatch.await();
@@ -298,7 +342,7 @@ public void fallbackToSafeWithIncludedFile_FollowedByRecovery() throws IOExcepti
298342
statusChecker.assertContainsMatch(Status.WARN, FALLING_BACK_TO_SAFE_CONFIGURATION);
299343
statusChecker.assertContainsMatch(Status.INFO, RE_REGISTERING_PREVIOUS_SAFE_CONFIGURATION);
300344

301-
//statusPrinter2.print(loggerContext);
345+
statusPrinter2.print(loggerContext);
302346

303347
loggerContext.getStatusManager().clear();
304348

@@ -312,17 +356,13 @@ public void fallbackToSafeWithIncludedFile_FollowedByRecovery() throws IOExcepti
312356
}
313357

314358
CountDownLatch registerNewReconfigurationDoneSuccessfullyListener() {
315-
return registerNewReconfigurationDoneSuccessfullyListener(null);
316-
}
317-
318-
CountDownLatch registerNewReconfigurationDoneSuccessfullyListener(ReconfigureOnChangeTask roct) {
319359
CountDownLatch latch = new CountDownLatch(1);
320-
ReconfigurationDoneListener reconfigurationDoneListener = new ReconfigurationDoneListener(latch, roct);
360+
ReconfigurationDoneListener reconfigurationDoneListener = new ReconfigurationDoneListener(latch);
321361
loggerContext.addConfigurationEventListener(reconfigurationDoneListener);
322362
return latch;
323363
}
324364

325-
class RunMethodInvokedListener implements ConfigurationEventListener {
365+
static class RunMethodInvokedListener implements ConfigurationEventListener {
326366
CountDownLatch countDownLatch;
327367
ReconfigureOnChangeTask reconfigureOnChangeTask;
328368

@@ -332,15 +372,12 @@ class RunMethodInvokedListener implements ConfigurationEventListener {
332372

333373
@Override
334374
public void listen(ConfigurationEvent configurationEvent) {
335-
switch (configurationEvent.getEventType()) {
336-
case CHANGE_DETECTOR_RUNNING:
375+
if (configurationEvent.getEventType() == ConfigurationEvent.EventType.CHANGE_DETECTOR_RUNNING) {
337376
countDownLatch.countDown();
338377
Object data = configurationEvent.getData();
339378
if (data instanceof ReconfigureOnChangeTask) {
340379
reconfigureOnChangeTask = (ReconfigureOnChangeTask) data;
341380
}
342-
break;
343-
default:
344381
}
345382
}
346383
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--
2+
~ Logback: the reliable, generic, fast and flexible logging framework.
3+
~ Copyright (C) 1999-2026, QOS.ch. All rights reserved.
4+
~
5+
~ This program and the accompanying materials are dual-licensed under
6+
~ either the terms of the Eclipse Public License v2.0 as published by
7+
~ the Eclipse Foundation
8+
~
9+
~ or (per the licensee's choosing)
10+
~
11+
~ under the terms of the GNU Lesser General Public License version 2.1
12+
~ as published by the Free Software Foundation.
13+
-->
14+
15+
<configuration scan="true" scanPeriod="50 millisecond">
16+
17+
<include file="${fileCreatedLater}"/>
18+
</configuration>

logback-core/src/main/java/ch/qos/logback/core/model/processor/IncludeModelHandler.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ protected Class<IncludeModel> getSupportedModelClass() {
6262
public void handle(ModelInterpretationContext mic, Model model) throws ModelHandlerException {
6363
IncludeModel includeModel = (IncludeModel) model;
6464

65+
System.out.println("==============================IncludeModelHandler.handle");
66+
6567
URL topURL = mic.getTopURL();
6668
Boolean topScan = mic.getTopScanBoolean();
6769
Model modelFromIncludedFile = buildModelFromIncludedFile(mic, topURL, topScan, includeModel);
@@ -96,15 +98,16 @@ public Model buildModelFromIncludedFile(ContextAwarePropertyContainer capc, URL
9698
return null;
9799
}
98100

101+
// allow for the creation of the URL at a later time
102+
// updateConfigurationWatchList should be invoked before attempting to open the URL
103+
updateConfigurationWatchList(inputURL, topURL, topScan);
104+
99105
InputStream in = openURL(inputURL);
100106
if (in == null) {
101107
inError = true;
102108
return null;
103109
}
104110

105-
updateConfigurationWatchList(inputURL, topURL, topScan);
106-
107-
108111
SaxEventRecorder recorder = null;
109112

110113
try {
@@ -146,7 +149,6 @@ public SaxEventRecorder populateSaxEventRecorder(final InputStream inputStream)
146149
}
147150

148151
private void updateConfigurationWatchList(URL inputURL, URL topURL, Boolean topScan) throws ModelHandlerException {
149-
150152
if(topScan == Boolean.TRUE) {
151153
if(topURL != null) {
152154
ConfigurationWatchListUtil.addToWatchList(context, inputURL);

0 commit comments

Comments
 (0)