Skip to content

Commit 48fa4f8

Browse files
committed
Add tests
1 parent 23e8cd4 commit 48fa4f8

File tree

6 files changed

+185
-86
lines changed

6 files changed

+185
-86
lines changed

build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ repositories {
4646
}
4747

4848
dependencies {
49-
compile "org.springframework:spring-core:3.0.5.RELEASE"
50-
compile "org.springframework:spring-beans:3.0.5.RELEASE"
51-
compile "org.springframework.cloud:spring-cloud-aws-autoconfigure:1.0.4.RELEASE"
49+
compile "org.springframework:spring-core:4.3.4.RELEASE"
50+
compile "org.springframework:spring-beans:4.3.4.RELEASE"
51+
compile "org.springframework.cloud:spring-cloud-aws-autoconfigure:1.1.3.RELEASE"
5252

5353
testCompile "junit:junit:4.12"
5454
testCompile "org.mockito:mockito-core:1.10.19"
@@ -66,4 +66,4 @@ artifacts {
6666
archives sourcesJar
6767
}
6868

69-
mainClassName = ''
69+
mainClassName = ''

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

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,56 @@
11
package com.spring.loader;
22

3+
import static java.util.Arrays.asList;
4+
import static java.util.stream.Collectors.toList;
5+
36
import java.util.ArrayList;
4-
import java.util.HashSet;
57
import java.util.List;
6-
import java.util.Properties;
78

89
import org.springframework.beans.BeansException;
910
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
1011
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
1112
import org.springframework.core.io.Resource;
1213

14+
import com.amazonaws.services.s3.AmazonS3;
15+
1316
public class S3PropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
1417

1518
private S3ResourceLoader resourceLoader;
16-
private String[] s3Locations = new String[0];
17-
private Resource[] conventionalResources = new Resource[0];
19+
private List<String> s3Locations = new ArrayList<>();
20+
private List<Resource> conventionalResources = new ArrayList<>();
1821

1922
public S3PropertyPlaceholderConfigurer(S3ResourceLoader resourceLoader) {
2023
this.resourceLoader = resourceLoader;
2124
}
25+
2226

23-
@Override
24-
public void setLocations(Resource... locations) {
25-
this.conventionalResources = locations;
27+
public S3PropertyPlaceholderConfigurer(AmazonS3 s3) {
28+
this(new S3ResourceLoader(s3));
2629
}
2730

28-
@SuppressWarnings("deprecation")
29-
public void setS3Locations(String[] s3Locations) {
30-
this.s3Locations = new String[s3Locations.length];
31-
for (int i = 0; i < s3Locations.length; i++) {
32-
this.s3Locations[i] = parseStringValue(s3Locations[i], new Properties(), new HashSet<>());
33-
}
34-
31+
public void setS3Locations(String...s3Locations) {
32+
this.s3Locations.addAll(asList(s3Locations));
3533
}
36-
34+
3735
@Override
38-
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
39-
injectS3Resources();
40-
super.postProcessBeanFactory(beanFactory);
36+
public void setLocations(Resource... locations) {
37+
this.conventionalResources.addAll(asList(locations));
4138
}
4239

43-
private void injectS3Resources() {
44-
int total = conventionalResources.length + s3Locations.length;
40+
@Override
41+
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
42+
int total = conventionalResources.size() + s3Locations.size();
4543

4644
if (total > 0) {
47-
List<Resource> allResources = new ArrayList<>();
48-
for (String s3Location : s3Locations) {
49-
allResources.add(resourceLoader.getResource(s3Location));
50-
}
51-
for (Resource conventionalResource : conventionalResources) {
52-
allResources.add(conventionalResource);
53-
}
54-
55-
super.setLocations(allResources.toArray(new Resource[0]));
45+
List<Resource> allResources = s3Locations.stream()
46+
.map(resourceLoader::getResource)
47+
.collect(toList());
48+
49+
conventionalResources.forEach(allResources::add);
50+
51+
super.setLocations(allResources.toArray(new Resource[allResources.size()]));
5652
}
57-
53+
54+
super.postProcessBeanFactory(beanFactory);
5855
}
5956
}
Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.spring.loader;
22

3+
import static java.lang.String.format;
4+
35
import org.springframework.core.io.InputStreamResource;
46
import org.springframework.core.io.Resource;
57
import org.springframework.core.io.ResourceLoader;
8+
import org.springframework.util.StringUtils;
69

710
import com.amazonaws.auth.AWSCredentials;
811
import com.amazonaws.services.s3.AmazonS3;
@@ -12,7 +15,6 @@
1215
class S3ResourceLoader implements ResourceLoader {
1316

1417
private static final String S3_PROTOCOL_PREFIX = "s3://";
15-
1618
private final AmazonS3 s3;
1719

1820
public S3ResourceLoader(AWSCredentials credentials) {
@@ -23,43 +25,30 @@ public S3ResourceLoader(AmazonS3 s3) {
2325
this.s3 = s3;
2426
}
2527

26-
@Override
27-
public ClassLoader getClassLoader() {
28-
return this.getClassLoader();
29-
}
30-
3128
@Override
3229
public Resource getResource(String location) {
30+
if (StringUtils.isEmpty(location)) {
31+
throw new S3ResourceException("Location cannot be empty or null");
32+
}
33+
34+
if (!location.startsWith(S3_PROTOCOL_PREFIX)) {
35+
throw new S3ResourceException(format("%s does not starts with '%s'", location, S3_PROTOCOL_PREFIX));
36+
}
37+
38+
String path = location.substring(S3_PROTOCOL_PREFIX.length(), location.length());
39+
String bucketName = path.substring(0, path.indexOf('/'));
40+
String keyName = path.substring(path.indexOf('/') + 1);
41+
3342
try {
34-
S3Path s3Path = parseS3Path(location);
35-
S3Object s3Object = s3.getObject(s3Path.getBucketName(), s3Path.getKeyName());
43+
S3Object s3Object = s3.getObject(bucketName, keyName);
3644
return new InputStreamResource(s3Object.getObjectContent(), location);
37-
3845
} catch (Exception e) {
3946
throw new S3ResourceException("Could not load resource from " + location, e);
4047
}
4148
}
42-
43-
private static S3Path parseS3Path(String location) {
44-
45-
String path = getLocationPath(location);
46-
String bucketName = path.substring(0, path.indexOf("/"));
47-
String keyName = path.substring(path.indexOf("/") + 1);
48-
49-
return new S3Path(bucketName, keyName);
50-
}
51-
52-
private static String getLocationPath(String location) {
53-
54-
if (location == null || "".equals(location.trim())) {
55-
throw new S3ResourceException("Location cannot be empty or null");
56-
}
57-
58-
if (location.startsWith(S3_PROTOCOL_PREFIX)) {
59-
return location.substring(S3_PROTOCOL_PREFIX.length(), location.length());
60-
}
61-
62-
throw new S3ResourceException(location + " does not begin with '" + S3_PROTOCOL_PREFIX + "'");
49+
50+
@Override
51+
public ClassLoader getClassLoader() {
52+
return this.getClassLoader();
6353
}
64-
6554
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.spring.loader;
2+
3+
import static org.mockito.Matchers.anyString;
4+
import static org.mockito.Mockito.never;
5+
import static org.mockito.Mockito.verify;
6+
import static org.mockito.Mockito.when;
7+
8+
import org.junit.Before;
9+
import org.junit.Test;
10+
import org.junit.runner.RunWith;
11+
import org.mockito.Mock;
12+
import org.mockito.runners.MockitoJUnitRunner;
13+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
14+
import org.springframework.core.io.Resource;
15+
16+
import com.amazonaws.services.s3.AmazonS3;
17+
import com.amazonaws.services.s3.model.S3Object;
18+
import com.amazonaws.services.s3.model.S3ObjectInputStream;
19+
20+
@RunWith(MockitoJUnitRunner.class)
21+
public class S3PropertyPlaceholderConfigurerTest {
22+
23+
private String location = "s3://somebucket/somefolder";
24+
25+
private S3PropertyPlaceholderConfigurer subject;
26+
private S3ResourceLoader resourceLoader;
27+
28+
@Mock
29+
private AmazonS3 s3;
30+
@Mock
31+
private ConfigurableListableBeanFactory beanFactory;
32+
@Mock
33+
private Resource resource;
34+
@Mock
35+
private S3Object s3Object;
36+
@Mock
37+
private S3ObjectInputStream s3ObjectInputStream;
38+
39+
@Before
40+
public void setup() {
41+
resourceLoader = new S3ResourceLoader(s3);
42+
subject = new S3PropertyPlaceholderConfigurer(resourceLoader);
43+
44+
when(beanFactory.getBeanDefinitionNames()).thenReturn(new String[]{});
45+
}
46+
47+
@Test
48+
public void shouldProcessDefaultProperties() {
49+
subject.postProcessBeanFactory(beanFactory);
50+
51+
verify(s3Object, never()).getObjectContent();
52+
}
53+
54+
@Test
55+
public void shouldProcessS3Properties() {
56+
when(s3.getObject(anyString(), anyString())).thenReturn(s3Object);
57+
when(s3Object.getObjectContent()).thenReturn(s3ObjectInputStream);
58+
59+
subject.setS3Locations(location);
60+
subject.postProcessBeanFactory(beanFactory);
61+
62+
verify(s3Object).getObjectContent();
63+
}
64+
65+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.spring.loader;
2+
3+
import static org.mockito.Mockito.never;
4+
import static org.mockito.Mockito.verify;
5+
import static org.mockito.Mockito.when;
6+
7+
import org.junit.Before;
8+
import org.junit.Test;
9+
import org.junit.runner.RunWith;
10+
import org.mockito.Mock;
11+
import org.mockito.Mockito;
12+
import org.mockito.runners.MockitoJUnitRunner;
13+
14+
import com.amazonaws.services.s3.AmazonS3;
15+
import com.amazonaws.services.s3.model.S3Object;
16+
import com.amazonaws.services.s3.model.S3ObjectInputStream;
17+
18+
@RunWith(MockitoJUnitRunner.class)
19+
public class S3ResourceLoaderTest {
20+
21+
private S3ResourceLoader subject;
22+
23+
@Mock
24+
private AmazonS3 s3;
25+
@Mock
26+
private S3Object s3Object;
27+
@Mock
28+
private S3ObjectInputStream inputStream;
29+
30+
private String validLocation = "s3://mybucket/myfolder";
31+
private String invalidLocation = "mybucket/myfolder";
32+
private String emptyLocation = "";
33+
34+
@Before
35+
public void setup() {
36+
subject = new S3ResourceLoader(s3);
37+
}
38+
39+
@Test
40+
public void shouldGetAValidResource() {
41+
when(s3.getObject(Mockito.anyString(), Mockito.anyString())).thenReturn(s3Object);
42+
when(s3Object.getObjectContent()).thenReturn(inputStream);
43+
44+
subject.getResource(validLocation);
45+
46+
verify(s3).getObject(Mockito.anyString(), Mockito.anyString());
47+
}
48+
49+
@Test(expected = S3ResourceException.class)
50+
public void shouldNotGetAValidResourceWhenLocationIsEmpty() {
51+
when(s3.getObject(Mockito.anyString(), Mockito.anyString())).thenReturn(s3Object);
52+
when(s3Object.getObjectContent()).thenReturn(inputStream);
53+
54+
subject.getResource(emptyLocation);
55+
56+
verify(s3, never()).getObject(Mockito.anyString(), Mockito.anyString());
57+
}
58+
59+
@Test(expected = S3ResourceException.class)
60+
public void shouldNotGetAValidResourceWhenLocationIsInvald() {
61+
when(s3.getObject(Mockito.anyString(), Mockito.anyString())).thenReturn(s3Object);
62+
when(s3Object.getObjectContent()).thenReturn(inputStream);
63+
64+
subject.getResource(invalidLocation);
65+
66+
verify(s3, never()).getObject(Mockito.anyString(), Mockito.anyString());
67+
}
68+
69+
}

0 commit comments

Comments
 (0)