Skip to content

Commit cf58378

Browse files
authored
Merge pull request #356 from GraciesPadre/read_retry
Implementing read retries
2 parents d395bb8 + c195f39 commit cf58378

File tree

10 files changed

+340859
-340653
lines changed

10 files changed

+340859
-340653
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.txt text
2+

ds3-sdk-integration/src/test/java/com/spectralogic/ds3client/integration/GetJobManagement_Test.java

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,50 @@
1717

1818
import com.google.common.collect.Lists;
1919
import com.spectralogic.ds3client.Ds3Client;
20+
import com.spectralogic.ds3client.Ds3ClientImpl;
2021
import com.spectralogic.ds3client.commands.GetObjectRequest;
2122
import com.spectralogic.ds3client.commands.GetObjectResponse;
2223
import com.spectralogic.ds3client.commands.PutObjectRequest;
2324
import com.spectralogic.ds3client.commands.spectrads3.GetJobSpectraS3Request;
2425
import com.spectralogic.ds3client.commands.spectrads3.GetJobSpectraS3Response;
2526
import com.spectralogic.ds3client.helpers.Ds3ClientHelpers;
27+
import com.spectralogic.ds3client.helpers.FileObjectGetter;
28+
import com.spectralogic.ds3client.helpers.FileObjectPutter;
2629
import com.spectralogic.ds3client.helpers.options.ReadJobOptions;
2730
import com.spectralogic.ds3client.integration.test.helpers.ABMTestHelper;
31+
import com.spectralogic.ds3client.integration.test.helpers.Ds3ClientShim;
2832
import com.spectralogic.ds3client.integration.test.helpers.TempStorageIds;
2933
import com.spectralogic.ds3client.integration.test.helpers.TempStorageUtil;
3034
import com.spectralogic.ds3client.models.ChecksumType;
3135
import com.spectralogic.ds3client.models.Priority;
3236
import com.spectralogic.ds3client.models.bulk.Ds3Object;
37+
import com.spectralogic.ds3client.models.bulk.PartialDs3Object;
38+
import com.spectralogic.ds3client.models.common.Range;
3339
import com.spectralogic.ds3client.utils.ResourceUtils;
40+
import org.apache.commons.io.FileUtils;
3441
import org.junit.AfterClass;
3542
import org.junit.BeforeClass;
3643
import org.junit.Test;
3744
import org.slf4j.Logger;
3845
import org.slf4j.LoggerFactory;
3946

47+
import java.io.File;
4048
import java.io.IOException;
49+
import java.io.InputStream;
50+
import java.lang.reflect.InvocationTargetException;
4151
import java.net.URISyntaxException;
4252
import java.nio.channels.SeekableByteChannel;
4353
import java.nio.channels.WritableByteChannel;
4454
import java.nio.file.Files;
4555
import java.nio.file.Path;
46-
import java.util.UUID;
56+
import java.nio.file.Paths;
57+
import java.util.*;
4758

4859
import static com.spectralogic.ds3client.integration.Util.RESOURCE_BASE_NAME;
4960
import static com.spectralogic.ds3client.integration.Util.deleteAllContents;
5061
import static org.hamcrest.Matchers.is;
5162
import static org.junit.Assert.assertThat;
63+
import static org.junit.Assert.assertTrue;
5264

5365
public class GetJobManagement_Test {
5466

@@ -128,6 +140,75 @@ public void createReadJob() throws IOException, InterruptedException, URISyntaxE
128140
assertThat(jobSpectraS3Response.getStatusCode(), is(200));
129141
}
130142

