Skip to content

Commit 86c38be

Browse files
committed
add hash and introduce tests
1 parent e0a1cf7 commit 86c38be

3 files changed

Lines changed: 110 additions & 8 deletions

File tree

pom.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,26 @@
168168
</archive>
169169
</configuration>
170170
</plugin>
171+
<plugin>
172+
<groupId>pl.project13.maven</groupId>
173+
<artifactId>git-commit-id-plugin</artifactId>
174+
<version>5.0.0</version>
175+
<executions>
176+
<execution>
177+
<goals>
178+
<goal>revision</goal>
179+
</goals>
180+
</execution>
181+
</executions>
182+
<configuration>
183+
<generateGitPropertiesFile>true</generateGitPropertiesFile>
184+
<gitPropertiesFile>${project.build.outputDirectory}/git.properties</gitPropertiesFile>
185+
<includeOnlyProperties>
186+
<includeOnlyProperty>git.commit.id.abbrev</includeOnlyProperty>
187+
<includeOnlyProperty>git.commit.id</includeOnlyProperty>
188+
</includeOnlyProperties>
189+
</configuration>
190+
</plugin>
171191
<plugin>
172192
<groupId>org.apache.maven.plugins</groupId>
173193
<artifactId>maven-javadoc-plugin</artifactId>

src/main/java/org/gaul/s3proxy/S3ProxyHandler.java

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@
3333
import java.security.NoSuchAlgorithmException;
3434
import java.text.ParseException;
3535
import java.text.SimpleDateFormat;
36+
import java.time.Instant;
3637
import java.util.ArrayList;
3738
import java.util.Base64;
3839
import java.util.Collection;
3940
import java.util.Collections;
4041
import java.util.Date;
4142
import java.util.List;
43+
import java.util.Locale;
4244
import java.util.Map;
4345
import java.util.Optional;
46+
import java.util.Properties;
4447
import java.util.Set;
4548
import java.util.SortedMap;
4649
import java.util.TimeZone;
@@ -58,6 +61,7 @@
5861
import javax.xml.stream.XMLStreamWriter;
5962

6063
import com.fasterxml.jackson.core.JsonParseException;
64+
import com.fasterxml.jackson.databind.ObjectMapper;
6165
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
6266
import com.google.common.base.CharMatcher;
6367
import com.google.common.base.Splitter;
@@ -193,6 +197,9 @@ public class S3ProxyHandler {
193197
"*-./_", /*plusForSpace=*/ false);
194198
@SuppressWarnings("deprecation")
195199
private static final HashFunction MD5 = Hashing.md5();
200+
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
201+
private static final String UNKNOWN_VALUE = "unknown";
202+
private static final StatusMetadata STATUS_METADATA = StatusMetadata.load();
196203

197204
private final boolean anonymousIdentity;
198205
private final AuthenticationType authenticationType;
@@ -206,6 +213,7 @@ public class S3ProxyHandler {
206213
private final XmlMapper mapper = new XmlMapper();
207214
private final XMLOutputFactory xmlOutputFactory =
208215
XMLOutputFactory.newInstance();
216+
private final Instant serverStartTime;
209217
private BlobStoreLocator blobStoreLocator;
210218
// TODO: hack to allow per-request anonymous access
211219
private final BlobStore defaultBlobStore;
@@ -268,6 +276,7 @@ public Map.Entry<String, BlobStore> locateBlobStore(
268276
Boolean.FALSE);
269277
this.servicePath = Strings.nullToEmpty(servicePath);
270278
this.maximumTimeSkew = maximumTimeSkew;
279+
this.serverStartTime = Instant.now();
271280
}
272281

