use of edu.unc.lib.boxc.deposit.work.JobInterruptedException in project box-c by UNC-Libraries.
the class IngestContentObjectsJob method addFileToWork.
/**
* Ingests the object represented by childResc as a FileObject as the child
* of the given WorkObject, with the file properties provided with
* childResc.
*
* @param work
* @param childResc
* if true, then acl and other properties from the child resource
* will be added to the file object's aip
* @return
* @throws DepositException
*/
private FileObject addFileToWork(WorkObject work, Resource childResc) throws DepositException {
log.debug("Adding file {} to work {}", childResc, work.getPid());
PID childPid = PIDs.get(childResc.getURI());
Resource originalResc = DepositModelHelpers.getDatastream(childResc);
String storageString = originalResc != null ? getPropertyValue(originalResc, CdrDeposit.storageUri) : null;
if (storageString == null) {
// throw exception, child must be a file with a staging path
throw new DepositException("No staging location provided for child (" + childResc.getURI() + ") of Work object (" + work.getPid().getQualifiedId() + ")");
}
URI storageUri = URI.create(storageString);
// Pull out file properties if they are present
String mimetype = getPropertyValue(originalResc, CdrDeposit.mimetype);
String sha1 = getPropertyValue(originalResc, CdrDeposit.sha1sum);
String md5 = getPropertyValue(originalResc, CdrDeposit.md5sum);
// Label comes from file object if not set for binary
String label = getPropertyValue(originalResc, CdrDeposit.label);
if (label == null) {
label = getPropertyValue(childResc, CdrDeposit.label);
}
// Construct a model to store properties about this new fileObject
Model aipModel = ModelFactory.createDefaultModel();
Resource aResc = aipModel.getResource(childResc.getURI());
addAclProperties(childResc, aResc);
populateAIPProperties(childResc, aResc);
// Add the file to the work as the datafile of its own FileObject
FileObject fileObj = null;
// Retry if there are checksum failures
for (int retryCnt = 1; retryCnt <= CHECKSUM_RETRIES; retryCnt++) {
try {
fileObj = work.addDataFile(childPid, storageUri, label, mimetype, sha1, md5, aipModel);
break;
} catch (ChecksumMismatchException e) {
if ((CHECKSUM_RETRIES - retryCnt) > 0) {
log.warn("Failed to ingest file {} due to a checksum mismatch, {} retries remaining: {}", childPid.getQualifiedId(), CHECKSUM_RETRIES - retryCnt, e.getMessage());
try {
Thread.sleep(retryCnt * 1000);
} catch (InterruptedException ef) {
throw new JobInterruptedException(e.getMessage());
}
} else {
failJob("Unable to ingest " + childPid.getQualifiedId(), e.getMessage());
}
}
}
// Record the size of the file for throughput stats
if (storageUri.getScheme().equals("file")) {
metricsClient.incrDepositFileThroughput(getDepositUUID(), Paths.get(storageUri).toFile().length());
}
// Add the FITS report for this file
addFitsHistory(fileObj, childResc);
addFitsReport(fileObj, childResc);
return fileObj;
}
use of edu.unc.lib.boxc.deposit.work.JobInterruptedException in project box-c by UNC-Libraries.
the class IngestContentObjectsJobIT method interruptTest.
@Test
public void interruptTest() throws Exception {
String label = "testwork";
// Construct the deposit model with work object
Model model = job.getWritableModel();
Bag depBag = model.createBag(depositPid.getRepositoryPath());
PID folderObj1Pid = pidMinter.mintContentPid();
Bag folder1Bag = model.createBag(folderObj1Pid.getRepositoryPath());
folder1Bag.addProperty(RDF.type, Cdr.Folder);
depBag.add(folder1Bag);
// Constructing the work in the deposit model with a label
PID workPid = pidMinter.mintContentPid();
Bag workBag = model.createBag(workPid.getRepositoryPath());
workBag.addProperty(RDF.type, Cdr.Work);
workBag.addProperty(CdrDeposit.label, label);
PID mainPid = addFileObject(workBag, FILE1_LOC, FILE1_MIMETYPE, FILE1_SHA1, FILE1_MD5);
folder1Bag.add(workBag);
workBag.asResource().addProperty(Cdr.primaryObject, model.getResource(mainPid.getRepositoryPath()));
job.closeModel();
AtomicBoolean gotJobInterrupted = new AtomicBoolean(false);
AtomicReference<Exception> otherException = new AtomicReference<>();
Thread thread = new Thread(() -> {
try {
job.run();
} catch (JobInterruptedException e) {
gotJobInterrupted.set(true);
} catch (Exception e) {
otherException.set(e);
}
});
thread.start();
// Wait random amount of time and then interrupt thread if still alive
Thread.sleep(50 + (long) new Random().nextFloat() * 600);
if (thread.isAlive()) {
thread.interrupt();
thread.join();
if (gotJobInterrupted.get()) {
// success
} else {
if (otherException.get() != null) {
throw otherException.get();
}
}
} else {
log.warn("Job completed before interruption");
}
}
use of edu.unc.lib.boxc.deposit.work.JobInterruptedException in project box-c by UNC-Libraries.
the class TransferBinariesToStorageJobTest method interruptionTest.
// Ensure that interruptions come through as JobInterruptedExceptions
@Test
public void interruptionTest() throws Exception {
Bag workBag = addContainerObject(depBag, Cdr.Work);
Resource fileResc = addFileObject(workBag, FILE_CONTENT1, true);
workBag.addProperty(Cdr.primaryObject, fileResc);
Bag workBag1 = addContainerObject(depBag, Cdr.Work);
Resource fileResc1 = addFileObject(workBag1, FILE_CONTENT1, true);
workBag1.addProperty(Cdr.primaryObject, fileResc1);
job.closeModel();
AtomicBoolean gotJobInterrupted = new AtomicBoolean(false);
AtomicReference<Exception> otherException = new AtomicReference<>();
Thread thread = new Thread(() -> {
try {
job.run();
} catch (JobInterruptedException e) {
gotJobInterrupted.set(true);
} catch (Exception e) {
otherException.set(e);
}
});
thread.start();
// Wait random amount of time and then interrupt thread if still alive
Thread.sleep((long) new Random().nextFloat() * 20);
if (thread.isAlive()) {
thread.interrupt();
thread.join();
if (gotJobInterrupted.get()) {
// success
} else {
if (otherException.get() != null) {
throw otherException.get();
}
}
} else {
log.warn("Job completed before interruption");
}
}
use of edu.unc.lib.boxc.deposit.work.JobInterruptedException in project box-c by UNC-Libraries.
the class IngestContentObjectsJobTest method pauseAndResumeTest.
@Test
public void pauseAndResumeTest() throws Exception {
PID workPid = makePid(RepositoryPathConstants.CONTENT_BASE);
WorkObject work = mock(WorkObject.class);
Bag workBag = setupWork(workPid, work);
String mainLoc = "pdf.pdf";
String mainMime = "application/pdf";
PID mainPid = addFileObject(workBag, mainLoc, mainMime);
workBag.addProperty(Cdr.primaryObject, model.getResource(mainPid.getRepositoryPath()));
job.closeModel();
when(work.addDataFile(any(PID.class), any(URI.class), anyString(), anyString(), anyString(), anyString(), any(Model.class))).thenReturn(mockFileObj);
when(mockFileObj.getPid()).thenReturn(mainPid);
when(repoObjLoader.getWorkObject(eq(workPid))).thenReturn(work);
when(depositStatusFactory.getState(depositUUID)).thenReturn(DepositState.running).thenReturn(DepositState.running).thenReturn(DepositState.paused);
try {
job.run();
fail("Job must be interrupted due to pausing");
} catch (JobInterruptedException e) {
// expected
}
when(depositStatusFactory.getState(depositUUID)).thenReturn(DepositState.running);
job.run();
verify(repoObjFactory, times(2)).createWorkObject(eq(workPid), any(Model.class));
verify(destinationObj, times(2)).addMember(eq(work));
verify(work).addDataFile(eq(mainPid), any(URI.class), eq(mainLoc), eq(mainMime), anyString(), anyString(), any(Model.class));
verify(work).setPrimaryObject(mainPid);
verify(jobStatusFactory, times(2)).setTotalCompletion(eq(jobUUID), eq(2));
}
use of edu.unc.lib.boxc.deposit.work.JobInterruptedException in project box-c by UNC-Libraries.
the class IngestDepositRecordJobIT method interruptTest.
@Test
public void interruptTest() throws Exception {
depositStatusFactory.set(depositUUID, DepositField.packagingType, PackagingType.BAGIT.getUri());
depositStatusFactory.set(depositUUID, DepositField.packageProfile, "no profile");
depositStatusFactory.set(depositUUID, DepositField.depositorName, DEPOSITOR_NAME);
Model model = job.getWritableModel();
Bag depBag = model.createBag(depositPid.getRepositoryPath());
String manifestFilename1 = "manifest-md5.txt";
addManifest(model, depBag, manifestFilename1, "text/special", MANIFEST_BODY1, true, true);
String manifestFilename2 = "bagit.txt";
addManifest(model, depBag, manifestFilename2, null, MANIFEST_BODY2, true, false);
job.closeModel();
AtomicBoolean gotJobInterrupted = new AtomicBoolean(false);
AtomicReference<Exception> otherException = new AtomicReference<>();
Thread thread = new Thread(() -> {
try {
job.run();
} catch (JobInterruptedException e) {
gotJobInterrupted.set(true);
} catch (Exception e) {
otherException.set(e);
}
});
thread.start();
// Wait random amount of time and then interrupt thread if still alive
Thread.sleep(50 + (long) new Random().nextFloat() * 600);
if (thread.isAlive()) {
thread.interrupt();
thread.join();
if (gotJobInterrupted.get()) {
// success
} else {
if (otherException.get() != null) {
throw otherException.get();
}
}
} else {
log.warn("Job completed before interruption");
}
}
Aggregations