Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions core/src/main/java/google/registry/config/RegistryConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import google.registry.bsa.UploadBsaUnavailableDomainsAction;
import google.registry.dns.ReadDnsRefreshRequestsAction;
import google.registry.model.common.DnsRefreshRequest;
import google.registry.mosapi.client.MosApiClient;
import google.registry.persistence.transaction.JpaTransactionManager;
import google.registry.request.Action.Service;
import google.registry.util.RegistryEnvironment;
Expand All @@ -49,6 +50,7 @@
import java.lang.annotation.Retention;
import java.net.URI;
import java.net.URL;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Supplier;
Expand Down Expand Up @@ -1415,6 +1417,40 @@ public static String provideBsaUploadUnavailableDomainsUrl(RegistryConfigSetting
return config.bsa.uploadUnavailableDomainsUrl;
}

/**
* Returns the URL we send HTTP requests for MoSAPI.
*
* @see MosApiClient
*/
@Provides
@Config("mosapiUrl")
public static String provideMosapiUrl(RegistryConfigSettings config) {
return config.mosapi.mosapiUrl;
}

/**
* Returns the entityType we send HTTP requests for MoSAPI.
*
* @see MosApiClient
*/
@Provides
@Config("entityType")
public static String provideMosapiEntityType(RegistryConfigSettings config) {
return config.mosapi.entityType;
}

@Provides
@Config("mosapiTlds")
public static List<String> provideMosapiTlds(RegistryConfigSettings config) {
return ImmutableList.copyOf(config.mosapi.tlds);
}

@Provides
@Config("mosapiServices")
public static List<String> provideMosapiServices(RegistryConfigSettings config) {
return ImmutableList.copyOf(config.mosapi.services);
}