143+
@Test
144+
public void createReadJobWithBigFile() throws IOException, URISyntaxException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
145+
putBigFile();
146+
147+
final String tempPathPrefix = null;
148+
final Path tempDirectory = Files.createTempDirectory(Paths.get("."), tempPathPrefix);
149+
150+
try {
151+
final String DIR_NAME = "largeFiles/";
152+
final String FILE_NAME = "lesmis-copies.txt";
153+
154+
final Path objPath = ResourceUtils.loadFileResource(DIR_NAME + FILE_NAME);
155+
final long bookSize = Files.size(objPath);
156+
final Ds3Object obj = new Ds3Object(FILE_NAME, bookSize);
157+
158+
final Ds3ClientShim ds3ClientShim = new Ds3ClientShim((Ds3ClientImpl)client);
159+
160+
final int maxNumBlockAllocationRetries = 1;
161+
final int maxNumObjectTransferAttempts = 3;
162+
final Ds3ClientHelpers ds3ClientHelpers = Ds3ClientHelpers.wrap(ds3ClientShim,
163+
maxNumBlockAllocationRetries,
164+
maxNumObjectTransferAttempts);
165+
166+
final Ds3ClientHelpers.Job readJob = ds3ClientHelpers.startReadJob(BUCKET_NAME, Arrays.asList(obj));
167+
168+
final GetJobSpectraS3Response jobSpectraS3Response = ds3ClientShim
169+
.getJobSpectraS3(new GetJobSpectraS3Request(readJob.getJobId()));
170+
171+
assertThat(jobSpectraS3Response.getStatusCode(), is(200));
172+
173+
readJob.transfer(new FileObjectGetter(tempDirectory));
174+
175+
final File originalFile = ResourceUtils.loadFileResource(DIR_NAME + FILE_NAME).toFile();
176+
final File fileCopiedFromBP = Paths.get(tempDirectory.toString(), FILE_NAME).toFile();
177+
assertTrue(FileUtils.contentEquals(originalFile, fileCopiedFromBP));
178+
179+
} finally {
180+
FileUtils.deleteDirectory(tempDirectory.toFile());
181+
}
182+
}
183+
184+
private void putBigFile() throws IOException, URISyntaxException {
185+
final String DIR_NAME = "largeFiles/";
186+
final String[] FILE_NAMES = new String[] { "lesmis-copies.txt" };
187+
188+
final Path dirPath = ResourceUtils.loadFileResource(DIR_NAME);
189+
190+
final List<String> bookTitles = new ArrayList<>();
191+
final List<Ds3Object> objects = new ArrayList<>();
192+
for (final String book : FILE_NAMES) {
193+
final Path objPath = ResourceUtils.loadFileResource(DIR_NAME + book);
194+
final long bookSize = Files.size(objPath);
195+
final Ds3Object obj = new Ds3Object(book, bookSize);
196+
197+
bookTitles.add(book);
198+
objects.add(obj);
199+
}
200+
201+
final int maxNumBlockAllocationRetries = 1;
202+
final int maxNumObjectTransferAttempts = 3;
203+
final Ds3ClientHelpers ds3ClientHelpers = Ds3ClientHelpers.wrap(client,
204+
maxNumBlockAllocationRetries,
205+
maxNumObjectTransferAttempts);
206+
207+
final Ds3ClientHelpers.Job writeJob = ds3ClientHelpers.startWriteJob(BUCKET_NAME, objects);
208+
writeJob.transfer(new FileObjectPutter(dirPath));
209+
}
210+
211+
131212
@Test
132213
public void createReadJobWithPriorityOption() throws IOException,
133214
InterruptedException, URISyntaxException {
@@ -165,4 +246,53 @@ public void createReadJobWithNameAndPriorityOptions() throws IOException,
165246
assertThat(jobSpectraS3Response.getMasterObjectListResult().getName(), is("test_job"));
166247
assertThat(jobSpectraS3Response.getMasterObjectListResult().getPriority(), is(Priority.LOW));
167248
}
168-
}
249+
250+
@Test
251+
public void testPartialRetriesWithInjectedFailures() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, IOException, URISyntaxException {
252+
putBigFile();
253+
254+
final String tempPathPrefix = null;
255+
final Path tempDirectory = Files.createTempDirectory(Paths.get("."), tempPathPrefix);
256+
257+
try {
258+
final List<Ds3Object> filesToGet = new ArrayList<>();
259+
260+
final String DIR_NAME = "largeFiles/";
261+
final String FILE_NAME = "lesmis-copies.txt";
262+
263+
filesToGet.add(new PartialDs3Object(FILE_NAME, Range.byLength(0, 100)));
264+
265+
filesToGet.add(new PartialDs3Object(FILE_NAME, Range.byLength(100, 100)));
266+
267+
final Ds3ClientShim ds3ClientShim = new Ds3ClientShim((Ds3ClientImpl) client);
268+
269+
final int maxNumBlockAllocationRetries = 1;
270+
final int maxNumObjectTransferAttempts = 3;
271+
final Ds3ClientHelpers ds3ClientHelpers = Ds3ClientHelpers.wrap(ds3ClientShim,
272+
maxNumBlockAllocationRetries,
273+
maxNumObjectTransferAttempts);
274+
275+
final Ds3ClientHelpers.Job job = ds3ClientHelpers.startReadJob(BUCKET_NAME, filesToGet);
276+
277+
job.transfer(new FileObjectGetter(tempDirectory));
278+
279+
try (final InputStream originalFileStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(DIR_NAME + FILE_NAME)) {
280+
final byte[] first200Bytes = new byte[200];
281+
int numBytesRead = originalFileStream.read(first200Bytes, 0, 200);
282+
283+
assertThat(numBytesRead, is(200));
284+
285+
try (final InputStream fileReadFromBP = Files.newInputStream(Paths.get(tempDirectory.toString(), FILE_NAME))) {
286+
final byte[] first200BytesFromBP = new byte[200];
287+
288+
numBytesRead = fileReadFromBP.read(first200BytesFromBP, 0, 200);
289+
assertThat(numBytesRead, is(200));
290+
291+
assertTrue(Arrays.equals(first200Bytes, first200BytesFromBP));
292+
}
293+
}
294+
} finally {
295+
FileUtils.deleteDirectory(tempDirectory.toFile());
296+
}
297+
}
298+
}

