/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.tasks.test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
import divconq.hub.Hub;
import divconq.lang.op.OperationContext;
import divconq.struct.FieldStruct;
import divconq.struct.RecordStruct;
import divconq.util.HexUtil;
import divconq.util.StringUtil;
import divconq.work.IWork;
import divconq.work.TaskRun;
public class AsyncHashWork implements IWork {
@Override
public void run(final TaskRun run) {
run.info(0, "AsyncHashTask at running in thread: " + Thread.currentThread().getName());
RecordStruct params = run.getTask().getParams();
if (params == null) {
run.error(1, "Unable to Greet, missing params structure.");
run.complete();
return;
}
String name = params.getFieldAsString("Path");
if (StringUtil.isEmpty(name)) {
run.error(1, "Unable to Greet, missing Path param.");
run.complete();
return;
}
final Path path = Paths.get(name);
final ByteBuffer buf = ByteBuffer.allocate(64 * 1024);
AsynchronousFileChannel sbc = null;
try {
Set<OpenOption> opts = new HashSet<>();
opts.add(StandardOpenOption.READ);
sbc = AsynchronousFileChannel.open(path, opts, Hub.instance.getWorkPool());
}
catch (IOException x) {
run.error(1, "Unable to open file: " + x);
}
sbc.read(buf, 0, sbc, new CompletionHandler<Integer, AsynchronousFileChannel>() {
protected MessageDigest md = null;
protected int pos = 0;
@Override
public void completed(Integer result, AsynchronousFileChannel sbc) {
run.info(0, "A) AsyncHashTask completed after read in context: " + OperationContext.get().getOpId());
// TODO review what is intended and rework
//run.thawContext();
run.info(0, "B) AsyncHashTask completed after read in context: " + OperationContext.get().getOpId());
run.info(0, "C) AsyncHashTask completed after read in thread: " + Thread.currentThread().getName());
if (this.md == null) {
try {
this.md = MessageDigest.getInstance("SHA-256");
}
catch (NoSuchAlgorithmException x) {
run.error(1, "Unable to create digest object: " + x);
try {
sbc.close();
}
catch (IOException x2) {
}
run.complete();
return;
}
}
if (result == -1) {
try {
sbc.close();
}
catch (IOException x) {
}
String sha256 = HexUtil.bufferToHex(this.md.digest());
run.info(0, "Hash of " + path + " is " + sha256);
run.setResult(new RecordStruct(
new FieldStruct("Hash", sha256)
));
run.complete();
return;
}
if (result > 0) {
buf.flip();
this.md.update(buf);
this.pos += result;
}
buf.clear();
sbc.read(buf, this.pos, sbc, this);
}
@Override
public void failed(Throwable x, AsynchronousFileChannel sbc) {
run.info(0, "A) AsyncHashTask failed after read in context: " + OperationContext.get().getOpId());
// TODO review what is intended and rework
//run.thawContext();
run.info(0, "B) AsyncHashTask failed after read in context: " + OperationContext.get().getOpId());
run.info(0, "C) AsyncHashTask failed after read in thread: " + Thread.currentThread().getName());
run.error(1, "Async hash task failed to read file: " + x);
try {
sbc.close();
}
catch (IOException x2) {
}
run.complete();
}
});
}
}