mirror of
https://github.com/google/nomulus.git
synced 2025-08-03 08:22:13 +02:00
mv com/google/domain/registry google/registry
This change renames directories in preparation for the great package rename. The repository is now in a broken state because the code itself hasn't been updated. However this should ensure that git correctly preserves history for each file.
This commit is contained in:
parent
a41677aea1
commit
5012893c1d
2396 changed files with 0 additions and 0 deletions
74
javatests/google/registry/server/BUILD
Normal file
74
javatests/google/registry/server/BUILD
Normal file
|
@ -0,0 +1,74 @@
|
|||
package(default_visibility = ["//java/com/google/domain/registry:registry_project"])
|
||||
|
||||
|
||||
java_library(
|
||||
name = "TestServer",
|
||||
visibility = ["//visibility:public"],
|
||||
srcs = [
|
||||
"HealthzServlet.java",
|
||||
"Route.java",
|
||||
"ServletWrapperDelegatorServlet.java",
|
||||
"StaticResourceServlet.java",
|
||||
"TestServer.java",
|
||||
"UrlChecker.java",
|
||||
],
|
||||
deps = [
|
||||
"//java/com/google/common/base",
|
||||
"//java/com/google/common/collect",
|
||||
"//java/com/google/common/net",
|
||||
"//java/com/google/common/primitives",
|
||||
"//java/com/google/common/util/concurrent",
|
||||
"//java/com/google/domain/registry/util",
|
||||
"//third_party/java/auto:auto_value",
|
||||
"//third_party/java/jetty/v6_1_22",
|
||||
"//third_party/java/jsr305_annotations",
|
||||
"//third_party/java/servlet/servlet_api",
|
||||
],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "Fixture",
|
||||
srcs = ["Fixture.java"],
|
||||
deps = [
|
||||
"//java/com/google/common/collect",
|
||||
"//java/com/google/domain/registry/model",
|
||||
"//javatests/com/google/domain/registry/testing",
|
||||
"//third_party/java/appengine:appengine-api",
|
||||
"//third_party/java/joda_time",
|
||||
],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "RegistryTestServer",
|
||||
srcs = ["RegistryTestServer.java"],
|
||||
data = ["//java/com/google/domain/registry/ui:runfiles_debug"],
|
||||
deps = [
|
||||
":TestServer",
|
||||
"//java/com/google/common/collect",
|
||||
"//java/com/google/common/net",
|
||||
"//java/com/google/domain/registry/flows",
|
||||
"//java/com/google/domain/registry/module/backend",
|
||||
"//java/com/google/domain/registry/module/frontend",
|
||||
"//java/com/google/domain/registry/ui/server/api",
|
||||
"//java/com/google/domain/registry/ui/server/registrar",
|
||||
"//third_party/java/jsr305_annotations",
|
||||
"//third_party/java/servlet/servlet_api",
|
||||
],
|
||||
)
|
||||
|
||||
java_binary(
|
||||
name = "server",
|
||||
srcs = ["RegistryTestServerMain.java"],
|
||||
main_class = "com.google.domain.registry.server.RegistryTestServerMain",
|
||||
deps = [
|
||||
":Fixture",
|
||||
":RegistryTestServer",
|
||||
"//java/com/google/common/collect",
|
||||
"//java/com/google/common/net",
|
||||
"//java/com/google/domain/registry/tools/params",
|
||||
"//java/com/google/domain/registry/ui",
|
||||
"//javatests/com/google/domain/registry/testing",
|
||||
"//third_party/java/jcommander",
|
||||
"//third_party/java/junit",
|
||||
],
|
||||
)
|
150
javatests/google/registry/server/Fixture.java
Normal file
150
javatests/google/registry/server/Fixture.java
Normal file
|
@ -0,0 +1,150 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import static com.google.domain.registry.model.domain.DesignatedContact.Type.ADMIN;
|
||||
import static com.google.domain.registry.model.domain.DesignatedContact.Type.BILLING;
|
||||
import static com.google.domain.registry.model.domain.DesignatedContact.Type.TECH;
|
||||
import static com.google.domain.registry.testing.DatastoreHelper.createTlds;
|
||||
import static com.google.domain.registry.testing.DatastoreHelper.newContactResource;
|
||||
import static com.google.domain.registry.testing.DatastoreHelper.newDomainResource;
|
||||
import static com.google.domain.registry.testing.DatastoreHelper.persistActiveHost;
|
||||
import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.domain.registry.model.contact.ContactAddress;
|
||||
import com.google.domain.registry.model.contact.ContactResource;
|
||||
import com.google.domain.registry.model.contact.PostalInfo;
|
||||
import com.google.domain.registry.model.domain.DesignatedContact;
|
||||
import com.google.domain.registry.model.domain.ReferenceUnion;
|
||||
import com.google.domain.registry.model.ofy.Ofy;
|
||||
import com.google.domain.registry.model.registrar.Registrar;
|
||||
import com.google.domain.registry.testing.FakeClock;
|
||||
import com.google.domain.registry.testing.InjectRule;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Datastore fixtures for the development webserver.
|
||||
*
|
||||
* <p><b>Warning:</b> These fixtures aren't really intended for unit tests, since they take upwards
|
||||
* of a second to load.
|
||||
*/
|
||||
public enum Fixture {
|
||||
|
||||
INJECTED_FAKE_CLOCK {
|
||||
@Override
|
||||
public void load() {
|
||||
new InjectRule()
|
||||
.setStaticField(Ofy.class, "clock", new FakeClock(DateTime.parse("2000-01-01TZ")));
|
||||
}
|
||||
},
|
||||
|
||||
/** Fixture of two TLDs, three contacts, two domains, and six hosts. */
|
||||
BASIC {
|
||||
@Override
|
||||
public void load() {
|
||||
createTlds("xn--q9jyb4c", "example");
|
||||
|
||||
ContactResource google = persistResource(newContactResource("google")
|
||||
.asBuilder()
|
||||
.setLocalizedPostalInfo(new PostalInfo.Builder()
|
||||
.setType(PostalInfo.Type.LOCALIZED)
|
||||
.setName("Mr. Google")
|
||||
.setOrg("Google Inc.")
|
||||
.setAddress(new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("111 8th Ave", "4th Floor"))
|
||||
.setCity("New York")
|
||||
.setState("NY")
|
||||
.setZip("10011")
|
||||
.setCountryCode("US")
|
||||
.build())
|
||||
.build())
|
||||
.build());
|
||||
|
||||
ContactResource justine = persistResource(newContactResource("justine")
|
||||
.asBuilder()
|
||||
.setLocalizedPostalInfo(new PostalInfo.Builder()
|
||||
.setType(PostalInfo.Type.LOCALIZED)
|
||||
.setName("Justine Bean")
|
||||
.setOrg("(✿◕ ‿◕ )ノ Incorporated")
|
||||
.setAddress(new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of("123 Fake St."))
|
||||
.setCity("Stratford")
|
||||
.setState("CT")
|
||||
.setZip("06615")
|
||||
.setCountryCode("US")
|
||||
.build())
|
||||
.build())
|
||||
.build());
|
||||
|
||||
ContactResource robert = persistResource(newContactResource("robert")
|
||||
.asBuilder()
|
||||
.setLocalizedPostalInfo(new PostalInfo.Builder()
|
||||
.setType(PostalInfo.Type.LOCALIZED)
|
||||
.setName("Captain Robert")
|
||||
.setOrg("Ancient World")
|
||||
.setAddress(new ContactAddress.Builder()
|
||||
.setStreet(ImmutableList.of(
|
||||
"A skeleton crew is what came back",
|
||||
"And once in port he filled his sack",
|
||||
"With bribes and cash and fame and coin"))
|
||||
.setCity("Things to make a new crew join")
|
||||
.setState("NY")
|
||||
.setZip("10011")
|
||||
.setCountryCode("US")
|
||||
.build())
|
||||
.build())
|
||||
.build());
|
||||
|
||||
persistResource(
|
||||
newDomainResource("love.xn--q9jyb4c", justine).asBuilder()
|
||||
.setContacts(ImmutableSet.of(
|
||||
DesignatedContact.create(ADMIN, ReferenceUnion.create(robert)),
|
||||
DesignatedContact.create(BILLING, ReferenceUnion.create(google)),
|
||||
DesignatedContact.create(TECH, ReferenceUnion.create(justine))))
|
||||
.setNameservers(ImmutableSet.of(
|
||||
ReferenceUnion.create(
|
||||
persistActiveHost("ns1.love.xn--q9jyb4c")),
|
||||
ReferenceUnion.create(
|
||||
persistActiveHost("ns2.love.xn--q9jyb4c"))))
|
||||
.build());
|
||||
|
||||
persistResource(
|
||||
newDomainResource("moogle.example", justine).asBuilder()
|
||||
.setContacts(ImmutableSet.of(
|
||||
DesignatedContact.create(ADMIN, ReferenceUnion.create(robert)),
|
||||
DesignatedContact.create(BILLING, ReferenceUnion.create(google)),
|
||||
DesignatedContact.create(TECH, ReferenceUnion.create(justine))))
|
||||
.setNameservers(ImmutableSet.of(
|
||||
ReferenceUnion.create(persistActiveHost("ns1.linode.com")),
|
||||
ReferenceUnion.create(persistActiveHost("ns2.linode.com")),
|
||||
ReferenceUnion.create(persistActiveHost("ns3.linode.com")),
|
||||
ReferenceUnion.create(persistActiveHost("ns4.linode.com")),
|
||||
ReferenceUnion.create(persistActiveHost("ns5.linode.com"))))
|
||||
.build());
|
||||
|
||||
persistResource(
|
||||
Registrar.loadByClientId("TheRegistrar").asBuilder()
|
||||
.setAllowedTlds(ImmutableSet.of("example", "xn--q9jyb4c"))
|
||||
.setBillingMethod(Registrar.BillingMethod.BRAINTREE)
|
||||
.build());
|
||||
}
|
||||
};
|
||||
|
||||
/** Loads this fixture into the datastore. */
|
||||
public abstract void load();
|
||||
}
|
36
javatests/google/registry/server/HealthzServlet.java
Normal file
36
javatests/google/registry/server/HealthzServlet.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/** Servlet for responding to {@code /healthz} requests. */
|
||||
public final class HealthzServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
|
||||
rsp.setStatus(SC_OK);
|
||||
rsp.setContentType(PLAIN_TEXT_UTF_8.toString());
|
||||
rsp.getWriter().write("ok\n");
|
||||
rsp.getWriter().close();
|
||||
}
|
||||
}
|
110
javatests/google/registry/server/RegistryTestServer.java
Normal file
110
javatests/google/registry/server/RegistryTestServer.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import static com.google.domain.registry.server.Route.route;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.HostAndPort;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/** Lightweight HTTP server for testing the Domain Registry Admin and Registrar consoles. */
|
||||
public final class RegistryTestServer {
|
||||
|
||||
public static final ImmutableMap<String, Path> RUNFILES =
|
||||
new ImmutableMap.Builder<String, Path>()
|
||||
.put("/index.html", Paths.get("java/com/google/domain/registry/ui/html/index.html"))
|
||||
.put("/error.html", Paths.get("java/com/google/domain/registry/ui/html/error.html"))
|
||||
.put("/assets/js/*", Paths.get("java/com/google/domain/registry/ui"))
|
||||
.put("/assets/css/*", Paths.get("java/com/google/domain/registry/ui/css"))
|
||||
.put("/assets/sources/deps-runfiles.js",
|
||||
Paths.get("java/com/google/domain/registry/ui/deps-runfiles.js"))
|
||||
.put("/assets/sources/*", Paths.get(""))
|
||||
.put("/assets/*", Paths.get("java/com/google/domain/registry/ui/assets"))
|
||||
.build();
|
||||
|
||||
private static final ImmutableList<Route> ROUTES = ImmutableList.of(
|
||||
// Frontend Services
|
||||
route("/whois/*", com.google.domain.registry.module.frontend.FrontendServlet.class),
|
||||
route("/rdap/*", com.google.domain.registry.module.frontend.FrontendServlet.class),
|
||||
route("/registrar-xhr", com.google.domain.registry.flows.EppConsoleServlet.class),
|
||||
route("/check", com.google.domain.registry.ui.server.api.CheckApiServlet.class),
|
||||
|
||||
// Proxy Services
|
||||
route("/_dr/epp", com.google.domain.registry.flows.EppTlsServlet.class),
|
||||
route("/_dr/whois", com.google.domain.registry.module.frontend.FrontendServlet.class),
|
||||
|
||||
// Registry Data Escrow (RDE)
|
||||
route("/_dr/cron/rdeCreate", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
route("/_dr/task/rdeStaging", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
route("/_dr/task/rdeUpload", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
route("/_dr/task/rdeReport", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
route("/_dr/task/brdaCopy", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
|
||||
// Trademark Clearinghouse (TMCH)
|
||||
route("/_dr/cron/tmchDnl", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
route("/_dr/task/tmchSmdrl", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
route("/_dr/task/tmchCrl", com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
|
||||
// Notification of Registered Domain Names (NORDN)
|
||||
route("/_dr/task/nordnUpload",
|
||||
com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
route("/_dr/task/nordnVerify",
|
||||
com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
|
||||
// Process DNS pull queue
|
||||
route("/_dr/task/writeDns",
|
||||
com.google.domain.registry.module.backend.BackendServlet.class),
|
||||
|
||||
// Registrar Console
|
||||
route("/registrar", com.google.domain.registry.module.frontend.FrontendServlet.class),
|
||||
route("/registrar-settings",
|
||||
com.google.domain.registry.ui.server.registrar.RegistrarServlet.class),
|
||||
route("/registrar-payment",
|
||||
com.google.domain.registry.module.frontend.FrontendServlet.class),
|
||||
route("/registrar-payment-setup",
|
||||
com.google.domain.registry.module.frontend.FrontendServlet.class));
|
||||
|
||||
private final TestServer server;
|
||||
|
||||
/** @see TestServer#TestServer(HostAndPort, java.util.Map, Iterable) */
|
||||
public RegistryTestServer(HostAndPort address) {
|
||||
server = new TestServer(address, RUNFILES, ROUTES);
|
||||
}
|
||||
|
||||
/** @see TestServer#start() */
|
||||
public void start() {
|
||||
server.start();
|
||||
}
|
||||
|
||||
/** @see TestServer#process() */
|
||||
public void process() throws InterruptedException {
|
||||
server.process();
|
||||
}
|
||||
|
||||
/** @see TestServer#stop() */
|
||||
public void stop() {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
/** @see TestServer#getUrl(java.lang.String) */
|
||||
public URL getUrl(String path) {
|
||||
return server.getUrl(path);
|
||||
}
|
||||
}
|
172
javatests/google/registry/server/RegistryTestServerMain.java
Normal file
172
javatests/google/registry/server/RegistryTestServerMain.java
Normal file
|
@ -0,0 +1,172 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.net.HostAndPort;
|
||||
import com.google.domain.registry.testing.AppEngineRule;
|
||||
import com.google.domain.registry.testing.UserInfo;
|
||||
import com.google.domain.registry.tools.params.HostAndPortParameter;
|
||||
import com.google.domain.registry.ui.ConsoleDebug;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Command-line interface for {@link RegistryTestServer}. */
|
||||
public final class RegistryTestServerMain {
|
||||
|
||||
private static final String RESET = "\u001b[0m";
|
||||
private static final String BLUE = "\u001b[1;34m";
|
||||
private static final String PURPLE = "\u001b[1;35m";
|
||||
private static final String PINK = "\u001b[1;38;5;205m";
|
||||
private static final String LIGHT_PURPLE = "\u001b[38;5;139m";
|
||||
private static final String ORANGE = "\u001b[1;38;5;172m";
|
||||
|
||||
@Parameter(
|
||||
names = "--mode",
|
||||
description = "UI console debug mode. RAW allows live editing; DEBUG allows rename testing.")
|
||||
private ConsoleDebug mode = ConsoleDebug.RAW;
|
||||
|
||||
@Parameter(
|
||||
names = "--address",
|
||||
description = "Listening address.",
|
||||
validateWith = HostAndPortParameter.class)
|
||||
private HostAndPort address = HostAndPort.fromString("[::]:8080");
|
||||
|
||||
@Parameter(
|
||||
names = "--fixtures",
|
||||
description = "Fixtures to load into the datastore.")
|
||||
private List<Fixture> fixtures = ImmutableList.of(Fixture.BASIC);
|
||||
|
||||
@Parameter(
|
||||
names = "--login_email",
|
||||
description = "Login email address for App Engine Local User Service.")
|
||||
private String loginEmail = "Marla.Singer@crr.com";
|
||||
|
||||
@Parameter(
|
||||
names = "--login_user_id",
|
||||
description = "GAE User ID for App Engine Local User Service.")
|
||||
private String loginUserId = AppEngineRule.THE_REGISTRAR_GAE_USER_ID;
|
||||
|
||||
@Parameter(
|
||||
names = "--login_is_admin",
|
||||
description = "Should logged in user be an admin for App Engine Local User Service.",
|
||||
arity = 1)
|
||||
private boolean loginIsAdmin = true;
|
||||
|
||||
@Parameter(
|
||||
names = "--jetty_debug",
|
||||
description = "Enables Jetty debug logging.")
|
||||
private boolean jettyDebug;
|
||||
|
||||
@Parameter(
|
||||
names = "--jetty_verbose",
|
||||
description = "Enables Jetty verbose logging.")
|
||||
private boolean jettyVerbose;
|
||||
|
||||
@Parameter(
|
||||
names = {"-h", "--help"},
|
||||
description = "Display help and list flags for this command.",
|
||||
help = true)
|
||||
private boolean help;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
RegistryTestServerMain serverMain = new RegistryTestServerMain();
|
||||
JCommander jCommander = new JCommander(serverMain);
|
||||
jCommander.setProgramName("dr-run server");
|
||||
jCommander.parse(args);
|
||||
if (serverMain.help) {
|
||||
jCommander.usage();
|
||||
return;
|
||||
}
|
||||
serverMain.run();
|
||||
}
|
||||
|
||||
private void run() throws Throwable {
|
||||
ConsoleDebug.set(mode);
|
||||
if (jettyDebug) {
|
||||
System.setProperty("DEBUG", "true");
|
||||
}
|
||||
if (jettyVerbose) {
|
||||
System.setProperty("VERBOSE", "true");
|
||||
}
|
||||
|
||||
System.out.printf("\n"
|
||||
+ " CHARLESTON ROAD REGISTRY SHARED REGISTRATION SYSTEM\n"
|
||||
+ " ICANN-GTLD-AGB-20120604\n\n%s"
|
||||
+ " ▓█████▄ ▒█████ ███▄ ▄███▓ ▄▄▄ ██▓ ███▄ █\n"
|
||||
+ " ▒██▀ ██▌▒██▒ ██▒▓██▒▀█▀ ██▒▒████▄ ▓██▒ ██ ▀█ █\n"
|
||||
+ " ░██ █▌▒██░ ██▒▓██ ▓██░▒██ ▀█▄ ▒██▒▓██ ▀█ ██▒\n"
|
||||
+ " ░▓█▄ ▌▒██ ██░▒██ ▒██ ░██▄▄▄▄██ ░██░▓██▒ ▐▌██▒\n"
|
||||
+ " ░▒████▓ ░ ████▓▒░▒██▒ ░██▒ ▓█ ▓██▒░██░▒██░ ▓██░\n"
|
||||
+ " ▒▒▓ ▒ ░ ▒░▒░▒░ ░ ▒░ ░ ░ ▒▒ ▓▒█░░▓ ░ ▒░ ▒ ▒\n"
|
||||
+ " ░ ▒ ▒ ░ ▒ ▒░ ░ ░ ░ ▒ ▒▒ ░ ▒ ░░ ░░ ░ ▒░\n"
|
||||
+ " ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ▒ ░ ░ ░ ░\n"
|
||||
+ " ░ ░ ░ ░ ░ ░ ░ ░\n"
|
||||
+ " ░\n%s"
|
||||
+ " ██▀███ ▓█████ ▄████ ██▓ ██████ ▄▄▄█████▓ ██▀███ ▓██ ██▓\n"
|
||||
+ " ▓██ ▒ ██▒▓█ ▀ ██▒ ▀█▒▓██▒▒██ ▒ ▓ ██▒ ▓▒▓██ ▒ ██▒▒██ ██▒\n"
|
||||
+ " ▓██ ░▄█ ▒▒███ ▒██░▄▄▄░▒██▒░ ▓██▄ ▒ ▓██░ ▒░▓██ ░▄█ ▒ ▒██ ██░\n"
|
||||
+ " ▒██▀▀█▄ ▒▓█ ▄ ░▓█ ██▓░██░ ▒ ██▒░ ▓██▓ ░ ▒██▀▀█▄ ░ ▐██▓░\n"
|
||||
+ " ░██▓ ▒██▒░▒████▒░▒▓███▀▒░██░▒██████▒▒ ▒██▒ ░ ░██▓ ▒██▒ ░ ██▒▓░\n"
|
||||
+ " ░ ▒▓ ░▒▓░░░ ▒░ ░ ░▒ ▒ ░▓ ▒ ▒▓▒ ▒ ░ ▒ ░░ ░ ▒▓ ░▒▓░ ██▒▒▒\n"
|
||||
+ " ░▒ ░ ▒░ ░ ░ ░ ░ ░ ▒ ░░ ░▒ ░ ░ ░ ░▒ ░ ▒░▓██ ░▒░\n"
|
||||
+ " ░░ ░ ░ ░ ░ ░ ▒ ░░ ░ ░ ░ ░░ ░ ▒ ▒ ░░\n"
|
||||
+ " ░ ░ ░ ░ ░ ░ ░ ░ ░\n"
|
||||
+ " ░ ░\n%s"
|
||||
+ "(✿◕ ‿◕ )ノ%s\n",
|
||||
LIGHT_PURPLE, ORANGE, PINK, RESET);
|
||||
|
||||
final RegistryTestServer server = new RegistryTestServer(address);
|
||||
Statement runner = new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws InterruptedException {
|
||||
System.out.printf("%sLoading datastore fixtures...%s\n", BLUE, RESET);
|
||||
for (Fixture fixture : fixtures) {
|
||||
fixture.load();
|
||||
}
|
||||
System.out.printf("%sStarting Jetty6 HTTP Server...%s\n", BLUE, RESET);
|
||||
server.start();
|
||||
System.out.printf("%sListening on: %s%s\n", PURPLE, server.getUrl("/"), RESET);
|
||||
try {
|
||||
while (true) {
|
||||
server.process();
|
||||
}
|
||||
} finally {
|
||||
server.stop();
|
||||
}
|
||||
}};
|
||||
|
||||
System.out.printf("%sLoading AppEngineRule...%s\n", BLUE, RESET);
|
||||
AppEngineRule.builder()
|
||||
.withDatastore()
|
||||
.withUrlFetch()
|
||||
.withTaskQueue()
|
||||
.withLocalModules()
|
||||
.withUserService(loginIsAdmin
|
||||
? UserInfo.createAdmin(loginEmail, loginUserId)
|
||||
: UserInfo.create(loginEmail, loginUserId))
|
||||
.build()
|
||||
.apply(runner, Description.EMPTY)
|
||||
.evaluate();
|
||||
}
|
||||
|
||||
private RegistryTestServerMain() {}
|
||||
}
|
34
javatests/google/registry/server/Route.java
Normal file
34
javatests/google/registry/server/Route.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
/** Pair of servlet path and servlet instance object. */
|
||||
@AutoValue
|
||||
public abstract class Route {
|
||||
|
||||
abstract String path();
|
||||
abstract Class<? extends HttpServlet> servletClass();
|
||||
|
||||
/** Creates a new route mapping between a path (may have wildcards) and a servlet. */
|
||||
public static Route route(String path, Class<? extends HttpServlet> servletClass) {
|
||||
return new AutoValue_Route(path, servletClass);
|
||||
}
|
||||
|
||||
Route() {}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Suppliers.memoize;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.util.concurrent.Uninterruptibles;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Servlet that wraps a servlet and delegates request execution to a queue.
|
||||
*
|
||||
* @see TestServer
|
||||
*/
|
||||
public final class ServletWrapperDelegatorServlet extends HttpServlet {
|
||||
|
||||
private final Queue<FutureTask<Void>> requestQueue;
|
||||
private final Supplier<HttpServlet> servlet;
|
||||
|
||||
ServletWrapperDelegatorServlet(
|
||||
Class<? extends HttpServlet> servletClass,
|
||||
Queue<FutureTask<Void>> requestQueue) {
|
||||
this.servlet = lazilyInstantiate(checkNotNull(servletClass, "servletClass"));
|
||||
this.requestQueue = checkNotNull(requestQueue, "requestQueue");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(final HttpServletRequest req, final HttpServletResponse rsp)
|
||||
throws ServletException, IOException {
|
||||
FutureTask<Void> task = new FutureTask<>(new Callable<Void>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Void call() throws ServletException, IOException {
|
||||
servlet.get().service(req, rsp);
|
||||
return null;
|
||||
}});
|
||||
requestQueue.add(task);
|
||||
try {
|
||||
Uninterruptibles.getUninterruptibly(task);
|
||||
} catch (ExecutionException e) {
|
||||
Throwables.propagateIfInstanceOf(e.getCause(), ServletException.class);
|
||||
Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
|
||||
throw Throwables.propagate(e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> Supplier<T> lazilyInstantiate(final Class<? extends T> clazz) {
|
||||
return memoize(new Supplier<T>() {
|
||||
@Override
|
||||
public T get() {
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}});
|
||||
}
|
||||
}
|
164
javatests/google/registry/server/StaticResourceServlet.java
Normal file
164
javatests/google/registry/server/StaticResourceServlet.java
Normal file
|
@ -0,0 +1,164 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Verify.verify;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.domain.registry.util.FormattingLogger;
|
||||
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Servlet for serving static resources on a Jetty development server path prefix.
|
||||
*
|
||||
* <p>This servlet can serve either a single file or the contents of a directory.
|
||||
*
|
||||
* <p><b>Note:</b> This code should never be used in production. It's for testing purposes only.
|
||||
*/
|
||||
public final class StaticResourceServlet extends HttpServlet {
|
||||
|
||||
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
||||
|
||||
private static final MediaType DEFAULT_MIME_TYPE = MediaType.OCTET_STREAM;
|
||||
|
||||
private static final ImmutableMap<String, MediaType> MIMES_BY_EXTENSION =
|
||||
new ImmutableMap.Builder<String, MediaType>()
|
||||
.put("css", MediaType.CSS_UTF_8)
|
||||
.put("csv", MediaType.CSV_UTF_8)
|
||||
.put("gif", MediaType.GIF)
|
||||
.put("html", MediaType.HTML_UTF_8)
|
||||
.put("jpeg", MediaType.JPEG)
|
||||
.put("jpg", MediaType.JPEG)
|
||||
.put("js", MediaType.JAVASCRIPT_UTF_8)
|
||||
.put("json", MediaType.JSON_UTF_8)
|
||||
.put("png", MediaType.PNG)
|
||||
.put("txt", MediaType.PLAIN_TEXT_UTF_8)
|
||||
.put("xml", MediaType.XML_UTF_8)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Creates a servlet holder for this servlet so it can be used with Jetty.
|
||||
*
|
||||
* @param prefix servlet path starting with a slash and ending with {@code "/*"} if {@code root}
|
||||
* is a directory
|
||||
* @param root file or root directory to serve
|
||||
*/
|
||||
public static ServletHolder create(String prefix, Path root) {
|
||||
root = root.toAbsolutePath();
|
||||
checkArgument(Files.exists(root), "Root must exist: %s", root);
|
||||
checkArgument(prefix.startsWith("/"), "Prefix must start with a slash: %s", prefix);
|
||||
ServletHolder holder = new ServletHolder(StaticResourceServlet.class);
|
||||
holder.setInitParameter("root", root.toString());
|
||||
if (Files.isDirectory(root)) {
|
||||
checkArgument(prefix.endsWith("/*"),
|
||||
"Prefix (%s) must end with /* since root (%s) is a directory", prefix, root);
|
||||
holder.setInitParameter("prefix", prefix.substring(0, prefix.length() - 1));
|
||||
} else {
|
||||
holder.setInitParameter("prefix", prefix);
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
private Optional<FileServer> fileServer = Optional.absent();
|
||||
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void init(ServletConfig config) {
|
||||
Path root = Paths.get(config.getInitParameter("root"));
|
||||
String prefix = config.getInitParameter("prefix");
|
||||
verify(prefix.startsWith("/"));
|
||||
boolean isDirectory = Files.isDirectory(root);
|
||||
verify(!isDirectory || isDirectory && prefix.endsWith("/"));
|
||||
fileServer = Optional.of(new FileServer(root, prefix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doHead(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
|
||||
fileServer.get().doHead(req, rsp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
|
||||
fileServer.get().doGet(req, rsp);
|
||||
}
|
||||
|
||||
private static final class FileServer {
|
||||
private final Path root;
|
||||
private final String prefix;
|
||||
|
||||
FileServer(Path root, String prefix) {
|
||||
this.root = root;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
Optional<Path> doHead(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
|
||||
verify(req.getRequestURI().startsWith(prefix));
|
||||
Path file = root.resolve(req.getRequestURI().substring(prefix.length())).normalize();
|
||||
if (!file.startsWith(root)) {
|
||||
logger.infofmt("Evil request: %s (%s) (%s + %s)", req.getRequestURI(), file, root, prefix);
|
||||
rsp.sendError(SC_BAD_REQUEST, "Naughty naughty!");
|
||||
return Optional.absent();
|
||||
}
|
||||
if (!Files.exists(file)) {
|
||||
logger.infofmt("Not found: %s (%s)", req.getRequestURI(), file);
|
||||
rsp.sendError(SC_NOT_FOUND, "Not found");
|
||||
return Optional.absent();
|
||||
}
|
||||
if (Files.isDirectory(file)) {
|
||||
logger.infofmt("Directory listing forbidden: %s (%s)", req.getRequestURI(), file);
|
||||
rsp.sendError(SC_FORBIDDEN, "No directory listing");
|
||||
return Optional.absent();
|
||||
}
|
||||
rsp.setContentType(
|
||||
firstNonNull(
|
||||
MIMES_BY_EXTENSION.get(getExtension(file.getFileName().toString())),
|
||||
DEFAULT_MIME_TYPE)
|
||||
.toString());
|
||||
rsp.setContentLength(Ints.checkedCast(Files.size(file)));
|
||||
return Optional.of(file);
|
||||
}
|
||||
|
||||
void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
|
||||
for (Path file : doHead(req, rsp).asSet()) {
|
||||
rsp.getOutputStream().write(Files.readAllBytes(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getExtension(String filename) {
|
||||
int dot = filename.lastIndexOf('.');
|
||||
return dot == -1 ? "" : filename.substring(dot + 1);
|
||||
}
|
||||
}
|
189
javatests/google/registry/server/TestServer.java
Normal file
189
javatests/google/registry/server/TestServer.java
Normal file
|
@ -0,0 +1,189 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.domain.registry.util.NetworkUtils.getCanonicalHostName;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.net.HostAndPort;
|
||||
import com.google.common.util.concurrent.Callables;
|
||||
import com.google.common.util.concurrent.SimpleTimeLimiter;
|
||||
|
||||
import org.mortbay.jetty.Connector;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.bio.SocketConnector;
|
||||
import org.mortbay.jetty.servlet.Context;
|
||||
import org.mortbay.jetty.servlet.DefaultServlet;
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
/**
|
||||
* HTTP server that serves static content and handles servlet requests in the calling thread.
|
||||
*
|
||||
* <p>Using this server is similar to to other server classes, in that it has {@link #start()} and
|
||||
* {@link #stop()} methods. However a {@link #process()} method was added, which is used to process
|
||||
* requests made to servlets (not static files) in the calling thread.
|
||||
*
|
||||
* <p><b>Note:</b> This server is intended for development purposes. For the love all that is good,
|
||||
* do not make this public facing.
|
||||
*
|
||||
* <h3>Implementation Details</h3>
|
||||
*
|
||||
* <p>Jetty6 is multithreaded and provides no mechanism for controlling which threads execute your
|
||||
* requests. HttpServer solves this problem by wrapping all the servlets provided to the constructor
|
||||
* inside {@link ServletWrapperDelegatorServlet}. When requests come in, a {@link FutureTask} will
|
||||
* be sent back to this class using a {@link LinkedBlockingDeque} message queue. Those messages are
|
||||
* then consumed by the {@code process()} method.
|
||||
*
|
||||
* <p>The reason why this is necessary is because the App Engine local testing services (created by
|
||||
* {@code LocalServiceTestHelper}) only apply to a single thread (probably to allow multi-threaded
|
||||
* tests). So when Jetty creates random threads to handle requests, they won't have access to the
|
||||
* datastore and other stuff.
|
||||
*/
|
||||
public final class TestServer {
|
||||
|
||||
private static final int DEFAULT_PORT = 80;
|
||||
private static final String CONTEXT_PATH = "/";
|
||||
private static final int STARTUP_TIMEOUT_MS = 5000;
|
||||
private static final int SHUTDOWN_TIMEOUT_MS = 5000;
|
||||
|
||||
private final HostAndPort urlAddress;
|
||||
private final Server server = new Server();
|
||||
private final BlockingQueue<FutureTask<Void>> requestQueue = new LinkedBlockingDeque<>();
|
||||
|
||||
/**
|
||||
* Creates a new instance, but does not begin serving.
|
||||
*
|
||||
* @param address socket bind address
|
||||
* @param runfiles map of server paths to local directories or files, to be served statically
|
||||
* @param routes list of servlet endpoints
|
||||
*/
|
||||
public TestServer(HostAndPort address, Map<String, Path> runfiles, Iterable<Route> routes) {
|
||||
urlAddress = createUrlAddress(address);
|
||||
server.addConnector(createConnector(address));
|
||||
server.addHandler(createHandler(runfiles, routes));
|
||||
}
|
||||
|
||||
/** Starts the HTTP server in a new thread and returns once it's online. */
|
||||
public void start() {
|
||||
try {
|
||||
server.start();
|
||||
} catch (Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
UrlChecker.waitUntilAvailable(getUrl("/healthz"), STARTUP_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a single servlet request.
|
||||
*
|
||||
* <p>This method should be called from within a loop.
|
||||
*
|
||||
* @throws InterruptedException if this thread was interrupted while waiting for a request.
|
||||
*/
|
||||
public void process() throws InterruptedException {
|
||||
requestQueue.take().run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a fake entry to this server's event loop.
|
||||
*
|
||||
* <p>This is useful in situations when a random thread wants {@link #process()} to return in the
|
||||
* main event loop, for post-request processing.
|
||||
*/
|
||||
public void ping() {
|
||||
requestQueue.add(new FutureTask<>(Callables.<Void>returning(null)));
|
||||
}
|
||||
|
||||
/** Stops the HTTP server. */
|
||||
public void stop() {
|
||||
try {
|
||||
new SimpleTimeLimiter().callWithTimeout(new Callable<Void>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
server.stop();
|
||||
return null;
|
||||
}
|
||||
}, SHUTDOWN_TIMEOUT_MS, TimeUnit.MILLISECONDS, true);
|
||||
} catch (Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a URL that can be used to communicate with this server. */
|
||||
public URL getUrl(String path) {
|
||||
checkArgument(path.startsWith("/"), "Path must start with a slash: %s", path);
|
||||
try {
|
||||
return new URL(String.format("http://%s%s", urlAddress, path));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Context createHandler(Map<String, Path> runfiles, Iterable<Route> routes) {
|
||||
Context context = new Context(server, CONTEXT_PATH, Context.SESSIONS);
|
||||
context.addServlet(new ServletHolder(HealthzServlet.class), "/healthz");
|
||||
for (Map.Entry<String, Path> runfile : runfiles.entrySet()) {
|
||||
context.addServlet(
|
||||
StaticResourceServlet.create(runfile.getKey(), runfile.getValue()),
|
||||
runfile.getKey());
|
||||
}
|
||||
for (Route route : routes) {
|
||||
context.addServlet(new ServletHolder(wrapServlet(route.servletClass())), route.path());
|
||||
}
|
||||
ServletHolder holder = new ServletHolder(DefaultServlet.class);
|
||||
holder.setInitParameter("aliases", "1");
|
||||
context.addServlet(holder, "/*");
|
||||
return context;
|
||||
}
|
||||
|
||||
private HttpServlet wrapServlet(Class<? extends HttpServlet> servletClass) {
|
||||
return new ServletWrapperDelegatorServlet(servletClass, requestQueue);
|
||||
}
|
||||
|
||||
private static Connector createConnector(HostAndPort address) {
|
||||
SocketConnector connector = new SocketConnector();
|
||||
connector.setHost(address.getHostText());
|
||||
connector.setPort(address.getPortOrDefault(DEFAULT_PORT));
|
||||
return connector;
|
||||
}
|
||||
|
||||
/** Converts a bind address into an address that other machines can use to connect here. */
|
||||
private static HostAndPort createUrlAddress(HostAndPort address) {
|
||||
if (address.getHostText().equals("::") || address.getHostText().equals("0.0.0.0")) {
|
||||
return address.getPortOrDefault(DEFAULT_PORT) == DEFAULT_PORT
|
||||
? HostAndPort.fromHost(getCanonicalHostName())
|
||||
: HostAndPort.fromParts(getCanonicalHostName(), address.getPort());
|
||||
} else {
|
||||
return address.getPortOrDefault(DEFAULT_PORT) == DEFAULT_PORT
|
||||
? HostAndPort.fromHost(address.getHostText())
|
||||
: address;
|
||||
}
|
||||
}
|
||||
}
|
70
javatests/google/registry/server/UrlChecker.java
Normal file
70
javatests/google/registry/server/UrlChecker.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright 2016 The Domain Registry Authors. 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.domain.registry.server;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.util.concurrent.SimpleTimeLimiter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class UrlChecker {
|
||||
|
||||
private static final int READ_TIMEOUT_MS = 1000;
|
||||
private static final int CONNECT_TIMEOUT_MS = 500;
|
||||
|
||||
/** Probes {@code url} until it becomes available. */
|
||||
static void waitUntilAvailable(final URL url, int timeoutMs) {
|
||||
try {
|
||||
new SimpleTimeLimiter().callWithTimeout(new Callable<Void>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Void call() throws InterruptedException, IOException {
|
||||
int exponentialBackoffMs = 1;
|
||||
while (true) {
|
||||
if (isAvailable(url)) {
|
||||
return null;
|
||||
}
|
||||
Thread.sleep(exponentialBackoffMs *= 2);
|
||||
}
|
||||
}
|
||||
}, timeoutMs, TimeUnit.MILLISECONDS, true);
|
||||
} catch (Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns {@code true} if page is available and returns {@code 200 OK}. */
|
||||
static boolean isAvailable(URL url) throws IOException {
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setConnectTimeout(CONNECT_TIMEOUT_MS);
|
||||
connection.setReadTimeout(READ_TIMEOUT_MS);
|
||||
try {
|
||||
connection.connect();
|
||||
return connection.getResponseCode() == HttpURLConnection.HTTP_OK;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private UrlChecker() {}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue