Skip to content

Commit 23ab4f5

Browse files
committed
Update ResourcePropertySourceLoaderTest.java
1 parent f47f699 commit 23ab4f5

1 file changed

Lines changed: 146 additions & 6 deletions

File tree

microsphere-spring-context/src/test/java/io/microsphere/spring/config/context/annotation/ResourcePropertySourceLoaderTest.java

Lines changed: 146 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,45 @@
1717

1818
package io.microsphere.spring.config.context.annotation;
1919

20+
import io.microsphere.lang.function.ThrowableAction;
21+
import io.microsphere.spring.config.env.event.PropertySourcesChangedEvent;
2022
import org.junit.After;
2123
import org.junit.Before;
2224
import org.junit.Test;
2325
import org.springframework.beans.factory.BeanDefinitionStoreException;
26+
import org.springframework.context.ApplicationListener;
2427
import org.springframework.context.ConfigurableApplicationContext;
2528
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2629
import org.springframework.core.env.CompositePropertySource;
2730
import org.springframework.core.env.ConfigurableEnvironment;
2831
import org.springframework.core.env.MutablePropertySources;
2932
import org.springframework.core.env.PropertySource;
33+
import org.springframework.core.io.Resource;
3034

35+
import java.io.File;
36+
import java.io.FileOutputStream;
37+
import java.io.IOException;
38+
import java.io.OutputStream;
3139
import java.util.Collection;
3240
import java.util.Iterator;
3341
import java.util.ListIterator;
42+
import java.util.Map;
43+
import java.util.Properties;
44+
import java.util.concurrent.atomic.AtomicBoolean;
3445
import java.util.function.BiConsumer;
46+
import java.util.function.Consumer;
3547

48+
import static io.microsphere.io.FileUtils.forceDelete;
49+
import static io.microsphere.lang.function.ThrowableAction.execute;
50+
import static java.lang.Thread.sleep;
51+
import static java.util.UUID.randomUUID;
3652
import static org.junit.Assert.assertEquals;
3753
import static org.junit.Assert.assertNotNull;
3854
import static org.junit.Assert.assertSame;
3955
import static org.junit.Assert.assertTrue;
4056
import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
4157
import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
58+
import static org.springframework.core.io.support.PropertiesLoaderUtils.loadProperties;
4259