273282
private static String getBlobStoreType(BlobStore blobStore) {
@@ -293,9 +302,10 @@ public final void doHandle(HttpServletRequest baseRequest,
293302
String uri = request.getRequestURI();
294303
String originalUri = request.getRequestURI();
295304

296-
// Check for the /version endpoint
297-
if ("/healthz".equals(uri) && "GET".equalsIgnoreCase(method)) {
298-
handleVersionRequest(response);
305+
String healthzUri = servicePath.isEmpty() ? "/healthz" :
306+
servicePath + "/healthz";
307+
if (healthzUri.equals(uri) && "GET".equalsIgnoreCase(method)) {
308+
handleStatuszRequest(response);
299309
return;
300310
}
301311

@@ -2035,19 +2045,62 @@ private void handlePutBlob(HttpServletRequest request,
20352045

20362046
response.addHeader(HttpHeaders.ETAG, maybeQuoteETag(eTag));
20372047
}
2038-
private void handleVersionRequest(HttpServletResponse response) throws IOException {
2048+
2049+
private void handleStatuszRequest(HttpServletResponse response)
2050+
throws IOException {
20392051
response.setStatus(HttpServletResponse.SC_OK);
20402052
response.setContentType("application/json");
2041-
response.setCharacterEncoding("UTF-8");
2042-
2043-
String versionInfo = "{ \"status\": \"OK\"}";
2044-
2053+
response.setCharacterEncoding(UTF_8);
2054+
2055+
var statusBody = ImmutableMap.of("gitHash", STATUS_METADATA.gitHash);
2056+
String versionInfo = JSON_MAPPER.writeValueAsString(statusBody);
2057+
20452058
try (PrintWriter writer = response.getWriter()) {
20462059
writer.write(versionInfo);
20472060
writer.flush();
20482061
}
20492062
}
20502063

2064+
private static final class StatusMetadata {
2065+
private final String version;
2066+
private final String gitHash;
2067+
2068+
private StatusMetadata(String version, String gitHash) {
2069+
this.version = version;
2070+
this.gitHash = gitHash;
2071+
}
2072+
2073+
static StatusMetadata load() {
2074+
Package handlerPackage = S3ProxyHandler.class.getPackage();
2075+
String version = handlerPackage == null ?
2076+
UNKNOWN_VALUE :
2077+
handlerPackage.getImplementationVersion();
2078+
if (Strings.isNullOrEmpty(version)) {
2079+
version = UNKNOWN_VALUE;
2080+
}
2081+
String gitHash = loadGitHash();
2082+
return new StatusMetadata(version, gitHash);
2083+
}
2084+
2085+
private static String loadGitHash() {
2086+
try (InputStream stream = S3ProxyHandler.class.getClassLoader()
2087+
.getResourceAsStream("git.properties")) {
2088+
if (stream == null) {
2089+
return UNKNOWN_VALUE;
2090+
}
2091+
Properties properties = new Properties();
2092+
properties.load(stream);
2093+
return Optional.ofNullable(
2094+
properties.getProperty("git.commit.id.abbrev"))
2095+
.orElseGet(() -> properties.getProperty("git.commit.id",
2096+
UNKNOWN_VALUE));
2097+
} catch (IOException ioe) {
2098+
logger.debug("Unable to load git.properties", ioe);
2099+
return UNKNOWN_VALUE;
2100+
}
2101+
}
2102+
}
2103+
20512104
private void handlePostBlob(HttpServletRequest request,
20522105
HttpServletResponse response, InputStream is, BlobStore blobStore,
20532106
String containerName)

src/test/java/org/gaul/s3proxy/AwsSdkAnonymousTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
import static org.assertj.core.api.Assertions.assertThat;
2020

2121
import java.io.InputStream;
22+
import java.net.HttpURLConnection;
2223
import java.net.URI;
24+
import java.nio.charset.StandardCharsets;
2325
import java.util.Random;
2426

2527
import com.amazonaws.SDKGlobalConfiguration;
@@ -50,6 +52,7 @@ public final class AwsSdkAnonymousTest {
5052
private static final ByteSource BYTE_SOURCE = ByteSource.wrap(new byte[1]);
5153

5254
private URI s3Endpoint;
55+
private URI httpEndpoint;
5356
private EndpointConfiguration s3EndpointConfig;
5457
private S3Proxy s3Proxy;
5558
private BlobStoreContext context;
@@ -66,6 +69,7 @@ public void setUp() throws Exception {
6669
awsCreds = new AnonymousAWSCredentials();
6770
context = info.getBlobStore().getContext();
6871
s3Proxy = info.getS3Proxy();
72+
httpEndpoint = info.getEndpoint();
6973
s3Endpoint = info.getSecureEndpoint();
7074
servicePath = info.getServicePath();
7175
s3EndpointConfig = new EndpointConfiguration(
@@ -128,6 +132,31 @@ public void testAwsV4SignatureChunkedAnonymous() throws Exception {
128132
}
129133
}
130134

135+
@Test
136+
public void testHealthzEndpoint() throws Exception {
137+
URI baseUri = httpEndpoint != null ? httpEndpoint : s3Endpoint;
138+
String path = (servicePath == null ? "" : servicePath) + "/healthz";
139+
URI healthzUri = new URI(baseUri.getScheme(), baseUri.getUserInfo(),
140+
baseUri.getHost(), baseUri.getPort(), path,
141+
baseUri.getQuery(), baseUri.getFragment());
142+
143+
HttpURLConnection connection =
144+
(HttpURLConnection) healthzUri.toURL().openConnection();
145+
connection.setRequestMethod("GET");
146+
147+
assertThat(connection.getResponseCode()).isEqualTo(200);
148+
149+
String body;
150+
try (InputStream stream = connection.getInputStream()) {
151+
body = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
152+
} finally {
153+
connection.disconnect();
154+
}
155+
156+
assertThat(body).contains("\"gitHash\":\"");
157+
assertThat(body).startsWith("{").endsWith("}");
158+
}
159+
131160
private static String createRandomContainerName() {
132161
return "s3proxy-" + new Random().nextInt(Integer.MAX_VALUE);
133162
}

0 commit comments

Comments
 (0)