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
1 change: 1 addition & 0 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ dependencies {
compile 'org.codehaus.woodstox:woodstox-core-asl:4.2.0'
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.2.3'
compile 'com.google.guava:guava:16.0.1'
compile 'org.hamcrest:hamcrest-library:1.3'
}
6 changes: 6 additions & 0 deletions sdk/src/main/java/com/spectralogic/ds3client/Ds3Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.spectralogic.ds3client;

import com.spectralogic.ds3client.commands.*;
import com.spectralogic.ds3client.models.bulk.Node;

import java.io.IOException;
import java.security.SignatureException;
Expand Down Expand Up @@ -236,4 +237,9 @@ public abstract CancelJobResponse cancelJob(CancelJobRequest request)
*/
public abstract ModifyJobResponse modifyJob(ModifyJobRequest request)
throws IOException, SignatureException;

/**
* Creates a factory based on a set of nodes that can return clients by node id.
*/
public abstract Ds3ClientFactory buildFactory(Iterable<Node> nodes);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@
* ****************************************************************************
*/

package com.spectralogic.ds3client.helpers;

import com.spectralogic.ds3client.Ds3Client;
package com.spectralogic.ds3client;

import java.util.UUID;

interface Ds3ClientFactory {
public interface Ds3ClientFactory {
Ds3Client getClientForNodeId(UUID nodeId);
}
13 changes: 13 additions & 0 deletions sdk/src/main/java/com/spectralogic/ds3client/Ds3ClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package com.spectralogic.ds3client;

import com.spectralogic.ds3client.commands.*;
import com.spectralogic.ds3client.models.bulk.Node;
import com.spectralogic.ds3client.networking.NetworkClient;

import java.io.IOException;
import java.security.SignatureException;
import java.util.UUID;

class Ds3ClientImpl implements Ds3Client {
private final NetworkClient netClient;
Expand Down Expand Up @@ -115,4 +117,15 @@ public CancelJobResponse cancelJob(final CancelJobRequest request) throws IOExce
public ModifyJobResponse modifyJob(final ModifyJobRequest request) throws IOException, SignatureException {
return new ModifyJobResponse(this.netClient.getResponse(request));
}

@Override
public Ds3ClientFactory buildFactory(final Iterable<Node> nodes) {
return new Ds3ClientFactory() {
@Override
public Ds3Client getClientForNodeId(final UUID nodeId) {
//TODO: pay attention to actual nodes.
return Ds3ClientImpl.this;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,4 @@ private String readResponseString() throws IOException {
public String getMd5() {
return md5;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class AllocateJobChunkResponse extends AbstractResponse {
private int retryAfterSeconds;

static public enum Status {
ALLOCATED, RETRYLATER, NOTFOUND
ALLOCATED, RETRYLATER
}

public AllocateJobChunkResponse(final WebResponse response) throws IOException {
Expand All @@ -53,7 +53,7 @@ public int getRetryAfterSeconds() {
@Override
protected void processResponse() throws IOException {
try (final WebResponse response = this.getResponse()) {
checkStatusCode(200, 503, 404);
checkStatusCode(200, 503);
switch (this.getStatusCode()) {
case 200:
this.status = Status.ALLOCATED;
Expand All @@ -63,9 +63,6 @@ protected void processResponse() throws IOException {
this.status = Status.RETRYLATER;
this.retryAfterSeconds = parseRetryAfter(response);
break;
case 404:
this.status = Status.NOTFOUND;
break;
default:
assert false : "checkStatusCode should have made it impossible to reach this line.";
}
Expand All @@ -80,7 +77,11 @@ private static Objects parseChunk(final WebResponse webResponse) throws IOExcept
}
}

private static int parseRetryAfter(final WebResponse response) {
return Integer.parseInt(response.getHeaders().get("Retry-After"));
private static int parseRetryAfter(final WebResponse webResponse) {
final String retryAfter = webResponse.getHeaders().get("Retry-After");
if (retryAfter == null) {
throw new RetryAfterExpectedException();
}
return Integer.parseInt(retryAfter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.spectralogic.ds3client.commands;

import com.spectralogic.ds3client.BulkCommand;
import com.spectralogic.ds3client.models.bulk.ChunkClientProcessingOrderGuarantee;
import com.spectralogic.ds3client.models.bulk.Ds3Object;
import com.spectralogic.ds3client.models.bulk.Priority;
import com.spectralogic.ds3client.models.bulk.WriteOptimization;
Expand All @@ -40,6 +41,15 @@ public BulkGetRequest withWriteOptimization(final WriteOptimization writeOptimiz
super.withWriteOptimization(writeOptimization);
return this;
}

public BulkGetRequest withChunkOrdering(final ChunkClientProcessingOrderGuarantee chunkOrdering) {
this.chunkOrdering = chunkOrdering;
return this;
}

public ChunkClientProcessingOrderGuarantee getChunkOrdering() {
return this.chunkOrdering;
}

@Override
public BulkCommand getCommand() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@

import com.spectralogic.ds3client.BulkCommand;
import com.spectralogic.ds3client.HttpVerb;
import com.spectralogic.ds3client.models.bulk.Ds3Object;
import com.spectralogic.ds3client.models.bulk.Ds3ObjectList;
import com.spectralogic.ds3client.models.bulk.Priority;
import com.spectralogic.ds3client.models.bulk.WriteOptimization;
import com.spectralogic.ds3client.models.bulk.*;
import com.spectralogic.ds3client.serializer.XmlOutput;

import java.io.ByteArrayInputStream;
Expand All @@ -35,6 +32,7 @@ abstract class BulkRequest extends AbstractRequest {
private long size;
private Priority priority;
private WriteOptimization writeOptimization;
protected ChunkClientProcessingOrderGuarantee chunkOrdering;

public BulkRequest(final String bucket, final List<Ds3Object> objects) {
this.bucket = bucket;
Expand All @@ -57,6 +55,7 @@ private InputStream generateStream() {
objects.setObjects(this.ds3Objects);
objects.setPriority(this.priority);
objects.setWriteOptimization(this.writeOptimization);
objects.setChunkClientProcessingOrderGuarantee(this.chunkOrdering);
final String xmlOutput = XmlOutput.toXml(objects, this.getCommand());

final byte[] stringBytes = xmlOutput.getBytes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class GetAvailableJobChunksResponse extends AbstractResponse {
private int retryAfterSeconds;

static public enum Status {
AVAILABLE, RETRYLATER, NOTFOUND
AVAILABLE, RETRYLATER
}

public Status getStatus() {
Expand All @@ -53,7 +53,7 @@ public GetAvailableJobChunksResponse(final WebResponse response) throws IOExcept
@Override
protected void processResponse() throws IOException {
try (final WebResponse webResponse = this.getResponse()) {
this.checkStatusCode(200, 404);
this.checkStatusCode(200);
switch (this.getStatusCode()) {
case 200:
this.masterObjectList = parseMasterObjectList(webResponse);
Expand All @@ -64,9 +64,6 @@ protected void processResponse() throws IOException {
this.status = Status.AVAILABLE;
}
break;
case 404:
this.status = Status.NOTFOUND;
break;
default:
assert false : "checkStatusCode should have made it impossible to reach this line.";
}
Expand All @@ -82,6 +79,10 @@ private static MasterObjectList parseMasterObjectList(final WebResponse webRespo
}

private static int parseRetryAfter(final WebResponse webResponse) {
return Integer.parseInt(webResponse.getHeaders().get("Retry-After"));
final String retryAfter = webResponse.getHeaders().get("Retry-After");
if (retryAfter == null) {
throw new RetryAfterExpectedException();
}
return Integer.parseInt(retryAfter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* ******************************************************************************
* Copyright 2014 Spectra Logic Corporation. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file.
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
* ****************************************************************************
*/

package com.spectralogic.ds3client.commands;

public class RetryAfterExpectedException extends RuntimeException {
private static final long serialVersionUID = 6193215224073981762L;

public RetryAfterExpectedException() {
super("Based on the response the server should have returned a Retry-After HTTP header.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* ******************************************************************************
* Copyright 2014 Spectra Logic Corporation. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file.
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
* ****************************************************************************
*/

package com.spectralogic.ds3client.helpers;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

class AutoCloseableCache<Key, Value extends AutoCloseable> implements AutoCloseable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why AutoCloseable instead of Closeable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutoCloseable throws Exception, while Closeable throws IOException. I thought I'd make it a more generic class.

private final ValueBuilder<Key, Value> valueBuilder;
private final Set<Key> closedKeys = new HashSet<>();
private Map<Key, Value> values = new HashMap<>();

public interface ValueBuilder<Key, Value extends AutoCloseable> {
Value get(final Key key);
}

public AutoCloseableCache(final ValueBuilder<Key, Value> valueBuilder) {
this.valueBuilder = valueBuilder;
}

public synchronized Value get(final Key key) {
if (this.values == null) {
throw new IllegalStateException("Cache already closed.");
}
if (this.closedKeys.contains(key)) {
throw new IllegalStateException("Cache has already closed the requested key.");
}
Value value = this.values.get(key);
if (value == null) {
value = this.valueBuilder.get(key);
this.values.put(key, value);
}
return value;
}

public synchronized void close(final Key key) throws Exception {
if (this.values == null) {
throw new IllegalStateException("Cache already closed.");
}
final Value value = this.values.remove(key);
if (value != null) {
value.close();
}
this.closedKeys.add(key);
}

@Override
public synchronized void close() throws Exception {
if (this.values != null) {
for (final Value value : this.values.values()) {
value.close();
}
this.values = null;
}
}
}
Loading