package imsdebug; import edu.umiacs.ace.exception.StatusCode; import edu.umiacs.ace.ims.api.IMSService; import edu.umiacs.ace.ims.api.RequestBatchCallback; import edu.umiacs.ace.ims.api.TokenRequestBatch; import edu.umiacs.ace.ims.ws.TokenRequest; import edu.umiacs.ace.ims.ws.TokenResponse; import edu.umiacs.ace.util.HashValue; import edu.umiacs.io.IO; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.DigestInputStream; import java.security.MessageDigest; import java.util.List; /** * Class demonstrating how to register items within the IMS. * * Usage: BatchSample <directory> * * @author toaster */ public class BatchSample { private static final String IMS_HOST = "ims.umiacs.umd.edu"; private static final int IMS_PORT = 8080; private long numTotalRequests = 0; private long numTotalResponses = 0; private long numTotalErrors = 0; private MessageDigest digest; private byte[] buffer = new byte[4096]; public static void main(String[] args) throws Exception { String dirName = args[0]; new BatchTest().run(dirName); } /** * Register all the files in a directory. * * @param dirName directory to scan * * @throws java.lang.Exception since this is just example code */ public void run(String dirName) throws Exception { // Create digest service to use for local file digesting digest = MessageDigest.getInstance("SHA-256"); // Create connection to IMS IMSService ims = IMSService.connect(IMS_HOST, IMS_PORT); // Create registration service with 1000 files/batch max and 5s delay max TokenRequestBatch batch = ims.createImmediateTokenRequestBatch( "SHA-256-0", new BatchCallback(), 1000, 5000); // process all files in the directory processDirectory(batch, new File(dirName)); // block until all outstanding requests have been serviced batch.close(); System.out.println("\nComplete: " + numTotalRequests + " request(s), " + numTotalResponses + " response(s), " + numTotalErrors + " error(s)"); } /** * Register all files in the current directory and recurse to any child * directories * * @param batch batch processor used to register files * * @param dir directory to scan for items */ private void processDirectory(TokenRequestBatch batch, File dir) { System.out.println("Directory: " + dir); File[] files = dir.listFiles(); for ( File file : files ) { if ( file.isDirectory() ) { processDirectory(batch, file); } else { processFile(batch, file); } } } /** * Read in a file, calculate its digest and add it to the current batch * * @param batch * @param file */ @SuppressWarnings("empty-statement") private void processFile(TokenRequestBatch batch, File file) { numTotalRequests++; System.out.println("File: " + file + ", " + file.length()); DigestInputStream dis = null; try { // reset digest and prepare to read file digest.reset(); dis = new DigestInputStream(new FileInputStream(file), digest); // read file, updating digest and it occurs while ( dis.read(buffer) >= 0 ) { ; } byte[] hashValue = digest.digest(); dis.close(); // create token request and add it to the current open batch // results will be returned via callback registered to batch TokenRequest request = new TokenRequest(); request.setHashValue(HashValue.asHexString(hashValue)); request.setName(file.getPath()); batch.add(request); } catch ( IOException ie ) { System.out.println(file.getPath() + ": IOException: " + ie.getMessage()); numTotalErrors++; } catch ( InterruptedException ie ) { Thread.currentThread().interrupt(); } finally { IO.release(dis); } } /** * Simple callback for the token request batch */ class BatchCallback implements RequestBatchCallback { /** * A response was received for a batch of requests. Just becuase this was * received, doesn't mean the token is OK. You should check to make sure * that the resulting status code is StatusCode.SUCCESS. The result may have * mixed successful and unsuccessful responses. * * @param requests requests that were sent in the batch. * @param responses responses received. */ public void tokensReceived(List requests, List responses) { int numResponses = 0; int numErrors = 0; for ( TokenResponse response : responses ) { if ( response.getStatusCode() != StatusCode.SUCCESS ) { System.out.println("Unsuccessful request: " + "name: " + response.getName() + ", status code: " + response.getStatusCode()); numErrors++; numTotalErrors++; } else { System.out.println("Suffessful request: " + "name: " + response.getName() + ", status code: " + response.getStatusCode()); numResponses++; numTotalResponses++; } } System.out.println("" + requests.size() + " request(s), " + numResponses + " response(s), " + numErrors + " error(s)"); } /** * Exception occurred when attempting to contact the IMS. Most likely this * is a network-related error. Any item in this * batch was not registered, however the thread is still running and * future add attempts may work assuming the underlying connectivity * issue is resolved * * @param requests list of requests that was being transmitted when the exception occurred. * @param t */ public void exceptionThrown(List requests, Throwable t) { System.out.println("" + requests.size() + " error(s) on exception: " + t.getMessage()); } /** * Uncaught throwable occured in the token registion thread. This should * never happen and may indicate out of memory or other really bad things. * After this exception, the request thread has died and no future requests * will return. * * @param t */ public void unexpectedException(Throwable t) { System.out.println("*** ERROR: " + t.getMessage()); t.printStackTrace(); } } }