1
0
mirror of https://github.com/google/nomulus synced 2026-01-05 04:56:03 +00:00

Replace Front/Back-end servlets with single TestServlet (#2874)

The servlets, at this point now that we're off GAE, are only used for
the test server (and, indirectly, in one BSA test). Instead of having
them all remain separate, we can unify them in one test servlet that
lives in the test/ folder.

This removes one avenue of potential confusion w/r/t how request routing
actually works and where we would want to add new routing.
This commit is contained in:
gbrodman
2025-11-12 16:01:14 -05:00
committed by GitHub
parent 816180f3b3
commit 759aaddb5f
24 changed files with 133 additions and 830 deletions

View File

@@ -1,193 +0,0 @@
// Copyright 2017 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.backend;
import dagger.Module;
import dagger.Subcomponent;
import google.registry.batch.BatchModule;
import google.registry.batch.CannedScriptExecutionAction;
import google.registry.batch.DeleteExpiredDomainsAction;
import google.registry.batch.DeleteLoadTestDataAction;
import google.registry.batch.DeleteProberDataAction;
import google.registry.batch.ExpandBillingRecurrencesAction;
import google.registry.batch.RelockDomainAction;
import google.registry.batch.RemoveAllDomainContactsAction;
import google.registry.batch.ResaveAllEppResourcesPipelineAction;
import google.registry.batch.ResaveEntityAction;
import google.registry.batch.SendExpiringCertificateNotificationEmailAction;
import google.registry.batch.WipeOutContactHistoryPiiAction;
import google.registry.cron.CronModule;
import google.registry.cron.TldFanoutAction;
import google.registry.dns.DnsModule;
import google.registry.dns.PublishDnsUpdatesAction;
import google.registry.dns.ReadDnsRefreshRequestsAction;
import google.registry.dns.RefreshDnsAction;
import google.registry.dns.RefreshDnsOnHostRenameAction;
import google.registry.dns.writer.DnsWritersModule;
import google.registry.dns.writer.dnsupdate.DnsUpdateConfigModule;
import google.registry.export.ExportDomainListsAction;
import google.registry.export.ExportPremiumTermsAction;
import google.registry.export.ExportReservedTermsAction;
import google.registry.export.SyncGroupMembersAction;
import google.registry.export.sheet.SheetModule;
import google.registry.export.sheet.SyncRegistrarsSheetAction;
import google.registry.flows.FlowComponent;
import google.registry.flows.custom.CustomLogicModule;
import google.registry.monitoring.whitebox.WhiteboxModule;
import google.registry.rdap.UpdateRegistrarRdapBaseUrlsAction;
import google.registry.rde.BrdaCopyAction;
import google.registry.rde.RdeModule;
import google.registry.rde.RdeReportAction;
import google.registry.rde.RdeReporter;
import google.registry.rde.RdeStagingAction;
import google.registry.rde.RdeUploadAction;
import google.registry.reporting.ReportingModule;
import google.registry.reporting.billing.BillingModule;
import google.registry.reporting.billing.CopyDetailReportsAction;
import google.registry.reporting.billing.GenerateInvoicesAction;
import google.registry.reporting.billing.PublishInvoicesAction;
import google.registry.reporting.icann.DnsCountQueryCoordinator.DnsCountQueryCoordinatorModule;
import google.registry.reporting.icann.IcannReportingModule;
import google.registry.reporting.icann.IcannReportingStagingAction;
import google.registry.reporting.icann.IcannReportingUploadAction;
import google.registry.reporting.spec11.GenerateSpec11ReportAction;
import google.registry.reporting.spec11.PublishSpec11ReportAction;
import google.registry.reporting.spec11.Spec11Module;
import google.registry.request.RequestComponentBuilder;
import google.registry.request.RequestModule;
import google.registry.request.RequestScope;
import google.registry.tmch.NordnUploadAction;
import google.registry.tmch.NordnVerifyAction;
import google.registry.tmch.TmchCrlAction;
import google.registry.tmch.TmchDnlAction;
import google.registry.tmch.TmchModule;
import google.registry.tmch.TmchSmdrlAction;
/** Dagger component with per-request lifetime for "backend" App Engine module. */
@RequestScope
@Subcomponent(
modules = {
BatchModule.class,
BillingModule.class,
CronModule.class,
CustomLogicModule.class,
DnsCountQueryCoordinatorModule.class,
DnsModule.class,
DnsUpdateConfigModule.class,
DnsWritersModule.class,
IcannReportingModule.class,
RdeModule.class,
ReportingModule.class,
RequestModule.class,
SheetModule.class,
Spec11Module.class,
TmchModule.class,
WhiteboxModule.class,
})
public interface BackendRequestComponent {
BrdaCopyAction brdaCopyAction();
CannedScriptExecutionAction cannedScriptExecutionAction();
CopyDetailReportsAction copyDetailReportAction();
DeleteExpiredDomainsAction deleteExpiredDomainsAction();
DeleteLoadTestDataAction deleteLoadTestDataAction();
DeleteProberDataAction deleteProberDataAction();
ExpandBillingRecurrencesAction expandBillingRecurrencesAction();
ExportDomainListsAction exportDomainListsAction();
ExportPremiumTermsAction exportPremiumTermsAction();
ExportReservedTermsAction exportReservedTermsAction();
FlowComponent.Builder flowComponentBuilder();
GenerateInvoicesAction generateInvoicesAction();
GenerateSpec11ReportAction generateSpec11ReportAction();
IcannReportingStagingAction icannReportingStagingAction();
IcannReportingUploadAction icannReportingUploadAction();
NordnUploadAction nordnUploadAction();
NordnVerifyAction nordnVerifyAction();
PublishDnsUpdatesAction publishDnsUpdatesAction();
PublishInvoicesAction uploadInvoicesAction();
PublishSpec11ReportAction publishSpec11ReportAction();
ReadDnsRefreshRequestsAction readDnsRefreshRequestsAction();
RdeReportAction rdeReportAction();
RdeStagingAction rdeStagingAction();
RdeUploadAction rdeUploadAction();
RdeReporter rdeReporter();
RefreshDnsAction refreshDnsAction();
RefreshDnsOnHostRenameAction refreshDnsOnHostRenameAction();
RelockDomainAction relockDomainAction();
RemoveAllDomainContactsAction removeAllDomainContactsAction();
ResaveAllEppResourcesPipelineAction resaveAllEppResourcesPipelineAction();
ResaveEntityAction resaveEntityAction();
SendExpiringCertificateNotificationEmailAction sendExpiringCertificateNotificationEmailAction();
SyncGroupMembersAction syncGroupMembersAction();
SyncRegistrarsSheetAction syncRegistrarsSheetAction();
TldFanoutAction tldFanoutAction();
TmchCrlAction tmchCrlAction();
TmchDnlAction tmchDnlAction();
TmchSmdrlAction tmchSmdrlAction();
UpdateRegistrarRdapBaseUrlsAction updateRegistrarRdapBaseUrlsAction();
WipeOutContactHistoryPiiAction wipeOutContactHistoryPiiAction();
@Subcomponent.Builder
abstract class Builder implements RequestComponentBuilder<BackendRequestComponent> {
@Override
public abstract Builder requestModule(RequestModule requestModule);
@Override
public abstract BackendRequestComponent build();
}
@Module(subcomponents = BackendRequestComponent.class)
class BackendRequestComponentModule {}
}

View File

@@ -1,31 +0,0 @@
// Copyright 2017 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.backend;
import com.google.monitoring.metrics.MetricReporter;
import dagger.Lazy;
import google.registry.module.ServletBase;
/** Servlet that should handle all requests to our "backend" App Engine module. */
public final class BackendServlet extends ServletBase {
private static final BackendComponent component = DaggerBackendComponent.create();
private static final BackendRequestHandler requestHandler = component.requestHandler();
private static final Lazy<MetricReporter> metricReporter = component.metricReporter();
public BackendServlet() {
super(requestHandler, metricReporter);
}
}

View File

@@ -1,16 +0,0 @@
// Copyright 2017 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.backend;

View File

@@ -1,70 +0,0 @@
// Copyright 2017 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.frontend;
import com.google.monitoring.metrics.MetricReporter;
import dagger.Component;
import dagger.Lazy;
import google.registry.config.CloudTasksUtilsModule;
import google.registry.config.CredentialModule;
import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.flows.ServerTridProviderModule;
import google.registry.flows.custom.CustomLogicFactoryModule;
import google.registry.flows.domain.DomainDeletionTimeCacheModule;
import google.registry.groups.DirectoryModule;
import google.registry.groups.GmailModule;
import google.registry.groups.GroupsModule;
import google.registry.groups.GroupssettingsModule;
import google.registry.keyring.KeyringModule;
import google.registry.keyring.api.KeyModule;
import google.registry.module.frontend.FrontendRequestComponent.FrontendRequestComponentModule;
import google.registry.monitoring.whitebox.StackdriverModule;
import google.registry.privileges.secretmanager.SecretManagerModule;
import google.registry.request.Modules.GsonModule;
import google.registry.request.Modules.NetHttpTransportModule;
import google.registry.request.auth.AuthModule;
import google.registry.util.UtilsModule;
import jakarta.inject.Singleton;
/** Dagger component with instance lifetime for "default" App Engine module. */
@Singleton
@Component(
modules = {
AuthModule.class,
CloudTasksUtilsModule.class,
ConfigModule.class,
CredentialModule.class,
CustomLogicFactoryModule.class,
CloudTasksUtilsModule.class,
DirectoryModule.class,
DomainDeletionTimeCacheModule.class,
FrontendRequestComponentModule.class,
GmailModule.class,
GroupsModule.class,
GroupssettingsModule.class,
GsonModule.class,
KeyModule.class,
KeyringModule.class,
NetHttpTransportModule.class,
SecretManagerModule.class,
ServerTridProviderModule.class,
StackdriverModule.class,
UtilsModule.class
})
interface FrontendComponent {
FrontendRequestHandler requestHandler();
Lazy<MetricReporter> metricReporter();
}

View File

@@ -1,111 +0,0 @@
// Copyright 2017 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.frontend;
import dagger.Module;
import dagger.Subcomponent;
import google.registry.batch.BatchModule;
import google.registry.dns.DnsModule;
import google.registry.flows.EppTlsAction;
import google.registry.flows.FlowComponent;
import google.registry.flows.TlsCredentials.EppTlsModule;
import google.registry.module.ReadinessProbeAction.ReadinessProbeActionFrontend;
import google.registry.module.ReadinessProbeAction.ReadinessProbeConsoleAction;
import google.registry.monitoring.whitebox.WhiteboxModule;
import google.registry.request.RequestComponentBuilder;
import google.registry.request.RequestModule;
import google.registry.request.RequestScope;
import google.registry.ui.server.console.ConsoleDomainGetAction;
import google.registry.ui.server.console.ConsoleDomainListAction;
import google.registry.ui.server.console.ConsoleDumDownloadAction;
import google.registry.ui.server.console.ConsoleEppPasswordAction;
import google.registry.ui.server.console.ConsoleModule;
import google.registry.ui.server.console.ConsoleOteAction;
import google.registry.ui.server.console.ConsoleRegistryLockAction;
import google.registry.ui.server.console.ConsoleRegistryLockVerifyAction;
import google.registry.ui.server.console.ConsoleUpdateRegistrarAction;
import google.registry.ui.server.console.ConsoleUserDataAction;
import google.registry.ui.server.console.ConsoleUsersAction;
import google.registry.ui.server.console.PasswordResetRequestAction;
import google.registry.ui.server.console.PasswordResetVerifyAction;
import google.registry.ui.server.console.RegistrarsAction;
import google.registry.ui.server.console.domains.ConsoleBulkDomainAction;
import google.registry.ui.server.console.settings.ContactAction;
import google.registry.ui.server.console.settings.RdapRegistrarFieldsAction;
import google.registry.ui.server.console.settings.SecurityAction;
/** Dagger component with per-request lifetime for "default" App Engine module. */
@RequestScope
@Subcomponent(
modules = {
BatchModule.class,
DnsModule.class,
EppTlsModule.class,
ConsoleModule.class,
RequestModule.class,
WhiteboxModule.class,
})
public interface FrontendRequestComponent {
ConsoleBulkDomainAction consoleBulkDomainAction();
ConsoleDomainGetAction consoleDomainGetAction();
ConsoleDomainListAction consoleDomainListAction();
ConsoleEppPasswordAction consoleEppPasswordAction();
ConsoleOteAction consoleOteAction();
ConsoleRegistryLockAction consoleRegistryLockAction();
ConsoleRegistryLockVerifyAction consoleRegistryLockVerifyAction();
ConsoleUpdateRegistrarAction consoleUpdateRegistrarAction();
ConsoleUserDataAction consoleUserDataAction();
ConsoleUsersAction consoleUsersAction();
ConsoleDumDownloadAction consoleDumDownloadAction();
ContactAction contactAction();
EppTlsAction eppTlsAction();
FlowComponent.Builder flowComponentBuilder();
PasswordResetRequestAction passwordResetRequestAction();
PasswordResetVerifyAction passwordResetVerifyAction();
RdapRegistrarFieldsAction rdapRegistrarFieldsAction();
ReadinessProbeActionFrontend readinessProbeActionFrontend();
ReadinessProbeConsoleAction readinessProbeConsoleAction();
RegistrarsAction registrarsAction();
SecurityAction securityAction();
@Subcomponent.Builder
abstract class Builder implements RequestComponentBuilder<FrontendRequestComponent> {
@Override public abstract Builder requestModule(RequestModule requestModule);
@Override public abstract FrontendRequestComponent build();
}
@Module(subcomponents = FrontendRequestComponent.class)
class FrontendRequestComponentModule {}
}

View File

@@ -1,30 +0,0 @@
// Copyright 2017 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.frontend;
import google.registry.request.RequestHandler;
import google.registry.request.auth.RequestAuthenticator;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
/** Request handler for the frontend module. */
public class FrontendRequestHandler extends RequestHandler<FrontendRequestComponent> {
@Inject FrontendRequestHandler(
Provider<FrontendRequestComponent.Builder> componentBuilderProvider,
RequestAuthenticator requestAuthenticator) {
super(componentBuilderProvider, requestAuthenticator);
}
}

View File

@@ -1,31 +0,0 @@
// Copyright 2017 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.frontend;
import com.google.monitoring.metrics.MetricReporter;
import dagger.Lazy;
import google.registry.module.ServletBase;
/** Servlet that should handle all requests to our "default" App Engine module. */
public final class FrontendServlet extends ServletBase {
private static final FrontendComponent component = DaggerFrontendComponent.create();
private static final FrontendRequestHandler requestHandler = component.requestHandler();
private static final Lazy<MetricReporter> metricReporter = component.metricReporter();
public FrontendServlet() {
super(requestHandler, metricReporter);
}
}

View File

@@ -1,16 +0,0 @@
// Copyright 2017 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.frontend;

View File

@@ -31,11 +31,7 @@ import jakarta.servlet.http.HttpServletRequest;
import java.util.Optional;
import org.joda.time.DateTime;
/**
* Dagger module for RDE package.
*
* @see "google.registry.module.backend.BackendRequestComponent"
*/
/** Dagger module for RDE package. */
@Module
public abstract class RdeModule {

View File

@@ -169,7 +169,7 @@ public class UploadBsaUnavailableDomainsActionTest {
new TestServer(
HostAndPort.fromParts(InetAddress.getLocalHost().getHostAddress(), pickUnusedPort()),
ImmutableMap.of(),
ImmutableList.of(Route.route("/upload", Servelet.class)));
ImmutableList.of(Route.route("/upload", Servlet.class)));
testServer.start();
newSingleThreadExecutor()
.execute(
@@ -191,7 +191,7 @@ public class UploadBsaUnavailableDomainsActionTest {
maxRequestSize = 20971520L, // 20MB
fileSizeThreshold = 1048576 // Save in memory if file size < 1MB
)
public static class Servelet extends HttpServlet {
public static class Servlet extends HttpServlet {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@Override

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.module.frontend;
package google.registry.module;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;

View File

@@ -1,4 +1,4 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
// Copyright 2025 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.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.module.backend;
package google.registry.module;
import com.google.monitoring.metrics.MetricReporter;
import dagger.Component;
@@ -27,13 +27,12 @@ import google.registry.export.sheet.SheetsServiceModule;
import google.registry.flows.ServerTridProviderModule;
import google.registry.flows.custom.CustomLogicFactoryModule;
import google.registry.flows.domain.DomainDeletionTimeCacheModule;
import google.registry.groups.DirectoryModule;
import google.registry.groups.GmailModule;
import google.registry.groups.GroupsModule;
import google.registry.groups.GroupssettingsModule;
import google.registry.keyring.KeyringModule;
import google.registry.keyring.api.KeyModule;
import google.registry.module.backend.BackendRequestComponent.BackendRequestComponentModule;
import google.registry.module.TestRequestComponent.TestRequestComponentModule;
import google.registry.monitoring.whitebox.StackdriverModule;
import google.registry.persistence.PersistenceModule;
import google.registry.privileges.secretmanager.SecretManagerModule;
@@ -45,39 +44,39 @@ import google.registry.request.auth.AuthModule;
import google.registry.util.UtilsModule;
import jakarta.inject.Singleton;
/** Dagger component with instance lifetime for "backend" App Engine module. */
/** Dagger component with instance lifetime for the test server. */
@Singleton
@Component(
modules = {
AuthModule.class,
BackendRequestComponentModule.class,
BatchModule.class,
BigqueryModule.class,
ConfigModule.class,
CloudTasksUtilsModule.class,
ConfigModule.class,
CredentialModule.class,
CustomLogicFactoryModule.class,
DomainDeletionTimeCacheModule.class,
DirectoryModule.class,
DriveModule.class,
GmailModule.class,
GroupsModule.class,
GroupssettingsModule.class,
JSchModule.class,
GsonModule.class,
JSchModule.class,
KeyModule.class,
KeyringModule.class,
MockDirectoryModule.class,
NetHttpTransportModule.class,
PersistenceModule.class,
SecretManagerModule.class,
ServerTridProviderModule.class,
SheetsServiceModule.class,
StackdriverModule.class,
TestRequestComponentModule.class,
UrlConnectionServiceModule.class,
UtilsModule.class
})
interface BackendComponent {
BackendRequestHandler requestHandler();
interface TestRegistryComponent {
TestRequestHandler requestHandler();
Lazy<MetricReporter> metricReporter();
}

View File

@@ -0,0 +1,86 @@
// Copyright 2025 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;
import dagger.Module;
import dagger.Subcomponent;
import google.registry.batch.BatchModule;
import google.registry.cron.CronModule;
import google.registry.dns.DnsModule;
import google.registry.dns.writer.DnsWritersModule;
import google.registry.dns.writer.dnsupdate.DnsUpdateConfigModule;
import google.registry.export.sheet.SheetModule;
import google.registry.flows.CheckApiAction.CheckApiModule;
import google.registry.flows.EppToolAction.EppToolModule;
import google.registry.flows.TlsCredentials.EppTlsModule;
import google.registry.flows.custom.CustomLogicModule;
import google.registry.loadtest.LoadTestModule;
import google.registry.monitoring.whitebox.WhiteboxModule;
import google.registry.rdap.RdapModule;
import google.registry.rde.RdeModule;
import google.registry.reporting.ReportingModule;
import google.registry.reporting.billing.BillingModule;
import google.registry.reporting.icann.DnsCountQueryCoordinator.DnsCountQueryCoordinatorModule;
import google.registry.reporting.icann.IcannReportingModule;
import google.registry.reporting.spec11.Spec11Module;
import google.registry.request.RequestComponentBuilder;
import google.registry.request.RequestModule;
import google.registry.request.RequestScope;
import google.registry.tmch.TmchModule;
import google.registry.tools.server.ToolsServerModule;
import google.registry.ui.server.console.ConsoleModule;
/** Dagger component with per-request lifetime for the test server. */
@RequestScope
@Subcomponent(
modules = {
BatchModule.class,
BillingModule.class,
CheckApiModule.class,
ConsoleModule.class,
CronModule.class,
CustomLogicModule.class,
DnsCountQueryCoordinatorModule.class,
DnsModule.class,
DnsUpdateConfigModule.class,
DnsWritersModule.class,
EppTlsModule.class,
EppToolModule.class,
IcannReportingModule.class,
LoadTestModule.class,
RdapModule.class,
RdeModule.class,
ReportingModule.class,
RequestModule.class,
SheetModule.class,
Spec11Module.class,
TmchModule.class,
ToolsServerModule.class,
WhiteboxModule.class
})
interface TestRequestComponent extends RequestComponent {
@Subcomponent.Builder
abstract class Builder implements RequestComponentBuilder<TestRequestComponent> {
@Override
public abstract TestRequestComponent.Builder requestModule(RequestModule requestModule);
@Override
public abstract TestRequestComponent build();
}
@Module(subcomponents = TestRequestComponent.class)
static class TestRequestComponentModule {}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
// Copyright 2025 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.
@@ -12,18 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.module.backend;
package google.registry.module;
import google.registry.request.RequestHandler;
import google.registry.request.auth.RequestAuthenticator;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
/** Request handler for the backend module. */
public class BackendRequestHandler extends RequestHandler<BackendRequestComponent> {
/** Request handler for the specialized test server. */
public class TestRequestHandler extends RequestHandler<TestRequestComponent> {
@Inject BackendRequestHandler(
Provider<BackendRequestComponent.Builder> componentBuilderProvider,
@Inject
public TestRequestHandler(
Provider<TestRequestComponent.Builder> componentBuilderProvider,
RequestAuthenticator requestAuthenticator) {
super(componentBuilderProvider, requestAuthenticator);
}

View File

@@ -12,19 +12,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.module.frontend;
package google.registry.module;
import com.google.monitoring.metrics.MetricReporter;
import dagger.Lazy;
import google.registry.module.ServletBase;
public class FrontendTestServlet extends ServletBase {
private static final FrontendTestComponent component = DaggerFrontendTestComponent.create();
private static final FrontendRequestHandler requestHandler = component.requestHandler();
/**
* Servlet used in the test server to handle routing.
*
* <p>This functions somewhat as a mock, because in the production environment our routing is
* handled through the Kubernetes configuration (in the jetty package). Here, we can manually
* configure routes for the test server when we need them.
*/
public class TestServlet extends ServletBase {
private static final TestRegistryComponent component = DaggerTestRegistryComponent.create();
private static final TestRequestHandler requestHandler = component.requestHandler();
private static final Lazy<MetricReporter> metricReporter = component.metricReporter();
public FrontendTestServlet() {
public TestServlet() {
super(requestHandler, metricReporter);
}
}

View File

@@ -1,41 +0,0 @@
// Copyright 2017 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.backend;
import static com.google.common.truth.Truth.assertThat;
import google.registry.request.Action.GaeService;
import google.registry.request.RouterDisplayHelper;
import google.registry.testing.GoldenFileTestHelper;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link BackendRequestComponent}. */
class BackendRequestComponentTest {
@Test
void testRoutingMap() {
GoldenFileTestHelper.assertThatRoutesFromComponent(BackendRequestComponent.class)
.describedAs("backend routing map")
.isEqualToGolden(BackendRequestComponentTest.class, "backend_routing.txt");
}
@Test
void testRoutingService() {
assertThat(
RouterDisplayHelper.extractHumanReadableRoutesWithWrongService(
BackendRequestComponent.class, GaeService.BACKEND))
.isEmpty();
}
}

View File

@@ -1,38 +0,0 @@
// Copyright 2017 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.backend;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link BackendServlet}. */
class BackendServletTest {
private final HttpServletRequest req = mock(HttpServletRequest.class);
private final HttpServletResponse rsp = mock(HttpServletResponse.class);
@Test
void testService_unknownPath_returnsNotFound() throws Exception {
when(req.getMethod()).thenReturn("GET");
when(req.getRequestURI()).thenReturn("/lol");
new BackendServlet().service(req, rsp);
verify(rsp).sendError(404);
}
}

View File

@@ -1,41 +0,0 @@
// Copyright 2017 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.frontend;
import static com.google.common.truth.Truth.assertThat;
import google.registry.request.Action.GaeService;
import google.registry.request.RouterDisplayHelper;
import google.registry.testing.GoldenFileTestHelper;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link FrontendRequestComponent}. */
class FrontendRequestComponentTest {
@Test
void testRoutingMap() {
GoldenFileTestHelper.assertThatRoutesFromComponent(FrontendRequestComponent.class)
.describedAs("frontend routing map")
.isEqualToGolden(FrontendRequestComponentTest.class, "frontend_routing.txt");
}
@Test
void testRoutingService() {
assertThat(
RouterDisplayHelper.extractHumanReadableRoutesWithWrongService(
FrontendRequestComponent.class, GaeService.DEFAULT))
.isEmpty();
}
}

View File

@@ -1,38 +0,0 @@
// Copyright 2017 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.frontend;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link FrontendServlet}. */
class FrontendServletTest {
private final HttpServletRequest req = mock(HttpServletRequest.class);
private final HttpServletResponse rsp = mock(HttpServletResponse.class);
@Test
void testService_unknownPath_returnNotFound() throws Exception {
when(req.getMethod()).thenReturn("GET");
when(req.getRequestURI()).thenReturn("/lol");
new FrontendServlet().service(req, rsp);
verify(rsp).sendError(404);
}
}

View File

@@ -1,60 +0,0 @@
// Copyright 2025 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.frontend;
import dagger.Component;
import google.registry.config.CloudTasksUtilsModule;
import google.registry.config.CredentialModule;
import google.registry.config.RegistryConfig;
import google.registry.flows.ServerTridProviderModule;
import google.registry.flows.custom.CustomLogicFactoryModule;
import google.registry.flows.domain.DomainDeletionTimeCacheModule;
import google.registry.groups.GmailModule;
import google.registry.groups.GroupsModule;
import google.registry.groups.GroupssettingsModule;
import google.registry.keyring.KeyringModule;
import google.registry.keyring.api.KeyModule;
import google.registry.monitoring.whitebox.StackdriverModule;
import google.registry.privileges.secretmanager.SecretManagerModule;
import google.registry.request.Modules;
import google.registry.request.auth.AuthModule;
import google.registry.util.UtilsModule;
import jakarta.inject.Singleton;
@Singleton
@Component(
modules = {
AuthModule.class,
CloudTasksUtilsModule.class,
RegistryConfig.ConfigModule.class,
CredentialModule.class,
CustomLogicFactoryModule.class,
CloudTasksUtilsModule.class,
DomainDeletionTimeCacheModule.class,
FrontendRequestComponent.FrontendRequestComponentModule.class,
GmailModule.class,
GroupsModule.class,
GroupssettingsModule.class,
MockDirectoryModule.class,
Modules.GsonModule.class,
KeyModule.class,
KeyringModule.class,
Modules.NetHttpTransportModule.class,
SecretManagerModule.class,
ServerTridProviderModule.class,
StackdriverModule.class,
UtilsModule.class
})
interface FrontendTestComponent extends FrontendComponent {}

View File

@@ -21,9 +21,7 @@ import static google.registry.util.BuildPathUtils.getResourcesDir;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.HostAndPort;
import google.registry.module.backend.BackendServlet;
import google.registry.module.frontend.FrontendServlet;
import google.registry.module.frontend.FrontendTestServlet;
import google.registry.module.TestServlet;
import java.net.URL;
import java.nio.file.Path;
@@ -40,29 +38,28 @@ public final class RegistryTestServer {
public static final ImmutableList<Route> ROUTES =
ImmutableList.of(
route("/rdap/*", TestServlet.class),
// Frontend Services
route("/rdap/*", FrontendServlet.class),
route("/check", FrontendServlet.class),
route("/console-api/*", FrontendTestServlet.class),
route("/console-api/*", TestServlet.class),
// Proxy Services
route("/_dr/epp", FrontendServlet.class),
route("/_dr/epp", TestServlet.class),
// Registry Data Escrow (RDE)
route("/_dr/cron/rdeCreate", BackendServlet.class),
route("/_dr/task/rdeStaging", BackendServlet.class),
route("/_dr/task/rdeUpload", BackendServlet.class),
route("/_dr/task/rdeReport", BackendServlet.class),
route("/_dr/task/brdaCopy", BackendServlet.class),
route("/_dr/cron/rdeCreate", TestServlet.class),
route("/_dr/task/rdeStaging", TestServlet.class),
route("/_dr/task/rdeUpload", TestServlet.class),
route("/_dr/task/rdeReport", TestServlet.class),
route("/_dr/task/brdaCopy", TestServlet.class),
// Trademark Clearinghouse (TMCH)
route("/_dr/cron/tmchDnl", BackendServlet.class),
route("/_dr/task/tmchSmdrl", BackendServlet.class),
route("/_dr/task/tmchCrl", BackendServlet.class),
route("/_dr/cron/tmchDnl", TestServlet.class),
route("/_dr/task/tmchSmdrl", TestServlet.class),
route("/_dr/task/tmchCrl", TestServlet.class),
// Notification of Registered Domain Names (NORDN)
route("/_dr/task/nordnUpload", BackendServlet.class),
route("/_dr/task/nordnVerify", BackendServlet.class));
route("/_dr/task/nordnUpload", TestServlet.class),
route("/_dr/task/nordnVerify", TestServlet.class));
private final TestServer server;

View File

@@ -247,11 +247,6 @@ public final class TestServerExtension implements BeforeEachCallback, AfterEachC
return this;
}
/** Sets the list of servlet {@link Route} objects for {@link TestServer}. */
public Builder setRoutes(Route... routes) {
return setRoutes(ImmutableList.copyOf(routes));
}
/** Sets an ordered list of fixtures that should be loaded on startup. */
public Builder setFixtures(Fixture... fixtures) {
this.fixtures = ImmutableList.copyOf(fixtures);

View File

@@ -1,39 +0,0 @@
SERVICE PATH CLASS METHODS OK MIN USER_POLICY
BACKEND /_dr/cron/fanout TldFanoutAction GET y APP ADMIN
BACKEND /_dr/task/brdaCopy BrdaCopyAction POST y APP ADMIN
BACKEND /_dr/task/copyDetailReports CopyDetailReportsAction POST n APP ADMIN
BACKEND /_dr/task/deleteExpiredDomains DeleteExpiredDomainsAction GET n APP ADMIN
BACKEND /_dr/task/deleteLoadTestData DeleteLoadTestDataAction POST n APP ADMIN
BACKEND /_dr/task/deleteProberData DeleteProberDataAction POST n APP ADMIN
BACKEND /_dr/task/dnsRefresh RefreshDnsAction GET y APP ADMIN
BACKEND /_dr/task/executeCannedScript CannedScriptExecutionAction POST,GET y APP ADMIN
BACKEND /_dr/task/expandBillingRecurrences ExpandBillingRecurrencesAction GET n APP ADMIN
BACKEND /_dr/task/exportDomainLists ExportDomainListsAction POST n APP ADMIN
BACKEND /_dr/task/exportPremiumTerms ExportPremiumTermsAction POST n APP ADMIN
BACKEND /_dr/task/exportReservedTerms ExportReservedTermsAction POST n APP ADMIN
BACKEND /_dr/task/generateInvoices GenerateInvoicesAction POST n APP ADMIN
BACKEND /_dr/task/generateSpec11 GenerateSpec11ReportAction POST n APP ADMIN
BACKEND /_dr/task/icannReportingStaging IcannReportingStagingAction POST n APP ADMIN
BACKEND /_dr/task/icannReportingUpload IcannReportingUploadAction POST n APP ADMIN
BACKEND /_dr/task/nordnUpload NordnUploadAction POST y APP ADMIN
BACKEND /_dr/task/nordnVerify NordnVerifyAction POST y APP ADMIN
BACKEND /_dr/task/publishDnsUpdates PublishDnsUpdatesAction POST y APP ADMIN
BACKEND /_dr/task/publishInvoices PublishInvoicesAction POST n APP ADMIN
BACKEND /_dr/task/publishSpec11 PublishSpec11ReportAction POST n APP ADMIN
BACKEND /_dr/task/rdeReport RdeReportAction POST n APP ADMIN
BACKEND /_dr/task/rdeStaging RdeStagingAction GET,POST n APP ADMIN
BACKEND /_dr/task/rdeUpload RdeUploadAction POST n APP ADMIN
BACKEND /_dr/task/readDnsRefreshRequests ReadDnsRefreshRequestsAction POST y APP ADMIN
BACKEND /_dr/task/refreshDnsOnHostRename RefreshDnsOnHostRenameAction POST n APP ADMIN
BACKEND /_dr/task/relockDomain RelockDomainAction POST y APP ADMIN
BACKEND /_dr/task/removeAllDomainContacts RemoveAllDomainContactsAction POST n APP ADMIN
BACKEND /_dr/task/resaveAllEppResourcesPipeline ResaveAllEppResourcesPipelineAction GET n APP ADMIN
BACKEND /_dr/task/resaveEntity ResaveEntityAction POST n APP ADMIN
BACKEND /_dr/task/sendExpiringCertificateNotificationEmail SendExpiringCertificateNotificationEmailAction GET n APP ADMIN
BACKEND /_dr/task/syncGroupMembers SyncGroupMembersAction POST n APP ADMIN
BACKEND /_dr/task/syncRegistrarsSheet SyncRegistrarsSheetAction POST n APP ADMIN
BACKEND /_dr/task/tmchCrl TmchCrlAction POST y APP ADMIN
BACKEND /_dr/task/tmchDnl TmchDnlAction POST y APP ADMIN
BACKEND /_dr/task/tmchSmdrl TmchSmdrlAction POST y APP ADMIN
BACKEND /_dr/task/updateRegistrarRdapBaseUrls UpdateRegistrarRdapBaseUrlsAction GET y APP ADMIN
BACKEND /_dr/task/wipeOutContactHistoryPii WipeOutContactHistoryPiiAction GET n APP ADMIN

View File

@@ -1,21 +0,0 @@
SERVICE PATH CLASS METHODS OK MIN USER_POLICY
FRONTEND /_dr/epp EppTlsAction POST n APP ADMIN
FRONTEND /ready/frontend ReadinessProbeActionFrontend GET n NONE PUBLIC
CONSOLE /console-api/bulk-domain ConsoleBulkDomainAction POST n USER PUBLIC
CONSOLE /console-api/domain ConsoleDomainGetAction GET n USER PUBLIC
CONSOLE /console-api/domain-list ConsoleDomainListAction GET n USER PUBLIC
CONSOLE /console-api/dum-download ConsoleDumDownloadAction GET n USER PUBLIC
CONSOLE /console-api/eppPassword ConsoleEppPasswordAction POST n USER PUBLIC
CONSOLE /console-api/ote ConsoleOteAction GET,POST n USER PUBLIC
CONSOLE /console-api/password-reset-request PasswordResetRequestAction POST n USER PUBLIC
CONSOLE /console-api/password-reset-verify PasswordResetVerifyAction GET,POST n USER PUBLIC
CONSOLE /console-api/registrar ConsoleUpdateRegistrarAction POST n USER PUBLIC
CONSOLE /console-api/registrars RegistrarsAction GET,POST n USER PUBLIC
CONSOLE /console-api/registry-lock ConsoleRegistryLockAction GET,POST n USER PUBLIC
CONSOLE /console-api/registry-lock-verify ConsoleRegistryLockVerifyAction GET n USER PUBLIC
CONSOLE /console-api/settings/contacts ContactAction GET,POST,DELETE,PUT n USER PUBLIC
CONSOLE /console-api/settings/rdap-fields RdapRegistrarFieldsAction POST n USER PUBLIC
CONSOLE /console-api/settings/security SecurityAction POST n USER PUBLIC
CONSOLE /console-api/userdata ConsoleUserDataAction GET n USER PUBLIC
CONSOLE /console-api/users ConsoleUsersAction GET,POST,DELETE,PUT n USER PUBLIC
CONSOLE /ready/console ReadinessProbeConsoleAction GET n NONE PUBLIC