Skip to content

Commit

Permalink
low-level storage service doesn't need sessions.
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeer committed May 22, 2013
1 parent 330289e commit 67813a2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 87 deletions.
Expand Up @@ -9,6 +9,8 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

Expand All @@ -25,6 +27,7 @@
import org.fcrepo.services.functions.GetCacheStore;
import org.fcrepo.utils.LowLevelCacheEntry;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.CacheStoreConfiguration;
import org.infinispan.loaders.CacheLoaderException;
import org.infinispan.loaders.CacheStore;
import org.infinispan.loaders.decorators.ChainingCacheStore;
Expand Down Expand Up @@ -55,21 +58,23 @@ public class LowLevelStorageService {


/**
* For use with non-mutating methods.
* Apply some Function to the low-level cache entries for the Node
* @param resource a JCR Node containing a jcr:data binary property (e.g. a jcr:content node)
* @param transform a Function to transform the cache entries with
* @throws RepositoryException if the jcr:data property isn't found, a RepositoryException is thrown
*/
private Session readOnlySession;

public <T> Collection<T> transformLowLevelCacheEntries(final Node resource,
final Function<LowLevelCacheEntry, T> transform)
throws RepositoryException {
return transform(getLowLevelCacheEntries(resource), transform);
}

/**
* Get the low-level cache entries for a Node containing a jcr:data binary property
*
* @param resource a JCR node that has a jcr:content/jcr:data child.
* @param resource a JCR node that has a jcr:data property.
* @return a map of binary stores and input streams
* @throws RepositoryException
* @throws RepositoryException if the jcr:data property isn't found, a RepositoryException is thrown
*/
public Set<LowLevelCacheEntry> getLowLevelCacheEntries(final Node resource)
throws RepositoryException {
Expand All @@ -79,10 +84,10 @@ public Set<LowLevelCacheEntry> getLowLevelCacheEntries(final Node resource)
}

/**
*
* @param resource a JCR node that has a jcr:content/jcr:data child.
* Get the low-level cache entries for a JCR Binary property
* @param jcrBinaryProperty a JCR Binary property (e.g. jcr:data)
* @return a map of binary stores and input streams
* @throws RepositoryException
* @throws RepositoryException if the binary key for property isn't found, a RepositoryException is thrown
*/
public Set<LowLevelCacheEntry> getLowLevelCacheEntries(final Property jcrBinaryProperty)
throws RepositoryException {
Expand All @@ -92,7 +97,7 @@ public Set<LowLevelCacheEntry> getLowLevelCacheEntries(final Property jcrBinaryP
}

/**
*
* Get the low-level Cache etnries for a Modeshpae BinaryKey
* @param key a Modeshape BinaryValue's key.
* @return a set of binary stores
*/
Expand All @@ -101,14 +106,15 @@ public Set<LowLevelCacheEntry> getLowLevelCacheEntries(final BinaryKey key) {
final BinaryStore store = getBinaryStore.apply(repo);

if (store == null) {
return new HashSet<LowLevelCacheEntry>();
return new HashSet<>();
}

return getLowLevelCacheEntriesFromStore(store, key);
}

/**
*
* Get the low-level cache entries from a particular BinaryStore
*
* @param key a Modeshape BinaryValue's key.
* @return a set of binary stores
*/
Expand All @@ -129,7 +135,7 @@ public Set<LowLevelCacheEntry> getLowLevelCacheEntriesFromStore(final BinaryStor
}

/**
*
* Get the low-level cache entries from a particular CompositeBinaryStore
* @param key a Modeshape BinaryValue's key.
* @return a set of binary stores
*/
Expand Down Expand Up @@ -159,73 +165,79 @@ protected Set<LowLevelCacheEntry> getLowLevelCacheEntriesFromStore(final Composi
}

/**
*
* Get the low-level cache entries from a particular InfinispanBinaryStore
* @param key a Modeshape BinaryValue's key.
* @return a set of binary stores
*/
protected Set<LowLevelCacheEntry> getLowLevelCacheEntriesFromStore(final InfinispanBinaryStore ispnStore, final BinaryKey key) {

logger.trace("Retrieving low-level cache entries for key {} from an InfinispanBinaryStore {}", key, ispnStore);

final ImmutableSet.Builder<LowLevelCacheEntry> blobs = builder();

for (final Cache<?, ?> c : ImmutableSet.copyOf(ispnStore.getCaches())) {
final List<Cache<?,?>> caches = ispnStore.getCaches();
logger.trace("Found {} caches", caches.size());
for (final Cache<?, ?> c : ImmutableSet.copyOf(caches)) {
logger.trace("Looking in Infinispan cache {}", c);

final CacheStore cacheStore = getCacheStore.apply(c);

if (cacheStore == null) {
logger.trace("Could not retrieve cache store from component registry");
continue;
}

// A ChainingCacheStore indicates we (may) have multiple CacheStores at play
if (cacheStore instanceof ChainingCacheStore) {
logger.trace("Found a ChainingCacheStore; looking in each cache store for key");
final ChainingCacheStore chainingCacheStore =
(ChainingCacheStore) cacheStore;
// the stores are a map of the cache store and the configuration; i'm just throwing the configuration away..
for (final CacheStore s : chainingCacheStore.getStores()
.keySet()) {
try {
if (s.containsKey(key + "-data-0")) {
blobs.add(new LowLevelCacheEntry(ispnStore, s, key));
}
} catch (CacheLoaderException e) {
logger.warn("Cache loader raised exception: {}", e);
}
final LinkedHashMap<CacheStore,CacheStoreConfiguration> stores = chainingCacheStore.getStores();
logger.trace("Found {} chained cache stores", stores.size());

for (final CacheStore s : stores.keySet()) {
final Set<LowLevelCacheEntry> lowLevelCacheEntriesFromStore = getLowLevelCacheEntriesFromStore(ispnStore, s, key);

blobs.addAll(lowLevelCacheEntriesFromStore);
}
} else {
// just a nice, simple infinispan cache.
try {
if (cacheStore.containsKey(key + "-data-0")) {
blobs.add(new LowLevelCacheEntry(ispnStore, cacheStore, key));
}
} catch (CacheLoaderException e) {
logger.warn("Cache loader raised exception: {}", e);
}
// just a nice, simple infinispan cache.
blobs.addAll(getLowLevelCacheEntriesFromStore(ispnStore, cacheStore, key));
}
}

return blobs.build();
}

@PostConstruct
public final void getSession() {
/**
* Get the low-level cache entries for a particular Cache Store inside an InfinispanBinaryStore
* @param ispnStore an InfinispanBinaryStore to look in
* @param cacheStore an Infinispan CacheStore reference
* @param key a Modeshape BinaryValue key
* @return
*/
private Set<LowLevelCacheEntry> getLowLevelCacheEntriesFromStore(final InfinispanBinaryStore ispnStore, final CacheStore cacheStore, final BinaryKey key) {

final ImmutableSet.Builder<LowLevelCacheEntry> blobs = builder();
logger.trace("Looking in Infinispan CacheStore {}", cacheStore);

try {
readOnlySession = repo.login();
} catch (final RepositoryException e) {
throw propagate(e);
if (cacheStore.containsKey(key + "-data-0")) {
logger.trace("Found first part of binary in CacheStore {}", cacheStore);
blobs.add(new LowLevelCacheEntry(ispnStore, cacheStore, key));
} else {
logger.trace("CacheStore {} did not contain the first part of our binary", cacheStore);
}
} catch (CacheLoaderException e) {
logger.warn("Cache loader raised exception: {}", e);
}
}

@PreDestroy
public final void logoutSession() {
readOnlySession.logout();
return blobs.build();

}

public void setRepository(final Repository repository) {
if (readOnlySession != null) {
logoutSession();
}
repo = repository;

getSession();
}

public void setGetBinaryStore(final GetBinaryStore getBinaryStore) {
Expand Down
Expand Up @@ -16,12 +16,10 @@
import java.util.List;
import java.util.Set;

import javax.jcr.LoginException;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.fcrepo.services.functions.GetBinaryKey;
import org.fcrepo.services.functions.GetCacheStore;
Expand Down Expand Up @@ -99,45 +97,6 @@ public void testGetBinaryBlobs() throws RepositoryException {
assertEquals("/foo", actual.iterator().next().getExternalIdentifier());
}

@Test
public void testGetSession() throws LoginException, RepositoryException {
final Repository mockRepo = mock(Repository.class);
final Session mockSession = mock(Session.class);
final Session mockAnotherSession = mock(Session.class);
when(mockRepo.login()).thenReturn(mockSession, mockAnotherSession);
final LowLevelStorageService testObj = new LowLevelStorageService();
testObj.setRepository(mockRepo);
testObj.getSession();
verify(mockRepo, times(2)).login();
}

@Test
public void testLogoutSession() throws LoginException, RepositoryException {
final Repository mockRepo = mock(Repository.class);
final Session mockSession = mock(Session.class);
when(mockRepo.login()).thenReturn(mockSession);
final LowLevelStorageService testObj = new LowLevelStorageService();
testObj.setRepository(mockRepo);
testObj.logoutSession();
verify(mockSession).logout();
verify(mockRepo).login();
}

@Test
public void testSetRepository() throws LoginException, RepositoryException {
final Repository mockRepo = mock(Repository.class);
final Repository mockAnotherRepo = mock(Repository.class);
final Session mockSession = mock(Session.class);
final Session mockAnotherSession = mock(Session.class);
when(mockRepo.login()).thenReturn(mockSession);
when(mockAnotherRepo.login()).thenReturn(mockAnotherSession);
final LowLevelStorageService testObj = new LowLevelStorageService();
testObj.setRepository(mockRepo);
testObj.setRepository(mockAnotherRepo);
verify(mockSession).logout();
verify(mockAnotherRepo).login();
}

@Test
public void shouldRetrieveLowLevelCacheEntryForDefaultBinaryStore()
throws RepositoryException {
Expand Down

0 comments on commit 67813a2

Please sign in to comment.