ds3-sdk-integration/src/test/java/com/spectralogic/ds3client/integration/PutJobManagement_Test.java

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@
3232
import com.spectralogic.ds3client.integration.test.helpers.TempStorageUtil;
3333
import com.spectralogic.ds3client.models.*;
3434
import com.spectralogic.ds3client.models.bulk.Ds3Object;
35-
import com.spectralogic.ds3client.networking.ConnectionDetails;
3635
import com.spectralogic.ds3client.networking.FailedRequestException;
37-
import com.spectralogic.ds3client.networking.NetworkClient;
38-
import com.spectralogic.ds3client.networking.NetworkClientImpl;
3936
import com.spectralogic.ds3client.utils.ByteArraySeekableByteChannel;
4037
import com.spectralogic.ds3client.utils.ResourceUtils;
4138
import org.apache.commons.io.FileUtils;
@@ -45,7 +42,6 @@
4542
import java.io.File;
4643
import java.io.IOException;
4744
import java.lang.reflect.InvocationTargetException;
48-
import java.lang.reflect.Method;
4945
import java.net.URISyntaxException;
5046
import java.nio.ByteBuffer;
5147
import java.nio.channels.SeekableByteChannel;
@@ -56,6 +52,7 @@
5652
import java.util.Date;
5753
import java.util.List;
5854
import java.util.UUID;
55+
import com.spectralogic.ds3client.integration.test.helpers.Ds3ClientShim;
5956

6057
import static com.spectralogic.ds3client.integration.Util.RESOURCE_BASE_NAME;
6158
import static com.spectralogic.ds3client.integration.Util.deleteAllContents;
@@ -907,53 +904,6 @@ public void objectCompleted(final String name) {
907904
}
908905
}
909906

