Fixing incremental feed of share Acl and DFS share Acl
diff --git a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
index c12f3b3..972cc84 100644
--- a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
+++ b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
@@ -27,6 +27,7 @@
import com.google.enterprise.adaptor.DocIdPusher;
import com.google.enterprise.adaptor.DocIdPusher.Record;
import com.google.enterprise.adaptor.IOHelper;
+import com.google.enterprise.adaptor.PollingIncrementalLister;
import com.google.enterprise.adaptor.Principal;
import com.google.enterprise.adaptor.Request;
import com.google.enterprise.adaptor.Response;
@@ -71,7 +72,8 @@
* <li>Uses hierarchical ACL model
* </ul>
*/
-public class FsAdaptor extends AbstractAdaptor {
+public class FsAdaptor extends AbstractAdaptor implements
+ PollingIncrementalLister {
private static final Logger log
= Logger.getLogger(FsAdaptor.class.getName());
@@ -138,6 +140,7 @@
private DocId rootPathDocId;
private FileDelegate delegate;
private FsMonitor monitor;
+ private ShareAcls lastPushedShareAcls = new ShareAcls(null, null);
public FsAdaptor() {
// At the moment, we only support Windows.
@@ -228,6 +231,8 @@
maxLatencyMillis);
delegate.startMonitorPath(rootPath, monitor.getQueue());
monitor.start();
+
+ context.setPollingIncrementalLister(this);
}
@Override
@@ -237,17 +242,9 @@
monitor = null;
}
- @Override
- public void getDocIds(DocIdPusher pusher) throws InterruptedException,
- IOException {
- log.entering("FsAdaptor", "getDocIds", new Object[] {pusher, rootPath});
- pusher.pushDocIds(Arrays.asList(delegate.newDocId(rootPath)));
-
- // The pusher does not support fragments in named resources.
- // Feed a DocId that is just the SHARE_ACL fragment to avoid
- // collisions with the root docid.
-
- Map<DocId, Acl> namedResources = new HashMap<DocId, Acl>();
+ private ShareAcls getShareAcls() throws IOException {
+ Acl shareAcl;
+ Acl dfsShareAcl;
if (isDfsUnc) {
// For a DFS UNC we have a DFS Acl that must be sent. Also, the share Acl
@@ -257,8 +254,8 @@
AclBuilder builder = new AclBuilder(rootPath,
delegate.getDfsShareAclView(rootPath.getParent()),
supportedWindowsAccounts, builtinPrefix, namespace);
- namedResources.put(DFS_SHARE_ACL_DOCID, builder.getAcl()
- .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build());
+ dfsShareAcl = builder.getAcl().setInheritanceType(
+ InheritanceType.AND_BOTH_PERMIT).build();
// Push the Acl for the active storage UNC path.
Path activeStorage = delegate.getDfsUncActiveStorageUnc(rootPath);
@@ -270,21 +267,58 @@
builder = new AclBuilder(activeStorage,
delegate.getShareAclView(activeStorage),
supportedWindowsAccounts, builtinPrefix, namespace);
- namedResources.put(SHARE_ACL_DOCID, builder.getAcl()
+ shareAcl = builder.getAcl()
.setInheritFrom(DFS_SHARE_ACL_DOCID)
- .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build());
+ .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build();
} else {
// For a non-DFS UNC we have only have a share Acl to push.
AclBuilder builder = new AclBuilder(rootPath,
delegate.getShareAclView(rootPath),
supportedWindowsAccounts, builtinPrefix, namespace);
- namedResources.put(SHARE_ACL_DOCID, builder.getAcl()
- .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build());
+ dfsShareAcl = null;
+ shareAcl = builder.getAcl().setInheritanceType(
+ InheritanceType.AND_BOTH_PERMIT).build();
}
- pusher.pushNamedResources(namedResources);
+ return new ShareAcls(shareAcl, dfsShareAcl);
+ }
- log.exiting("FsAdaptor", "getDocIds");
+ @Override
+ public void getDocIds(DocIdPusher pusher) throws InterruptedException,
+ IOException {
+ log.entering("FsAdaptor", "getDocIds", new Object[] {pusher, rootPath});
+ pusher.pushDocIds(Arrays.asList(delegate.newDocId(rootPath)));
+ pushShareAcls(pusher, true);
+ log.exiting("FsAdaptor", "getDocIds", pusher);
+ }
+
+ @Override
+ public void getModifiedDocIds(DocIdPusher pusher)
+ throws InterruptedException, IOException {
+ log.entering("FsAdaptor", "getModifiedDocIds");
+ pushShareAcls(pusher, false);
+ log.exiting("FsAdaptor", "getModifiedDocIds", pusher);
+ }
+
+ private void pushShareAcls(DocIdPusher pusher, boolean forcePush)
+ throws InterruptedException, IOException {
+ // The pusher does not support fragments in named resources.
+ // Feed a DocId that is just the SHARE_ACL fragment to avoid
+ // collisions with the root docid.
+ ShareAcls shareAcls = getShareAcls();
+ Map<DocId, Acl> namedResources = new HashMap<DocId, Acl>();
+ if (forcePush || ((shareAcls.dfsShareAcl != null)
+ && !shareAcls.dfsShareAcl.equals(lastPushedShareAcls.dfsShareAcl))) {
+ namedResources.put(DFS_SHARE_ACL_DOCID, shareAcls.dfsShareAcl);
+ }
+ if (forcePush || ((shareAcls.shareAcl != null)
+ && !shareAcls.shareAcl.equals(lastPushedShareAcls.shareAcl))) {
+ namedResources.put(SHARE_ACL_DOCID, shareAcls.shareAcl);
+ }
+ if (namedResources.size() > 0) {
+ pusher.pushNamedResources(namedResources);
+ lastPushedShareAcls = shareAcls;
+ }
}
@Override
@@ -571,6 +605,19 @@
}
}
+ private class ShareAcls {
+ private final Acl shareAcl;
+ private final Acl dfsShareAcl;
+
+ public ShareAcls(Acl shareAcl, Acl dfsShareAcl) {
+ Preconditions.checkNotNull(shareAcl, "the share Acl may not be null");
+ Preconditions.checkArgument(!isDfsUnc || (dfsShareAcl != null),
+ "the DFS share Acl may not be null");
+ this.shareAcl = shareAcl;
+ this.dfsShareAcl = dfsShareAcl;
+ }
+ }
+
/** Call default main for adaptors. */
public static void main(String[] args) {
AbstractAdaptor.main(new FsAdaptor(), args);
diff --git a/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java b/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
index 539b74b..9eb2d16 100644
--- a/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
@@ -14,6 +14,8 @@
package com.google.enterprise.adaptor.fs;
+import com.google.enterprise.adaptor.AccumulatingDocIdPusher;
+
import static org.junit.Assert.*;
import org.junit.*;
@@ -34,4 +36,16 @@
assertEquals("folder2",
adaptor.getPathName(Paths.get("C:/folder1/folder2/")));
}
+
+ @Test
+ public void testIncrementalShareAcls() throws Exception {
+ FsAdaptor adaptor = new FsAdaptor();
+ AccumulatingDocIdPusher pusher = new AccumulatingDocIdPusher();
+ adaptor.getDocIds(pusher);
+
+ adaptor.getModifiedDocIds(pusher);
+ assertEquals("share", adaptor.getPathName(Paths.get("\\\\host/share/")));
+ assertEquals("folder2",
+ adaptor.getPathName(Paths.get("C:/folder1/folder2/")));
+ }
}