Skip to content

Commit 34713e7

Browse files
ericdalloelo7-developer
authored andcommitted
Search property from PropertySource
1 parent cc18a77 commit 34713e7

File tree

8 files changed

+158
-10
lines changed

8 files changed

+158
-10
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,18 @@ There 2 ways to configure your application to load properties from s3:
3232

3333
**Anotation**
3434

35-
Add this annotation to any spring managed bean
35+
- Adding this annotation to any spring managed bean
3636
```java
3737
@S3PropertiesLocation("my-bucket/my-folder/my-properties.properties")
3838
```
39-
or using a specific profile to only load properties if the app is running with that profile
39+
- Using a specific profile to only load properties if the app is running with that profile
4040
```java
4141
@S3PropertiesLocation(path = "my-bucket/my-folder/my-properties.properties", profiles = "production")
4242
```
43-
43+
- Load from a System env variable
44+
```java
45+
@S3PropertiesLocation(path = "${AWS_S3_LOCATION}", profiles = "production")
46+
```
4447
**Configuration**
4548
```java
4649
@Bean
@@ -55,4 +58,4 @@ S3PropertyPlaceholderConfigurer s3PropertyPlaceholderConfigurer(AmazonS3 amazonS
5558
## Requisites
5659

5760
Official spring aws sdk lib.
58-
See: https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-aws
61+
See: https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-aws

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ dependencies {
6767
testCompile "junit:junit:4.12"
6868
testCompile "org.mockito:mockito-core:1.10.19"
6969
testCompile "org.assertj:assertj-core:1.0.0"
70+
testCompile "org.powermock:powermock-api-mockito:1.6.6"
71+
testCompile "org.powermock:powermock-module-junit4:1.6.6"
7072
}
7173

7274
task sourcesJar(type: Jar) {

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=1.0.5-SNAPSHOT
1+
version=2.0-SNAPSHOT

src/main/java/com/spring/loader/S3PropertiesLocation.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@
1717
*/
1818
@Target(ElementType.TYPE)
1919
@Retention(RetentionPolicy.RUNTIME)
20-
@Import({S3ResourseLoaderConfiguration.class, S3PropertiesLocationRegistrar.class})
20+
@Import({ S3ResourseLoaderConfiguration.class, S3PropertiesLocationRegistrar.class })
2121
@Documented
2222
public @interface S3PropertiesLocation {
23-
23+
2424
/**
2525
* The location of the properties in aws s3.
2626
*
27-
* @return the path of aws s3 properties, e.g. my-bucket/my-folder/app.properties
27+
* @return the path of aws s3 properties e.g. "my-bucket/my-folder/app.properties"
28+
* or a enviroment system to the s3 path e.g. "${MY_BUCKET_IN_AWS_S3}"
2829
*/
2930
String[] value();
30-
31+
3132
/**
3233
* The profiles to load the properties in aws s3.
3334
*

src/main/java/com/spring/loader/S3PropertiesLocationRegistrar.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424
class S3PropertiesLocationRegistrar implements EnvironmentAware, ImportBeanDefinitionRegistrar {
2525

2626
private Environment environment;
27+
private SystemPropertyResolver resolver;
28+
29+
public S3PropertiesLocationRegistrar() {
30+
resolver = new SystemPropertyResolver();
31+
}
32+
33+
public S3PropertiesLocationRegistrar(Environment environment, SystemPropertyResolver resolver) {
34+
this.environment = environment;
35+
this.resolver = resolver;
36+
}
2737

2838
@Override
2939
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
@@ -36,10 +46,16 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
3646

3747
String[] locations = attributes.getStringArray("value");
3848

49+
String[] formattedLocations = new String[locations.length];
50+
51+
for (int i = 0; i < locations.length; i++) {
52+
formattedLocations[i] = resolver.getFormattedValue(locations[i]);
53+
}
54+
3955
BeanDefinition bd = new RootBeanDefinition(S3PropertiesSourceConfigurer.class);
4056

4157
bd.getPropertyValues().addPropertyValue("s3ResourceLoader", new RuntimeBeanReference("s3ResourceLoader"));
42-
bd.getPropertyValues().add("s3Locations", locations);
58+
bd.getPropertyValues().add("s3Locations", formattedLocations);
4359

4460
String beanName = S3PropertiesSourceConfigurer.class.getSimpleName();
4561
registry.registerBeanDefinition(toLowerCase(beanName.charAt(0)) + beanName.substring(1), bd);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.spring.loader;
2+
3+
import static java.lang.String.format;
4+
import static org.springframework.util.StringUtils.isEmpty;
5+
6+
import com.spring.loader.exception.EnviromentPropertyNotFoundException;
7+
import com.spring.loader.exception.InvalidS3LocationException;
8+
9+
/**
10+
* Resolver for properties that will be retrieved from system environment.
11+
*
12+
* @author Eric Dallo
13+
* @since 2.0
14+
*/
15+
public class SystemPropertyResolver {
16+
17+
private static final String SYSTEM_NOTATION_PREFIX = "${";
18+
private static final String SYSTEM_NOTATION_SUFIX = "}";
19+
20+
public String getFormattedValue(String value) {
21+
if (isEmpty(value)) {
22+
throw new InvalidS3LocationException("The location cannot be empty or null");
23+
}
24+
if (value.startsWith(SYSTEM_NOTATION_PREFIX)) {
25+
26+
if (value.endsWith(SYSTEM_NOTATION_SUFIX)) {
27+
String rawProperty = value.substring(SYSTEM_NOTATION_PREFIX.length(), value.length() - SYSTEM_NOTATION_SUFIX.length());
28+
String valueFromEnv = System.getenv(rawProperty);
29+
30+
if (isEmpty(valueFromEnv)) {
31+
throw new EnviromentPropertyNotFoundException(format("Enviroment variable %s not found in system", rawProperty));
32+
}
33+
34+
return valueFromEnv;
35+
}
36+
throw new InvalidS3LocationException("Syntax error for system property: " + value);
37+
}
38+
39+
return value;
40+
}
41+
42+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.spring.loader.exception;
2+
3+
public class EnviromentPropertyNotFoundException extends S3ResourceException {
4+
private static final long serialVersionUID = -3434756303367606716L;
5+
6+
public EnviromentPropertyNotFoundException(String message) {
7+
super(message);
8+
}
9+
10+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.spring.loader.resolver;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import org.junit.Before;
6+
import org.junit.Test;
7+
import org.junit.runner.RunWith;
8+
import org.mockito.Mockito;
9+
import org.powermock.api.mockito.PowerMockito;
10+
import org.powermock.core.classloader.annotations.PrepareForTest;
11+
import org.powermock.modules.junit4.PowerMockRunner;
12+
13+
import com.spring.loader.SystemPropertyResolver;
14+
import com.spring.loader.exception.EnviromentPropertyNotFoundException;
15+
import com.spring.loader.exception.InvalidS3LocationException;
16+
17+
@PrepareForTest(SystemPropertyResolver.class)
18+
@RunWith(PowerMockRunner.class)
19+
public class SystemPropertyResolverTest {
20+
21+
private SystemPropertyResolver subject;
22+
23+
@Before
24+
public void setup() {
25+
subject = new SystemPropertyResolver();
26+
PowerMockito.mockStatic(System.class);
27+
}
28+
29+
@Test
30+
public void shouldGetFormattedValueWhenValueIsValid() {
31+
String expected = "someValue";
32+
33+
PowerMockito.when(System.getenv(Mockito.eq("AWS_S3"))).thenReturn(expected);
34+
35+
String env = "${AWS_S3}";
36+
37+
String formattedValue = subject.getFormattedValue(env);
38+
39+
assertEquals(expected, formattedValue);
40+
}
41+
42+
@Test
43+
public void shouldGetFormattedValueWhenValueIsValidAndNotASystemEnv() {
44+
String expected = "someValue";
45+
46+
String formattedValue = subject.getFormattedValue(expected);
47+
48+
assertEquals(expected, formattedValue);
49+
}
50+
51+
@Test(expected = InvalidS3LocationException.class)
52+
public void shouldNotGetFormattedValueWhenValueIsEmpty() {
53+
String expected = "";
54+
55+
subject.getFormattedValue(expected);
56+
}
57+
58+
@Test(expected = InvalidS3LocationException.class)
59+
public void shouldNotGetFormattedValueWhenValueHasAInvalidSyntax() {
60+
String expected = "${AWS_S3";
61+
62+
subject.getFormattedValue(expected);
63+
}
64+
65+
@Test(expected = EnviromentPropertyNotFoundException.class)
66+
public void shouldNotGetFormattedValueWhenSystemDoesNotHasTheEnvironmentVariable() {
67+
PowerMockito.when(System.getenv(Mockito.eq("AWS_S3"))).thenReturn(null);
68+
69+
String env = "${AWS_S3}";
70+
71+
subject.getFormattedValue(env);
72+
}
73+
74+
}

0 commit comments

Comments
 (0)