blob: d7f62736603eb9358b746400e9aa2c2f7a9adadc [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
//
// 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 com.google.enterprise.adaptor;
import static org.junit.Assert.*;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.junit.*;
import org.junit.rules.ExpectedException;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.x500.X500Principal;
/**
* Tests for {@link DocumentHandler}.
*/
public class DocumentHandlerTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private MockAdaptor mockAdaptor = new MockAdaptor();
private MockDocIdCodec docIdCodec = new MockDocIdCodec();
private DocumentHandler handler = createDefaultHandlerForAdaptor(mockAdaptor);
private DocId defaultDocId = new DocId("test docId");
private String defaultPath
= docIdCodec.encodeDocId(defaultDocId).getRawPath();
private MockHttpExchange ex = new MockHttpExchange("GET", defaultPath,
new MockHttpContext("/"));
@Test
public void testSuccessBuilder() {
createHandlerBuilder().build();
}
@Test
public void testNullDocIdDecoder() {
thrown.expect(NullPointerException.class);
createHandlerBuilder().setDocIdDecoder(null).build();
}
@Test
public void testNullDocIdEncoder() {
thrown.expect(NullPointerException.class);
createHandlerBuilder().setDocIdEncoder(null).build();
}
@Test
public void testNullJournal() {
thrown.expect(NullPointerException.class);
createHandlerBuilder().setJournal(null).build();
}
@Test
public void testNullAdaptor() {
thrown.expect(NullPointerException.class);
createHandlerBuilder().setAdaptor(null).build();
}
@Test
public void testNullWatchdog() {
thrown.expect(NullPointerException.class);
createHandlerBuilder().setWatchdog(null).build();
}
@Test
public void testDenyForSecMgr() throws Exception {
ex.getRequestHeaders().add("User-Agent", "SecMgr");
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testSecurityDeny() throws Exception {
DocumentHandler handler = createDefaultHandlerForAdaptor(
new PrivateMockAdaptor());
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testSecurityDenyWithAuthnHandler() throws Exception {
SamlServiceProvider samlServiceProvider = new MockSamlServiceProvider() {
@Override
public void handleAuthentication(HttpExchange ex) throws IOException {
// Translation.HTTP_NOT_FOUND was randomly chosen.
HttpExchanges.cannedRespond(ex, 1234, Translation.HTTP_NOT_FOUND);
}
};
PrivateMockAdaptor adaptor = new PrivateMockAdaptor();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor).setAuthzAuthority(adaptor)
.setSamlServiceProvider(samlServiceProvider).build();
handler.handle(ex);
assertEquals(1234, ex.getResponseCode());
}
@Test
public void testSecurityPermit() throws Exception {
MockSamlServiceProvider samlServiceProvider = new MockSamlServiceProvider();
samlServiceProvider.setUserIdentity(new AuthnIdentityImpl
.Builder(new UserPrincipal("test")).build());
UserPrivateMockAdaptor adaptor = new UserPrivateMockAdaptor();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor).setAuthzAuthority(adaptor)
.setSamlServiceProvider(samlServiceProvider).build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
}
@Test
public void testSecurityNotFound() throws Exception {
Adaptor mockAdaptor = new MockAdaptor() {
@Override
public Map<DocId, AuthzStatus> isUserAuthorized(AuthnIdentity identity,
Collection<DocId> ids) {
Map<DocId, AuthzStatus> result
= new HashMap<DocId, AuthzStatus>(ids.size() * 2);
for (DocId id : ids) {
result.put(id, AuthzStatus.INDETERMINATE);
}
return Collections.unmodifiableMap(result);
}
@Override
public void getDocContent(Request request, Response response) {
throw new UnsupportedOperationException();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(mockAdaptor);
handler.handle(ex);
assertEquals(404, ex.getResponseCode());
}
@Test
public void testSecurityDisallowedUser() throws Exception {
MockSamlServiceProvider samlServiceProvider = new MockSamlServiceProvider();
samlServiceProvider.setUserIdentity(new AuthnIdentityImpl
.Builder(new UserPrincipal("test")).build());
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(new PrivateMockAdaptor())
.setSamlServiceProvider(samlServiceProvider).build();
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testSecurityFromGsa() throws Exception {
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(new PrivateMockAdaptor())
.setFullAccessHosts(new String[] {remoteIp, " "})
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertArrayEquals(mockAdaptor.documentBytes, ex.getResponseBytes());
assertEquals(Arrays.asList("", ""),
ex.getResponseHeaders().get("X-Gsa-External-Metadata"));
}
@Test
public void testSecuritySecureFromGsa() throws Exception {
DocumentHandler handler = createDefaultHandlerForAdaptor(
new PrivateMockAdaptor());
MockHttpExchange httpEx = ex;
MockHttpsExchange ex = new MockHttpsExchange(httpEx, new MockSslSession(
new X500Principal("CN=localhost, OU=Unknown, O=Unknown, C=Unknown")));
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertArrayEquals(mockAdaptor.documentBytes, ex.getResponseBytes());
assertEquals("public",
ex.getResponseHeaders().getFirst("X-Gsa-Serve-Security"));
}
@Test
public void testSecuritySecureNoCertificate() throws Exception {
DocumentHandler handler = createDefaultHandlerForAdaptor(
new PrivateMockAdaptor());
MockHttpExchange httpEx = ex;
MockHttpsExchange ex = new MockHttpsExchange(httpEx, new MockSslSession(
null));
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testSecuritySecureNotX500Principal() throws Exception {
DocumentHandler handler = createDefaultHandlerForAdaptor(
new PrivateMockAdaptor());
MockHttpExchange httpEx = ex;
MockHttpsExchange ex = new MockHttpsExchange(httpEx, new MockSslSession(
new KerberosPrincipal("someuser@not-domain")));
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testSecuritySecureNoCommonName() throws Exception {
DocumentHandler handler = createDefaultHandlerForAdaptor(
new PrivateMockAdaptor());
MockHttpExchange httpEx = ex;
MockHttpsExchange ex = new MockHttpsExchange(httpEx, new MockSslSession(
new X500Principal("OU=Unknown, O=Unknown, C=Unknown")));
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testSecuritySecureNotWhitelisted() throws Exception {
DocumentHandler handler = createDefaultHandlerForAdaptor(
new PrivateMockAdaptor());
MockHttpExchange httpEx = ex;
MockHttpsExchange ex = new MockHttpsExchange(httpEx, new MockSslSession(
new X500Principal("CN=nottrusted, OU=Unknown, O=Unknown, C=Unknown")));
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testSecurityFromGsaAutoAddWhitelist() throws Exception {
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(new PrivateMockAdaptor())
.setGsaHostname(remoteIp)
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertArrayEquals(mockAdaptor.documentBytes, ex.getResponseBytes());
}
@Test
public void testNormal() throws Exception {
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertArrayEquals(mockAdaptor.documentBytes, ex.getResponseBytes());
assertFalse(ex.getResponseHeaders().containsKey("X-Gsa-External-Metadata"));
assertFalse(ex.getResponseHeaders().containsKey("X-Gsa-External-Anchor"));
assertFalse(ex.getResponseHeaders().containsKey("X-Robots-Tag"));
assertFalse(ex.getResponseHeaders().containsKey("X-Gsa-Serve-Security"));
assertFalse(ex.getResponseHeaders().containsKey("Last-Modified"));
}
@Test
public void testNormalHead() throws Exception {
MockHttpExchange ex = new MockHttpExchange("HEAD", defaultPath,
new MockHttpContext(handler, "/"));
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertArrayEquals(new byte[] {}, ex.getResponseBytes());
}
@Test
public void testNormalPost() throws Exception {
MockHttpExchange ex = new MockHttpExchange("POST", defaultPath,
new MockHttpContext(handler, "/"));
handler.handle(ex);
assertEquals(405, ex.getResponseCode());
}
@Test
public void testWatchdogInterruption() throws Exception {
ScheduledExecutorService executor
= Executors.newSingleThreadScheduledExecutor();
Watchdog watchdog = new Watchdog(executor);
mockAdaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException, InterruptedException {
Thread.sleep(100);
super.getDocContent(request, response);
}
};
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(mockAdaptor)
.setAuthzAuthority(mockAdaptor)
.setWatchdog(watchdog)
.setHeaderTimeoutMillis(1)
.build();
try {
thrown.expect(RuntimeException.class);
handler.handle(ex);
} finally {
executor.shutdownNow();
}
}
@Test
public void testWatchdogNoInterruption() throws Exception {
ScheduledExecutorService executor
= Executors.newSingleThreadScheduledExecutor();
Watchdog watchdog = new Watchdog(executor);
DocumentHandler handler = createHandlerBuilder()
.setAuthzAuthority(new MockAdaptor())
.setWatchdog(watchdog)
.setHeaderTimeoutMillis(100)
.setContentTimeoutMillis(100)
.build();
try {
handler.handle(ex);
} finally {
executor.shutdownNow();
}
assertEquals(200, ex.getResponseCode());
}
@Test
public void testTransform() throws Exception {
final String key = "testing key";
List<DocumentTransform> transforms = new LinkedList<DocumentTransform>();
transforms.add(new DocumentTransform() {
@Override
public void transform(Metadata metadata, Map<String, String> params) {
metadata.set(key, metadata.getOneValue(key).toUpperCase());
metadata.set("docid", params.get("DocId"));
}
});
TransformPipeline transform = new TransformPipeline(transforms,
Arrays.asList("t1"));
mockAdaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException, InterruptedException {
response.addMetadata(key, "testing value");
super.getDocContent(request, response);
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(mockAdaptor)
.setFullAccessHosts(new String[] {remoteIp})
.setTransform(transform)
.build();
mockAdaptor.documentBytes = new byte[] {1, 2, 3};
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals("docid=test%20docId,testing%20key=TESTING%20VALUE",
ex.getResponseHeaders().getFirst("X-Gsa-External-Metadata"));
}
@Test
public void testAclTransform() throws Exception {
AclTransform aclTransform = new AclTransform(Arrays.asList(
new AclTransform.Rule(
new AclTransform.MatchData(null, "u1", null, null),
new AclTransform.MatchData(null, "u2", null, null))));
mockAdaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException, InterruptedException {
response.setAcl(new Acl.Builder()
.setPermitUsers(Arrays.asList(
new UserPrincipal("u1"), new UserPrincipal("u3")))
.build());
super.getDocContent(request, response);
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(mockAdaptor)
.setFullAccessHosts(new String[] {remoteIp})
.setAclTransform(aclTransform)
.build();
mockAdaptor.documentBytes = new byte[] {1, 2, 3};
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals("google%3Aaclusers=u2,google%3Aaclusers=u3",
ex.getResponseHeaders().get("X-Gsa-External-Metadata").get(1));
}
@Test
public void testNullAuthzResponse() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public Map<DocId, AuthzStatus> isUserAuthorized(
AuthnIdentity identity, Collection<DocId> ids) {
return null;
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
handler.handle(ex);
assertEquals(403, ex.getResponseCode());
}
@Test
public void testFileNotFound() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.respondNotFound();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
handler.handle(ex);
assertEquals(404, ex.getResponseCode());
}
@Test
public void testIOException() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
throw new IOException();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(IOException.class);
handler.handle(ex);
}
@Test
public void testRuntimeException() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
throw new RuntimeException();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testNoOutput() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(IOException.class);
handler.handle(ex);
}
@Test
public void testNotModified() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.respondNotModified();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
handler.handle(ex);
assertEquals(304, ex.getResponseCode());
}
@Test
public void testNotModifiedThenOutputStream() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.respondNotModified();
response.getOutputStream();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testOutputStreamThenNotModified() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.respondNotModified();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testOutputStreamTwice() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.getOutputStream();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
}
@Test
public void testSetContentTypeLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setContentType("text/plain");
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetLastModifiedLast() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setLastModified(new Date(0));
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetMetadataLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.addMetadata("not", "important");
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetAclLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setAcl(Acl.EMPTY);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetSecureLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setSecure(true);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testAddAnchorLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.addAnchor(URI.create("http://h/"), null);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetNoIndexLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setNoIndex(true);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetNoFollowLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setNoFollow(true);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetNoArchiveLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setNoArchive(true);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetDisplayUrlLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setDisplayUrl(null);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetCrawlOnceLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setCrawlOnce(true);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetLockLate() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
response.setLock(true);
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testSetNoIndexFollowArchiveFalse() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setNoIndex(false);
response.setNoFollow(false);
response.setNoArchive(false);
response.getOutputStream();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertFalse(ex.getResponseHeaders().containsKey("X-Robots-Tag"));
}
@Test
public void testSmartAdaptor() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
if (!request.getDocId().equals(defaultDocId)) {
response.respondNotFound();
return;
}
// For convenience, check that the unique id is part of the
// request's toString().
assertTrue(request.toString().contains(defaultDocId.getUniqueId()));
if (!request.hasChangedSinceLastAccess(new Date(1 * 1000))) {
response.respondNotModified();
return;
}
response.setContentType("text/plain");
response.setLastModified(new Date(1 * 1000));
response.addMetadata("not", "important");
response.setAcl(Acl.EMPTY);
response.getOutputStream();
// It is free to get it multiple times. Is free to close() stream.
// Other tests choose not to close the stream.
response.getOutputStream().close();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
ex.getRequestHeaders().set("If-Modified-Since",
"Thu, 1 Jan 1970 00:00:01 GMT");
handler.handle(ex);
assertEquals(304, ex.getResponseCode());
MockHttpExchange ex = new MockHttpExchange("GET", defaultPath,
new MockHttpContext(handler, "/"));
ex.getRequestHeaders().set("If-Modified-Since",
"Thu, 1 Jan 1970 00:00:00 GMT");
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals("text/plain",
ex.getResponseHeaders().getFirst("Content-Type"));
assertEquals("Thu, 01 Jan 1970 00:00:01 GMT",
ex.getResponseHeaders().getFirst("Last-Modified"));
ex = new MockHttpExchange("HEAD", defaultPath,
new MockHttpContext(handler, "/"));
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
}
@Test
public void testMetadataGsa() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.addMetadata("test", "ing");
response.setAcl(new Acl.Builder()
.setInheritFrom(new DocId("testing")).build());
response.setSecure(true);
response.addAnchor(URI.create("http://test/"), null);
response.addAnchor(URI.create("ftp://host/path?val=1"),
"AaZz09,=-%");
response.setNoIndex(true);
response.setNoFollow(true);
response.setNoArchive(true);
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp, "someUnknownHost!@#$"})
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals(Arrays.asList("test=ing", "google%3Aaclinheritfrom="
+ "http%3A%2F%2Flocalhost%2Ftesting"),
ex.getResponseHeaders().get("X-Gsa-External-Metadata"));
assertEquals("secure",
ex.getResponseHeaders().getFirst("X-Gsa-Serve-Security"));
assertEquals("http%3A%2F%2Ftest%2F,"
+ "AaZz09%2C%3D-%25=ftp%3A%2F%2Fhost%2Fpath%3Fval%3D1",
ex.getResponseHeaders().getFirst("X-Gsa-External-Anchor"));
List<String> robots = ex.getResponseHeaders().get("X-Robots-Tag");
assertTrue(robots.contains("noindex"));
assertTrue(robots.contains("nofollow"));
assertTrue(robots.contains("noarchive"));
}
@Test
public void testMetadataNonGsa() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.addMetadata("test", "ing");
response.setAcl(new Acl.Builder()
.setInheritFrom(new DocId("testing")).build());
response.getOutputStream();
}
};
DocumentHandler handler = createDefaultHandlerForAdaptor(adaptor);
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertNull(ex.getResponseHeaders().getFirst("X-Gsa-External-Metadata"));
}
private DocumentHandlerBuilder createHandlerBuilder() {
return new DocumentHandlerBuilder()
.setDocIdDecoder(docIdCodec)
.setDocIdEncoder(docIdCodec)
.setJournal(new Journal(new MockTimeProvider()))
.setAdaptor(new MockAdaptor())
.setGsaHostname("localhost")
.setWatchdog(new MockWatchdog())
.setPusher(new MockPusher());
}
private DocumentHandler createDefaultHandlerForAdaptor(Adaptor adaptor) {
AuthzAuthority authzAuthority = null;
if (adaptor instanceof AuthzAuthority) {
authzAuthority = (AuthzAuthority) adaptor;
}
return createHandlerBuilder().setAdaptor(adaptor)
.setAuthzAuthority(authzAuthority).build();
}
@Test
public void testFormMetadataHeader() {
Metadata metadata = new Metadata();
metadata.add("test", "ing");
metadata.add("another", "item");
metadata.add("equals=", "==");
String result = DocumentHandler.formMetadataHeader(metadata);
assertEquals("another=item,equals%3D=%3D%3D,test=ing", result);
}
@Test
public void testFormMetadataHeaderEmpty() {
String header = DocumentHandler.formMetadataHeader(new Metadata());
assertEquals("", header);
}
private static UserPrincipal u(String name) {
return new UserPrincipal(name);
}
private static UserPrincipal u(String name, String ns) {
return new UserPrincipal(name, ns);
}
private static GroupPrincipal g(String name) {
return new GroupPrincipal(name);
}
private static GroupPrincipal g(String name, String ns) {
return new GroupPrincipal(name, ns);
}
@Test
public void testFormAclHeader() {
final String golden
= "google%3Aaclusers=pu1,google%3Aaclusers=uid%3Dpu2%2Cdc%3Dcom,"
+ "google%3Aaclgroups=gid%3Dpg2%2Cdc%3Dcom,google%3Aaclgroups=pg1,"
+ "google%3Aacldenyusers=du1,"
+ "google%3Aacldenyusers=uid%3Ddu2%2Cdc%3Dcom,"
+ "google%3Aacldenygroups=dg1,"
+ "google%3Aacldenygroups=gid%3Ddg2%2Cdc%3Dcom,"
// The space is encoded as %20 by URI, and then that string is encoded
// by percentEncode to give %2520.
+ "google%3Aaclinheritfrom=http%3A%2F%2Flocalhost%2Fsome%2520docId,"
+ "google%3Aaclinheritancetype=parent-overrides";
String result = DocumentHandler.formUnqualifiedAclHeader(new Acl.Builder()
.setPermitUsers(Arrays.asList(u("pu1"), u("uid=pu2,dc=com")))
.setPermitGroups(Arrays.asList(g("pg1"), g("gid=pg2,dc=com")))
.setDenyUsers(Arrays.asList(u("du1"), u("uid=du2,dc=com")))
.setDenyGroups(Arrays.asList(g("dg1"), g("gid=dg2,dc=com")))
.setInheritFrom(new DocId("some docId"))
.setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES)
.build(), new MockDocIdCodec());
assertEquals(golden, result);
}
@Test
public void testFormUnqualifiedAclHeaderNull() {
assertEquals("", DocumentHandler
.formUnqualifiedAclHeader(null, new MockDocIdCodec()));
}
@Test
public void testFormUnqualifiedAclHeaderEmpty() {
DocIdEncoder enc = new MockDocIdCodec();
assertEquals("google%3Aacldenyusers=google%3AfakeUserToPreventMissingAcl",
DocumentHandler.formUnqualifiedAclHeader(Acl.EMPTY, enc));
}
@Test
public void testFormNamespacedAclHeaderNull() {
assertEquals("", DocumentHandler
.formNamespacedAclHeader(null, new MockDocIdCodec()));
}
@Test
public void testFormNamespacedAclHeaderEmpty() {
DocIdEncoder enc = new MockDocIdCodec();
String golden = "{\"entries\":[{"
+ "\"access\":\"deny\""
+ ","
+ "\"name\":\"google:fakeUserToPreventMissingAcl\""
+ ","
+ "\"scope\":\"user\""
+ "}]}";
String aclHeader = DocumentHandler.formNamespacedAclHeader(Acl.EMPTY, enc);
assertEquals(golden, aclHeader);
}
@Test
public void testFormNamespacedAclHeaderFragment() {
DocIdEncoder enc = new MockDocIdCodec();
String golden = "{\"inherit_from\":\"http:\\/\\/localhost\\/t?f?=$%25\"}";
String aclHeader = DocumentHandler.formNamespacedAclHeader(new Acl.Builder()
.setInheritFrom(new DocId("t"), "f?=$%").build(), enc);
assertEquals(golden, aclHeader);
}
@Test
public void testFormNamespacedAclHeaderBusy() {
DocIdEncoder enc = new MockDocIdCodec();
String golden = "{"
+ "\"entries\":["
+ "{\"access\":\"permit\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"pg1@d.g\",\"scope\":\"group\"},"
+ "{\"access\":\"permit\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"gid=pg2,dc=m\",\"namespace\":\"ns\","
+ "\"scope\":\"group\"},"
+ "{\"access\":\"deny\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"gid=dg2,dc=com\",\"scope\":\"group\"},"
+ "{\"access\":\"deny\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"dg1@d.g\",\"namespace\":\"ns\","
+ "\"scope\":\"group\"},"
+ "{\"access\":\"permit\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"uid=pu2,dc=m\",\"scope\":\"user\"},"
+ "{\"access\":\"permit\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"pu1@d.g\",\"namespace\":\"ns\","
+ "\"scope\":\"user\"},"
+ "{\"access\":\"deny\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"du1@d.g\",\"scope\":\"user\"},"
+ "{\"access\":\"deny\","
+ "\"case_sensitivity_type\":\"everything_case_insensitive\","
+ "\"name\":\"uid=du2,dc=com\",\"namespace\":\"ns\","
+ "\"scope\":\"user\"}"
+ "],"
+ "\"inherit_from\":\"http:\\/\\/localhost\\/some%20docId\","
+ "\"inheritance_type\":\"PARENT_OVERRIDES\""
+ "}";
Acl busyAcl = new Acl.Builder()
.setPermitUsers(Arrays.asList(u("pu1@d.g", "ns"), u("uid=pu2,dc=m")))
.setPermitGroups(Arrays.asList(g("pg1@d.g"), g("gid=pg2,dc=m", "ns")))
.setDenyUsers(Arrays.asList(u("du1@d.g"), u("uid=du2,dc=com", "ns")))
.setDenyGroups(Arrays.asList(g("dg1@d.g", "ns"), g("gid=dg2,dc=com")))
.setInheritFrom(new DocId("some docId"))
.setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES)
.setEverythingCaseInsensitive()
.build();
String aclHeader = DocumentHandler.formNamespacedAclHeader(busyAcl, enc);
assertEquals(golden, aclHeader);
}
@Test
public void testDisplayUrlHeader() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
try {
response.setDisplayUrl(new URI("http://www.google.com"));
} catch (URISyntaxException urie) {
throw new RuntimeException(urie);
}
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp, "someUnknownHost!@#$"})
.setSendDocControls(true)
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertTrue(ex.getResponseHeaders().get("X-Gsa-Doc-Controls")
.contains("display_url=http%3A%2F%2Fwww.google.com"));
}
@Test
public void testLockHeaderTrueSent() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setLock(true);
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp, "someUnknownHost!@#$"})
.setSendDocControls(true)
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertTrue(ex.getResponseHeaders().get("X-Gsa-Doc-Controls")
.contains("lock=true"));
}
@Test
public void testScoringTypeSent() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp})
.setSendDocControls(true)
.setScoringType("guess!")
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertTrue(ex.getResponseHeaders().get("X-Gsa-Doc-Controls")
.contains("scoring=guess!"));
}
@Test
public void testLockHeaderFalseSent() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setLock(false);
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp, "someUnknownHost!@#$"})
.setSendDocControls(true)
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertTrue(ex.getResponseHeaders().get("X-Gsa-Doc-Controls")
.contains("lock=false"));
}
@Test
public void testCrawlOnceHeaderTrueSent() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setCrawlOnce(true);
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp, "someUnknownHost!@#$"})
.setSendDocControls(true)
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertTrue(ex.getResponseHeaders().get("X-Gsa-Doc-Controls")
.contains("crawl_once=true"));
}
@Test
public void testCrawlOnceHeaderFalseSent() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setCrawlOnce(false);
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp, "someUnknownHost!@#$"})
.setSendDocControls(true)
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertTrue(ex.getResponseHeaders().get("X-Gsa-Doc-Controls")
.contains("crawl_once=false"));
}
@Test
public void testAclMeansServeSecurity() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setAcl(new Acl.Builder()
.setInheritFrom(new DocId("testing")).build());
response.setSecure(false);
response.getOutputStream();
}
};
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp, "someUnknownHost!@#$"})
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals("secure",
ex.getResponseHeaders().getFirst("X-Gsa-Serve-Security"));
}
@Test
public void testEmulatedFields() throws Exception {
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setDisplayUrl(URI.create("http://example.com"));
response.setCrawlOnce(true);
response.setLock(true);
response.getOutputStream();
}
};
DocumentHandler.AsyncPusher pusher = new DocumentHandler.AsyncPusher() {
@Override
public void asyncPushItem(DocIdSender.Item item) {
assertTrue(item instanceof DocIdPusher.Record);
DocIdPusher.Record record = (DocIdPusher.Record) item;
assertEquals(URI.create("http://example.com"), record.getResultLink());
assertTrue(record.isToBeCrawledOnce());
assertTrue(record.isToBeLocked());
}
};
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp})
.setPusher(pusher)
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
}
@Test
public void testEmulatedAcls() throws Exception {
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
final AtomicReference<Acl> providedAcl = new AtomicReference<Acl>();
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setAcl(providedAcl.get());
response.getOutputStream();
}
};
DocumentHandlerBuilder builder = createHandlerBuilder()
.setAdaptor(adaptor)
.setFullAccessHosts(new String[] {remoteIp});
DocumentHandler handler;
providedAcl.set(new Acl.Builder()
.setPermitUsers(Arrays.asList(
new UserPrincipal("user2"), new UserPrincipal("user", "ns")))
.build());
handler = builder.setPusher(new DocumentHandler.AsyncPusher() {
@Override
public void asyncPushItem(DocIdSender.Item item) {
assertTrue(item instanceof DocIdSender.AclItem);
DocIdSender.AclItem aclItem = (DocIdSender.AclItem) item;
assertEquals(defaultDocId, aclItem.getDocId());
assertEquals("generated", aclItem.getDocIdFragment());
assertEquals(new Acl.Builder(providedAcl.get())
.setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES)
.build(),
aclItem.getAcl());
}
})
.build();
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals(Arrays.asList("", "google%3Aaclinheritfrom="
+ "http%3A%2F%2Flocalhost%2Ftest%2520docId%3Fgenerated"),
ex.getResponseHeaders().get("X-Gsa-External-Metadata"));
providedAcl.set(new Acl.Builder()
.setDenyUsers(Arrays.asList(new UserPrincipal("user", "ns")))
.setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES)
.build());
handler = builder.setPusher(new DocumentHandler.AsyncPusher() {
@Override
public void asyncPushItem(DocIdSender.Item item) {
assertTrue(item instanceof DocIdSender.AclItem);
DocIdSender.AclItem aclItem = (DocIdSender.AclItem) item;
assertEquals(defaultDocId, aclItem.getDocId());
assertEquals("generated", aclItem.getDocIdFragment());
assertEquals(providedAcl.get(), aclItem.getAcl());
}
})
.build();
ex = new MockHttpExchange("GET", defaultPath, new MockHttpContext("/"));
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals(Arrays.asList("", "google%3Aaclinheritfrom="
+ "http%3A%2F%2Flocalhost%2Ftest%2520docId%3Fgenerated,"
+ "google%3Aaclinheritancetype=parent-overrides"),
ex.getResponseHeaders().get("X-Gsa-External-Metadata"));
providedAcl.set(new Acl.Builder()
.setPermitGroups(Arrays.asList(new GroupPrincipal("group", "ns")))
.setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES)
.build());
handler = builder.setPusher(new DocumentHandler.AsyncPusher() {
@Override
public void asyncPushItem(DocIdSender.Item item) {
assertTrue(item instanceof DocIdSender.AclItem);
DocIdSender.AclItem aclItem = (DocIdSender.AclItem) item;
assertEquals(defaultDocId, aclItem.getDocId());
assertEquals("generated", aclItem.getDocIdFragment());
assertEquals(providedAcl.get(), aclItem.getAcl());
}
})
.build();
ex = new MockHttpExchange("GET", defaultPath, new MockHttpContext("/"));
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals(Arrays.asList("", "google%3Aaclinheritfrom="
+ "http%3A%2F%2Flocalhost%2Ftest%2520docId%3Fgenerated,"
+ "google%3Aaclinheritancetype=child-overrides"),
ex.getResponseHeaders().get("X-Gsa-External-Metadata"));
providedAcl.set(new Acl.Builder()
.setDenyGroups(Arrays.asList(new GroupPrincipal("group", "ns")))
.setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES)
.build());
handler = builder.setPusher(new DocumentHandler.AsyncPusher() {
@Override
public void asyncPushItem(DocIdSender.Item item) {
assertTrue(item instanceof DocIdSender.AclItem);
DocIdSender.AclItem aclItem = (DocIdSender.AclItem) item;
assertEquals(defaultDocId, aclItem.getDocId());
assertEquals("generated", aclItem.getDocIdFragment());
assertEquals(providedAcl.get(), aclItem.getAcl());
}
})
.build();
ex = new MockHttpExchange("GET", defaultPath, new MockHttpContext("/"));
handler.handle(ex);
assertEquals(200, ex.getResponseCode());
assertEquals(Arrays.asList("", "google%3Aaclinheritfrom="
+ "http%3A%2F%2Flocalhost%2Ftest%2520docId%3Fgenerated,"
+ "google%3Aaclinheritancetype=child-overrides"),
ex.getResponseHeaders().get("X-Gsa-External-Metadata"));
}
@Test
public void testEmulatedAclsFail() throws Exception {
String remoteIp = ex.getRemoteAddress().getAddress().getHostAddress();
final Acl providedAcl = new Acl.Builder()
.setDenyGroups(Arrays.asList(new GroupPrincipal("group")))
.setInheritanceType(Acl.InheritanceType.AND_BOTH_PERMIT)
.setEverythingCaseInsensitive()
.build();
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocContent(Request request, Response response)
throws IOException {
response.setAcl(providedAcl);
response.getOutputStream();
}
};
DocumentHandler handler = createHandlerBuilder()
.setAdaptor(adaptor)
.setPusher(new DocumentHandler.AsyncPusher() {
@Override
public void asyncPushItem(DocIdSender.Item item) {
fail("Should not have been called");
}
})
.setFullAccessHosts(new String[] {remoteIp})
.build();
ex = new MockHttpExchange("GET", defaultPath, new MockHttpContext("/"));
thrown.expect(RuntimeException.class);
handler.handle(ex);
}
@Test
public void testFormAnchorHeaderEmpty() {
assertEquals("", DocumentHandler.formAnchorHeader(
Collections.<URI>emptyList(), Collections.<String>emptyList()));
}
@Test
public void testPercentEncoding() {
String encoded = DocumentHandler.percentEncode(
"AaZz09-_.~`=/?+';\\/\"!@#$%^&*()[]{}ë\u0001");
assertEquals("AaZz09-_.~%60%3D%2F%3F%2B%27%3B%5C%2F%22%21%40%23%24%25%5E%26"
+ "%2A%28%29%5B%5D%7B%7D%C3%AB%01", encoded);
}
private static class UserPrivateMockAdaptor extends MockAdaptor {
@Override
public Map<DocId, AuthzStatus> isUserAuthorized(AuthnIdentity identity,
Collection<DocId> ids) {
Map<DocId, AuthzStatus> result
= new HashMap<DocId, AuthzStatus>(ids.size() * 2);
for (DocId id : ids) {
result.put(id,
identity == null ? AuthzStatus.DENY : AuthzStatus.PERMIT);
}
return Collections.unmodifiableMap(result);
}
};
private static class MockPusher implements DocumentHandler.AsyncPusher {
@Override
public void asyncPushItem(DocIdSender.Item item) {
fail("Should not have been called");
}
}
private static class MockSamlServiceProvider extends SamlServiceProvider {
static {
GsaCommunicationHandler.bootstrapOpenSaml();
}
private AuthnIdentity identity;
public MockSamlServiceProvider() {
super(new SessionManager<HttpExchange>(
new SessionManager.HttpExchangeClientStore(), 1000, 1000),
new SamlMetadata("localhost", 80,
"thegsa", "http://google.com/enterprise/gsa/security-manager",
"http://google.com/enterprise/gsa/adaptor"),
null);
}
@Override
public HttpHandler getAssertionConsumer() {
throw new UnsupportedOperationException();
}
@Override
public AuthnIdentity getUserIdentity(HttpExchange ex) {
return identity;
}
public void setUserIdentity(AuthnIdentity identity) {
this.identity = identity;
}
@Override
public void handleAuthentication(HttpExchange ex) throws IOException {
throw new UnsupportedOperationException();
}
}
private static class DocumentHandlerBuilder {
private DocIdDecoder docIdDecoder;
private DocIdEncoder docIdEncoder;
private Journal journal;
private Adaptor adaptor;
private AuthzAuthority authzAuthority;
private String gsaHostname;
private String[] fullAccessHosts = new String[0];
private SamlServiceProvider samlServiceProvider;
private TransformPipeline transform;
private AclTransform aclTransform
= new AclTransform(Arrays.<AclTransform.Rule>asList());
private int transformMaxBytes;
private boolean transformRequired;
private boolean useCompression;
private Watchdog watchdog;
private DocumentHandler.AsyncPusher pusher;
private boolean sendDocControls;
private long headerTimeoutMillis = 30 * 1000;
private long contentTimeoutMillis = 180 * 1000;
private String scoring = "content";
public DocumentHandlerBuilder setDocIdDecoder(DocIdDecoder docIdDecoder) {
this.docIdDecoder = docIdDecoder;
return this;
}
public DocumentHandlerBuilder setDocIdEncoder(DocIdEncoder docIdEncoder) {
this.docIdEncoder = docIdEncoder;
return this;
}
public DocumentHandlerBuilder setJournal(Journal journal) {
this.journal = journal;
return this;
}
public DocumentHandlerBuilder setAdaptor(Adaptor adaptor) {
this.adaptor = adaptor;
return this;
}
public DocumentHandlerBuilder setAuthzAuthority(
AuthzAuthority authzAuthority) {
this.authzAuthority = authzAuthority;
return this;
}
public DocumentHandlerBuilder setGsaHostname(String gsaHostname) {
this.gsaHostname = gsaHostname;
return this;
}
public DocumentHandlerBuilder setFullAccessHosts(String[] fullAccessHosts) {
this.fullAccessHosts = fullAccessHosts;
return this;
}
public DocumentHandlerBuilder setSamlServiceProvider(
SamlServiceProvider samlServiceProvider) {
this.samlServiceProvider = samlServiceProvider;
return this;
}
public DocumentHandlerBuilder setTransform(TransformPipeline transform) {
this.transform = transform;
return this;
}
public DocumentHandlerBuilder setAclTransform(AclTransform aclTransform) {
this.aclTransform = aclTransform;
return this;
}
public DocumentHandlerBuilder setUseCompression(boolean useCompression) {
this.useCompression = useCompression;
return this;
}
public DocumentHandlerBuilder setWatchdog(Watchdog watchdog) {
this.watchdog = watchdog;
return this;
}
public DocumentHandlerBuilder setPusher(
DocumentHandler.AsyncPusher pusher) {
this.pusher = pusher;
return this;
}
public DocumentHandlerBuilder setSendDocControls(boolean sendDocControls) {
this.sendDocControls = sendDocControls;
return this;
}
public DocumentHandlerBuilder setHeaderTimeoutMillis(
long headerTimeoutMillis) {
this.headerTimeoutMillis = headerTimeoutMillis;
return this;
}
public DocumentHandlerBuilder setContentTimeoutMillis(
long contentTimeoutMillis) {
this.contentTimeoutMillis = contentTimeoutMillis;
return this;
}
public DocumentHandlerBuilder setScoringType(String scoringType) {
this.scoring = scoringType;
return this;
}
public DocumentHandler build() {
return new DocumentHandler(docIdDecoder, docIdEncoder, journal, adaptor,
authzAuthority, gsaHostname, fullAccessHosts, samlServiceProvider,
transform, aclTransform, useCompression, watchdog, pusher,
sendDocControls, headerTimeoutMillis, contentTimeoutMillis, scoring);
}
}
}