diff --git a/java/google/registry/BUILD b/java/google/registry/BUILD index 697c04745..a76e2bee2 100644 --- a/java/google/registry/BUILD +++ b/java/google/registry/BUILD @@ -40,6 +40,7 @@ registry_ear_file( }, wars = { "registry_default.war": "default", + "registry_pubapi.war": "pubapi", "registry_backend.war": "backend", "registry_tools.war": "tools", }, @@ -57,6 +58,7 @@ registry_ear_file( }, wars = { "registry_default_nocron.war": "default", + "registry_pubapi.war": "pubapi", "registry_backend.war": "backend", "registry_tools.war": "tools", }, @@ -93,6 +95,27 @@ zip_file( deps = [":registry_default_war"], ) +zip_file( + name = "registry_pubapi_war", + srcs = [ + "env/common/pubapi/WEB-INF/dos.xml", + "env/common/pubapi/WEB-INF/logging.properties", + "env/common/pubapi/WEB-INF/web.xml", + "env/production/pubapi/WEB-INF/appengine-web.xml", + "//java/google/registry/module/pubapi:pubapi_jar_deploy.jar", + ], + out = "registry_pubapi.war", + mappings = { + "domain_registry/java/google/registry/env/common/pubapi": "", + "domain_registry/java/google/registry/env/production/pubapi": "", + "domain_registry/java/google/registry/module/pubapi": "WEB-INF/lib", + }, + deps = [ + ":common_war", + "//java/google/registry/ui:war_debug", + ], +) + zip_file( name = "registry_backend_war", srcs = [ @@ -148,6 +171,7 @@ registry_ear_file( }, wars = { "registry_default_sandbox.war": "default", + "registry_pubapi_sandbox.war": "pubapi", "registry_backend_sandbox.war": "backend", "registry_tools_sandbox.war": "tools", }, @@ -166,6 +190,18 @@ zip_file( deps = [":registry_default_war"], ) +zip_file( + name = "registry_pubapi_sandbox_war", + srcs = [ + "env/sandbox/pubapi/WEB-INF/appengine-web.xml", + ], + out = "registry_pubapi_sandbox.war", + mappings = { + "domain_registry/java/google/registry/env/sandbox/pubapi": "", + }, + deps = [":registry_pubapi_war"], +) + zip_file( name = "registry_backend_sandbox_war", srcs = [ @@ -204,6 +240,7 @@ registry_ear_file( }, wars = { "registry_default_alpha.war": "default", + "registry_pubapi_alpha.war": "pubapi", "registry_backend_alpha.war": "backend", "registry_tools_alpha.war": "tools", }, @@ -224,6 +261,7 @@ registry_ear_file( }, wars = { "registry_default_alpha_nocron.war": "default", + "registry_pubapi_alpha.war": "pubapi", "registry_backend_alpha.war": "backend", "registry_tools_alpha.war": "tools", }, @@ -249,6 +287,18 @@ zip_file( deps = [":registry_default_alpha_war"], ) +zip_file( + name = "registry_pubapi_alpha_war", + srcs = [ + "env/alpha/pubapi/WEB-INF/appengine-web.xml", + ], + out = "registry_pubapi_alpha.war", + mappings = { + "domain_registry/java/google/registry/env/alpha/pubapi": "", + }, + deps = [":registry_pubapi_war"], +) + zip_file( name = "registry_backend_alpha_war", srcs = [ @@ -287,6 +337,7 @@ registry_ear_file( }, wars = { "registry_default_crash.war": "default", + "registry_pubapi_crash.war": "pubapi", "registry_backend_crash.war": "backend", "registry_tools_crash.war": "tools", }, @@ -307,6 +358,7 @@ registry_ear_file( }, wars = { "registry_default_crash_nocron.war": "default", + "registry_pubapi_crash.war": "pubapi", "registry_backend_crash.war": "backend", "registry_tools_crash.war": "tools", }, @@ -332,6 +384,18 @@ zip_file( deps = [":registry_default_crash_war"], ) +zip_file( + name = "registry_pubapi_crash_war", + srcs = [ + "env/crash/pubapi/WEB-INF/appengine-web.xml", + ], + out = "registry_pubapi_crash.war", + mappings = { + "domain_registry/java/google/registry/env/crash/pubapi": "", + }, + deps = [":registry_pubapi_war"], +) + zip_file( name = "registry_backend_crash_war", srcs = [ @@ -370,6 +434,7 @@ registry_ear_file( }, wars = { "registry_default_local.war": "default", + "registry_pubapi_local.war": "pubapi", "registry_backend_local.war": "backend", "registry_tools_local.war": "tools", }, @@ -387,6 +452,18 @@ zip_file( deps = [":registry_default_war"], ) +zip_file( + name = "registry_pubapi_local_war", + srcs = [ + "env/local/pubapi/WEB-INF/appengine-web.xml", + ], + out = "registry_pubapi_local.war", + mappings = { + "domain_registry/java/google/registry/env/local/pubapi": "", + }, + deps = [":registry_pubapi_war"], +) + zip_file( name = "registry_backend_local_war", srcs = [ diff --git a/java/google/registry/env/alpha/pubapi/WEB-INF/appengine-web.xml b/java/google/registry/env/alpha/pubapi/WEB-INF/appengine-web.xml new file mode 100644 index 000000000..ca8587338 --- /dev/null +++ b/java/google/registry/env/alpha/pubapi/WEB-INF/appengine-web.xml @@ -0,0 +1,29 @@ + + + + domain-registry + 1 + java8 + pubapi + true + true + B4 + + 8 + 10m + + + + + + + + + + + + + + diff --git a/java/google/registry/env/common/META-INF/application.xml b/java/google/registry/env/common/META-INF/application.xml index 485557063..80d8baf00 100644 --- a/java/google/registry/env/common/META-INF/application.xml +++ b/java/google/registry/env/common/META-INF/application.xml @@ -19,6 +19,12 @@ encoding="UTF-8"?> default + + + pubapi + pubapi + + backend diff --git a/java/google/registry/env/common/pubapi/WEB-INF/dos.xml b/java/google/registry/env/common/pubapi/WEB-INF/dos.xml new file mode 100644 index 000000000..14af3ba15 --- /dev/null +++ b/java/google/registry/env/common/pubapi/WEB-INF/dos.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/java/google/registry/env/common/pubapi/WEB-INF/logging.properties b/java/google/registry/env/common/pubapi/WEB-INF/logging.properties new file mode 100644 index 000000000..064aa4905 --- /dev/null +++ b/java/google/registry/env/common/pubapi/WEB-INF/logging.properties @@ -0,0 +1,13 @@ +# A default java.util.logging configuration. +# (All App Engine logging is through java.util.logging by default). +# +# To use this configuration, copy it into your application's WEB-INF +# folder and add the following to your appengine-web.xml: +# +# +# +# +# + +# Set the default logging level for all loggers to INFO. +.level = INFO diff --git a/java/google/registry/env/common/pubapi/WEB-INF/web.xml b/java/google/registry/env/common/pubapi/WEB-INF/web.xml new file mode 100644 index 000000000..ca266e06e --- /dev/null +++ b/java/google/registry/env/common/pubapi/WEB-INF/web.xml @@ -0,0 +1,129 @@ + + + + + + + PubApiServlet + pubapi-servlet + google.registry.module.pubapi.PubApiServlet + 1 + + + + + pubapi-servlet + /whois/* + + + + + pubapi-servlet + /_dr/whois + + + + + pubapi-servlet + /rdap/* + + + + + pubapi-servlet + /check + + + + + + Internal + + Admin-only internal section. Requests for paths covered by the URL patterns below will be + checked for a logged-in user account that's allowed to access the AppEngine admin console + (NOTE: this includes Editor/Viewer permissions in addition to Owner and the new IAM + App Engine Admin role. See https://cloud.google.com/appengine/docs/java/access-control + specifically the "Access handlers that have a login:admin restriction" line.) + + TODO(b/28219927): lift some of these restrictions so that we can allow OAuth authentication + for endpoints that need to be accessed by open-source automated processes. + + + + /_ah/* + + + /assets/sources/* + + + /assets/js/registrar_bin.js.map + /assets/js/registrar_dbg.js + /assets/js/brain_bin.js.map + /assets/css/registrar_dbg.css + + + + admin + + + + + CONFIDENTIAL + + + + + + Registrar console + + Registrar console requires user login. This is in addition to the + code-level "requireLogin" configuration on individual @Actions. + + /registrar* + + + * + + + + CONFIDENTIAL + + + + + + + Secure + + Require encryption for all paths. http URLs will be redirected to https. + + /* + + + CONFIDENTIAL + + + + + + ObjectifyFilter + com.googlecode.objectify.ObjectifyFilter + + + ObjectifyFilter + /* + + + + + OfyFilter + google.registry.model.ofy.OfyFilter + + + OfyFilter + /* + + diff --git a/java/google/registry/env/crash/pubapi/WEB-INF/appengine-web.xml b/java/google/registry/env/crash/pubapi/WEB-INF/appengine-web.xml new file mode 100644 index 000000000..47a7f6edf --- /dev/null +++ b/java/google/registry/env/crash/pubapi/WEB-INF/appengine-web.xml @@ -0,0 +1,29 @@ + + + + domain-registry + 1 + java8 + pubapi + true + true + B4 + + 8 + 10m + + + + + + + + + + + + + + diff --git a/java/google/registry/env/local/pubapi/WEB-INF/appengine-web.xml b/java/google/registry/env/local/pubapi/WEB-INF/appengine-web.xml new file mode 100644 index 000000000..a26210a8a --- /dev/null +++ b/java/google/registry/env/local/pubapi/WEB-INF/appengine-web.xml @@ -0,0 +1,39 @@ + + + + domain-registry + 1 + java8 + pubapi + true + true + B4 + + 8 + 10m + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/google/registry/env/production/pubapi/WEB-INF/appengine-web.xml b/java/google/registry/env/production/pubapi/WEB-INF/appengine-web.xml new file mode 100644 index 000000000..5a6ea5c8e --- /dev/null +++ b/java/google/registry/env/production/pubapi/WEB-INF/appengine-web.xml @@ -0,0 +1,33 @@ + + + + domain-registry + 1 + java8 + pubapi + true + true + B4_1G + + 20 + + + + + + + + + + + + + + + + + + + diff --git a/java/google/registry/env/sandbox/pubapi/WEB-INF/appengine-web.xml b/java/google/registry/env/sandbox/pubapi/WEB-INF/appengine-web.xml new file mode 100644 index 000000000..cde9e57a8 --- /dev/null +++ b/java/google/registry/env/sandbox/pubapi/WEB-INF/appengine-web.xml @@ -0,0 +1,33 @@ + + + + domain-registry + 1 + java8 + pubapi + true + true + B4_1G + + 20 + + + + + + + + + + + + + + + + + + + diff --git a/java/google/registry/module/pubapi/BUILD b/java/google/registry/module/pubapi/BUILD new file mode 100644 index 000000000..9e52e21e5 --- /dev/null +++ b/java/google/registry/module/pubapi/BUILD @@ -0,0 +1,43 @@ +package( + default_visibility = ["//java/google/registry:registry_project"], +) + +licenses(["notice"]) # Apache 2.0 + +java_library( + name = "pubapi", + srcs = glob(["*.java"]), + deps = [ + "//java/google/registry/config", + "//java/google/registry/dns", + "//java/google/registry/flows", + "//java/google/registry/keyring/api", + "//java/google/registry/keyring/kms", + "//java/google/registry/monitoring/whitebox", + "//java/google/registry/rdap", + "//java/google/registry/request", + "//java/google/registry/request:modules", + "//java/google/registry/request/auth", + "//java/google/registry/util", + "//java/google/registry/whois", + "@com_google_appengine_api_1_0_sdk", + "@com_google_code_findbugs_jsr305", + "@com_google_dagger", + "@com_google_guava", + "@com_google_monitoring_client_metrics", + "@javax_servlet_api", + "@org_bouncycastle_bcpkix_jdk15on", + ], +) + +# This rule is used so bazel can generate "frontend_jar_deploy.jar" (which +# contains transitive dependencies) for deployment to App Engine. It MUST +# explicitly depend upon upon anything loaded at runtime, e.g. old servlets +# referenced by the module's web.xml file, that isn't statically linked above. +java_binary( + name = "pubapi_jar", + create_executable = 0, + runtime_deps = [ + ":pubapi", + ], +) diff --git a/java/google/registry/module/pubapi/PubApiComponent.java b/java/google/registry/module/pubapi/PubApiComponent.java new file mode 100644 index 000000000..d1edf4172 --- /dev/null +++ b/java/google/registry/module/pubapi/PubApiComponent.java @@ -0,0 +1,71 @@ +// Copyright 2018 The Nomulus 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 google.registry.module.pubapi; + +import com.google.monitoring.metrics.MetricReporter; +import dagger.Component; +import dagger.Lazy; +import google.registry.config.RegistryConfig.ConfigModule; +import google.registry.flows.ServerTridProviderModule; +import google.registry.flows.custom.CustomLogicFactoryModule; +import google.registry.keyring.api.KeyModule; +import google.registry.keyring.kms.KmsModule; +import google.registry.module.pubapi.PubApiRequestComponent.PubApiRequestComponentModule; +import google.registry.monitoring.whitebox.StackdriverModule; +import google.registry.request.Modules.AppIdentityCredentialModule; +import google.registry.request.Modules.GoogleCredentialModule; +import google.registry.request.Modules.Jackson2Module; +import google.registry.request.Modules.ModulesServiceModule; +import google.registry.request.Modules.NetHttpTransportModule; +import google.registry.request.Modules.UrlFetchTransportModule; +import google.registry.request.Modules.UseAppIdentityCredentialForGoogleApisModule; +import google.registry.request.Modules.UserServiceModule; +import google.registry.request.auth.AuthModule; +import google.registry.util.SystemClock.SystemClockModule; +import google.registry.util.SystemSleeper.SystemSleeperModule; +import javax.inject.Singleton; + +/** Dagger component with instance lifetime for "pubapi" App Engine module. */ +@Singleton +@Component( + modules = { + // TODO(b/79692981): Remove flow-related includes once check API is rewritten to not wrap flow. + AppIdentityCredentialModule.class, + AuthModule.class, + ConfigModule.class, + CustomLogicFactoryModule.class, + google.registry.keyring.api.DummyKeyringModule.class, + PubApiMetricsModule.class, + PubApiRequestComponentModule.class, + GoogleCredentialModule.class, + Jackson2Module.class, + KeyModule.class, + KmsModule.class, + ModulesServiceModule.class, + NetHttpTransportModule.class, + ServerTridProviderModule.class, + StackdriverModule.class, + SystemClockModule.class, + SystemSleeperModule.class, + UrlFetchTransportModule.class, + UseAppIdentityCredentialForGoogleApisModule.class, + UserServiceModule.class, + } +) +interface PubApiComponent { + PubApiRequestHandler requestHandler(); + + Lazy metricReporter(); +} diff --git a/java/google/registry/module/pubapi/PubApiMetricsModule.java b/java/google/registry/module/pubapi/PubApiMetricsModule.java new file mode 100644 index 000000000..d2e5b9cc2 --- /dev/null +++ b/java/google/registry/module/pubapi/PubApiMetricsModule.java @@ -0,0 +1,25 @@ +// Copyright 2018 The Nomulus 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 google.registry.module.pubapi; + +import dagger.Module; +import javax.inject.Singleton; + +/** + * Dagger module for injecting metrics. All metrics should have {@link Singleton} scope to avoid + * being recreated per-request, as the metrics generally track cumulative values. + */ +@Module +public class PubApiMetricsModule {} diff --git a/java/google/registry/module/pubapi/PubApiRequestComponent.java b/java/google/registry/module/pubapi/PubApiRequestComponent.java new file mode 100644 index 000000000..2e3612517 --- /dev/null +++ b/java/google/registry/module/pubapi/PubApiRequestComponent.java @@ -0,0 +1,78 @@ +// Copyright 2018 The Nomulus 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 google.registry.module.pubapi; + +import dagger.Module; +import dagger.Subcomponent; +import google.registry.dns.DnsModule; +import google.registry.flows.CheckApiAction; +import google.registry.flows.CheckApiAction.CheckApiModule; +import google.registry.flows.FlowComponent; +import google.registry.flows.TlsCredentials.EppTlsModule; +import google.registry.monitoring.whitebox.WhiteboxModule; +import google.registry.rdap.RdapAutnumAction; +import google.registry.rdap.RdapDomainAction; +import google.registry.rdap.RdapDomainSearchAction; +import google.registry.rdap.RdapEntityAction; +import google.registry.rdap.RdapEntitySearchAction; +import google.registry.rdap.RdapHelpAction; +import google.registry.rdap.RdapIpAction; +import google.registry.rdap.RdapModule; +import google.registry.rdap.RdapNameserverAction; +import google.registry.rdap.RdapNameserverSearchAction; +import google.registry.request.RequestComponentBuilder; +import google.registry.request.RequestModule; +import google.registry.request.RequestScope; +import google.registry.whois.WhoisAction; +import google.registry.whois.WhoisHttpAction; +import google.registry.whois.WhoisModule; + +/** Dagger component with per-request lifetime for "pubapi" App Engine module. */ +@RequestScope +@Subcomponent( + modules = { + CheckApiModule.class, + DnsModule.class, + EppTlsModule.class, + RdapModule.class, + RequestModule.class, + WhiteboxModule.class, + WhoisModule.class, + }) +interface PubApiRequestComponent { + CheckApiAction checkApiAction(); + // TODO(b/79692981): Remove flow-related includes once check API is rewritten to not wrap flow. + FlowComponent.Builder flowComponentBuilder(); + RdapAutnumAction rdapAutnumAction(); + RdapDomainAction rdapDomainAction(); + RdapDomainSearchAction rdapDomainSearchAction(); + RdapEntityAction rdapEntityAction(); + RdapEntitySearchAction rdapEntitySearchAction(); + RdapHelpAction rdapHelpAction(); + RdapIpAction rdapDefaultAction(); + RdapNameserverAction rdapNameserverAction(); + RdapNameserverSearchAction rdapNameserverSearchAction(); + WhoisHttpAction whoisHttpAction(); + WhoisAction whoisAction(); + + @Subcomponent.Builder + abstract class Builder implements RequestComponentBuilder { + @Override public abstract Builder requestModule(RequestModule requestModule); + @Override public abstract PubApiRequestComponent build(); + } + + @Module(subcomponents = PubApiRequestComponent.class) + class PubApiRequestComponentModule {} +} diff --git a/java/google/registry/module/pubapi/PubApiRequestHandler.java b/java/google/registry/module/pubapi/PubApiRequestHandler.java new file mode 100644 index 000000000..71a263c89 --- /dev/null +++ b/java/google/registry/module/pubapi/PubApiRequestHandler.java @@ -0,0 +1,31 @@ +// Copyright 2018 The Nomulus 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 google.registry.module.pubapi; + +import google.registry.request.RequestHandler; +import google.registry.request.auth.RequestAuthenticator; +import javax.inject.Inject; +import javax.inject.Provider; + +/** Request handler for the frontend module. */ +public class PubApiRequestHandler extends RequestHandler { + + @Inject + PubApiRequestHandler( + Provider componentBuilderProvider, + RequestAuthenticator requestAuthenticator) { + super(componentBuilderProvider, requestAuthenticator); + } +} diff --git a/java/google/registry/module/pubapi/PubApiServlet.java b/java/google/registry/module/pubapi/PubApiServlet.java new file mode 100644 index 000000000..aab42779b --- /dev/null +++ b/java/google/registry/module/pubapi/PubApiServlet.java @@ -0,0 +1,68 @@ +// Copyright 2018 The Nomulus 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 google.registry.module.pubapi; + +import com.google.appengine.api.LifecycleManager; +import com.google.monitoring.metrics.MetricReporter; +import dagger.Lazy; +import google.registry.util.FormattingLogger; +import java.io.IOException; +import java.security.Security; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +/** Servlet that should handle all requests to our "default" App Engine module. */ +public final class PubApiServlet extends HttpServlet { + + private static final PubApiComponent component = DaggerPubApiComponent.create(); + private static final PubApiRequestHandler requestHandler = component.requestHandler(); + private static final Lazy metricReporter = component.metricReporter(); + private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass(); + + @Override + public void init() { + Security.addProvider(new BouncyCastleProvider()); + + // If metric reporter failed to instantiate for any reason (bad keyring, bad json credential, + // etc), we log the error but keep the main thread running. Also the shutdown hook will only be + // registered if metric reporter starts up correctly. + try { + metricReporter.get().startAsync().awaitRunning(10, TimeUnit.SECONDS); + logger.info("Started up MetricReporter"); + LifecycleManager.getInstance() + .setShutdownHook( + () -> { + try { + metricReporter.get().stopAsync().awaitTerminated(10, TimeUnit.SECONDS); + logger.info("Shut down MetricReporter"); + } catch (TimeoutException e) { + logger.severe(e, "Failed to stop MetricReporter."); + } + }); + } catch (Exception e) { + logger.severe(e, "Failed to initialize MetricReporter."); + } + } + + @Override + public void service(HttpServletRequest req, HttpServletResponse rsp) throws IOException { + logger.info("Received frontend request"); + requestHandler.handleRequest(req, rsp); + } +} diff --git a/java/google/registry/module/pubapi/package-info.java b/java/google/registry/module/pubapi/package-info.java new file mode 100644 index 000000000..55adfa585 --- /dev/null +++ b/java/google/registry/module/pubapi/package-info.java @@ -0,0 +1,16 @@ +// Copyright 2018 The Nomulus 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. + +@javax.annotation.ParametersAreNonnullByDefault +package google.registry.module.pubapi; diff --git a/java/google/registry/tools/BUILD b/java/google/registry/tools/BUILD index e042c8026..67c521c45 100644 --- a/java/google/registry/tools/BUILD +++ b/java/google/registry/tools/BUILD @@ -51,6 +51,7 @@ java_library( "//java/google/registry/model", "//java/google/registry/module/backend", "//java/google/registry/module/frontend", + "//java/google/registry/module/pubapi", "//java/google/registry/module/tools", "//java/google/registry/pricing", "//java/google/registry/rde", diff --git a/javatests/google/registry/module/pubapi/BUILD b/javatests/google/registry/module/pubapi/BUILD new file mode 100644 index 000000000..6af438dd1 --- /dev/null +++ b/javatests/google/registry/module/pubapi/BUILD @@ -0,0 +1,35 @@ +package( + default_testonly = 1, + default_visibility = ["//java/google/registry:registry_project"], +) + +licenses(["notice"]) # Apache 2.0 + +java_library( + name = "pubapi", + srcs = glob(["*.java"]), + resources = glob(["testdata/*"]), + runtime_deps = [ + # TODO(b/19332643): Remove this dependency when Modules is lazy. + "@com_google_appengine_api_1_0_sdk//:testonly", + ], + deps = [ + "//java/google/registry/module/pubapi", + "//java/google/registry/request", + "//javatests/google/registry/testing", + "@com_google_guava", + "@com_google_truth", + "@com_google_truth_extensions_truth_java8_extension", + "@javax_servlet_api", + "@junit", + "@org_mockito_all", + ], +) + +load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules") + +GenTestRules( + name = "GeneratedTestRules", + test_files = glob(["*Test.java"]), + deps = [":pubapi"], +) diff --git a/javatests/google/registry/module/pubapi/PubApiRequestComponentTest.java b/javatests/google/registry/module/pubapi/PubApiRequestComponentTest.java new file mode 100644 index 000000000..f85549a72 --- /dev/null +++ b/javatests/google/registry/module/pubapi/PubApiRequestComponentTest.java @@ -0,0 +1,33 @@ +// Copyright 2018 The Nomulus 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 google.registry.module.pubapi; + + +import google.registry.testing.GoldenFileTestHelper; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link PubApiRequestComponent}. */ +@RunWith(JUnit4.class) +public class PubApiRequestComponentTest { + + @Test + public void testRoutingMap() throws Exception { + GoldenFileTestHelper.assertThatRoutesFromComponent(PubApiRequestComponent.class) + .describedAs("pubapi routing map") + .isEqualToGolden(PubApiRequestComponentTest.class, "pubapi_routing.txt"); + } +} diff --git a/javatests/google/registry/module/pubapi/PubApiServletTest.java b/javatests/google/registry/module/pubapi/PubApiServletTest.java new file mode 100644 index 000000000..58439782e --- /dev/null +++ b/javatests/google/registry/module/pubapi/PubApiServletTest.java @@ -0,0 +1,47 @@ +// Copyright 2018 The Nomulus 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 google.registry.module.pubapi; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import google.registry.testing.AppEngineRule; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link PubApiServlet}. */ +@RunWith(JUnit4.class) +public class PubApiServletTest { + + @Rule + public final AppEngineRule appEngine = + AppEngineRule.builder().withDatastore().withLocalModules().build(); + + private final HttpServletRequest req = mock(HttpServletRequest.class); + private final HttpServletResponse rsp = mock(HttpServletResponse.class); + + @Test + public void testService_unknownPath_returnNotFound() throws Exception { + when(req.getMethod()).thenReturn("GET"); + when(req.getRequestURI()).thenReturn("/lol"); + new PubApiServlet().service(req, rsp); + verify(rsp).sendError(404); + } +} diff --git a/javatests/google/registry/module/pubapi/testdata/pubapi_routing.txt b/javatests/google/registry/module/pubapi/testdata/pubapi_routing.txt new file mode 100644 index 000000000..089d67c16 --- /dev/null +++ b/javatests/google/registry/module/pubapi/testdata/pubapi_routing.txt @@ -0,0 +1,13 @@ +PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY +/_dr/whois WhoisAction POST n INTERNAL,API APP PUBLIC +/check CheckApiAction GET n INTERNAL NONE PUBLIC +/rdap/autnum/(*) RdapAutnumAction GET,HEAD n INTERNAL NONE PUBLIC +/rdap/domain/(*) RdapDomainAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC +/rdap/domains RdapDomainSearchAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC +/rdap/entities RdapEntitySearchAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC +/rdap/entity/(*) RdapEntityAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC +/rdap/help(*) RdapHelpAction GET,HEAD n INTERNAL NONE PUBLIC +/rdap/ip/(*) RdapIpAction GET,HEAD n INTERNAL NONE PUBLIC +/rdap/nameserver/(*) RdapNameserverAction GET,HEAD n INTERNAL NONE PUBLIC +/rdap/nameservers RdapNameserverSearchAction GET,HEAD n INTERNAL NONE PUBLIC +/whois/(*) WhoisHttpAction GET n INTERNAL NONE PUBLIC