IGNITE-3530: IGFS: Added missing "setTimes" method to IgfsSeconadryFileSystem.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c075ab33 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c075ab33 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c075ab33 Branch: refs/heads/ignite-3300 Commit: c075ab33254b7178c6e6b0a7b16801e787189ced Parents: ce53491 Author: vozerov-gridgain <voze...@gridgain.com> Authored: Mon Jul 25 08:54:05 2016 +0300 Committer: vozerov-gridgain <voze...@gridgain.com> Committed: Mon Jul 25 08:54:05 2016 +0300 ---------------------------------------------------------------------- .../internal/processors/igfs/IgfsImpl.java | 12 +- .../processors/igfs/IgfsMetaManager.java | 115 ++++++++++++------- .../igfs/IgfsSecondaryFileSystemImpl.java | 15 ++- .../igfs/IgfsSecondaryFileSystemV2.java | 40 +++++++ .../processors/igfs/IgfsAbstractSelfTest.java | 111 +++++++++++++++++- .../igfs/IgfsDualAbstractSelfTest.java | 34 ++++++ .../igfs/IgfsExUniversalFileSystemAdapter.java | 15 +++ .../processors/igfs/IgfsModesSelfTest.java | 2 - .../igfs/UniversalFileSystemAdapter.java | 11 ++ .../fs/IgniteHadoopIgfsSecondaryFileSystem.java | 16 ++- ...oopFileSystemUniversalFileSystemAdapter.java | 8 ++ 11 files changed, 316 insertions(+), 63 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java index 5b87698..df7dfb5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java @@ -1139,16 +1139,12 @@ public final class IgfsImpl implements IgfsEx { safeOp(new Callable<Void>() { @Override public Void call() throws Exception { - FileDescriptor desc = getFileDescriptor(path); - - if (desc == null) - throw new IgfsPathNotFoundException("Failed to update times (path not found): " + path); + IgfsMode mode = resolveMode(path); - // Cannot update times for root. - if (desc.parentId == null) - return null; + boolean useSecondary = IgfsUtils.isDualMode(mode) && secondaryFs instanceof IgfsSecondaryFileSystemV2; - meta.updateTimes(desc.parentId, desc.fileId, desc.fileName, accessTime, modificationTime); + meta.updateTimes(path, accessTime, modificationTime, + useSecondary ? (IgfsSecondaryFileSystemV2)secondaryFs : null); return null; } http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java index 1640918..d891b38 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java @@ -51,14 +51,14 @@ import org.apache.ignite.internal.processors.igfs.client.IgfsClientAbstractCalla import org.apache.ignite.internal.processors.igfs.client.meta.IgfsClientMetaIdsForPathCallable; import org.apache.ignite.internal.processors.igfs.client.meta.IgfsClientMetaInfoForPathCallable; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryCreateProcessor; +import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingAddProcessor; +import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingRemoveProcessor; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingRenameProcessor; +import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingReplaceProcessor; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaFileCreateProcessor; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaFileLockProcessor; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaFileReserveSpaceProcessor; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaFileUnlockProcessor; -import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingAddProcessor; -import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingRemoveProcessor; -import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingReplaceProcessor; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaUpdatePropertiesProcessor; import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaUpdateTimesProcessor; import org.apache.ignite.internal.util.GridLeanMap; @@ -1155,16 +1155,20 @@ public class IgfsMetaManager extends IgfsManager { } /** - * Wheter operation must be re-tries because we have suspicious links which may broke secondary file system + * Whether operation must be re-tried because we have suspicious links which may broke secondary file system * consistency. * * @param pathIds Path IDs. * @param lockInfos Lock infos. * @return Whether to re-try. */ - private boolean isRetryForSecondary(IgfsPathIds pathIds, Map<IgniteUuid, IgfsEntryInfo> lockInfos) { + private static boolean isRetryForSecondary(IgfsPathIds pathIds, Map<IgniteUuid, IgfsEntryInfo> lockInfos) { // We need to ensure that the last locked info is not linked with expected child. // Otherwise there was some concurrent file system update and we have to re-try. + // That is, the following situation lead to re-try: + // 1) We queried path /A/B/C + // 2) Returned IDs are ROOT_ID, A_ID, B_ID, null + // 3) But B's info contains C as child. It mean's that if (!pathIds.allExists()) { // Find the last locked index IgfsEntryInfo lastLockedInfo = null; @@ -2754,59 +2758,82 @@ public class IgfsMetaManager extends IgfsManager { } /** - * Updates last access and last modification times. + * Update times. * - * @param parentId File parent ID. - * @param fileId File ID to update. - * @param fileName File name to update. Must match file ID. - * @param accessTime Access time to set. If {@code -1}, will not be updated. - * @param modificationTime Modification time to set. If {@code -1}, will not be updated. - * @throws IgniteCheckedException If update failed. + * @param path Path. + * @param accessTime Access time. + * @param modificationTime Modification time. + * @param secondaryFs Secondary file system. + * @throws IgniteCheckedException If failed. */ - public void updateTimes(IgniteUuid parentId, IgniteUuid fileId, String fileName, long accessTime, - long modificationTime) throws IgniteCheckedException { - if (busyLock.enterBusy()) { - try { - validTxState(false); + public void updateTimes(IgfsPath path, long accessTime, long modificationTime, + IgfsSecondaryFileSystemV2 secondaryFs) throws IgniteCheckedException { + while (true) { + if (busyLock.enterBusy()) { + try { + validTxState(false); - // Start pessimistic transaction. - try (IgniteInternalTx tx = startTx()) { - Map<IgniteUuid, IgfsEntryInfo> infoMap = lockIds(fileId, parentId); + // Prepare path IDs. + IgfsPathIds pathIds = pathIds(path); + + // Prepare lock IDs. + Set<IgniteUuid> lockIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR); + + pathIds.addExistingIds(lockIds, relaxed); + + // Start TX. + try (IgniteInternalTx tx = startTx()) { + Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(lockIds); - IgfsEntryInfo fileInfo = infoMap.get(fileId); + if (secondaryFs != null && isRetryForSecondary(pathIds, lockInfos)) + continue; - if (fileInfo == null) - throw fsException(new IgfsPathNotFoundException("Failed to update times " + - "(path was not found): " + fileName)); + if (!pathIds.verifyIntegrity(lockInfos, relaxed)) + // Directory structure changed concurrently. So we re-try. + continue; - IgfsEntryInfo parentInfo = infoMap.get(parentId); + if (pathIds.allExists()) { + // All files are in place. Update both primary and secondary file systems. + if (secondaryFs != null) + secondaryFs.setTimes(path, accessTime, modificationTime); - if (parentInfo == null) - throw fsException(new IgfsPathNotFoundException("Failed to update times " + - "(parent was not found): " + fileName)); + IgniteUuid targetId = pathIds.lastExistingId(); + IgfsEntryInfo targetInfo = lockInfos.get(targetId); - // Validate listing. - if (!parentInfo.hasChild(fileName, fileId)) - throw fsException(new IgfsConcurrentModificationException("Failed to update times " + - "(file concurrently modified): " + fileName)); + id2InfoPrj.invoke(targetId, new IgfsMetaUpdateTimesProcessor( + accessTime == -1 ? targetInfo.accessTime() : accessTime, + modificationTime == -1 ? targetInfo.modificationTime() : modificationTime) + ); - assert parentInfo.isDirectory(); + tx.commit(); - id2InfoPrj.invoke(fileId, new IgfsMetaUpdateTimesProcessor( - accessTime == -1 ? fileInfo.accessTime() : accessTime, - modificationTime == -1 ? fileInfo.modificationTime() : modificationTime) - ); + return; + } + else { + // Propagate call to the secondary FS, as we might haven't cache this part yet. + if (secondaryFs != null) { + secondaryFs.setTimes(path, accessTime, modificationTime); - tx.commit(); + return; + } + else + throw new IgfsPathNotFoundException("Failed to update times (path not found): " + path); + } + } + } + catch (IgniteException | IgniteCheckedException e) { + throw e; + } + catch (Exception e) { + throw new IgniteCheckedException("setTimes failed due to unexpected exception: " + path, e); + } + finally { + busyLock.leaveBusy(); } } - finally { - busyLock.leaveBusy(); - } + else + throw new IllegalStateException("Failed to update times because Grid is stopping: " + path); } - else - throw new IllegalStateException("Failed to update times because Grid is stopping [parentId=" + parentId + - ", fileId=" + fileId + ", fileName=" + fileName + ']'); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemImpl.java index 44e858f..453682c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemImpl.java @@ -17,20 +17,20 @@ package org.apache.ignite.internal.processors.igfs; -import java.io.OutputStream; -import java.util.Collection; -import java.util.Map; import org.apache.ignite.IgniteException; import org.apache.ignite.igfs.IgfsFile; import org.apache.ignite.igfs.IgfsPath; -import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem; import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystemPositionedReadable; import org.jetbrains.annotations.Nullable; +import java.io.OutputStream; +import java.util.Collection; +import java.util.Map; + /** * Secondary file system over native IGFS. */ -class IgfsSecondaryFileSystemImpl implements IgfsSecondaryFileSystem { +class IgfsSecondaryFileSystemImpl implements IgfsSecondaryFileSystemV2 { /** Delegate. */ private final IgfsEx igfs; @@ -115,4 +115,9 @@ class IgfsSecondaryFileSystemImpl implements IgfsSecondaryFileSystem { @Override public long usedSpaceSize() throws IgniteException { return igfs.usedSpaceSize(); } + + /** {@inheritDoc} */ + @Override public void setTimes(IgfsPath path, long accessTime, long modificationTime) throws IgniteException { + igfs.setTimes(path, accessTime, modificationTime); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemV2.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemV2.java new file mode 100644 index 0000000..3775574 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemV2.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.internal.processors.igfs; + +import org.apache.ignite.IgniteException; +import org.apache.ignite.igfs.IgfsPath; +import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem; + +/** + * Extended version of secondary file system with missing methods. + * + * @deprecated Will be removed in Apache Ignite 2.0. Methods will be merged to {@link IgfsSecondaryFileSystem}. + */ +@Deprecated +public interface IgfsSecondaryFileSystemV2 extends IgfsSecondaryFileSystem { + /** + * Set times for the given path. + * + * @param path Path. + * @param accessTime Access time. + * @param modificationTime Modification time. + * @throws IgniteException If failed. + */ + public void setTimes(IgfsPath path, long accessTime, long modificationTime) throws IgniteException; +} http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java index c1c6c6c..384da95 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java @@ -50,6 +50,7 @@ import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.lang.GridAbsPredicate; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.G; +import org.apache.ignite.internal.util.typedef.T2; import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; @@ -1123,6 +1124,112 @@ public abstract class IgfsAbstractSelfTest extends IgfsCommonAbstractTest { } /** + * Test setTimes operation. + * + * @throws Exception If failed. + */ + public void testSetTimes() throws Exception { + createFile(igfs.asSecondary(), FILE, true, chunk); + + checkExist(igfs, igfsSecondary, DIR); + checkExist(igfs, igfsSecondary, SUBDIR); + checkExist(igfs, igfsSecondary, FILE); + + checkSetTimes(SUBDIR); + checkSetTimes(FILE); + + try { + igfs.setTimes(FILE2, Long.MAX_VALUE, Long.MAX_VALUE); + + fail("Exception is not thrown for missing file."); + } + catch (Exception ignore) { + // No-op. + } + } + + /** + * Check setTimes logic for path. + * + * @param path Path. + * @throws Exception If failed. + */ + private void checkSetTimes(IgfsPath path) throws Exception { + IgfsFile info = igfs.info(path); + T2<Long, Long> secondaryTimes = dual ? igfsSecondary.times(path.toString()) : null; + + assert info != null; + + // Change nothing. + igfs.setTimes(path, -1, -1); + + IgfsFile newInfo = igfs.info(path); + + assert newInfo != null; + + assertEquals(info.accessTime(), newInfo.accessTime()); + assertEquals(info.modificationTime(), newInfo.modificationTime()); + + if (dual) { + T2<Long, Long> newSecondaryTimes = igfsSecondary.times(path.toString()); + + assertEquals(secondaryTimes.get1(), newSecondaryTimes.get1()); + assertEquals(secondaryTimes.get2(), newSecondaryTimes.get2()); + } + + // Change only access time. + igfs.setTimes(path, info.accessTime() + 1, -1); + + newInfo = igfs.info(path); + + assert newInfo != null; + + assertEquals(info.accessTime() + 1, newInfo.accessTime()); + assertEquals(info.modificationTime(), newInfo.modificationTime()); + + if (dual) { + T2<Long, Long> newSecondaryTimes = igfsSecondary.times(path.toString()); + + assertEquals(newInfo.accessTime(), (long)newSecondaryTimes.get1()); + assertEquals(secondaryTimes.get2(), newSecondaryTimes.get2()); + } + + // Change only modification time. + igfs.setTimes(path, -1, info.modificationTime() + 1); + + newInfo = igfs.info(path); + + assert newInfo != null; + + assertEquals(info.accessTime() + 1, newInfo.accessTime()); + assertEquals(info.modificationTime() + 1, newInfo.modificationTime()); + + if (dual) { + T2<Long, Long> newSecondaryTimes = igfsSecondary.times(path.toString()); + + assertEquals(newInfo.accessTime(), (long)newSecondaryTimes.get1()); + assertEquals(newInfo.modificationTime(), (long)newSecondaryTimes.get2()); + } + + // Change both. + igfs.setTimes(path, info.accessTime() + 2, info.modificationTime() + 2); + + newInfo = igfs.info(path); + + assert newInfo != null; + + assertEquals(info.accessTime() + 2, newInfo.accessTime()); + assertEquals(info.modificationTime() + 2, newInfo.modificationTime()); + + if (dual) { + T2<Long, Long> newSecondaryTimes = igfsSecondary.times(path.toString()); + + assertEquals(newInfo.accessTime(), (long)newSecondaryTimes.get1()); + assertEquals(newInfo.modificationTime(), (long)newSecondaryTimes.get2()); + } + } + + /** * Test regular create. * * @throws Exception If failed. @@ -2764,8 +2871,8 @@ public abstract class IgfsAbstractSelfTest extends IgfsCommonAbstractTest { * @param chunks Data chunks. * @throws IOException In case of IO exception. */ - protected static void createFile(IgfsSecondaryFileSystem igfs, IgfsPath file, boolean overwrite, @Nullable byte[]... chunks) - throws IOException { + protected static void createFile(IgfsSecondaryFileSystem igfs, IgfsPath file, boolean overwrite, + @Nullable byte[]... chunks) throws IOException { OutputStream os = null; try { http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java index b8c8978..124bec6 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java @@ -1682,4 +1682,38 @@ public abstract class IgfsDualAbstractSelfTest extends IgfsAbstractSelfTest { assertEquals(timesFile0, timesFile1); assertEquals(timesFile20, timesFile21); } + + /** + * Test setTimes method when path is partially missing. + * + * @throws Exception If failed. + */ + public void testSetTimesMissingPartially() throws Exception { + create(igfs, paths(DIR), null); + + createFile(igfsSecondary, FILE, chunk); + + igfs.setTimes(FILE, Long.MAX_VALUE - 1, Long.MAX_VALUE); + + IgfsFile info = igfs.info(FILE); + + assert info != null; + + assertEquals(Long.MAX_VALUE - 1, info.accessTime()); + assertEquals(Long.MAX_VALUE, info.modificationTime()); + + T2<Long, Long> secondaryTimes = igfsSecondary.times(FILE.toString()); + + assertEquals(info.accessTime(), (long)secondaryTimes.get1()); + assertEquals(info.modificationTime(), (long)secondaryTimes.get2()); + + try { + igfs.setTimes(FILE2, Long.MAX_VALUE, Long.MAX_VALUE); + + fail("Exception is not thrown for missing file."); + } + catch (Exception ignore) { + // No-op. + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsExUniversalFileSystemAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsExUniversalFileSystemAdapter.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsExUniversalFileSystemAdapter.java index c6bef72..80b320b 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsExUniversalFileSystemAdapter.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsExUniversalFileSystemAdapter.java @@ -21,8 +21,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Map; + +import org.apache.ignite.igfs.IgfsFile; import org.apache.ignite.igfs.IgfsOutputStream; import org.apache.ignite.igfs.IgfsPath; +import org.apache.ignite.internal.util.typedef.T2; /** * Universal adapter over {@link IgfsEx} filesystem. @@ -60,6 +63,7 @@ public class IgfsExUniversalFileSystemAdapter implements UniversalFileSystemAdap } /** {@inheritDoc} */ + @SuppressWarnings("ConstantConditions") @Override public Map<String, String> properties(String path) { return igfsEx.info(new IgfsPath(path)).properties(); } @@ -92,6 +96,17 @@ public class IgfsExUniversalFileSystemAdapter implements UniversalFileSystemAdap } /** {@inheritDoc} */ + @Override public T2<Long, Long> times(String path) throws IOException { + IgfsFile info = igfsEx.info(new IgfsPath(path)); + + if (info == null) + throw new IOException("Path not found: " + path); + + return new T2<>(info.accessTime(), info.modificationTime()); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public <T> T unwrap(Class<T> clazz) { if (clazz == IgfsEx.class) return (T)igfsEx; http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java index a6b7502..5fcd8dd 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java @@ -492,8 +492,6 @@ public class IgfsModesSelfTest extends IgfsCommonAbstractTest { * @throws Exception If failed. */ public void testPropagationDualAsync() throws Exception { - fail("https://issues.apache.org/jira/browse/IGNITE-822"); - mode = DUAL_ASYNC; checkPropagation(); http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/UniversalFileSystemAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/UniversalFileSystemAdapter.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/UniversalFileSystemAdapter.java index eef0057..3f6d07e 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/UniversalFileSystemAdapter.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/UniversalFileSystemAdapter.java @@ -17,6 +17,8 @@ package org.apache.ignite.internal.processors.igfs; +import org.apache.ignite.internal.util.typedef.T2; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -89,6 +91,15 @@ public interface UniversalFileSystemAdapter { OutputStream openOutputStream(String path, boolean append) throws IOException; /** + * Get times for path. + * + * @param path Path. + * @return Times for path. + * @throws IOException If failed. + */ + T2<Long, Long> times(String path) throws IOException; + + /** * Gets an entity of the given type (class) associated with this universal adapter. * @param clazz The class representing the type we wish to adapt to. * @param <T> The type we need to adapt to. http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/hadoop/src/main/java/org/apache/ignite/hadoop/fs/IgniteHadoopIgfsSecondaryFileSystem.java ---------------------------------------------------------------------- diff --git a/modules/hadoop/src/main/java/org/apache/ignite/hadoop/fs/IgniteHadoopIgfsSecondaryFileSystem.java b/modules/hadoop/src/main/java/org/apache/ignite/hadoop/fs/IgniteHadoopIgfsSecondaryFileSystem.java index 329c605..0f17fa2 100644 --- a/modules/hadoop/src/main/java/org/apache/ignite/hadoop/fs/IgniteHadoopIgfsSecondaryFileSystem.java +++ b/modules/hadoop/src/main/java/org/apache/ignite/hadoop/fs/IgniteHadoopIgfsSecondaryFileSystem.java @@ -36,13 +36,13 @@ import org.apache.ignite.igfs.IgfsPath; import org.apache.ignite.igfs.IgfsPathAlreadyExistsException; import org.apache.ignite.igfs.IgfsPathNotFoundException; import org.apache.ignite.igfs.IgfsUserContext; -import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem; import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystemPositionedReadable; import org.apache.ignite.internal.processors.hadoop.HadoopPayloadAware; import org.apache.ignite.internal.processors.hadoop.igfs.HadoopIgfsProperties; import org.apache.ignite.internal.processors.hadoop.igfs.HadoopIgfsSecondaryFileSystemPositionedReadable; import org.apache.ignite.internal.processors.igfs.IgfsEntryInfo; import org.apache.ignite.internal.processors.igfs.IgfsFileImpl; +import org.apache.ignite.internal.processors.igfs.IgfsSecondaryFileSystemV2; import org.apache.ignite.internal.processors.igfs.IgfsUtils; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteOutClosure; @@ -66,7 +66,7 @@ import java.util.concurrent.Callable; * <p> * Target {@code FileSystem}'s are created on per-user basis using passed {@link HadoopFileSystemFactory}. */ -public class IgniteHadoopIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, LifecycleAware, +public class IgniteHadoopIgfsSecondaryFileSystem implements IgfsSecondaryFileSystemV2, LifecycleAware, HadoopPayloadAware { /** The default user name. It is used if no user context is set. */ private String dfltUsrName; @@ -515,6 +515,18 @@ public class IgniteHadoopIgfsSecondaryFileSystem implements IgfsSecondaryFileSys } } + /** {@inheritDoc} */ + @Override public void setTimes(IgfsPath path, long accessTime, long modificationTime) throws IgniteException { + try { + // We don't use FileSystem#getUsed() since it counts only the files + // in the filesystem root, not all the files recursively. + fileSystemForUser().setTimes(convert(path), modificationTime, accessTime); + } + catch (IOException e) { + throw handleSecondaryFsError(e, "Failed set times for path: " + path); + } + } + /** * Gets the underlying {@link FileSystem}. * This method is used solely for testing. http://git-wip-us.apache.org/repos/asf/ignite/blob/c075ab33/modules/hadoop/src/test/java/org/apache/ignite/igfs/HadoopFileSystemUniversalFileSystemAdapter.java ---------------------------------------------------------------------- diff --git a/modules/hadoop/src/test/java/org/apache/ignite/igfs/HadoopFileSystemUniversalFileSystemAdapter.java b/modules/hadoop/src/test/java/org/apache/ignite/igfs/HadoopFileSystemUniversalFileSystemAdapter.java index 44b8f40..5239054 100644 --- a/modules/hadoop/src/test/java/org/apache/ignite/igfs/HadoopFileSystemUniversalFileSystemAdapter.java +++ b/modules/hadoop/src/test/java/org/apache/ignite/igfs/HadoopFileSystemUniversalFileSystemAdapter.java @@ -31,6 +31,7 @@ import org.apache.ignite.hadoop.fs.HadoopFileSystemFactory; import org.apache.ignite.internal.processors.hadoop.igfs.HadoopIgfsUtils; import org.apache.ignite.internal.processors.igfs.IgfsUtils; import org.apache.ignite.internal.processors.igfs.UniversalFileSystemAdapter; +import org.apache.ignite.internal.util.typedef.T2; /** * Universal adapter wrapping {@link org.apache.hadoop.fs.FileSystem} instance. @@ -111,6 +112,13 @@ public class HadoopFileSystemUniversalFileSystemAdapter implements UniversalFile } /** {@inheritDoc} */ + @Override public T2<Long, Long> times(String path) throws IOException { + FileStatus status = get().getFileStatus(new Path(path)); + + return new T2<>(status.getAccessTime(), status.getModificationTime()); + } + + /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public <T> T unwrap(Class<T> cls) { if (HadoopFileSystemFactory.class.isAssignableFrom(cls))