private static String formatComments(String text) {
return Splitter.on('\n').omitEmptyStrings().trimResults().splitToList(text).stream()
.map(s -> "# " + s)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class RegistryConfigSettings {
public DnsUpdate dnsUpdate;
public BulkPricingPackageMonitoring bulkPricingPackageMonitoring;
public Bsa bsa;
public MosApi mosapi;

/** Configuration options that apply to the entire GCP project. */
public static class GcpProject {
Expand Down Expand Up @@ -267,4 +268,12 @@ public static class Bsa {
public String unblockableDomainsUrl;
public String uploadUnavailableDomainsUrl;
}

/** Configuration for Mosapi. */
public static class MosApi {
public String mosapiUrl;
public String entityType;
public List<String> tlds;
public List<String> services;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,20 @@ bsa:
unblockableDomainsUrl: "https://"
# API endpoint for uploading the list of unavailable domain names.
uploadUnavailableDomainsUrl: "https://"

mosapi:
# URL for the MosAPI
mosapiUrl: https://mosapi.icann.org
entityType: ry
# List of TLDs to be monitored.
tlds:
- "test"
# List of services to check for each TLD.
services:
- "dns"
- "rdap"
- "rdds"
- "epp"
- "dnssec"


Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import google.registry.module.RegistryComponent.RegistryModule;
import google.registry.module.RequestComponent.RequestComponentModule;
import google.registry.monitoring.whitebox.StackdriverModule;
import google.registry.mosapi.module.MosApiModule;
import google.registry.persistence.PersistenceModule;
import google.registry.privileges.secretmanager.SecretManagerModule;
import google.registry.rde.JSchModule;
Expand All @@ -49,6 +50,7 @@
import google.registry.request.RequestHandler;
import google.registry.request.auth.AuthModule;
import google.registry.request.auth.RequestAuthenticator;
import google.registry.util.HttpModule;
import google.registry.util.UtilsModule;
import jakarta.inject.Provider;
import jakarta.inject.Singleton;
Expand All @@ -71,6 +73,8 @@
GroupsModule.class,
GroupssettingsModule.class,
GsonModule.class,
HttpModule.class,
MosApiModule.class,
JSchModule.class,
KeyModule.class,
KeyringModule.class,
Expand Down
18 changes: 18 additions & 0 deletions core/src/main/java/google/registry/module/RequestComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
import google.registry.module.ReadinessProbeAction.ReadinessProbeActionPubApi;
import google.registry.module.ReadinessProbeAction.ReadinessProbeConsoleAction;
import google.registry.monitoring.whitebox.WhiteboxModule;
import google.registry.mosapi.action.GetAlarmsStateAction;
import google.registry.mosapi.action.GetMetricaReportAction;
import google.registry.mosapi.action.GetServiceDowntimeAction;
import google.registry.mosapi.action.GetServiceStateAction;
import google.registry.mosapi.action.ListMetricaReportsAction;
import google.registry.mosapi.module.MosApiRequestModule;
import google.registry.rdap.RdapAutnumAction;
import google.registry.rdap.RdapDomainAction;
import google.registry.rdap.RdapDomainSearchAction;
Expand Down Expand Up @@ -150,6 +156,7 @@
EppToolModule.class,
IcannReportingModule.class,
LoadTestModule.class,
MosApiRequestModule.class,
RdapModule.class,
RdeModule.class,
ReportingModule.class,
Expand Down Expand Up @@ -229,6 +236,14 @@ interface RequestComponent {

GenerateZoneFilesAction generateZoneFilesAction();

GetAlarmsStateAction checkMosApiAlarmsAction();

GetMetricaReportAction getMetricaReportAction();

GetServiceDowntimeAction getServiceDowntimeAction();

GetServiceStateAction getServiceStateAction();

IcannReportingStagingAction icannReportingStagingAction();

IcannReportingUploadAction icannReportingUploadAction();
Expand All @@ -237,6 +252,8 @@ interface RequestComponent {

ListHostsAction listHostsAction();

ListMetricaReportsAction listMetricaReportsAction();

ListPremiumListsAction listPremiumListsAction();

ListRegistrarsAction listRegistrarsAction();
Expand Down Expand Up @@ -341,6 +358,7 @@ interface RequestComponent {

WipeOutContactHistoryPiiAction wipeOutContactHistoryPiiAction();


@Subcomponent.Builder
abstract class Builder implements RequestComponentBuilder<RequestComponent> {
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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.mosapi.action;

import static google.registry.request.Action.Method.GET;

import com.google.common.net.MediaType;
import com.google.gson.Gson;
import google.registry.mosapi.services.MosApiAlarmService;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import jakarta.inject.Inject;

/** An action that checks the alarm status for all configured MoSAPI entities. */
@Action(
service = Action.Service.BACKEND,
path = GetAlarmsStateAction.PATH,
method = GET,
auth = Auth.AUTH_ADMIN)
public class GetAlarmsStateAction implements Runnable {
public static final String PATH = "/_dr/mosapi/checkalarm";

private final MosApiAlarmService alarmsService;
private final Response response;
private final Gson gson;

@Inject
public GetAlarmsStateAction(MosApiAlarmService alarmsService, Response response, Gson gson) {
this.alarmsService = alarmsService;
this.response = response;
this.gson = gson;
}

@Override
public void run() {
response.setContentType(MediaType.JSON_UTF_8);
response.setPayload(gson.toJson(alarmsService.checkAllAlarms()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// 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.mosapi.action;

import com.google.common.flogger.FluentLogger;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import google.registry.mosapi.exception.MosApiException;
import google.registry.mosapi.services.MosApiMetricaService;
import google.registry.request.Action;
import google.registry.request.HttpException.ServiceUnavailableException;
import google.registry.request.Parameter;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import jakarta.inject.Inject;
import java.time.LocalDate;
import java.util.Optional;

@Action(
service = Action.Service.BACKEND,
path = GetMetricaReportAction.PATH,
method = Action.Method.GET,
auth = Auth.AUTH_ADMIN)
public class GetMetricaReportAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();

public static final String PATH = "/_dr/mosapi/getMetricaReport";
public static final String TLD_PARAM = "tld";
public static final String DATE_PARAM = "date";

private final MosApiMetricaService metricaService;
private final Response response;
private final Gson gson;
private final String tld;
private final Optional<LocalDate> date;

@Inject
public GetMetricaReportAction(
MosApiMetricaService metricaService,
Response response,
Gson gson,
@Parameter(TLD_PARAM) String tld,
@Parameter(DATE_PARAM) Optional<LocalDate> date) {
this.metricaService = metricaService;
this.response = response;
this.gson = gson;
this.tld = tld;
this.date = date;
}

@Override
public void run() {
try {
response.setContentType(MediaType.JSON_UTF_8);
response.setPayload(gson.toJson(metricaService.getReport(tld, date)));
} catch (MosApiException e) {
logger.atWarning().withCause(e).log(
"MoSAPI client failed to get response for Metrica report for TLD: %s", tld);
throw new ServiceUnavailableException("Error fetching METRICA report.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// 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.mosapi.action;

import com.google.common.net.MediaType;
import com.google.gson.Gson;
import google.registry.mosapi.services.MosApiDowntimeService;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import jakarta.inject.Inject;
import java.util.Optional;

/** An action that returns the MoSAPI downtime for a given TLD and service. */
@Action(
service = Action.Service.BACKEND,
path = GetServiceDowntimeAction.PATH,
method = Action.Method.GET,
auth = Auth.AUTH_ADMIN)
public class GetServiceDowntimeAction implements Runnable {

public static final String PATH = "/_dr/mosapi/getServiceDowntime";
public static final String TLD_PARAM = "tld";

private final MosApiDowntimeService downtimeService;
private final Response response;
private final Gson gson;
private final Optional<String> tld;

@Inject
public GetServiceDowntimeAction(
MosApiDowntimeService downtimeService,
Response response,
Gson gson,
@Parameter(TLD_PARAM) Optional<String> tld) {
this.downtimeService = downtimeService;
this.response = response;
this.gson = gson;
this.tld = tld;
}

@Override
public void run() {
response.setContentType(MediaType.JSON_UTF_8);
if (tld.isPresent()) {
// Handle the case for a single TLD.
response.setPayload(gson.toJson(downtimeService.getDowntimeForTld(tld.get())));
} else {
// Handle the case for all TLDs.
response.setPayload(gson.toJson(downtimeService.getDowntimeForAllTlds()));
}
}
}
Loading
Loading