4360
/**
4461
* {@link ResourcePropertySourceLoader} Test
@@ -52,6 +69,10 @@ public class ResourcePropertySourceLoaderTest {
5269

5370
static final Class<ResourcePropertySource> RESOURCE_PROPERTY_SOURCE_CLASS = ResourcePropertySource.class;
5471

72+
static final String PROPERTIES_DIRECTORY_RESOURCE_LOCATION = "classpath:/META-INF/test/";
73+
74+
static final String PROPERTIES_RESOURCE_LOCATION = PROPERTIES_DIRECTORY_RESOURCE_LOCATION + "*.properties";
75+
5576
@Before
5677
public void before() {
5778

@@ -120,6 +141,63 @@ public void testOnAutoRefreshedConfig() {
120141
}, AutoRefreshedConfig.class);
121142
}
122143

144+
@Test
145+
public void testOnFileCreated() {
146+
testInSpringContainer((context, environment) -> {
147+
execute(() -> {
148+
Resource propertiesDirectoryResource = context.getResource(PROPERTIES_DIRECTORY_RESOURCE_LOCATION);
149+
assertTrue(propertiesDirectoryResource.exists());
150+
File propertiesDirectory = propertiesDirectoryResource.getFile();
151+
File cPropertiesFile = new File(propertiesDirectory, "c.properties");
152+
try {
153+
testOnFileCreated(context, cPropertiesFile);
154+
} finally {
155+
// recovery
156+
delete(cPropertiesFile);
157+
}
158+
});
159+
}, AutoRefreshedConfig.class);
160+
}
161+
162+
@Test
163+
public void testOnFileModified() {
164+
testInSpringContainer((context, environment) -> {
165+
execute(() -> {
166+
Resource bPropertiesResource = context.getResource(PROPERTIES_DIRECTORY_RESOURCE_LOCATION + "b.properties");
167+
assertTrue(bPropertiesResource.exists());
168+
Properties bProperties = loadProperties(bPropertiesResource);
169+
File bPropertiesResourceFile = bPropertiesResource.getFile();
170+
try {
171+
testOnFile(context, bPropertiesResourceFile, new Properties(bProperties));
172+
} finally {
173+
// recovery
174+
writePropertiesFile(bPropertiesResourceFile, bProperties);
175+
}
176+
});
177+
}, AutoRefreshedConfig.class);
178+
}
179+
180+
@Test
181+
public void testOnFileDeleted() {
182+
testInSpringContainer((context, environment) -> {
183+
execute(() -> {
184+
Resource aPropertiesResource = context.getResource(PROPERTIES_DIRECTORY_RESOURCE_LOCATION + "a.properties");
185+
assertTrue(aPropertiesResource.exists());
186+
Properties aProperties = loadProperties(aPropertiesResource);
187+
File aPropertiesResourceFile = aPropertiesResource.getFile();
188+
try {
189+
testOnFileDeleted(context, aPropertiesResourceFile, removedProperties -> {
190+
assertEquals("1", removedProperties.get("a"));
191+
assertEquals("3", removedProperties.get("b"));
192+
});
193+
} finally {
194+
// recovery
195+
writePropertiesFile(aPropertiesResourceFile, aProperties);
196+
}
197+
});
198+
}, AutoRefreshedConfig.class);
199+
}
200+
123201
void assertDefaultPropertySource(ConfigurableEnvironment environment, Class<?> introspectedClass) {
124202
PropertySource<?> propertySource = assertLastPropertySource(environment);
125203
assertDefaultPropertySourceName(propertySource, introspectedClass);
@@ -225,33 +303,95 @@ void testInSpringContainer(BiConsumer<ConfigurableApplicationContext, Configurab
225303
context.close();
226304
}
227305

228-
@ResourcePropertySource("classpath*:/META-INF/test/*.properties")
306+
void testOnFileCreated(ConfigurableApplicationContext context, File newPropertiesFile) throws Throwable {
307+
testOnFile(context, newPropertiesFile, new Properties());
308+
}
309+
310+
void testOnFile(ConfigurableApplicationContext context, File propertiesFile, Properties properties) throws Throwable {
311+
312+
// watches the properties file
313+
AtomicBoolean notified = new AtomicBoolean();
314+
315+
String propertyName = propertiesFile.getName();
316+
String propertyValue = randomUUID().toString();
317+
318+
context.addApplicationListener((ApplicationListener<PropertySourcesChangedEvent>) event -> {
319+
notified.set(true);
320+
ConfigurableEnvironment environment = context.getEnvironment();
321+
assertEquals(propertyValue, environment.getProperty(propertyName));
322+
});
323+
324+
// appends the new content
325+
properties.setProperty(propertyName, propertyValue);
326+
327+
// waits for being notified
328+
waits(notified, () -> writePropertiesFile(propertiesFile, properties));
329+
}
330+
331+
void testOnFileDeleted(ConfigurableApplicationContext context, File deletedPropertiesFile, Consumer<Map<String, Object>> removedPropertiesConsumer) throws Throwable {
332+
// watches the properties file
333+
AtomicBoolean notified = new AtomicBoolean();
334+
335+
context.addApplicationListener((ApplicationListener<PropertySourcesChangedEvent>) event -> {
336+
notified.set(true);
337+
Map<String, Object> removedProperties = event.getRemovedProperties();
338+
removedPropertiesConsumer.accept(removedProperties);
339+
});
340+
341+
// waits for being notified
342+
waits(notified, () -> delete(deletedPropertiesFile));
343+
}
344+
345+
void writePropertiesFile(File propertiesFile, Properties properties) throws IOException {
346+
try (OutputStream outputStream = new FileOutputStream(propertiesFile)) {
347+
properties.store(outputStream, null);
348+
}
349+
}
350+
351+
void waits(AtomicBoolean notified, ThrowableAction action) throws Throwable {
352+
// waits for being notified
353+
for (int i = 0; i < 100; i++) {
354+
if (notified.get()) {
355+
break;
356+
}
357+
action.execute();
358+
sleep(500);
359+
}
360+
}
361+
362+
static void delete(File file) throws IOException {
363+
if (file.exists()) {
364+
forceDelete(file);
365+
}
366+
}
367+
368+
@ResourcePropertySource(PROPERTIES_RESOURCE_LOCATION)
229369
static class DefaultConfig {
230370
}
231371

232372
@ResourcePropertySource(
233373
name = "test-property-source",
234-
value = "classpath*:/META-INF/test/*.properties"
374+
value = PROPERTIES_RESOURCE_LOCATION
235375
)
236376
static class NamedConfig {
237377
}
238378

239379
@ResourcePropertySource(
240-
value = "classpath*:/META-INF/test/*.properties",
380+
value = PROPERTIES_RESOURCE_LOCATION,
241381
first = true
242382
)
243383
static class FirstConfig {
244384
}
245385

246386
@ResourcePropertySource(
247-
value = "classpath*:/META-INF/test/*.properties",
387+
value = PROPERTIES_RESOURCE_LOCATION,
248388
before = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME
249389
)
250390
static class BeforeConfig {
251391
}
252392

253393
@ResourcePropertySource(
254-
value = "classpath*:/META-INF/test/*.properties",
394+
value = PROPERTIES_RESOURCE_LOCATION,
255395
after = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME
256396
)
257397
static class AfterConfig {
@@ -269,7 +409,7 @@ static class NotFoundConfig {
269409
}
270410

271411
@ResourcePropertySource(
272-
value = "classpath*:/META-INF/test/*.properties",
412+
value = PROPERTIES_RESOURCE_LOCATION,
273413
autoRefreshed = true
274414
)
275415
static class AutoRefreshedConfig {

0 commit comments

Comments
 (0)