Don't use instanceof to infer Adaptor features
Instead, the Adaptor explicitly provides the way to handle a feature via
AdaptorContext.
diff --git a/src/com/google/enterprise/adaptor/Adaptor.java b/src/com/google/enterprise/adaptor/Adaptor.java
index d0b0380..b25e764 100644
--- a/src/com/google/enterprise/adaptor/Adaptor.java
+++ b/src/com/google/enterprise/adaptor/Adaptor.java
@@ -34,7 +34,7 @@
*
* @see com.google.enterprise.adaptor.examples.AdaptorTemplate
* @see AbstractAdaptor
- * @see PollingIncrementalAdaptor
+ * @see PollingIncrementalLister
*/
public interface Adaptor {
/**
diff --git a/src/com/google/enterprise/adaptor/AdaptorContext.java b/src/com/google/enterprise/adaptor/AdaptorContext.java
index c22f93f..a1e01be 100644
--- a/src/com/google/enterprise/adaptor/AdaptorContext.java
+++ b/src/com/google/enterprise/adaptor/AdaptorContext.java
@@ -103,4 +103,16 @@
* and {@code create = false}
*/
public Session getUserSession(HttpExchange ex, boolean create);
+
+ /**
+ * Register a polling incremental lister, so that it can be called when
+ * appropriate. Registration may not occur after {@link Adaptor#init}.
+ */
+ public void setPollingIncrementalLister(PollingIncrementalLister lister);
+
+ /**
+ * Register an authentication provider, so it can authenticate users for the
+ * GSA. Registration may not occur after {@link Adaptor#init}.
+ */
+ public void setAuthnAuthority(AuthnAuthority authnAuthority);
}
diff --git a/src/com/google/enterprise/adaptor/AuthnAdaptor.java b/src/com/google/enterprise/adaptor/AuthnAuthority.java
similarity index 95%
rename from src/com/google/enterprise/adaptor/AuthnAdaptor.java
rename to src/com/google/enterprise/adaptor/AuthnAuthority.java
index 9e26b85..79d3904 100644
--- a/src/com/google/enterprise/adaptor/AuthnAdaptor.java
+++ b/src/com/google/enterprise/adaptor/AuthnAuthority.java
@@ -20,8 +20,11 @@
/**
* Interface for adaptors capable of authenticating users.
+ *
+ * <p>Instances of this interface are typically registered with {@link
+ * AdaptorContext#setAuthnAuthority}.
*/
-public interface AuthnAdaptor extends Adaptor {
+public interface AuthnAuthority {
/**
* Authenticate the user connected via {@code ex}. After attempting to
* authenticate the user the implementation should respond by calling {@link
diff --git a/src/com/google/enterprise/adaptor/Config.java b/src/com/google/enterprise/adaptor/Config.java
index 056397d..4333a44 100644
--- a/src/com/google/enterprise/adaptor/Config.java
+++ b/src/com/google/enterprise/adaptor/Config.java
@@ -41,8 +41,8 @@
* hour, day of month, month, day of week). Defaults to 0 3 * * *
* <tr><td> </td><td>adaptor.incrementalPollPeriodSecs </td><td> number
* of seconds between invocations of {@link
- * PollingIncrementalAdaptor#getModifiedDocIds
- * PollingIncrementalAdaptor.getModifiedDocIds}. Defaults to 900
+ * PollingIncrementalLister#getModifiedDocIds
+ * PollingIncrementalLister.getModifiedDocIds}. Defaults to 900
* <tr><td> </td><td>adaptor.docContentTimeoutSecs </td><td> number of seconds
* adaptor has to complete sending content before it is interrupted. Timing
* starts when sending content starts. Defaults to 180
diff --git a/src/com/google/enterprise/adaptor/Dashboard.java b/src/com/google/enterprise/adaptor/Dashboard.java
index 7ed959c..3fa2e8a 100644
--- a/src/com/google/enterprise/adaptor/Dashboard.java
+++ b/src/com/google/enterprise/adaptor/Dashboard.java
@@ -39,6 +39,7 @@
private final GsaCommunicationHandler gsaCommHandler;
private final SessionManager<HttpExchange> sessionManager;
private final RpcHandler rpcHandler;
+ private final Adaptor adaptor;
public Dashboard(Config config, GsaCommunicationHandler gsaCommHandler,
Journal journal, SessionManager<HttpExchange> sessionManager,
@@ -47,6 +48,7 @@
this.gsaCommHandler = gsaCommHandler;
this.journal = journal;
this.sessionManager = sessionManager;
+ this.adaptor = adaptor;
rpcHandler = new RpcHandler(sessionManager);
rpcHandler.registerRpcMethod("startFeedPush", new StartFeedPushRpcMethod());
@@ -55,8 +57,6 @@
circularLogRpcMethod = new CircularLogRpcMethod();
rpcHandler.registerRpcMethod("getLog", circularLogRpcMethod);
rpcHandler.registerRpcMethod("getConfig", new ConfigRpcMethod(config));
- rpcHandler.registerRpcMethod("getStats",
- new StatRpcMethod(journal, adaptor));
rpcHandler.registerRpcMethod("getStatuses", new StatusRpcMethod(monitor));
rpcHandler.registerRpcMethod("checkForUpdatedConfig",
new CheckForUpdatedConfigRpcMethod(gsaCommHandler));
@@ -71,6 +71,9 @@
/** Starts listening for connections to the dashboard. */
public void start(HttpServer dashboardServer, String contextPrefix)
throws IOException {
+ rpcHandler.registerRpcMethod("getStats", new StatRpcMethod(journal, adaptor,
+ gsaCommHandler.isAdaptorIncremental()));
+
this.scope = new HttpServerScope(dashboardServer, contextPrefix);
int dashboardPort = dashboardServer.getAddress().getPort();
if (dashboardPort != config.getServerDashboardPort()) {
diff --git a/src/com/google/enterprise/adaptor/DocIdSender.java b/src/com/google/enterprise/adaptor/DocIdSender.java
index cd9ddd0..34b97fc 100644
--- a/src/com/google/enterprise/adaptor/DocIdSender.java
+++ b/src/com/google/enterprise/adaptor/DocIdSender.java
@@ -84,8 +84,8 @@
* Calls {@link Adaptor#getModifiedDocIds}. This method blocks until all
* DocIds are sent or retrying failed.
*/
- public void pushIncrementalDocIdsFromAdaptor(ExceptionHandler handler)
- throws InterruptedException {
+ public void pushIncrementalDocIdsFromAdaptor(PollingIncrementalLister lister,
+ ExceptionHandler handler) throws InterruptedException {
if (handler == null) {
throw new NullPointerException();
}
@@ -94,7 +94,7 @@
for (int ntries = 1;; ntries++) {
boolean keepGoing = true;
try {
- ((PollingIncrementalAdaptor) adaptor).getModifiedDocIds(this);
+ lister.getModifiedDocIds(this);
break; // Success
} catch (InterruptedException ex) {
// Stop early.
diff --git a/src/com/google/enterprise/adaptor/GsaCommunicationHandler.java b/src/com/google/enterprise/adaptor/GsaCommunicationHandler.java
index 6c883c9..05c2a0b 100644
--- a/src/com/google/enterprise/adaptor/GsaCommunicationHandler.java
+++ b/src/com/google/enterprise/adaptor/GsaCommunicationHandler.java
@@ -45,6 +45,9 @@
private final Adaptor adaptor;
private final Config config;
private final Journal journal;
+ private boolean afterInit;
+ private PollingIncrementalLister pollingIncrementalLister;
+ private AuthnAuthority authnAuthority;
/**
* Cron-style scheduler. Available for other uses, but necessary for
* scheduling {@link docIdFullPusher}. Tasks should execute quickly, to allow
@@ -254,6 +257,7 @@
// Since the Adaptor has been started, we can now issue other calls to it.
// Usages of 'adaptor' are completely safe after this point.
+ afterInit = true;
// Since we are white-listing particular keys for auto-update, things aren't
// ready enough to expose to adaptors.
@@ -269,16 +273,14 @@
config.getServerPort(), config.getGsaHostname(),
config.getGsaSamlEntityId(), config.getServerSamlEntityId());
- if (adaptor instanceof AuthnAdaptor) {
- log.config("Adaptor is an AuthnAdaptor; enabling adaptor-based "
- + "authentication");
+ if (authnAuthority != null) {
+ log.config("Adaptor-based authentication supported");
samlIdentityProvider = new SamlIdentityProvider(
- (AuthnAdaptor) adaptor, metadata, key);
+ authnAuthority, metadata, key);
addFilters(scope.createContext("/samlip",
samlIdentityProvider.getSingleSignOnHandler()));
} else {
- log.config("Adaptor is not an AuthnAdaptor; not enabling adaptor-based "
- + "authentication");
+ log.config("Adaptor-based authentication not supported");
}
samlServiceProvider
= new SamlServiceProvider(sessionManager, metadata, key);
@@ -323,9 +325,9 @@
checkAndScheduleImmediatePushOfDocIds();
}
- if (adaptor instanceof PollingIncrementalAdaptor) {
+ if (pollingIncrementalLister != null) {
docIdIncrementalPusher = new OneAtATimeRunnable(
- new IncrementalPushRunnable((PollingIncrementalAdaptor) adaptor),
+ new IncrementalPushRunnable(pollingIncrementalLister),
new AlreadyRunningRunnable());
scheduleExecutor.scheduleAtFixedRate(
@@ -493,6 +495,7 @@
scope.close();
}
if (dashboard != null) {
+ dashboard.clearStatusSources();
dashboard.stop();
}
if (scheduleExecutor != null) {
@@ -508,7 +511,6 @@
Thread.currentThread().interrupt();
}
}
- dashboard.clearStatusSources();
try {
adaptor.destroy();
} finally {
@@ -523,6 +525,9 @@
waiter = null;
sessionManager = null;
docIdCodec = null;
+ afterInit = false;
+ pollingIncrementalLister = null;
+ authnAuthority = null;
}
}
@@ -544,7 +549,7 @@
/**
* Perform an push of incremental changes. This works only for adaptors that
- * support incremental polling (implements {@link PollingIncrementalAdaptor}.
+ * support incremental polling (implements {@link PollingIncrementalLister}.
*/
public synchronized boolean checkAndScheduleIncrementalPushOfDocIds() {
if (docIdIncrementalPusher == null) {
@@ -562,6 +567,10 @@
return true;
}
+ boolean isAdaptorIncremental() {
+ return pollingIncrementalLister != null;
+ }
+
boolean ensureLatestConfigLoaded() {
try {
return config.ensureLatestConfigLoaded();
@@ -617,16 +626,17 @@
private class IncrementalPushRunnable implements Runnable {
private volatile ExceptionHandler handler
= ExceptionHandlers.defaultHandler();
- private PollingIncrementalAdaptor adaptor;
+ private PollingIncrementalLister adaptor;
- public IncrementalPushRunnable(PollingIncrementalAdaptor adaptor) {
+ public IncrementalPushRunnable(PollingIncrementalLister adaptor) {
this.adaptor = adaptor;
}
@Override
public void run() {
try {
- docIdSender.pushIncrementalDocIdsFromAdaptor(handler);
+ docIdSender.pushIncrementalDocIdsFromAdaptor(
+ pollingIncrementalLister, handler);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception ex) {
@@ -795,5 +805,21 @@
}
return nsSession;
}
+
+ @Override
+ public void setPollingIncrementalLister(PollingIncrementalLister lister) {
+ if (afterInit) {
+ throw new IllegalStateException("After init()");
+ }
+ pollingIncrementalLister = lister;
+ }
+
+ @Override
+ public void setAuthnAuthority(AuthnAuthority authnAuthority) {
+ if (afterInit) {
+ throw new IllegalStateException("After init()");
+ }
+ authnAuthority = authnAuthority;
+ }
}
}
diff --git a/src/com/google/enterprise/adaptor/PollingIncrementalAdaptor.java b/src/com/google/enterprise/adaptor/PollingIncrementalLister.java
similarity index 97%
rename from src/com/google/enterprise/adaptor/PollingIncrementalAdaptor.java
rename to src/com/google/enterprise/adaptor/PollingIncrementalLister.java
index d070213..6f23396 100644
--- a/src/com/google/enterprise/adaptor/PollingIncrementalAdaptor.java
+++ b/src/com/google/enterprise/adaptor/PollingIncrementalLister.java
@@ -33,7 +33,7 @@
* adaptor for the user. Thus, adaptors are encouraged to implement this
* interface if it is applicable.
*/
-public interface PollingIncrementalAdaptor extends Adaptor {
+public interface PollingIncrementalLister {
/**
* Check for documents modified since the last call to the method. This method
* is intended to provide little-effort updates to the GSA about recent
diff --git a/src/com/google/enterprise/adaptor/SamlIdentityProvider.java b/src/com/google/enterprise/adaptor/SamlIdentityProvider.java
index 852d43c..b4299e1 100644
--- a/src/com/google/enterprise/adaptor/SamlIdentityProvider.java
+++ b/src/com/google/enterprise/adaptor/SamlIdentityProvider.java
@@ -97,13 +97,13 @@
}
}
- private final AuthnAdaptor adaptor;
+ private final AuthnAuthority adaptor;
/** Credentials to use to sign messages. */
private final Credential cred;
private final SamlMetadata metadata;
private final SsoHandler ssoHandler = new SsoHandler();
- public SamlIdentityProvider(AuthnAdaptor adaptor, SamlMetadata metadata,
+ public SamlIdentityProvider(AuthnAuthority adaptor, SamlMetadata metadata,
KeyPair key) {
if (adaptor == null || metadata == null) {
throw new NullPointerException();
@@ -274,7 +274,7 @@
}
}
- private class AuthnCallback implements AuthnAdaptor.Callback {
+ private class AuthnCallback implements AuthnAuthority.Callback {
private final SAMLMessageContext<AuthnRequest, Response, NameID> context;
public AuthnCallback(
diff --git a/src/com/google/enterprise/adaptor/StatRpcMethod.java b/src/com/google/enterprise/adaptor/StatRpcMethod.java
index ca73c3d..9397697 100644
--- a/src/com/google/enterprise/adaptor/StatRpcMethod.java
+++ b/src/com/google/enterprise/adaptor/StatRpcMethod.java
@@ -29,9 +29,10 @@
private Journal journal;
private boolean isAdaptorIncremental;
- public StatRpcMethod(Journal journal, Adaptor adaptor) {
+ public StatRpcMethod(Journal journal, Adaptor adaptor,
+ boolean isAdaptorIncremental) {
this.journal = journal;
- this.isAdaptorIncremental = adaptor instanceof PollingIncrementalAdaptor;
+ this.isAdaptorIncremental = isAdaptorIncremental;
Class adaptorClass = adaptor.getClass();
if (adaptorClass.getPackage() != null) {
diff --git a/src/com/google/enterprise/adaptor/WrapperAdaptor.java b/src/com/google/enterprise/adaptor/WrapperAdaptor.java
index 595694d..38dc91b 100644
--- a/src/com/google/enterprise/adaptor/WrapperAdaptor.java
+++ b/src/com/google/enterprise/adaptor/WrapperAdaptor.java
@@ -477,5 +477,15 @@
public Session getUserSession(HttpExchange ex, boolean create) {
return context.getUserSession(ex, create);
}
+
+ @Override
+ public void setPollingIncrementalLister(PollingIncrementalLister lister) {
+ context.setPollingIncrementalLister(lister);
+ }
+
+ @Override
+ public void setAuthnAuthority(AuthnAuthority authnAuthority) {
+ context.setAuthnAuthority(authnAuthority);
+ }
}
}
diff --git a/test/com/google/enterprise/adaptor/GsaCommunicationHandlerTest.java b/test/com/google/enterprise/adaptor/GsaCommunicationHandlerTest.java
index a7364b1..3836651 100644
--- a/test/com/google/enterprise/adaptor/GsaCommunicationHandlerTest.java
+++ b/test/com/google/enterprise/adaptor/GsaCommunicationHandlerTest.java
@@ -115,11 +115,16 @@
@Test
public void testPollingIncrementalAdaptor() throws Exception {
class PollingIncrNullAdaptor extends NullAdaptor
- implements PollingIncrementalAdaptor {
+ implements PollingIncrementalLister {
public final ArrayBlockingQueue<Object> queue
= new ArrayBlockingQueue<Object>(1);
@Override
+ public void init(AdaptorContext context) {
+ context.setPollingIncrementalLister(this);
+ }
+
+ @Override
public void getModifiedDocIds(DocIdPusher pusher) {
queue.offer(new Object());
}
diff --git a/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java b/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java
index 4562ead..8b67eba 100644
--- a/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java
+++ b/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java
@@ -43,7 +43,7 @@
private UserPrincipal user = new UserPrincipal("user1");
private Set<GroupPrincipal> groups = GroupPrincipal.makeSet(Arrays.asList(
"group1", "group2"));
- private AuthnAdaptor adaptor = new AuthnAdaptorImpl();
+ private AuthnAuthority adaptor = new AuthnAuthorityImpl();
private SamlIdentityProvider identityProvider = new SamlIdentityProvider(
adaptor, metadata, null);
private MockHttpContext httpContext = new MockHttpsContext(null, "/samlip");
@@ -112,17 +112,7 @@
assertEquals(404, ex.getResponseCode());
}
- private class AuthnAdaptorImpl extends AbstractAdaptor
- implements AuthnAdaptor {
- @Override
- public void getDocContent(Request request, Response response)
- throws IOException {
- response.respondNotFound();
- }
-
- @Override
- public void getDocIds(DocIdPusher pusher) {}
-
+ private class AuthnAuthorityImpl implements AuthnAuthority {
@Override
public void authenticateUser(HttpExchange ex, Callback callback)
throws IOException {
diff --git a/test/com/google/enterprise/adaptor/StatRpcMethodTest.java b/test/com/google/enterprise/adaptor/StatRpcMethodTest.java
index c865684..f1b642a 100644
--- a/test/com/google/enterprise/adaptor/StatRpcMethodTest.java
+++ b/test/com/google/enterprise/adaptor/StatRpcMethodTest.java
@@ -18,19 +18,14 @@
import org.junit.Test;
-import java.io.IOException;
-
import java.util.*;
/**
* Tests for {@link StatRpcMethod}.
*/
public class StatRpcMethodTest {
- private RpcHandler.RpcMethod method;
-
- public StatRpcMethodTest() {
- method = new StatRpcMethod(new SnapshotMockJournal(), new AdaptorMock());
- }
+ private RpcHandler.RpcMethod method = new StatRpcMethod(
+ new SnapshotMockJournal(), new AdaptorMock(), false);
@Test
public void testStat() throws Exception {