Skip to content

Commit f99d434

Browse files
codebase/introduction-to-s3proxy [BAEL-8823] (#17839)
* adding module skeleton * adding storage configuration * adding live tests * hardcoding region in local file system s3client * converting live test to IT * disabling checksum validation for S3Client * update package name in test directory * update storage configuration * update local storage configuration * add base class for storage tests
1 parent 9d6afdd commit f99d434

14 files changed

+427
-0
lines changed

aws-modules/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<module>aws-reactive</module>
2424
<module>aws-rest</module>
2525
<module>aws-s3</module>
26+
<module>s3proxy</module>
2627
</modules>
2728

2829
<dependencies>

aws-modules/s3proxy/pom.xml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<artifactId>s3proxy</artifactId>
7+
<version>0.0.1</version>
8+
<packaging>jar</packaging>
9+
<name>s3proxy</name>
10+
<description>codebase demonstrating the use of s3proxy to access different storage backends via the S3 API</description>
11+
12+
<parent>
13+
<groupId>com.baeldung</groupId>
14+
<artifactId>parent-boot-3</artifactId>
15+
<version>0.0.1-SNAPSHOT</version>
16+
<relativePath>../../parent-boot-3</relativePath>
17+
</parent>
18+
19+
<dependencies>
20+
<dependency>
21+
<groupId>org.springframework.boot</groupId>
22+
<artifactId>spring-boot-starter-web</artifactId>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-configuration-processor</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.gaul</groupId>
30+
<artifactId>s3proxy</artifactId>
31+
<version>${s3proxy.version}</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>software.amazon.awssdk</groupId>
35+
<artifactId>s3</artifactId>
36+
<version>${aws-sdk.version}</version>
37+
</dependency>
38+
</dependencies>
39+
40+
<properties>
41+
<s3proxy.version>2.3.0</s3proxy.version>
42+
<aws-sdk.version>2.28.23</aws-sdk.version>
43+
</properties>
44+
45+
</project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.baeldung.s3proxy;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class Application {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(Application.class, args);
11+
}
12+
13+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.baeldung.s3proxy;
2+
3+
import java.net.URI;
4+
import java.util.Properties;
5+
6+
import org.gaul.s3proxy.AuthenticationType;
7+
import org.gaul.s3proxy.S3Proxy;
8+
import org.jclouds.ContextBuilder;
9+
import org.jclouds.blobstore.BlobStore;
10+
import org.jclouds.blobstore.BlobStoreContext;
11+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
12+
import org.springframework.context.annotation.Bean;
13+
import org.springframework.context.annotation.Configuration;
14+
import org.springframework.context.annotation.Profile;
15+
16+
import software.amazon.awssdk.regions.Region;
17+
import software.amazon.awssdk.services.s3.S3Client;
18+
19+
@Configuration
20+
@Profile("local | test")
21+
@EnableConfigurationProperties(StorageProperties.class)
22+
public class LocalStorageConfiguration {
23+
24+
private final StorageProperties storageProperties;
25+
26+
public LocalStorageConfiguration(StorageProperties storageProperties) {
27+
this.storageProperties = storageProperties;
28+
}
29+
30+
@Bean
31+
public BlobStore blobStore() {
32+
Properties properties = new Properties();
33+
properties.setProperty("jclouds.filesystem.basedir", storageProperties.getLocalFileBaseDirectory());
34+
return ContextBuilder
35+
.newBuilder("filesystem")
36+
.overrides(properties)
37+
.build(BlobStoreContext.class)
38+
.getBlobStore();
39+
}
40+
41+
@Bean
42+
public S3Proxy s3Proxy(BlobStore blobStore) {
43+
return S3Proxy
44+
.builder()
45+
.awsAuthentication(AuthenticationType.NONE, null, null)
46+
.blobStore(blobStore)
47+
.endpoint(URI.create(storageProperties.getProxyEndpoint()))
48+
.build();
49+
}
50+
51+
@Bean
52+
public S3Client s3Client() {
53+
return S3Client
54+
.builder()
55+
.region(Region.US_EAST_1)
56+
.endpointOverride(URI.create(storageProperties.getProxyEndpoint()))
57+
.build();
58+
}
59+
60+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.baeldung.s3proxy;
2+
3+
import org.gaul.s3proxy.S3Proxy;
4+
import org.springframework.boot.ApplicationArguments;
5+
import org.springframework.boot.ApplicationRunner;
6+
import org.springframework.stereotype.Component;
7+
8+
@Component
9+
public class S3ProxyInitializer implements ApplicationRunner {
10+
11+
private final S3Proxy s3Proxy;
12+
13+
public S3ProxyInitializer(S3Proxy s3Proxy) {
14+
this.s3Proxy = s3Proxy;
15+
}
16+
17+
@Override
18+
public void run(ApplicationArguments args) throws Exception {
19+
s3Proxy.start();
20+
}
21+
22+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.baeldung.s3proxy;
2+
3+
import java.net.URI;
4+
5+
import org.gaul.s3proxy.S3Proxy;
6+
import org.jclouds.ContextBuilder;
7+
import org.jclouds.blobstore.BlobStore;
8+
import org.jclouds.blobstore.BlobStoreContext;
9+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
10+
import org.springframework.context.annotation.Bean;
11+
import org.springframework.context.annotation.Configuration;
12+
import org.springframework.context.annotation.Profile;
13+
14+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
15+
import software.amazon.awssdk.auth.credentials.AwsCredentials;
16+
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
17+
import software.amazon.awssdk.regions.Region;
18+
import software.amazon.awssdk.services.s3.S3Client;
19+
import software.amazon.awssdk.services.s3.S3Configuration;
20+
21+
@Configuration
22+
@Profile("!local && !test")
23+
@EnableConfigurationProperties(StorageProperties.class)
24+
public class StorageConfiguration {
25+
26+
private final StorageProperties storageProperties;
27+
28+
public StorageConfiguration(StorageProperties storageProperties) {
29+
this.storageProperties = storageProperties;
30+
}
31+
32+
@Bean
33+
@Profile("azure")
34+
public BlobStore azureBlobStore() {
35+
return ContextBuilder
36+
.newBuilder("azureblob")
37+
.credentials(storageProperties.getIdentity(), storageProperties.getCredential())
38+
.build(BlobStoreContext.class)
39+
.getBlobStore();
40+
}
41+
42+
@Bean
43+
@Profile("gcp")
44+
public BlobStore gcpBlobStore() {
45+
return ContextBuilder
46+
.newBuilder("google-cloud-storage")
47+
.credentials(storageProperties.getIdentity(), storageProperties.getCredential())
48+
.build(BlobStoreContext.class)
49+
.getBlobStore();
50+
}
51+
52+
@Bean
53+
public S3Proxy s3Proxy(BlobStore blobStore) {
54+
return S3Proxy
55+
.builder()
56+
.blobStore(blobStore)
57+
.endpoint(URI.create(storageProperties.getProxyEndpoint()))
58+
.build();
59+
}
60+
61+
@Bean
62+
public S3Client s3Client() {
63+
S3Configuration s3Configuration = S3Configuration
64+
.builder()
65+
.checksumValidationEnabled(false)
66+
.build();
67+
AwsCredentials credentials = AwsBasicCredentials.create(
68+
storageProperties.getIdentity(),
69+
storageProperties.getCredential()
70+
);
71+
return S3Client
72+
.builder()
73+
.region(Region.of(storageProperties.getRegion()))
74+
.endpointOverride(URI.create(storageProperties.getProxyEndpoint()))
75+
.credentialsProvider(StaticCredentialsProvider.create(credentials))
76+
.serviceConfiguration(s3Configuration)
77+
.build();
78+
}
79+
80+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.baeldung.s3proxy;
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
5+
@ConfigurationProperties(prefix = "com.baeldung.storage")
6+
public class StorageProperties {
7+
8+
private String identity;
9+
10+
private String credential;
11+
12+
private String region;
13+
14+
private String bucketName;
15+
16+
private String proxyEndpoint;
17+
18+
private String localFileBaseDirectory;
19+
20+
public String getIdentity() {
21+
return identity;
22+
}
23+
24+
public void setIdentity(String identity) {
25+
this.identity = identity;
26+
}
27+
28+
public String getCredential() {
29+
return credential;
30+
}
31+
32+
public void setCredential(String credential) {
33+
this.credential = credential;
34+
}
35+
36+
public String getRegion() {
37+
return region;
38+
}
39+
40+
public void setRegion(String region) {
41+
this.region = region;
42+
}
43+
44+
public String getBucketName() {
45+
return bucketName;
46+
}
47+
48+
public void setBucketName(String bucketName) {
49+
this.bucketName = bucketName;
50+
}
51+
52+
public String getProxyEndpoint() {
53+
return proxyEndpoint;
54+
}
55+
56+
public void setProxyEndpoint(String proxyEndpoint) {
57+
this.proxyEndpoint = proxyEndpoint;
58+
}
59+
60+
public String getLocalFileBaseDirectory() {
61+
return localFileBaseDirectory;
62+
}
63+
64+
public void setLocalFileBaseDirectory(String localFileBaseDirectory) {
65+
this.localFileBaseDirectory = localFileBaseDirectory;
66+
}
67+
68+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.baeldung.s3proxy;
2+
3+
import org.springframework.test.context.ActiveProfiles;
4+
5+
@ActiveProfiles("azure")
6+
class AzureBlobStorageLiveTest extends BaseStorageTest {
7+
}

0 commit comments

Comments
 (0)