summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/AsyncHashGenerator.java
blob: 26b96cb6888a7b82e690938957c66447511509b7 (plain) (tree)

















































































                                                                                                                                     
package org.openslx.dozmod.filetransfer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.TInvalidTokenException;
import org.openslx.filetransfer.util.FileChunk;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.Util;

public class AsyncHashGenerator implements Runnable {

	private static final Logger LOGGER = Logger.getLogger(AsyncHashGenerator.class);

	private final File uploadFile;

	private final String uploadToken;

	public AsyncHashGenerator(String uploadToken, File uploadFile) {
		this.uploadToken = uploadToken;
		this.uploadFile = uploadFile;
	}

	@Override
	public void run() {
		MessageDigest digester;
		try {
			digester = MessageDigest.getInstance("SHA-1");
		} catch (NoSuchAlgorithmException e1) {
			LOGGER.warn("No SHA-1 MD available. Cannot hash file", e1);
			return;
		}
		final RandomAccessFile file;
		try {
			file = new RandomAccessFile(uploadFile, "r");
		} catch (FileNotFoundException e) {
			LOGGER.warn("Could not open file for hash-checking. Will not send checksums to satellite", e);
			return;
		}
		try {
			List<FileChunk> list = new ArrayList<>();
			FileChunk.createChunkList(list, uploadFile.length(), null);
			byte[] buffer = new byte[(int) TransferTask.CHUNK_SIZE];
			List<ByteBuffer> blockHashes = new ArrayList<>(list.size());
			for (int i = 0; i < list.size(); i++) {
				FileChunk chunk = list.get(i);
				try {
					file.seek(chunk.range.startOffset);
					file.readFully(buffer, 0, chunk.range.getLength());
				} catch (IOException e) {
					LOGGER.warn("Could not read file chunk " + chunk.getChunkIndex() + ", skipping", e);
					continue;
				}
				digester.update(buffer, 0, chunk.range.getLength());
				byte[] hash = digester.digest();
				blockHashes.add(ByteBuffer.wrap(hash));
				if (i <= 5 || i % 20 == 0 || i + 1 == list.size()) {
					try {
						ThriftManager.getSatClient().updateBlockHashes(uploadToken, blockHashes);
					} catch (TInvalidTokenException e) {
						LOGGER.warn("Cannot send hashList to satellite: Sat claims uploadToken is invalid!");
						break;
					} catch (TException e) {
						LOGGER.warn("Unknown exception when submitting hashList to sat", e);
					}
				}
			}
		} finally {
			Util.safeClose(file);
		}
	}

}