Skip to content

Commit ab60ac4

Browse files
gbrodmanjianglai
andauthored
Migrate DNS query table (#2543)
Co-authored-by: Lai Jiang <jianglai@google.com>
1 parent d9ad39c commit ab60ac4

30 files changed

Lines changed: 264 additions & 96 deletions

core/src/main/java/google/registry/config/files/default-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ registryPolicy:
8484

8585
# Custom logic class for handling DNS query count reporting for ICANN.
8686
# See reporting/icann/DnsCountQueryCoordinator.java
87-
dnsCountQueryCoordinatorClass: google.registry.reporting.icann.BasicDnsCountQueryCoordinator
87+
dnsCountQueryCoordinatorClass: google.registry.reporting.icann.DummyDnsCountQueryCoordinator
8888

8989
# Length of time after which contact transfers automatically conclude.
9090
contactAutomaticTransferDays: 5

core/src/main/java/google/registry/module/RequestComponent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
import google.registry.reporting.billing.CopyDetailReportsAction;
8282
import google.registry.reporting.billing.GenerateInvoicesAction;
8383
import google.registry.reporting.billing.PublishInvoicesAction;
84-
import google.registry.reporting.icann.DnsCountQueryCoordinatorModule;
84+
import google.registry.reporting.icann.DnsCountQueryCoordinator.DnsCountQueryCoordinatorModule;
8585
import google.registry.reporting.icann.IcannReportingModule;
8686
import google.registry.reporting.icann.IcannReportingStagingAction;
8787
import google.registry.reporting.icann.IcannReportingUploadAction;

core/src/main/java/google/registry/module/backend/BackendRequestComponent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
import google.registry.reporting.billing.CopyDetailReportsAction;
6060
import google.registry.reporting.billing.GenerateInvoicesAction;
6161
import google.registry.reporting.billing.PublishInvoicesAction;
62-
import google.registry.reporting.icann.DnsCountQueryCoordinatorModule;
62+
import google.registry.reporting.icann.DnsCountQueryCoordinator.DnsCountQueryCoordinatorModule;
6363
import google.registry.reporting.icann.IcannReportingModule;
6464
import google.registry.reporting.icann.IcannReportingStagingAction;
6565
import google.registry.reporting.icann.IcannReportingUploadAction;

core/src/main/java/google/registry/reporting/icann/ActivityReportingQueryBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public ImmutableMap<String, String> getViewQueryMap(YearMonth yearMonth) {
7777
queriesBuilder.put(
7878
getTableName(REGISTRAR_OPERATING_STATUS, yearMonth), operationalRegistrarsQuery);
7979

80-
String dnsCountsQuery = dnsCountQueryCoordinator.createQuery(yearMonth);
80+
String dnsCountsQuery = dnsCountQueryCoordinator.createQuery();
8181
queriesBuilder.put(getTableName(DNS_COUNTS, yearMonth), dnsCountsQuery);
8282

8383
// Convert reportingMonth into YYYYMMDD format for Bigquery table partition pattern-matching.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package google.registry.reporting.icann;
15+
16+
import com.google.common.flogger.FluentLogger;
17+
import com.google.common.io.Resources;
18+
import google.registry.bigquery.BigqueryUtils.TableType;
19+
import google.registry.util.ResourceUtils;
20+
import google.registry.util.SqlTemplate;
21+
import java.util.concurrent.ExecutionException;
22+
import org.joda.time.YearMonth;
23+
import org.joda.time.format.DateTimeFormat;
24+
25+
/**
26+
* DNS Count query that relies on a table Cloud DNS publishes internally to Google.
27+
*
28+
* <p>The internal Plx table is exposed as a BigQuery table via BQ-TS federation. This is not
29+
* applicable to external users who also happen to use Cloud DNS as the plx table is specific to
30+
* Google Registry's zones. External (non-Google) users must re-implement the abstract class and
31+
* configure the usage of the new class using the `registryPolicy.dnsCountQueryCoordinatorClass`
32+
* field in the config file.
33+
*/
34+
public class CloudDnsCountQueryCoordinator extends DnsCountQueryCoordinator {
35+
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
36+
private static final String PLX_DNS_TABLE_NAME = "dns_counts_from_plx";
37+
private static final String TABLE_ID = "zoneman_daily_query_counts";
38+
39+
@Override
40+
public String createQuery() {
41+
String template =
42+
ResourceUtils.readResourceUtf8(
43+
Resources.getResource(this.getClass(), "sql/dns_counts_cloud.sql"));
44+
return SqlTemplate.create(template)
45+
.put("PROJECT_ID", projectId)
46+
.put("ICANN_REPORTING_DATA_SET", icannReportingDataSet)
47+
.put("DNS_TABLE_NAME", PLX_DNS_TABLE_NAME)
48+
.build();
49+
}
50+
51+
@Override
52+
public void prepareForQuery(YearMonth yearMonth) throws InterruptedException {
53+
logger.atInfo().log("Generating intermediary table dns_counts");
54+
String query = getPlxDnsTableQuery(yearMonth);
55+
try {
56+
bigquery
57+
.startQuery(
58+
query,
59+
bigquery
60+
.buildDestinationTable(PLX_DNS_TABLE_NAME)
61+
.description("A table holding DNS query counts to generate ACTIVITY reports.")
62+
.type(TableType.TABLE)
63+
.build())
64+
.get();
65+
} catch (ExecutionException e) {
66+
throw new RuntimeException("Error while running BigQuery query", e.getCause());
67+
}
68+
}
69+
70+
String getPlxDnsTableQuery(YearMonth yearMonth) {
71+
String template =
72+
ResourceUtils.readResourceUtf8(
73+
Resources.getResource(this.getClass(), "sql/prepare_dns_counts_internal.sql"));
74+
SqlTemplate queryTemplate =
75+
SqlTemplate.create(template)
76+
.put("PROJECT_ID", projectId)
77+
.put("DATASET_ID", icannReportingDataSet)
78+
.put("TABLE_ID", TABLE_ID)
79+
.put("YEAR_MONTH", DateTimeFormat.forPattern("yyyyMM").print(yearMonth));
80+
return queryTemplate.build();
81+
}
82+
}

core/src/main/java/google/registry/reporting/icann/DnsCountQueryCoordinator.java

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,45 +14,43 @@
1414

1515
package google.registry.reporting.icann;
1616

17+
import static google.registry.reporting.icann.IcannReportingModule.ICANN_REPORTING_DATA_SET;
18+
import static google.registry.util.TypeUtils.getClassFromString;
19+
import static google.registry.util.TypeUtils.instantiate;
20+
21+
import dagger.MembersInjector;
22+
import dagger.Module;
23+
import dagger.Provides;
1724
import google.registry.bigquery.BigqueryConnection;
25+
import google.registry.config.RegistryConfig.Config;
26+
import javax.inject.Inject;
27+
import javax.inject.Named;
1828
import org.joda.time.YearMonth;
1929

2030
/**
2131
* Methods for preparing and querying DNS statistics.
2232
*
2333
* <p>DNS systems may have different ways of providing this information, so it's useful to
24-
* modularize this.
34+
* modularize this, by providing defining the `registryPolicy.dnsCountQueryCoordinatorClass` in your
35+
* config file.
2536
*
26-
* <p>Derived classes must provide a constructor that accepts a
27-
* {@link google.registry.reporting.icann.DnsCountQueryCoordinator.Params}. To override this,
28-
* define dnsCountQueryCoordinatorClass in your config file.
37+
* <p>Due to limitations of {@link MembersInjector}, any injectable field needs to be declared in
38+
* the base class, even if it is only used in a derived class.
2939
*/
30-
public interface DnsCountQueryCoordinator {
31-
32-
/**
33-
* Class to carry parameters for a new coordinator.
34-
*
35-
* <p>If your report query requires any additional parameters, add them here.
36-
*/
37-
class Params {
40+
public abstract class DnsCountQueryCoordinator {
3841

39-
public BigqueryConnection bigquery;
42+
@Inject BigqueryConnection bigquery;
4043

41-
/** The Google Cloud project id. */
42-
public String projectId;
44+
@Inject
45+
@Config("projectId")
46+
String projectId;
4347

44-
/** The BigQuery dataset from which to query. */
45-
public String icannReportingDataSet;
46-
47-
public Params(BigqueryConnection bigquery, String projectId, String icannReportingDataSet) {
48-
this.bigquery = bigquery;
49-
this.projectId = projectId;
50-
this.icannReportingDataSet = icannReportingDataSet;
51-
}
52-
}
48+
@Inject
49+
@Named(ICANN_REPORTING_DATA_SET)
50+
String icannReportingDataSet;
5351

5452
/** Creates the string used to query bigtable for DNS count information. */
55-
String createQuery(YearMonth yearMonth);
53+
abstract String createQuery();
5654

5755
/**
5856
* Do any necessary preparation for the DNS query.
@@ -61,5 +59,18 @@ public Params(BigqueryConnection bigquery, String projectId, String icannReporti
6159
* interruptible futures to prepare the query (and the correct thing to do with such exceptions is
6260
* to handle them correctly or propagate them as-is, no {@link RuntimeException} wrapping).
6361
*/
64-
void prepareForQuery(YearMonth yearMonth) throws InterruptedException;
62+
abstract void prepareForQuery(YearMonth yearMonth) throws InterruptedException;
63+
64+
@Module
65+
public static class DnsCountQueryCoordinatorModule {
66+
@Provides
67+
static DnsCountQueryCoordinator provideDnsCountQueryCoordinator(
68+
MembersInjector<DnsCountQueryCoordinator> injector,
69+
@Config("dnsCountQueryCoordinatorClass") String customClass) {
70+
DnsCountQueryCoordinator coordinator =
71+
instantiate(getClassFromString(customClass, DnsCountQueryCoordinator.class));
72+
injector.injectMembers(coordinator);
73+
return coordinator;
74+
}
75+
}
6576
}

core/src/main/java/google/registry/reporting/icann/DnsCountQueryCoordinatorModule.java

Lines changed: 0 additions & 41 deletions
This file was deleted.

core/src/main/java/google/registry/reporting/icann/BasicDnsCountQueryCoordinator.java renamed to core/src/main/java/google/registry/reporting/icann/DummyDnsCountQueryCoordinator.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,13 @@
1818
import google.registry.util.SqlTemplate;
1919
import org.joda.time.YearMonth;
2020

21-
/**
22-
* DNS Count query for the basic case.
23-
*/
24-
public class BasicDnsCountQueryCoordinator implements DnsCountQueryCoordinator {
25-
26-
BasicDnsCountQueryCoordinator(DnsCountQueryCoordinator.Params params) {}
21+
/** DNS Count query where returned values are all -1. */
22+
public class DummyDnsCountQueryCoordinator extends DnsCountQueryCoordinator {
2723

2824
@Override
29-
public String createQuery(YearMonth yearMonth) {
30-
return SqlTemplate.create(ResourceUtils.readResourceUtf8(this.getClass(), "sql/dns_counts.sql"))
25+
public String createQuery() {
26+
return SqlTemplate.create(
27+
ResourceUtils.readResourceUtf8(this.getClass(), "sql/dns_counts_dummy.sql"))
3128
.build();
3229
}
3330

core/src/test/resources/google/registry/reporting/icann/dns_counts_internal_test.sql renamed to core/src/main/resources/google/registry/reporting/icann/sql/dns_counts_cloud.sql

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,5 @@
1515

1616
-- Retrieve per-TLD DNS query counts.
1717

18-
-- This is a hack to enable using DNS counts from the internal-only #plx
19-
-- workflow. See other references to b/67301320 in the codebase to see the
20-
-- full extent of the hackery.
21-
-- TODO(b/67301320): Delete this when we can make open-source DNS metrics.
22-
2318
SELECT *
24-
FROM `domain-registry-alpha.icann_reporting.dns_counts_from_plx`
19+
FROM `%PROJECT_ID%.%ICANN_REPORTING_DATA_SET%.%DNS_TABLE_NAME%`

core/src/main/resources/google/registry/reporting/icann/sql/dns_counts.sql renamed to core/src/main/resources/google/registry/reporting/icann/sql/dns_counts_dummy.sql

File renamed without changes.

0 commit comments

Comments
 (0)