1   /*
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2024, 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 v1.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  package ch.qos.logback.classic.blackbox.joran.spi;
16  
17  import ch.qos.logback.classic.Level;
18  import ch.qos.logback.classic.Logger;
19  import ch.qos.logback.classic.LoggerContext;
20  import ch.qos.logback.classic.blackbox.joran.ReconfigureOnChangeTaskTest;
21  import ch.qos.logback.classic.blackbox.joran.ReconfigureTaskTestSupport;
22  import ch.qos.logback.core.CoreConstants;
23  import ch.qos.logback.core.joran.spi.ConfigurationWatchList;
24  import ch.qos.logback.core.joran.spi.HttpUtil;
25  import ch.qos.logback.core.joran.spi.JoranException;
26  import ch.qos.logback.core.testUtil.RandomUtil;
27  import jakarta.servlet.http.HttpServlet;
28  import org.junit.jupiter.api.*;
29  import org.slf4j.LoggerFactory;
30  
31  import java.io.UnsupportedEncodingException;
32  import java.net.HttpURLConnection;
33  import java.net.MalformedURLException;
34  import java.net.URL;
35  import java.util.concurrent.CountDownLatch;
36  import java.util.concurrent.TimeUnit;
37  
38  import static org.junit.jupiter.api.Assertions.*;
39  
40  public class ConfigurationWatchListTest extends ReconfigureTaskTestSupport {
41  
42      static String BAZINGA_LOGGER_NAME = "com.bazinga";
43      static String BAZINGA_LOGGER_SETUP_0 = "logback.logger."+BAZINGA_LOGGER_NAME+"=WARN";
44      static String BAZINGA_LOGGER_SETUP_1 = "logback.logger."+BAZINGA_LOGGER_NAME+"=ERROR";
45  
46      int randomPort = RandomUtil.getRandomServerPort();
47      ConfigEmbeddedJetty configEmbeddedJetty;
48      ConfigurationWatchList cwl = new ConfigurationWatchList();
49      static String FOO_PROPERTIES = "/foo.properties";
50      String urlString = "http://127.0.0.1:"+randomPort+FOO_PROPERTIES;
51  
52      @BeforeEach
53      public void setUp() throws Exception {
54          Logger rootLogger = (Logger) LoggerFactory.getLogger( Logger.ROOT_LOGGER_NAME );
55          rootLogger.setLevel(Level.INFO);
56  
57          configEmbeddedJetty = new ConfigEmbeddedJetty(randomPort);
58  
59          cwl.setContext(loggerContext);
60  
61          HttpServlet configServlet = new ConfigFileServlet(BAZINGA_LOGGER_SETUP_0);
62          configEmbeddedJetty.getServletMap().put(FOO_PROPERTIES, configServlet);
63  
64          configEmbeddedJetty.init();
65  
66      }
67  
68      @AfterEach
69      public void tearDown() throws Exception {
70          configEmbeddedJetty.stop();
71      }
72  
73  
74  
75      @Test
76      public void testInfrastructure() throws MalformedURLException {
77          String response = get(urlString);
78          assertNotNull(response);
79          Assertions.assertEquals(BAZINGA_LOGGER_SETUP_0, response);
80  
81          String setResponse1 = "bla bla";
82          String response1 = post(urlString, setResponse1);
83          assertEquals(response1, setResponse1);
84  
85          String response2 = get(urlString);
86          assertEquals(response1, response2);
87      }
88  
89      @Test
90      public void smoke() throws MalformedURLException {
91          URL url = new URL(urlString);
92          cwl.addToWatchList(url);
93          URL changedURL0 = cwl.changeDetectedInURL();
94          assertNull(changedURL0);
95        
96          String setResponse1 = "bla bla";
97          String response1 = post(urlString, setResponse1);
98          assertEquals(response1, setResponse1);
99  
100         URL changedURL1 = cwl.changeDetectedInURL();
101         assertEquals(urlString, changedURL1.toString());
102 
103         URL changedURL2 = cwl.changeDetectedInURL();
104         assertNull(changedURL2);
105 
106         URL changedURL3 = cwl.changeDetectedInURL();
107         assertNull(changedURL3);
108     }
109 
110     @Disabled
111     @Test
112     public void propertiesFromHTTP() throws UnsupportedEncodingException, JoranException, InterruptedException, MalformedURLException {
113 
114 
115 
116         String propertiesURLStr = urlString;
117         Logger bazingaLogger = loggerContext.getLogger(BAZINGA_LOGGER_NAME);
118 
119         assertEquals(BAZINGA_LOGGER_SETUP_0, get(urlString));
120 
121         String configurationStr = "<configuration debug=\"true\" scan=\"true\" scanPeriod=\"1 millisecond\"><propertiesConfigurator url=\"" + propertiesURLStr + "\"/></configuration>";
122 
123         configure(asBAIS(configurationStr));
124 
125         // allow for the first update
126         Thread.sleep(50);
127         assertEquals(Level.WARN, bazingaLogger.getLevel());
128         System.out.println("first test passed with success");
129 
130         CountDownLatch changeDetectedLatch0 = registerChangeDetectedListener();
131         CountDownLatch configurationDoneLatch0 = registerPartialConfigurationEndedSuccessfullyEventListener();
132 
133         String response1 = post(urlString, BAZINGA_LOGGER_SETUP_1);
134         assertEquals(BAZINGA_LOGGER_SETUP_1, get(urlString));
135 
136         changeDetectedLatch0.await(100, TimeUnit.MICROSECONDS);
137         configurationDoneLatch0.await(100, TimeUnit.MICROSECONDS);
138         assertEquals(Level.ERROR, bazingaLogger.getLevel());
139     }
140 
141 }