diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java index 0d18f9c9f0a54e434b64f1dd25e51c0e34458a49..a1792d1e687a70fc5a18408a2dcef2b6d91f0c8a 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java @@ -19,13 +19,12 @@ package ch.systemsx.cisd.openbis.dss.generic.shared; import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Properties; import org.apache.log4j.Logger; import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.action.IDelegatedAction; -import ch.systemsx.cisd.common.filesystem.FileOperations; -import ch.systemsx.cisd.common.filesystem.IFileOperations; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.server.ISessionTokenProvider; @@ -34,7 +33,6 @@ import ch.systemsx.cisd.common.ssl.SslCertificateHelper; import ch.systemsx.cisd.openbis.common.io.hierarchical_content.IHierarchicalContentFactory; import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContent; import ch.systemsx.cisd.openbis.dss.generic.shared.content.ContentCache; -import ch.systemsx.cisd.openbis.dss.generic.shared.content.DssServiceRpcGenericFactory; import ch.systemsx.cisd.openbis.dss.generic.shared.content.PathInfoDBAwareHierarchicalContentFactory; import ch.systemsx.cisd.openbis.dss.generic.shared.content.RemoteHierarchicalContent; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.PathInfoDataSourceProvider; @@ -105,13 +103,13 @@ public class HierarchicalContentProvider implements IHierarchicalContentProvider this.dataStoreCode = dataStoreCode; if (infoProvider != null) { - String trust = infoProvider.getResolvedProps().getProperty("trust-all-certificates"); + Properties properties = infoProvider.getResolvedProps(); + String trust = properties.getProperty("trust-all-certificates"); trustAllCertificates = (trust != null && trust.equalsIgnoreCase("true")); String sessionWorkspaceRoot = infoProvider.getResolvedProps().getProperty("session-workspace-root-dir", "data/sessionWorkspace"); - cacheWorkspace = - new File(new File(sessionWorkspaceRoot), "dss-cache"); + cacheWorkspace = new File(sessionWorkspaceRoot); if (cacheWorkspace.exists() == false) { cacheWorkspace.mkdirs(); @@ -120,10 +118,7 @@ public class HierarchicalContentProvider implements IHierarchicalContentProvider { trustAllCertificates = false; } - IFileOperations fileOperations = FileOperations.getInstance(); - cache = - new ContentCache(new DssServiceRpcGenericFactory(), sessionTokenProvider, - cacheWorkspace, fileOperations); + cache = new ContentCache(cacheWorkspace, true); } @Override diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java index f39eaf9078e9ebd0d967a15ae01b77bdff76d9e5..0dd02cb3fc126750c0fd4d5025be9a92419ed46d 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java @@ -25,98 +25,121 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.common.filesystem.FileOperations; import ch.systemsx.cisd.common.filesystem.IFileOperations; -import ch.systemsx.cisd.common.server.ISessionTokenProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetPathInfo; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation; /** - * Cache for files remotely retrieved from a DSS. + * Cache for files remotely retrieved from Data Store Servers. * * @author Franz-Josef Elmer */ public class ContentCache { - static final String CHACHED_FOLDER = "cached"; + static final String CACHE_FOLDER = "cached"; static final String DOWNLOADING_FOLDER = "downloading"; - - private final ISessionTokenProvider sessionTokenProvider; - - private final File cachedFiles; - private final File downloadingFolder; + private final LockManager dataSetLockManager; + + private final LockManager fileLockManager; + + private final IDssServiceRpcGenericFactory serviceFactory; - private Map<String, Lock> locks; + private final boolean sessionCache; - private final IDssServiceRpcGenericFactory serviceFactory; + private final File workspace; + + public ContentCache(File cacheWorkspace, boolean sessionCache) + { + this(new DssServiceRpcGenericFactory(), cacheWorkspace, sessionCache, FileOperations.getInstance()); + } - public ContentCache(IDssServiceRpcGenericFactory serviceFactory, - ISessionTokenProvider sessionTokenProvider, File cacheWorkSpace, - IFileOperations fileOperations) + ContentCache(IDssServiceRpcGenericFactory serviceFactory, File cacheWorkspace, + boolean sessionCache, IFileOperations fileOperations) { this.serviceFactory = serviceFactory; - this.sessionTokenProvider = sessionTokenProvider; - cachedFiles = new File(cacheWorkSpace, CHACHED_FOLDER); - creatFolder(cachedFiles); - downloadingFolder = new File(cacheWorkSpace, DOWNLOADING_FOLDER); - fileOperations.removeRecursivelyQueueing(downloadingFolder); - creatFolder(downloadingFolder); - locks = new HashMap<String, Lock>(); + this.workspace = cacheWorkspace; + this.sessionCache = sessionCache; + if (sessionCache == false) + { + fileOperations.removeRecursivelyQueueing(new File(cacheWorkspace, DOWNLOADING_FOLDER)); + } + dataSetLockManager = new LockManager(); + fileLockManager = new LockManager(); } - + IDssServiceRpcGeneric getDssService(IDatasetLocation dataSetLocation) { return serviceFactory.getService(dataSetLocation.getDataStoreUrl()); } - public void unlockFilesFor(String dataSetCode) + public void lockDataSet(String sessionToken, String dataSetCode) { + String dataSetPath = createDataSetPath(sessionToken, CACHE_FOLDER, dataSetCode); + dataSetLockManager.lock(dataSetPath); } - File getFile(IDatasetLocation dataSetLocation, DataSetPathInfo path) + public void unlockDataSet(String sessionToken, String dataSetCode) { - String dataSetCode = dataSetLocation.getDataSetCode(); - String pathInCache = dataSetCode + "/" + path.getRelativePath(); - lock(pathInCache); + String dataSetPath = createDataSetPath(sessionToken, CACHE_FOLDER, dataSetCode); + dataSetLockManager.unlock(dataSetPath); + } + + public boolean isDataSetLocked(String sessionToken, String dataSetCode) + { + String dataSetPath = createDataSetPath(sessionToken, CACHE_FOLDER, dataSetCode); + return dataSetLockManager.isLocked(dataSetPath); + } + + File getFile(String sessionToken, IDatasetLocation dataSetLocation, + DataSetPathInfo path) + { + String pathInWorkspace = + createPathInWorkspace(sessionToken, CACHE_FOLDER, dataSetLocation, path); + fileLockManager.lock(pathInWorkspace); try { - File file = new File(cachedFiles, pathInCache); + File file = new File(workspace, pathInWorkspace); if (file.exists() == false) { - downloadFile(dataSetLocation, path, pathInCache); + downloadFile(sessionToken, dataSetLocation, path); } return file; } finally { - unlock(pathInCache); + fileLockManager.unlock(pathInWorkspace); } } - private void downloadFile(IDatasetLocation dataSetLocation, DataSetPathInfo path, String pathInCache) + private void downloadFile(String sessionToken, + IDatasetLocation dataSetLocation, DataSetPathInfo path) { InputStream input = null; try { + String dataStoreUrl = dataSetLocation.getDataStoreUrl(); + IDssServiceRpcGeneric service = serviceFactory.getService(dataStoreUrl); + String dataSetCode = dataSetLocation.getDataSetCode(); + String relativePath = path.getRelativePath(); String url = - serviceFactory.getService(dataSetLocation.getDataStoreUrl()) - .getDownloadUrlForFileForDataSet( - sessionTokenProvider.getSessionToken(), - dataSetLocation.getDataSetCode(), path.getRelativePath()); + service.getDownloadUrlForFileForDataSet(sessionToken, dataSetCode, relativePath); input = createURL(url).openStream(); - File downloadedFile = createFileFromInputStream(pathInCache, input); - File file = new File(cachedFiles, pathInCache); - creatFolder(file.getParentFile()); + File downloadedFile = + createFileFromInputStream(sessionToken, dataSetLocation, path, input); + String pathInWorkspace = + createPathInWorkspace(sessionToken, CACHE_FOLDER, dataSetLocation, path); + File file = new File(workspace, pathInWorkspace); + createFolder(file.getParentFile()); downloadedFile.renameTo(file); } catch (Exception ex) { @@ -126,7 +149,21 @@ public class ContentCache IOUtils.closeQuietly(input); } } - + + private String createPathInWorkspace(String sessionToken, String folder, + IDatasetLocation dataSetLocation, DataSetPathInfo path) + { + String dataSetCode = dataSetLocation.getDataSetCode(); + return createDataSetPath(sessionToken, folder, dataSetCode) + "/" + + path.getRelativePath(); + } + + private String createDataSetPath(String sessionToken, String folder, + String dataSetCode) + { + return (sessionCache ? sessionToken + "/dss-cache/" : "") + folder + "/" + dataSetCode; + } + private URL createURL(String url) { try @@ -142,13 +179,13 @@ public class ContentCache } } - private File createFileFromInputStream(String filePath, InputStream inputStream) + private File createFileFromInputStream(String sessionToken, + IDatasetLocation dataSetLocation, DataSetPathInfo path, InputStream inputStream) { - final String subDir = FilenameUtils.getFullPath(filePath); - final String filename = FilenameUtils.getName(filePath); - final File dir = new File(downloadingFolder, subDir); - dir.mkdirs(); - final File file = new File(dir, filename); + File file = + new File(workspace, createPathInWorkspace(sessionToken, DOWNLOADING_FOLDER, + dataSetLocation, path)); + createFolder(file.getParentFile()); OutputStream ostream = null; try { @@ -164,8 +201,8 @@ public class ContentCache IOUtils.closeQuietly(ostream); } } - - private void creatFolder(File folder) + + private void createFolder(File folder) { if (folder.exists() == false) { @@ -177,35 +214,45 @@ public class ContentCache } } - private void lock(String pathInCache) - { - getLock(pathInCache).lock(); - } - private Lock getLock(String pathInCache) + private static final class LockManager { - synchronized (locks) + private final Map<String, ReentrantLock> locks = new HashMap<String, ReentrantLock>(); + + void lock(String path) { - Lock lock = locks.get(pathInCache); - if (lock == null) + ReentrantLock lock; + synchronized (locks) { - lock = new ReentrantLock(); - locks.put(pathInCache, lock); + lock = locks.get(path); + if (lock == null) + { + lock = new ReentrantLock(); + locks.put(path, lock); + } } - return lock; + lock.lock(); } - } - - private void unlock(String pathInCache) - { - synchronized (locks) + + synchronized void unlock(String path) { - Lock lock = locks.remove(pathInCache); + ReentrantLock lock = locks.get(path); if (lock != null) { lock.unlock(); + if (lock.isLocked() == false) + { + locks.remove(path); + } } } + + synchronized boolean isLocked(String path) + { + ReentrantLock lock = locks.get(path); + return lock != null && lock.isLocked(); + } + } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java index 2e45c3555412af6fb60882240ecbd37576c50a1f..1639b3cedd59c70fe3a554dc3024ae94bc9237d1 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java @@ -50,7 +50,7 @@ public class RemoteHierarchicalContent implements IHierarchicalContent this.provider = pathInfoProvider; this.sessionTokenProvider = sessionTokenProvider; this.cache = cache; - + cache.lockDataSet(sessionTokenProvider.getSessionToken(), location.getLocation().getDataSetCode()); } @Override @@ -140,7 +140,7 @@ public class RemoteHierarchicalContent implements IHierarchicalContent @Override public void close() { - cache.unlockFilesFor(location.getLocation().getDataSetCode()); + cache.unlockDataSet(sessionTokenProvider.getSessionToken(), location.getLocation().getDataSetCode()); } private IHierarchicalContentNode createNode(DataSetPathInfo info) diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java index 86c6018f9bcd8d0c452d03541dd5f7db76d4a73a..a7eae9a3c0d2542a18c3a1b5ba51b759552265da 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java @@ -176,7 +176,7 @@ public class RemoteHierarchicalContentNode implements IHierarchicalContentNode @Override public File getFile() throws UnsupportedOperationException { - return cache.getFile(dataSetLocation, path); + return cache.getFile(sessionTokenProvider.getSessionToken(), dataSetLocation, path); } @Override diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCacheTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCacheTest.java new file mode 100644 index 0000000000000000000000000000000000000000..682de24c9c9a08fb51da8c3b87b344ab237c40b5 --- /dev/null +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCacheTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2013 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.dss.generic.shared.content; + +import java.io.File; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.common.filesystem.IFileOperations; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class ContentCacheTest extends AssertJUnit +{ + private static final String SESSION_TOKEN = "session"; + + private Mockery context; + + private IFileOperations fileOperations; + + @BeforeMethod + public void setUp() + { + context = new Mockery(); + fileOperations = context.mock(IFileOperations.class); + } + + @AfterMethod + public void tearDown() + { + // To following line of code should also be called at the end of each test method. + // Otherwise one do not known which test failed. + context.assertIsSatisfied(); + } + + @Test + public void testDataSetLocking() + { + ContentCache cache = createCache(false); + + cache.lockDataSet(SESSION_TOKEN, "DS-1"); + + assertEquals(true, cache.isDataSetLocked(SESSION_TOKEN, "DS-1")); + assertEquals(false, cache.isDataSetLocked(SESSION_TOKEN, "DS-2")); + + cache.lockDataSet(SESSION_TOKEN, "DS-1"); + + assertEquals(true, cache.isDataSetLocked(SESSION_TOKEN, "DS-1")); + + cache.unlockDataSet(SESSION_TOKEN, "DS-1"); + + assertEquals(true, cache.isDataSetLocked(SESSION_TOKEN, "DS-1")); + + cache.unlockDataSet(SESSION_TOKEN, "DS-1"); + + assertEquals(false, cache.isDataSetLocked(SESSION_TOKEN, "DS-1")); + + context.assertIsSatisfied(); + } + + private ContentCache createCache(boolean sessionCache) + { + final File workSpace = new File("."); + if (sessionCache == false) + { + context.checking(new Expectations() + { + { + one(fileOperations).removeRecursivelyQueueing( + new File(workSpace, ContentCache.DOWNLOADING_FOLDER)); + } + }); + } + return new ContentCache(null, workSpace, sessionCache, fileOperations); + } +} diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java index 030b224292119978f54e8411668d08587221d2f3..d96e6517eb9fe813b8c91ba83503721b0bcc92aa 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java @@ -74,14 +74,14 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy private OpenBISSessionHolder sessionHolder; - private ContentCache cache; - private File workSpace; private File remoteFile1; private File remoteFile2; + private IDssServiceRpcGenericFactory serviceFactory; + @BeforeMethod public void setUpFixture() { @@ -99,20 +99,16 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy remoteFile2 = new File(remoteDataSetFolder, "file2.txt"); FileUtilities.writeToFile(remoteFile2, FILE2_CONTENT); workSpace = new File(workingDirectory, "workspace"); - final IDssServiceRpcGenericFactory serviceFactory = context.mock(IDssServiceRpcGenericFactory.class); + serviceFactory = context.mock(IDssServiceRpcGenericFactory.class); context.checking(new Expectations() { { - one(fileOperations).removeRecursivelyQueueing( - new File(workSpace, ContentCache.DOWNLOADING_FOLDER)); - allowing(serviceFactory).getService(DATA_STORE_URL); will(returnValue(remoteDss)); } }); - cache = new ContentCache(serviceFactory, sessionHolder, workSpace, fileOperations); } - + @AfterMethod public void tearDown() { @@ -124,10 +120,11 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy @Test public void testGetTwoDifferentFilesInSequence() throws Exception { + ContentCache cache = createCache(true); final DataSetPathInfo pathInfo1 = new DataSetPathInfo(); pathInfo1.setRelativePath(remoteFile1.getName()); pathInfo1.setDirectory(false); - IHierarchicalContentNode node1 = createRemoteNode(pathInfo1); + IHierarchicalContentNode node1 = createRemoteNode(pathInfo1, cache); context.checking(new Expectations() { { @@ -139,7 +136,7 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy final DataSetPathInfo pathInfo2 = new DataSetPathInfo(); pathInfo2.setRelativePath(remoteFile2.getName()); pathInfo2.setDirectory(false); - IHierarchicalContentNode node2 = createRemoteNode(pathInfo2); + IHierarchicalContentNode node2 = createRemoteNode(pathInfo2, cache); context.checking(new Expectations() { { @@ -152,11 +149,13 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy File file1 = node1.getFile(); File file2 = node2.getFile(); - assertEquals(new File(workSpace, ContentCache.CHACHED_FOLDER + "/" + DATA_SET_CODE + "/" - + remoteFile1.getName()).getAbsolutePath(), file1.getAbsolutePath()); + assertEquals(new File(workSpace, SESSION_TOKEN + "/dss-cache/" + ContentCache.CACHE_FOLDER + + "/" + DATA_SET_CODE + "/" + remoteFile1.getName()).getAbsolutePath(), + file1.getAbsolutePath()); assertEquals(FILE1_CONTENT, FileUtilities.loadToString(file1).trim()); - assertEquals(new File(workSpace, ContentCache.CHACHED_FOLDER + "/" + DATA_SET_CODE + "/" - + remoteFile2.getName()).getAbsolutePath(), file2.getAbsolutePath()); + assertEquals(new File(workSpace, SESSION_TOKEN + "/dss-cache/" + ContentCache.CACHE_FOLDER + + "/" + DATA_SET_CODE + "/" + remoteFile2.getName()).getAbsolutePath(), + file2.getAbsolutePath()); assertEquals(FILE2_CONTENT, FileUtilities.loadToString(file2).trim()); context.assertIsSatisfied(); } @@ -164,10 +163,11 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy @Test public void testGetSameFileInSequenceFirstTryFailing() throws Exception { + ContentCache cache = createCache(false); final DataSetPathInfo pathInfo = new DataSetPathInfo(); pathInfo.setRelativePath(remoteFile1.getName()); pathInfo.setDirectory(false); - IHierarchicalContentNode node = createRemoteNode(pathInfo); + IHierarchicalContentNode node = createRemoteNode(pathInfo, cache); context.checking(new Expectations() { { @@ -194,7 +194,7 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy } File file = node.getFile(); - assertEquals(new File(workSpace, ContentCache.CHACHED_FOLDER + "/" + DATA_SET_CODE + "/" + assertEquals(new File(workSpace, ContentCache.CACHE_FOLDER + "/" + DATA_SET_CODE + "/" + remoteFile1.getName()).getAbsolutePath(), file.getAbsolutePath()); assertEquals(FILE1_CONTENT, FileUtilities.loadToString(file).trim()); context.assertIsSatisfied(); @@ -203,10 +203,11 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy @Test public void testGetTwoDifferentFilesInTwoThreads() throws Exception { + ContentCache cache = createCache(false); final DataSetPathInfo pathInfo1 = new DataSetPathInfo(); pathInfo1.setRelativePath(remoteFile1.getName()); pathInfo1.setDirectory(false); - IHierarchicalContentNode node1 = createRemoteNode(pathInfo1); + IHierarchicalContentNode node1 = createRemoteNode(pathInfo1, cache); final MessageChannel channel1 = new MessageChannel(10000); GetFileRunnable fileRunnable1 = new GetFileRunnable(node1, channel1) { @@ -221,7 +222,7 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy final DataSetPathInfo pathInfo2 = new DataSetPathInfo(); pathInfo2.setRelativePath(remoteFile2.getName()); pathInfo2.setDirectory(false); - IHierarchicalContentNode node2 = createRemoteNode(pathInfo2); + IHierarchicalContentNode node2 = createRemoteNode(pathInfo2, cache); final MessageChannel channel2 = new MessageChannel(10000); GetFileRunnable fileRunnable2 = new GetFileRunnable(node2, channel2) { @@ -269,10 +270,10 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy File file1 = fileRunnable1.tryGetResult(); File file2 = fileRunnable2.tryGetResult(); - assertEquals(new File(workSpace, ContentCache.CHACHED_FOLDER + "/" + DATA_SET_CODE + "/" + assertEquals(new File(workSpace, ContentCache.CACHE_FOLDER + "/" + DATA_SET_CODE + "/" + remoteFile1.getName()).getAbsolutePath(), file1.getAbsolutePath()); assertEquals(FILE1_CONTENT, FileUtilities.loadToString(file1).trim()); - assertEquals(new File(workSpace, ContentCache.CHACHED_FOLDER + "/" + DATA_SET_CODE + "/" + assertEquals(new File(workSpace, ContentCache.CACHE_FOLDER + "/" + DATA_SET_CODE + "/" + remoteFile2.getName()).getAbsolutePath(), file2.getAbsolutePath()); assertEquals(FILE2_CONTENT, FileUtilities.loadToString(file2).trim()); context.assertIsSatisfied(); @@ -281,14 +282,15 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy @Test public void testGetSameFileInTwoThreads() throws Exception { + ContentCache cache = createCache(false); final DataSetPathInfo pathInfo = new DataSetPathInfo(); pathInfo.setRelativePath(remoteFile1.getName()); pathInfo.setDirectory(false); - final IHierarchicalContentNode node1 = createRemoteNode(pathInfo); + final IHierarchicalContentNode node1 = createRemoteNode(pathInfo, cache); ConsoleLogger logger = new ConsoleLogger(); final MessageChannel channel1 = new MessageChannelBuilder(10000).name("1").logger(logger).getChannel(); - final IHierarchicalContentNode node2 = createRemoteNode(pathInfo); + final IHierarchicalContentNode node2 = createRemoteNode(pathInfo, cache); final MessageChannel channel2 = new MessageChannelBuilder(10000).name("2").logger(logger).getChannel(); final MessageChannel channel3 = @@ -332,7 +334,7 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy File file1 = fileRunnable1.tryGetResult(); File file2 = fileRunnable2.tryGetResult(); - assertEquals(new File(workSpace, ContentCache.CHACHED_FOLDER + "/" + DATA_SET_CODE + "/" + assertEquals(new File(workSpace, ContentCache.CACHE_FOLDER + "/" + DATA_SET_CODE + "/" + remoteFile1.getName()).getAbsolutePath(), file1.getAbsolutePath()); assertEquals(FILE1_CONTENT, FileUtilities.loadToString(file1).trim()); assertEquals(file1, file2); @@ -342,14 +344,15 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy @Test public void testGetSameFileInTwoThreadsFirstDownloadFails() throws Exception { + ContentCache cache = createCache(false); final DataSetPathInfo pathInfo = new DataSetPathInfo(); pathInfo.setRelativePath(remoteFile1.getName()); pathInfo.setDirectory(false); - final IHierarchicalContentNode node1 = createRemoteNode(pathInfo); + final IHierarchicalContentNode node1 = createRemoteNode(pathInfo, cache); ConsoleLogger logger = new ConsoleLogger(); final MessageChannel channel1 = new MessageChannelBuilder(10000).name("1").logger(logger).getChannel(); - final IHierarchicalContentNode node2 = createRemoteNode(pathInfo); + final IHierarchicalContentNode node2 = createRemoteNode(pathInfo, cache); final MessageChannel channel2 = new MessageChannelBuilder(10000).name("2").logger(logger).getChannel(); final MessageChannel channel3 = @@ -408,13 +411,28 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy File file1 = fileRunnable1.tryGetResult(); assertEquals(null, file1); File file2 = fileRunnable2.tryGetResult(); - assertEquals(new File(workSpace, ContentCache.CHACHED_FOLDER + "/" + DATA_SET_CODE + "/" + assertEquals(new File(workSpace, ContentCache.CACHE_FOLDER + "/" + DATA_SET_CODE + "/" + remoteFile1.getName()).getAbsolutePath(), file2.getAbsolutePath()); assertEquals(FILE1_CONTENT, FileUtilities.loadToString(file2).trim()); context.assertIsSatisfied(); } - private IHierarchicalContentNode createRemoteNode(DataSetPathInfo pathInfo) + private ContentCache createCache(boolean sessionCache) + { + if (sessionCache == false) + { + context.checking(new Expectations() + { + { + one(fileOperations).removeRecursivelyQueueing( + new File(workSpace, ContentCache.DOWNLOADING_FOLDER)); + } + }); + } + return new ContentCache(serviceFactory, workSpace, sessionCache, fileOperations); + } + + private IHierarchicalContentNode createRemoteNode(DataSetPathInfo pathInfo, ContentCache cache) { return new RemoteHierarchicalContentNode(DATA_SET_LOCATION, pathInfo, provider, sessionHolder, cache); diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java index 425667d52ae30224c24e3868d682631d57850ccf..09183291403707667259c59845489171ba876c42 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java @@ -95,7 +95,7 @@ public class RemoteHierarchicalContentNodeTest "remote-file.txt"); fileInSessionWorkspace = - new File(SESSION_WORKSPACE_DIR, ContentCache.CHACHED_FOLDER + "/" + new File(SESSION_WORKSPACE_DIR, ContentCache.CACHE_FOLDER + "/" + CACHED_DATASET_LOCATION.getDataSetCode() + "/already-downloaded-file.txt"); create(remoteFile); create(fileInSessionWorkspace); @@ -110,7 +110,7 @@ public class RemoteHierarchicalContentNodeTest will(returnValue(remoteDss)); } }); - cache = new ContentCache(serviceFactory, sessionHolder, SESSION_WORKSPACE_DIR, fileOperations); + cache = new ContentCache(serviceFactory, SESSION_WORKSPACE_DIR, false, fileOperations); } @Test