Skip to content

Commit

Permalink
create a functional-style digest checker (functional java makes my he…
Browse files Browse the repository at this point in the history
…ad hurt)
  • Loading branch information
cbeer committed Mar 12, 2013
1 parent 64ec7c1 commit a0fe429
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 6 deletions.
@@ -1,5 +1,7 @@
package org.fcrepo.services;

import com.google.common.collect.Maps;
import org.apache.commons.codec.binary.Hex;
import org.fcrepo.utils.LowLevelCacheStore;
import org.infinispan.Cache;
import org.infinispan.loaders.CacheLoaderManager;
Expand All @@ -25,11 +27,15 @@
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class LowLevelStorageService {

Expand All @@ -52,13 +58,44 @@ private static JcrRepository getRepositoryInstance() {
return (JcrRepository)readOnlySession.getRepository();
}

public static Map<LowLevelCacheStore, Boolean> applyDigestToBlobs(final Node resource, final MessageDigest digest, final String checksum) throws RepositoryException {

This comment has been minimized.

Copy link
@cbeer

cbeer Mar 12, 2013

Author Contributor

@ajs6f can you help me make this better? I ended up all turned around and this was the best I could come up with that actually worked. I suspect:

  • the getBlobs() method can be replaced with something more functional
  • this can be written to accept a Node or a BinaryKey (or, maybe accepting a BinaryKey is too low-level for this, and is just an internal implementation detail?)
  • did I do the generics right "enough"?

This comment has been minimized.

Copy link
@ajs6f

ajs6f Mar 12, 2013

Contributor

First rough thought-- if we don't want to use INSPN's MapReduce (which I think we do) this might be better accomplished with Collections2.filter() and a Predicate<Map.Entry<LowLevelCacheStore,InputStream>> myPredicate. You'd filter the guys of interest with myPredicate or with Predicates.not(myPredicate), depending on whether you want to know who lives or who dies.

But I'm not totally sure I understand what's going on here. Let's circle back on IRC and bring me up to speed, then I can get involved more usefully.

This comment has been minimized.

Copy link
@ajs6f

ajs6f Mar 12, 2013

Contributor

Looks like all my XML brackets died in that comment. {sigh}

return applyToBlob(resource, new Maps.EntryTransformer<LowLevelCacheStore, InputStream, Boolean>() {
public Boolean transformEntry(LowLevelCacheStore store, InputStream is) {
DigestInputStream ds = null;
try {
ds = new DigestInputStream(is, (MessageDigest)digest.clone());

while (ds.read() != -1);

String calculatedDigest = Hex.encodeHexString(ds.getMessageDigest().digest());

return checksum.equals(calculatedDigest);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return Boolean.FALSE;
}
});

}

public static <T> Map<LowLevelCacheStore, T> applyToBlob(Node resource, Maps.EntryTransformer<LowLevelCacheStore, InputStream, T> transform) throws RepositoryException {
Map<LowLevelCacheStore, T> transformed =
Maps.transformEntries(getBlobs(resource), transform);

return transformed;
}

/**
*
* @param resource a JCR node that has a jcr:content/jcr:data child.
* @return a map of binary stores and input streams
* @throws RepositoryException
*/
public static HashMap<LowLevelCacheStore, InputStream> getContentBlobs(Node resource) throws RepositoryException {
public static Map<LowLevelCacheStore, InputStream> getBlobs(Node resource) throws RepositoryException {

BinaryValue v = (BinaryValue) resource.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();

Expand Down
Expand Up @@ -2,6 +2,7 @@

import org.apache.commons.io.IOUtils;
import org.fcrepo.Datastream;
import org.fcrepo.utils.LowLevelCacheStore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
Expand All @@ -12,15 +13,15 @@
import javax.jcr.Session;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.Iterator;
import java.util.Map;

import static org.fcrepo.services.DatastreamService.createDatastreamNode;
import static org.fcrepo.services.DatastreamService.getDatastream;
import static org.fcrepo.services.ObjectService.createObjectNode;
import static org.fcrepo.services.LowLevelStorageService.getContentBlobs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import static org.fcrepo.services.LowLevelStorageService.getBlobs;
import static org.junit.Assert.*;


@RunWith(SpringJUnit4ClassRunner.class)
Expand All @@ -30,6 +31,32 @@ public class LowLevelStorageServiceTest {
@Inject
Repository repo;

@Test
public void testChecksumBlobs() throws Exception {

Session session = repo.login();
createObjectNode(session, "testObject");
createDatastreamNode(session,
"/objects/testObject/testRepositoryContent",
"application/octet-stream", new ByteArrayInputStream(
"0123456789".getBytes()));


session.save();

final Datastream ds = getDatastream("testObject", "testRepositoryContent");

final Map<LowLevelCacheStore,Boolean> booleanMap = LowLevelStorageService.applyDigestToBlobs(ds.getNode(), MessageDigest.getInstance("SHA-1"), "87acec17cd9dcd20a716cc2cf67417b71c8a7016");

assertNotEquals(0, booleanMap.size());

Iterator<Boolean> it = booleanMap.values().iterator();

while(it.hasNext()) {
assertTrue(it.next());
}
}

@Test
public void testGetBlobs() throws Exception {
Session session = repo.login();
Expand All @@ -44,7 +71,7 @@ public void testGetBlobs() throws Exception {

final Datastream ds = getDatastream("testObject", "testRepositoryContent");

Iterator<InputStream> inputStreamList = getContentBlobs(ds.getNode()).values().iterator();
Iterator<InputStream> inputStreamList = getBlobs(ds.getNode()).values().iterator();

int i = 0;
while(inputStreamList.hasNext()) {
Expand Down

0 comments on commit a0fe429

Please sign in to comment.