Remove IDN elements from BRDA (#670)

Also added unit tests for RdeStagingReducer.
This commit is contained in:
Lai Jiang 2020-07-21 15:29:32 -04:00 committed by GitHub
parent c812807ab3
commit 4e0ca19d2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 348 additions and 6 deletions

View file

@ -48,6 +48,10 @@ public final class RdeRevision extends ImmutableObject {
*/
int revision;
public int getRevision() {
return revision;
}
/**
* Returns next revision ID to use when staging a new deposit file for the given triplet.
*

View file

@ -29,7 +29,7 @@ public enum RdeResourceType {
DOMAIN("urn:ietf:params:xml:ns:rdeDomain-1.0", EnumSet.of(FULL, THIN)),
HOST("urn:ietf:params:xml:ns:rdeHost-1.0", EnumSet.of(FULL)),
REGISTRAR("urn:ietf:params:xml:ns:rdeRegistrar-1.0", EnumSet.of(FULL, THIN)),
IDN("urn:ietf:params:xml:ns:rdeIDN-1.0", EnumSet.of(FULL, THIN)),
IDN("urn:ietf:params:xml:ns:rdeIDN-1.0", EnumSet.of(FULL)),
HEADER("urn:ietf:params:xml:ns:rdeHeader-1.0", EnumSet.of(FULL, THIN));
private final String uri;

View file

@ -77,7 +77,7 @@ public final class RdeStagingReducer extends Reducer<PendingDeposit, DepositFrag
private final byte[] stagingKeyBytes;
private final RdeMarshaller marshaller;
private RdeStagingReducer(
RdeStagingReducer(
TaskQueueUtils taskQueueUtils,
LockHandler lockHandler,
int gcsBufferSize,
@ -125,7 +125,7 @@ public final class RdeStagingReducer extends Reducer<PendingDeposit, DepositFrag
final DateTime watermark = key.watermark();
final int revision =
Optional.ofNullable(key.revision())
.orElse(RdeRevision.getNextRevision(tld, watermark, mode));
.orElseGet(() -> RdeRevision.getNextRevision(tld, watermark, mode));
String id = RdeUtil.timestampToId(watermark);
String prefix = RdeNamingUtils.makeRydeFilename(tld, watermark, mode, 1, revision);
if (key.manual()) {
@ -168,9 +168,13 @@ public final class RdeStagingReducer extends Reducer<PendingDeposit, DepositFrag
logger.atSevere().log("Fragment error: %s", fragment.error());
}
}
for (IdnTableEnum idn : IdnTableEnum.values()) {
output.write(marshaller.marshalIdn(idn.getTable()));
counter.increment(RdeResourceType.IDN);
// Don't write the IDN elements for BRDA.
if (mode == RdeMode.FULL) {
for (IdnTableEnum idn : IdnTableEnum.values()) {
output.write(marshaller.marshalIdn(idn.getTable()));
counter.increment(RdeResourceType.IDN);
}
}
// Output XML that says how many resources were emitted.

View file

@ -0,0 +1,255 @@
// Copyright 2020 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.rde;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.rde.RdeMode.FULL;
import static google.registry.model.rde.RdeMode.THIN;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.GcsTestingUtils.readGcsFile;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.google.appengine.tools.cloudstorage.GcsService;
import com.google.appengine.tools.cloudstorage.GcsServiceFactory;
import com.google.appengine.tools.mapreduce.ReducerInput;
import com.google.common.collect.ImmutableList;
import google.registry.keyring.api.PgpHelper;
import google.registry.model.common.Cursor;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.rde.RdeMode;
import google.registry.model.rde.RdeRevision;
import google.registry.model.registry.Registry;
import google.registry.request.RequestParameters;
import google.registry.schema.cursor.CursorDao;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeKeyringModule;
import google.registry.testing.FakeLockHandler;
import google.registry.testing.FakeSleeper;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.util.Retrier;
import google.registry.util.TaskQueueUtils;
import google.registry.xml.ValidationMode;
import java.io.IOException;
import java.util.Iterator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link RdeStagingReducer}. */
public class RdeStagingReducerTest {
@RegisterExtension
AppEngineRule appEngineRule =
AppEngineRule.builder().withDatastoreAndCloudSql().withTaskQueue().build();
private static final String GCS_BUCKET = "test-rde-bucket";
private static final GcsService gcsService = GcsServiceFactory.createGcsService();
private static final PGPPrivateKey decryptionKey =
new FakeKeyringModule().get().getRdeStagingDecryptionKey();
private static final PGPPublicKey encryptionKey =
new FakeKeyringModule().get().getRdeStagingEncryptionKey();
private static final DateTime now = DateTime.parse("2000-01-01TZ");
private Fragments brdaFragments =
new Fragments(
ImmutableList.of(
DepositFragment.create(RdeResourceType.DOMAIN, "<rdeDomain:domain/>\n", ""),
DepositFragment.create(
RdeResourceType.REGISTRAR, "<rdeRegistrar:registrar/>\n", "")));
private Fragments rdeFragments =
new Fragments(
ImmutableList.of(
DepositFragment.create(RdeResourceType.DOMAIN, "<rdeDomain:domain/>\n", ""),
DepositFragment.create(RdeResourceType.REGISTRAR, "<rdeRegistrar:registrar/>\n", ""),
DepositFragment.create(RdeResourceType.CONTACT, "<rdeContact:contact/>\n", ""),
DepositFragment.create(RdeResourceType.HOST, "<rdeHost:host/>\n", "")));
private PendingDeposit key;
private RdeStagingReducer reducer =
new RdeStagingReducer(
new TaskQueueUtils(new Retrier(new FakeSleeper(new FakeClock()), 1)),
new FakeLockHandler(true),
1024,
GCS_BUCKET,
Duration.ZERO,
PgpHelper.convertPublicKeyToBytes(encryptionKey),
ValidationMode.STRICT);
@BeforeEach
public void setUp() {
createTld("soy");
CursorDao.saveCursor(Cursor.create(CursorType.BRDA, now, Registry.get("soy")), "soy");
CursorDao.saveCursor(Cursor.create(CursorType.RDE_STAGING, now, Registry.get("soy")), "soy");
tm().transact(
() -> {
RdeRevision.saveRevision("soy", now, THIN, 0);
RdeRevision.saveRevision("soy", now, FULL, 0);
});
}
@Test
public void testSuccess_BRDA() throws Exception {
key = PendingDeposit.create("soy", now, THIN, CursorType.BRDA, Duration.standardDays(1));
reducer.reduce(key, brdaFragments);
String outputFile = decryptGhostrydeGcsFile("soy_2000-01-01_thin_S1_R1.xml.ghostryde");
assertThat(outputFile)
.isEqualTo(
readResourceUtf8(RdeStagingReducerTest.class, "reducer_brda.xml")
.replace("%RESEND%", " resend=\"1\""));
compareLength(outputFile, "soy_2000-01-01_thin_S1_R1.xml.length");
// BRDA doesn't write a report file.
assertThrows(
IOException.class,
() ->
readGcsFile(
gcsService,
new GcsFilename(GCS_BUCKET, "soy_2000-01-01_thin_S1_R1-report.xml.ghostryde")));
assertThat(loadCursorTime(CursorType.BRDA))
.isEquivalentAccordingToCompareTo(now.plus(Duration.standardDays(1)));
assertThat(loadRevision(THIN)).isEqualTo(1);
assertTasksEnqueued(
"brda",
new TaskMatcher()
.url(BrdaCopyAction.PATH)
.param(RequestParameters.PARAM_TLD, "soy")
.param(RdeModule.PARAM_WATERMARK, now.toString()));
}
@Test
public void testSuccess_BRDA_manual() throws Exception {
key = PendingDeposit.createInManualOperation("soy", now, THIN, "", 0);
reducer.reduce(key, brdaFragments);
String outputFile = decryptGhostrydeGcsFile("manual/soy_2000-01-01_thin_S1_R0.xml.ghostryde");
assertThat(outputFile)
.isEqualTo(
readResourceUtf8(RdeStagingReducerTest.class, "reducer_brda.xml")
.replace("%RESEND%", ""));
compareLength(outputFile, "manual/soy_2000-01-01_thin_S1_R0.xml.length");
// BRDA doesn't write a report file.
assertThrows(
IOException.class,
() ->
readGcsFile(
gcsService,
new GcsFilename(
GCS_BUCKET, "manual/soy_2000-01-01_thin_S1_R0-report.xml.ghostryde")));
// No extra operations in manual mode.
assertThat(loadCursorTime(CursorType.BRDA)).isEquivalentAccordingToCompareTo(now);
assertThat(loadRevision(THIN)).isEqualTo(0);
assertNoTasksEnqueued("brda");
}
@Test
public void testSuccess_RDE() throws Exception {
key = PendingDeposit.create("soy", now, FULL, CursorType.RDE_STAGING, Duration.standardDays(1));
reducer.reduce(key, rdeFragments);
String outputFile = decryptGhostrydeGcsFile("soy_2000-01-01_full_S1_R1.xml.ghostryde");
assertThat(outputFile)
.isEqualTo(
readResourceUtf8(RdeStagingReducerTest.class, "reducer_rde.xml")
.replace("%RESEND%", " resend=\"1\""));
compareLength(outputFile, "soy_2000-01-01_full_S1_R1.xml.length");
assertThat(decryptGhostrydeGcsFile("soy_2000-01-01_full_S1_R1-report.xml.ghostryde"))
.isEqualTo(
readResourceUtf8(RdeStagingReducerTest.class, "reducer_rde_report.xml")
.replace("%RESEND%", "1"));
assertThat(loadCursorTime(CursorType.RDE_STAGING))
.isEquivalentAccordingToCompareTo(now.plus(Duration.standardDays(1)));
assertThat(loadRevision(FULL)).isEqualTo(1);
assertTasksEnqueued(
"rde-upload",
new TaskMatcher().url(RdeUploadAction.PATH).param(RequestParameters.PARAM_TLD, "soy"));
}
@Test
public void testSuccess_RDE_manual() throws Exception {
key = PendingDeposit.createInManualOperation("soy", now, FULL, "", 0);
reducer.reduce(key, rdeFragments);
String outputFile = decryptGhostrydeGcsFile("manual/soy_2000-01-01_full_S1_R0.xml.ghostryde");
assertThat(outputFile)
.isEqualTo(
readResourceUtf8(RdeStagingReducerTest.class, "reducer_rde.xml")
.replace("%RESEND%", ""));
compareLength(outputFile, "manual/soy_2000-01-01_full_S1_R0.xml.length");
assertThat(decryptGhostrydeGcsFile("manual/soy_2000-01-01_full_S1_R0-report.xml.ghostryde"))
.isEqualTo(
readResourceUtf8(RdeStagingReducerTest.class, "reducer_rde_report.xml")
.replace("%RESEND%", "0"));
// No extra operations in manual mode.
assertThat(loadCursorTime(CursorType.RDE_STAGING)).isEquivalentAccordingToCompareTo(now);
assertThat(loadRevision(FULL)).isEqualTo(0);
assertNoTasksEnqueued("rde-upload");
}
private static void compareLength(String outputFile, String lengthFilename) throws IOException {
assertThat(String.valueOf(outputFile.getBytes(UTF_8).length))
.isEqualTo(
new String(
readGcsFile(gcsService, new GcsFilename(GCS_BUCKET, lengthFilename)), UTF_8));
}
private static DateTime loadCursorTime(CursorType type) {
return ofy().load().key(Cursor.createKey(type, Registry.get("soy"))).now().getCursorTime();
}
private static int loadRevision(RdeMode mode) {
return ofy()
.load()
.type(RdeRevision.class)
.id("soy_2000-01-01_" + mode.getFilenameComponent())
.now()
.getRevision();
}
private static String decryptGhostrydeGcsFile(String filename) throws IOException, PGPException {
return new String(
Ghostryde.decode(
readGcsFile(gcsService, new GcsFilename(GCS_BUCKET, filename)), decryptionKey),
UTF_8);
}
private static class Fragments extends ReducerInput<DepositFragment> {
private final Iterator<DepositFragment> iterator;
Fragments(Iterable<DepositFragment> iterable) {
this.iterator = iterable.iterator();
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public DepositFragment next() {
return iterator.next();
}
}
}

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rde:deposit xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xmlns:rdeContact="urn:ietf:params:xml:ns:rdeContact-1.0" xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" xmlns:rdeEppParams="urn:ietf:params:xml:ns:rdeEppParams-1.0" xmlns:rdeNotification="urn:ietf:params:xml:ns:rdeNotification-1.0" xmlns:host="urn:ietf:params:xml:ns:host-1.0" xmlns:rdeIDN="urn:ietf:params:xml:ns:rdeIDN-1.0" xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0" xmlns:smd="urn:ietf:params:xml:ns:signedMark-1.0" xmlns:rdeHost="urn:ietf:params:xml:ns:rdeHost-1.0" xmlns:rdeReport="urn:ietf:params:xml:ns:rdeReport-1.0" xmlns:fee11="urn:ietf:params:xml:ns:fee-0.11" xmlns:fee12="urn:ietf:params:xml:ns:fee-0.12" xmlns:iirdea="urn:ietf:params:xml:ns:iirdea-1.0" xmlns:rdeHeader="urn:ietf:params:xml:ns:rdeHeader-1.0" xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:rdeDomain="urn:ietf:params:xml:ns:rdeDomain-1.0" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:rdeNNDN="urn:ietf:params:xml:ns:rdeNNDN-1.0" xmlns:rdeRegistrar="urn:ietf:params:xml:ns:rdeRegistrar-1.0" xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:rde="urn:ietf:params:xml:ns:rde-1.0" xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1" xmlns:mark="urn:ietf:params:xml:ns:mark-1.0" xmlns:rdePolicy="urn:ietf:params:xml:ns:rdePolicy-1.0" xmlns:fee06="urn:ietf:params:xml:ns:fee-0.6" type="FULL" id="AAAABXDKZ6WAA"%RESEND%>
<rde:watermark>2000-01-01T00:00:00Z</rde:watermark>
<rde:rdeMenu>
<rde:version>1.0</rde:version>
<rde:objURI>urn:ietf:params:xml:ns:rdeDomain-1.0</rde:objURI>
<rde:objURI>urn:ietf:params:xml:ns:rdeHeader-1.0</rde:objURI>
<rde:objURI>urn:ietf:params:xml:ns:rdeRegistrar-1.0</rde:objURI>
</rde:rdeMenu>
<rde:contents>
<rdeDomain:domain/>
<rdeRegistrar:registrar/>
<rdeHeader:header>
<rdeHeader:tld>soy</rdeHeader:tld>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeDomain-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeRegistrar-1.0">1</rdeHeader:count>
</rdeHeader:header>
</rde:contents>
</rde:deposit>

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rde:deposit xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xmlns:rdeContact="urn:ietf:params:xml:ns:rdeContact-1.0" xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" xmlns:rdeEppParams="urn:ietf:params:xml:ns:rdeEppParams-1.0" xmlns:rdeNotification="urn:ietf:params:xml:ns:rdeNotification-1.0" xmlns:host="urn:ietf:params:xml:ns:host-1.0" xmlns:rdeIDN="urn:ietf:params:xml:ns:rdeIDN-1.0" xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0" xmlns:smd="urn:ietf:params:xml:ns:signedMark-1.0" xmlns:rdeHost="urn:ietf:params:xml:ns:rdeHost-1.0" xmlns:rdeReport="urn:ietf:params:xml:ns:rdeReport-1.0" xmlns:fee11="urn:ietf:params:xml:ns:fee-0.11" xmlns:fee12="urn:ietf:params:xml:ns:fee-0.12" xmlns:iirdea="urn:ietf:params:xml:ns:iirdea-1.0" xmlns:rdeHeader="urn:ietf:params:xml:ns:rdeHeader-1.0" xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:rdeDomain="urn:ietf:params:xml:ns:rdeDomain-1.0" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:rdeNNDN="urn:ietf:params:xml:ns:rdeNNDN-1.0" xmlns:rdeRegistrar="urn:ietf:params:xml:ns:rdeRegistrar-1.0" xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:rde="urn:ietf:params:xml:ns:rde-1.0" xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1" xmlns:mark="urn:ietf:params:xml:ns:mark-1.0" xmlns:rdePolicy="urn:ietf:params:xml:ns:rdePolicy-1.0" xmlns:fee06="urn:ietf:params:xml:ns:fee-0.6" type="FULL" id="AAAABXDKZ6WAA"%RESEND%>
<rde:watermark>2000-01-01T00:00:00Z</rde:watermark>
<rde:rdeMenu>
<rde:version>1.0</rde:version>
<rde:objURI>urn:ietf:params:xml:ns:rdeContact-1.0</rde:objURI>
<rde:objURI>urn:ietf:params:xml:ns:rdeDomain-1.0</rde:objURI>
<rde:objURI>urn:ietf:params:xml:ns:rdeHeader-1.0</rde:objURI>
<rde:objURI>urn:ietf:params:xml:ns:rdeHost-1.0</rde:objURI>
<rde:objURI>urn:ietf:params:xml:ns:rdeIDN-1.0</rde:objURI>
<rde:objURI>urn:ietf:params:xml:ns:rdeRegistrar-1.0</rde:objURI>
</rde:rdeMenu>
<rde:contents>
<rdeDomain:domain/>
<rdeRegistrar:registrar/>
<rdeContact:contact/>
<rdeHost:host/>
<rdeIDN:idnTableRef id="extended_latin">
<rdeIDN:url>https://www.iana.org/domains/idn-tables/tables/google_latn_1.0.txt</rdeIDN:url>
<rdeIDN:urlPolicy>https://www.registry.google/about/policies/domainabuse/</rdeIDN:urlPolicy>
</rdeIDN:idnTableRef>
<rdeIDN:idnTableRef id="ja">
<rdeIDN:url>https://www.iana.org/domains/idn-tables/tables/google_ja_1.0.txt</rdeIDN:url>
<rdeIDN:urlPolicy>https://www.registry.google/about/policies/domainabuse/</rdeIDN:urlPolicy>
</rdeIDN:idnTableRef>
<rdeHeader:header>
<rdeHeader:tld>soy</rdeHeader:tld>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeContact-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeDomain-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeHost-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeRegistrar-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeIDN-1.0">2</rdeHeader:count>
</rdeHeader:header>
</rde:contents>
</rde:deposit>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rdeReport:report xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xmlns:rdeContact="urn:ietf:params:xml:ns:rdeContact-1.0" xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" xmlns:rdeEppParams="urn:ietf:params:xml:ns:rdeEppParams-1.0" xmlns:rdeNotification="urn:ietf:params:xml:ns:rdeNotification-1.0" xmlns:host="urn:ietf:params:xml:ns:host-1.0" xmlns:rdeIDN="urn:ietf:params:xml:ns:rdeIDN-1.0" xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0" xmlns:smd="urn:ietf:params:xml:ns:signedMark-1.0" xmlns:rdeHost="urn:ietf:params:xml:ns:rdeHost-1.0" xmlns:rdeReport="urn:ietf:params:xml:ns:rdeReport-1.0" xmlns:fee11="urn:ietf:params:xml:ns:fee-0.11" xmlns:fee12="urn:ietf:params:xml:ns:fee-0.12" xmlns:iirdea="urn:ietf:params:xml:ns:iirdea-1.0" xmlns:rdeHeader="urn:ietf:params:xml:ns:rdeHeader-1.0" xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:rdeDomain="urn:ietf:params:xml:ns:rdeDomain-1.0" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:rdeNNDN="urn:ietf:params:xml:ns:rdeNNDN-1.0" xmlns:rdeRegistrar="urn:ietf:params:xml:ns:rdeRegistrar-1.0" xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:rde="urn:ietf:params:xml:ns:rde-1.0" xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1" xmlns:mark="urn:ietf:params:xml:ns:mark-1.0" xmlns:rdePolicy="urn:ietf:params:xml:ns:rdePolicy-1.0" xmlns:fee06="urn:ietf:params:xml:ns:fee-0.6">
<rdeReport:id>AAAABXDKZ6WAA</rdeReport:id>
<rdeReport:version>1</rdeReport:version>
<rdeReport:rydeSpecEscrow>draft-arias-noguchi-registry-data-escrow-06</rdeReport:rydeSpecEscrow>
<rdeReport:rydeSpecMapping>draft-arias-noguchi-dnrd-objects-mapping-05</rdeReport:rydeSpecMapping>
<rdeReport:resend>%RESEND%</rdeReport:resend>
<rdeReport:crDate>2000-01-01T00:00:00Z</rdeReport:crDate>
<rdeReport:kind>FULL</rdeReport:kind>
<rdeReport:watermark>2000-01-01T00:00:00Z</rdeReport:watermark>
<rdeHeader:header>
<rdeHeader:tld>soy</rdeHeader:tld>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeContact-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeDomain-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeHost-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeRegistrar-1.0">1</rdeHeader:count>
<rdeHeader:count uri="urn:ietf:params:xml:ns:rdeIDN-1.0">2</rdeHeader:count>
</rdeHeader:header>
</rdeReport:report>