Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ plugins {

allprojects {
group = 'com.spectralogic.ds3'
version = '5.1.2'
version = '5.1.3'
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.spectralogic.ds3client.networking.Metadata;
import com.spectralogic.ds3client.models.ChecksumType;
import com.google.common.collect.ImmutableMap;
import java.time.ZonedDateTime;
import java.util.UUID;

public class HeadObjectResponse extends AbstractResponse {

Expand All @@ -29,19 +31,25 @@ public enum Status { EXISTS, DOESNTEXIST, UNKNOWN }

private final ChecksumType.Type blobChecksumType;

private final ZonedDateTime creationDate;

private final Metadata metadata;

private final long objectSize;

private final Status status;

public HeadObjectResponse(final ImmutableMap<Long, String> blobChecksums, final ChecksumType.Type blobChecksumType, final Metadata metadata, final long objectSize, final Status status, final String checksum, final ChecksumType.Type checksumType) {
private final UUID versionId;

public HeadObjectResponse(final ImmutableMap<Long, String> blobChecksums, final ChecksumType.Type blobChecksumType, final ZonedDateTime creationDate, final Metadata metadata, final long objectSize, final Status status, final UUID versionId, final String checksum, final ChecksumType.Type checksumType) {
super(checksum, checksumType);
this.blobChecksums = blobChecksums;
this.blobChecksumType = blobChecksumType;
this.creationDate = creationDate;
this.metadata = metadata;
this.objectSize = objectSize;
this.status = status;
this.versionId = versionId;
}

public ImmutableMap<Long, String> getBlobChecksums() {
Expand All @@ -52,6 +60,10 @@ public ChecksumType.Type getBlobChecksumType() {
return this.blobChecksumType;
}

public ZonedDateTime getCreationDate() {
return this.creationDate;
}

public Metadata getMetadata() {
return this.metadata;
}
Expand All @@ -64,4 +76,8 @@ public Status getStatus() {
return this.status;
}

public UUID getVersionId() {
return this.versionId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.spectralogic.ds3client.networking.Metadata;
import com.google.common.collect.ImmutableMap;
import com.spectralogic.ds3client.models.ChecksumType;
import java.time.ZonedDateTime;
import java.util.UUID;
import com.spectralogic.ds3client.commands.HeadObjectResponse;
import com.spectralogic.ds3client.commands.parsers.interfaces.AbstractResponseParser;
import com.spectralogic.ds3client.commands.parsers.utils.ResponseParserUtils;
Expand All @@ -41,10 +43,12 @@ public HeadObjectResponse parseXmlResponse(final WebResponse response) throws IO
case 200:
final ChecksumType.Type blobChecksumType = getBlobChecksumType(response.getHeaders());
final ImmutableMap<Long, String> blobChecksumMap = getBlobChecksumMap(response.getHeaders());
return new HeadObjectResponse(blobChecksumMap, blobChecksumType, metadata, objectSize, HeadObjectResponse.Status.EXISTS, this.getChecksum(), this.getChecksumType());
final ZonedDateTime creationDate = getCreationDate(response.getHeaders());
final UUID versionId = getVersionId(response.getHeaders());
return new HeadObjectResponse(blobChecksumMap, blobChecksumType, creationDate, metadata, objectSize, HeadObjectResponse.Status.EXISTS, versionId, this.getChecksum(), this.getChecksumType());

case 404:
return new HeadObjectResponse(ImmutableMap.of(), ChecksumType.Type.NONE, metadata, objectSize, HeadObjectResponse.Status.DOESNTEXIST, this.getChecksum(), this.getChecksumType());
return new HeadObjectResponse(ImmutableMap.of(), ChecksumType.Type.NONE, null, metadata, objectSize, HeadObjectResponse.Status.DOESNTEXIST, null, this.getChecksum(), this.getChecksumType());

default:
assert false: "validateStatusCode should have made it impossible to reach this line";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.UUID;

public final class ResponseParserUtils {

Expand All @@ -44,6 +46,8 @@ public final class ResponseParserUtils {

private static final String BLOB_CHECKSUM_TYPE_HEADER = "ds3-blob-checksum-type";
private static final String BLOB_CHECKSUM_HEADER = "ds3-blob-checksum-offset-";
private static final String VERSION_ID_HEADER = "version-id";
private static final String CREATION_DATE_HEADER = "creation-date";

private ResponseParserUtils() {
// pass
Expand Down Expand Up @@ -150,6 +154,42 @@ private static String readResponseString(final WebResponse response) throws IOEx
}
}

/**
* Retrieves the version id from the response headers. If there is no version id header,
* then null is returned. This is used in HeadObject response parsing.
* @param headers The http response headers from the BP.
* @return The version id if one exists.
*/
public static UUID getVersionId(final Headers headers) {
final List<String> versions = headers.get(VERSION_ID_HEADER);
switch (versions.size()) {
case 0:
return null;
case 1:
return UUID.fromString(versions.get(0));
default:
throw new IllegalArgumentException(String.format("Response has more than one header value for '%s'", VERSION_ID_HEADER));
}
}

/**
* Retrieves the creation date from the response headers. If there is no creation date header,
* then null is returned. This is used in HeadObject response parsing.
* @param headers The http response headers from the BP.
* @return The creation date if one exists.
*/
public static ZonedDateTime getCreationDate(final Headers headers) {
final List<String> dates = headers.get(CREATION_DATE_HEADER);
switch (dates.size()) {
case 0:
return null;
case 1:
return ZonedDateTime.parse(dates.get(0));
default:
throw new IllegalArgumentException(String.format("Response has more than one header value for '%s'", CREATION_DATE_HEADER));
}
}

/**
* Retrieves the blob checksum type from the response headers. If there is no blob checksum
* type header, than NONE is returned. If there is more than one value for the blob checksum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import java.nio.file.StandardOpenOption;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Month;
import java.time.ZoneId;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -480,13 +482,16 @@ public void createObjectWithNullAndEmptyMetadata() throws IOException, URISyntax

@Test
public void headObjectWithMetadata() throws IOException {
final UUID versionId = UUID.randomUUID();

final Map<String, String> responseHeaders = new HashMap<>();
responseHeaders.put("x-amz-meta-key", "value");
responseHeaders.put("ds3-blob-checksum-type", "MD5");
responseHeaders.put("ds3-blob-checksum-offset-0", "4nQGNX4nyz0pi8Hvap79PQ==");
responseHeaders.put("ds3-blob-checksum-offset-10485760", "965Aa0/n8DlO1IwXYFh4bg==");
responseHeaders.put("ds3-blob-checksum-offset-20971520", "iV2OqJaXJ/jmqgRSb1HmFA==");
responseHeaders.put("creation-date", "2019-07-11T20:35:47.000Z");
responseHeaders.put("version-id", versionId.toString());


final HeadObjectRequest request = new HeadObjectRequest("bucket", "obj");
Expand All @@ -510,6 +515,15 @@ public void headObjectWithMetadata() throws IOException {
assertTrue(response.getBlobChecksums().containsKey(entry.getKey()));
assertThat(response.getBlobChecksums().get(entry.getKey()), is(entry.getValue()));
}

assertThat(response.getVersionId(), is(versionId));
assertThat(response.getCreationDate().getYear(), is(2019));
assertThat(response.getCreationDate().getMonth(), is(Month.JULY));
assertThat(response.getCreationDate().getDayOfMonth(), is(11));
assertThat(response.getCreationDate().getHour(), is(20));
assertThat(response.getCreationDate().getMinute(), is(35));
assertThat(response.getCreationDate().getSecond(), is(47));
assertThat(response.getCreationDate().getZone(), is(ZoneId.of("Z")));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
import com.google.common.collect.ImmutableMap;
import com.spectralogic.ds3client.MockedHeaders;
import com.spectralogic.ds3client.models.ChecksumType;
import com.spectralogic.ds3client.networking.Headers;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.UUID;

import static com.spectralogic.ds3client.commands.parsers.utils.ResponseParserUtils.*;
import static org.hamcrest.CoreMatchers.is;
Expand Down Expand Up @@ -125,4 +128,35 @@ public void getBlobChecksumTypeTest() {
final ChecksumType.Type result = getBlobChecksumType(new MockedHeaders(TEST_RESPONSE_HEADERS));
assertThat(result, is(ChecksumType.Type.MD5));
}

@Test
public void getCreationDateTest() {
final ImmutableMap<String, String> headers = ImmutableMap.of(
"creation-date", "2019-07-11T20:35:47.000Z",
"version-id", "eec64ea6-8434-492f-a068-ef516da801a3"
);

final ZonedDateTime result = getCreationDate(new MockedHeaders(headers));

assertThat(result.getYear(), is(2019));
assertThat(result.getMonth(), is(Month.JULY));
assertThat(result.getDayOfMonth(), is(11));
assertThat(result.getHour(), is(20));
assertThat(result.getMinute(), is(35));
assertThat(result.getSecond(), is(47));
assertThat(result.getZone(), is(ZoneId.of("Z")));
}

@Test
public void getVersionIdTest() {
final UUID versionId = UUID.fromString("eec64ea6-8434-492f-a068-ef516da801a3");

final ImmutableMap<String, String> headers = ImmutableMap.of(
"creation-date", "2019-07-11T20:35:47.000Z",
"version-id", versionId.toString()
);

final UUID result = getVersionId(new MockedHeaders(headers));
assertThat(result, is(versionId));
}
}