910-
private static class Ds3ClientShim extends Ds3ClientImpl {
911-
private static Method getNetClientMethod = null;
912-
913-
int numRetries = 0;
914-
915-
static {
916-
try {
917-
getNetClientMethod = Ds3ClientImpl.class.getDeclaredMethod("getNetClient");
918-
} catch (final NoSuchMethodException e) {
919-
fail("Could not find Ds3ClientImpl method getNetClient.");
920-
}
921-
922-
getNetClientMethod.setAccessible(true);
923-
}
924-
925-
public Ds3ClientShim(final NetworkClient netClient) {
926-
super(netClient);
927-
}
928-
929-
public Ds3ClientShim(final Ds3ClientImpl ds3ClientImpl) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
930-
this((NetworkClient)getNetClientMethod.invoke(ds3ClientImpl));
931-
}
932-
933-
@Override
934-
public PutObjectResponse putObject(final PutObjectRequest request) throws IOException {
935-
if(numRetries++ >= 1) {
936-
return super.putObject(request);
937-
}
938-
939-
throw new Ds3NoMoreRetriesException(1);
940-
}
941-
942-
@Override
943-
public Ds3Client newForNode(final JobNode node) {
944-
final ConnectionDetails newConnectionDetails;
945-
try {
946-
newConnectionDetails = ((NetworkClient)getNetClientMethod.invoke(this)).getConnectionDetails();
947-
final NetworkClient newNetClient = new NetworkClientImpl(newConnectionDetails);
948-
return new Ds3ClientShim(newNetClient);
949-
} catch (final IllegalAccessException | InvocationTargetException e) {
950-
fail("Failure trying to create Ds3Client used in verifying putObject retries: " + e.getMessage());
951-
}
952-
953-
return null;
954-
}
955-
}
956-
957907
private interface ObjectTransferExceptionHandler {
958908
boolean handleException(final Throwable t);
959909
}
@@ -975,4 +925,4 @@ public boolean handleException(final Throwable t) {
975925
}
976926
});
977927
}
978-
}
928+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* ****************************************************************************
3+
* Copyright 2014-2016 Spectra Logic Corporation. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
5+
* this file except in compliance with the License. A copy of the License is located at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* or in the "license" file accompanying this file.
10+
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
* specific language governing permissions and limitations under the License.
13+
* ****************************************************************************
14+
*/
15+
16+
package com.spectralogic.ds3client.integration.test.helpers;
17+
18+
import com.spectralogic.ds3client.Ds3Client;
19+
import com.spectralogic.ds3client.Ds3ClientImpl;
20+
import com.spectralogic.ds3client.commands.GetObjectRequest;
21+
import com.spectralogic.ds3client.commands.GetObjectResponse;
22+
import com.spectralogic.ds3client.commands.PutObjectRequest;
23+
import com.spectralogic.ds3client.commands.PutObjectResponse;
24+
import com.spectralogic.ds3client.exceptions.Ds3NoMoreRetriesException;
25+
import com.spectralogic.ds3client.models.JobNode;
26+
import com.spectralogic.ds3client.networking.ConnectionDetails;
27+
import com.spectralogic.ds3client.networking.NetworkClient;
28+
import com.spectralogic.ds3client.networking.NetworkClientImpl;
29+
30+
import java.io.IOException;
31+
import java.lang.reflect.InvocationTargetException;
32+
import java.lang.reflect.Method;
33+
34+
import static org.junit.Assert.fail;
35+
36+
public class Ds3ClientShim extends Ds3ClientImpl {
37+
private static Method getNetClientMethod = null;
38+
39+
int numRetries = 0;
40+
41+
static {
42+
try {
43+
getNetClientMethod = Ds3ClientImpl.class.getDeclaredMethod("getNetClient");
44+
} catch (final NoSuchMethodException e) {
45+
fail("Could not find Ds3ClientImpl method getNetClient.");
46+
}
47+
48+
getNetClientMethod.setAccessible(true);
49+
}
50+
51+
public Ds3ClientShim(final NetworkClient netClient) {
52+
super(netClient);
53+
}
54+
55+
public Ds3ClientShim(final Ds3ClientImpl ds3ClientImpl) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
56+
this((NetworkClient)getNetClientMethod.invoke(ds3ClientImpl));
57+
}
58+
59+
@Override
60+
public PutObjectResponse putObject(final PutObjectRequest request) throws IOException {
61+
if (numRetries++ >= 1) {
62+
return super.putObject(request);
63+
}
64+
65+
throw new Ds3NoMoreRetriesException(1);
66+
}
67+
68+
@Override
69+
public GetObjectResponse getObject(final GetObjectRequest request) throws IOException {
70+
if (numRetries++ >= 1) {
71+
return super.getObject(request);
72+
}
73+
74+
throw new Ds3NoMoreRetriesException(1);
75+
}
76+
77+
@Override
78+
public Ds3Client newForNode(final JobNode node) {
79+
final ConnectionDetails newConnectionDetails;
80+
try {
81+
newConnectionDetails = ((NetworkClient)getNetClientMethod.invoke(this)).getConnectionDetails();
82+
final NetworkClient newNetClient = new NetworkClientImpl(newConnectionDetails);
83+
return new Ds3ClientShim(newNetClient);
84+
} catch (final IllegalAccessException | InvocationTargetException e) {
85+
fail("Failure trying to create Ds3Client used in verifying putObject retries: " + e.getMessage());
86+
}
87+
88+
return null;
89+
}
90+
}

0 commit comments

Comments
 (0)