mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 07:57:13 +02:00
Refactor EppXmlTransformer to be in the model/ package
This will allow us to perform the OT&E history verification in the model/ package as well so that it can be used both by both the UI and the command line tool. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=225007167
This commit is contained in:
parent
f58211402a
commit
0a44ef0dca
27 changed files with 257 additions and 240 deletions
|
@ -17,8 +17,8 @@ package google.registry.flows;
|
||||||
import static com.google.common.base.Strings.nullToEmpty;
|
import static com.google.common.base.Strings.nullToEmpty;
|
||||||
import static com.google.common.flogger.LazyArgs.lazy;
|
import static com.google.common.flogger.LazyArgs.lazy;
|
||||||
import static com.google.common.io.BaseEncoding.base64;
|
import static com.google.common.io.BaseEncoding.base64;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
|
||||||
import static google.registry.flows.FlowReporter.extractTlds;
|
import static google.registry.flows.FlowReporter.extractTlds;
|
||||||
|
import static google.registry.flows.FlowUtils.unmarshalEpp;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -65,7 +65,7 @@ public final class EppController {
|
||||||
try {
|
try {
|
||||||
EppInput eppInput;
|
EppInput eppInput;
|
||||||
try {
|
try {
|
||||||
eppInput = unmarshal(EppInput.class, inputXmlBytes);
|
eppInput = unmarshalEpp(EppInput.class, inputXmlBytes);
|
||||||
} catch (EppException e) {
|
} catch (EppException e) {
|
||||||
// Log the unmarshalling error, with the raw bytes (in base64) to help with debugging.
|
// Log the unmarshalling error, with the raw bytes (in base64) to help with debugging.
|
||||||
logger.atInfo().withCause(e).log(
|
logger.atInfo().withCause(e).log(
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
package google.registry.flows;
|
package google.registry.flows;
|
||||||
|
|
||||||
import static google.registry.flows.EppXmlTransformer.marshalWithLenientRetry;
|
import static google.registry.flows.FlowUtils.marshalWithLenientRetry;
|
||||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_AND_CLOSE;
|
import static google.registry.model.eppoutput.Result.Code.SUCCESS_AND_CLOSE;
|
||||||
import static google.registry.xml.XmlTransformer.prettyPrint;
|
import static google.registry.xml.XmlTransformer.prettyPrint;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
|
@ -1,179 +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.flows;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
|
||||||
import static google.registry.xml.ValidationMode.LENIENT;
|
|
||||||
import static google.registry.xml.ValidationMode.STRICT;
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.flogger.FluentLogger;
|
|
||||||
import google.registry.flows.EppException.ParameterValueRangeErrorException;
|
|
||||||
import google.registry.flows.EppException.ParameterValueSyntaxErrorException;
|
|
||||||
import google.registry.flows.EppException.SyntaxErrorException;
|
|
||||||
import google.registry.flows.EppException.UnimplementedProtocolVersionException;
|
|
||||||
import google.registry.model.EppResourceUtils.InvalidRepoIdException;
|
|
||||||
import google.registry.model.ImmutableObject;
|
|
||||||
import google.registry.model.eppinput.EppInput;
|
|
||||||
import google.registry.model.eppinput.EppInput.WrongProtocolVersionException;
|
|
||||||
import google.registry.model.eppoutput.EppOutput;
|
|
||||||
import google.registry.model.host.InetAddressAdapter.IpVersionMismatchException;
|
|
||||||
import google.registry.model.translators.CurrencyUnitAdapter.UnknownCurrencyException;
|
|
||||||
import google.registry.xml.ValidationMode;
|
|
||||||
import google.registry.xml.XmlException;
|
|
||||||
import google.registry.xml.XmlTransformer;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/** {@link XmlTransformer} for marshalling to and from the Epp model classes. */
|
|
||||||
public class EppXmlTransformer {
|
|
||||||
|
|
||||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
|
||||||
|
|
||||||
// Hardcoded XML schemas, ordered with respect to dependency.
|
|
||||||
private static final ImmutableList<String> SCHEMAS = ImmutableList.of(
|
|
||||||
"eppcom.xsd",
|
|
||||||
"epp.xsd",
|
|
||||||
"contact.xsd",
|
|
||||||
"host.xsd",
|
|
||||||
"domain.xsd",
|
|
||||||
"rgp.xsd",
|
|
||||||
"secdns.xsd",
|
|
||||||
"fee06.xsd",
|
|
||||||
"fee11.xsd",
|
|
||||||
"fee12.xsd",
|
|
||||||
"metadata.xsd",
|
|
||||||
"mark.xsd",
|
|
||||||
"dsig.xsd",
|
|
||||||
"smd.xsd",
|
|
||||||
"launch.xsd",
|
|
||||||
"allocate.xsd",
|
|
||||||
"superuser.xsd",
|
|
||||||
"allocationToken-1.0.xsd");
|
|
||||||
|
|
||||||
private static final XmlTransformer INPUT_TRANSFORMER =
|
|
||||||
new XmlTransformer(SCHEMAS, EppInput.class);
|
|
||||||
|
|
||||||
private static final XmlTransformer OUTPUT_TRANSFORMER =
|
|
||||||
new XmlTransformer(SCHEMAS, EppOutput.class);
|
|
||||||
|
|
||||||
public static void validateOutput(String xml) throws XmlException {
|
|
||||||
OUTPUT_TRANSFORMER.validate(xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unmarshal bytes into Epp classes.
|
|
||||||
*
|
|
||||||
* @param clazz type to return, specified as a param to enforce typesafe generics
|
|
||||||
* @see <a href="https://errorprone.info/bugpattern/TypeParameterUnusedInFormals">TypeParameterUnusedInFormals</a>
|
|
||||||
*/
|
|
||||||
public static <T> T unmarshal(Class<T> clazz, byte[] bytes) throws EppException {
|
|
||||||
try {
|
|
||||||
return INPUT_TRANSFORMER.unmarshal(clazz, new ByteArrayInputStream(bytes));
|
|
||||||
} catch (XmlException e) {
|
|
||||||
// If this XmlException is wrapping a known type find it. If not, it's a syntax error.
|
|
||||||
List<Throwable> causalChain = Throwables.getCausalChain(e);
|
|
||||||
if (causalChain.stream().anyMatch(IpVersionMismatchException.class::isInstance)) {
|
|
||||||
throw new IpAddressVersionMismatchException();
|
|
||||||
}
|
|
||||||
if (causalChain.stream().anyMatch(WrongProtocolVersionException.class::isInstance)) {
|
|
||||||
throw new UnimplementedProtocolVersionException();
|
|
||||||
}
|
|
||||||
if (causalChain.stream().anyMatch(InvalidRepoIdException.class::isInstance)) {
|
|
||||||
throw new InvalidRepoIdEppException();
|
|
||||||
}
|
|
||||||
if (causalChain.stream().anyMatch(UnknownCurrencyException.class::isInstance)) {
|
|
||||||
throw new UnknownCurrencyEppException();
|
|
||||||
}
|
|
||||||
throw new GenericSyntaxErrorException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] marshal(
|
|
||||||
XmlTransformer transformer,
|
|
||||||
ImmutableObject root,
|
|
||||||
ValidationMode validation) throws XmlException {
|
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
||||||
transformer.marshal(root, byteArrayOutputStream, UTF_8, validation);
|
|
||||||
return byteArrayOutputStream.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] marshal(EppOutput root, ValidationMode validation) throws XmlException {
|
|
||||||
return marshal(OUTPUT_TRANSFORMER, root, validation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] marshalWithLenientRetry(EppOutput eppOutput) {
|
|
||||||
checkState(eppOutput != null);
|
|
||||||
// We need to marshal to a string instead of writing the response directly to the servlet's
|
|
||||||
// response writer, so that partial results don't get written on failure.
|
|
||||||
try {
|
|
||||||
return EppXmlTransformer.marshal(eppOutput, STRICT);
|
|
||||||
} catch (XmlException e) {
|
|
||||||
// We failed to marshal with validation. This is very bad, but we can potentially still send
|
|
||||||
// back slightly invalid xml, so try again without validation.
|
|
||||||
try {
|
|
||||||
byte[] lenient = EppXmlTransformer.marshal(eppOutput, LENIENT);
|
|
||||||
// Marshaling worked even though the results didn't validate against the schema.
|
|
||||||
logger.atSevere().withCause(e).log(
|
|
||||||
"Result marshaled but did not validate: %s", new String(lenient, UTF_8));
|
|
||||||
return lenient;
|
|
||||||
} catch (XmlException e2) {
|
|
||||||
throw new RuntimeException(e2); // Failing to marshal at all is not recoverable.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public static byte[] marshalInput(EppInput root, ValidationMode validation) throws XmlException {
|
|
||||||
return marshal(INPUT_TRANSFORMER, root, validation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public static void validateInput(String xml) throws XmlException {
|
|
||||||
INPUT_TRANSFORMER.validate(xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** IP address version mismatch. */
|
|
||||||
public static class IpAddressVersionMismatchException extends ParameterValueRangeErrorException {
|
|
||||||
public IpAddressVersionMismatchException() {
|
|
||||||
super("IP adddress version mismatch");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Invalid format for repository id. */
|
|
||||||
public static class InvalidRepoIdEppException extends ParameterValueSyntaxErrorException {
|
|
||||||
public InvalidRepoIdEppException() {
|
|
||||||
super("Invalid format for repository id");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Unknown currency. */
|
|
||||||
static class UnknownCurrencyEppException extends ParameterValueRangeErrorException {
|
|
||||||
public UnknownCurrencyEppException() {
|
|
||||||
super("Unknown currency.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generic syntax error that can be thrown by any flow. */
|
|
||||||
static class GenericSyntaxErrorException extends SyntaxErrorException {
|
|
||||||
public GenericSyntaxErrorException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,14 +14,32 @@
|
||||||
|
|
||||||
package google.registry.flows;
|
package google.registry.flows;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
|
import static google.registry.xml.ValidationMode.LENIENT;
|
||||||
|
import static google.registry.xml.ValidationMode.STRICT;
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.flogger.FluentLogger;
|
||||||
import google.registry.flows.EppException.CommandUseErrorException;
|
import google.registry.flows.EppException.CommandUseErrorException;
|
||||||
|
import google.registry.flows.EppException.ParameterValueRangeErrorException;
|
||||||
|
import google.registry.flows.EppException.SyntaxErrorException;
|
||||||
|
import google.registry.flows.EppException.UnimplementedProtocolVersionException;
|
||||||
import google.registry.flows.custom.EntityChanges;
|
import google.registry.flows.custom.EntityChanges;
|
||||||
|
import google.registry.model.eppcommon.EppXmlTransformer;
|
||||||
|
import google.registry.model.eppinput.EppInput.WrongProtocolVersionException;
|
||||||
|
import google.registry.model.eppoutput.EppOutput;
|
||||||
|
import google.registry.model.host.InetAddressAdapter.IpVersionMismatchException;
|
||||||
|
import google.registry.model.translators.CurrencyUnitAdapter.UnknownCurrencyException;
|
||||||
|
import google.registry.xml.XmlException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** Static utility functions for flows. */
|
/** Static utility functions for flows. */
|
||||||
public final class FlowUtils {
|
public final class FlowUtils {
|
||||||
|
|
||||||
|
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||||
|
|
||||||
private FlowUtils() {}
|
private FlowUtils() {}
|
||||||
|
|
||||||
/** Validate that there is a logged in client. */
|
/** Validate that there is a logged in client. */
|
||||||
|
@ -37,10 +55,75 @@ public final class FlowUtils {
|
||||||
ofy().delete().keys(entityChanges.getDeletes());
|
ofy().delete().keys(entityChanges.getDeletes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmarshal bytes into Epp classes. Does the same as {@link EppXmlTransformer#unmarshal(Class,
|
||||||
|
* byte[])} but with exception-handling logic to throw {@link EppException} instead.
|
||||||
|
*/
|
||||||
|
public static <T> T unmarshalEpp(Class<T> clazz, byte[] bytes) throws EppException {
|
||||||
|
try {
|
||||||
|
return EppXmlTransformer.unmarshal(clazz, bytes);
|
||||||
|
} catch (XmlException e) {
|
||||||
|
// If this XmlException is wrapping a known type find it. If not, it's a syntax error.
|
||||||
|
List<Throwable> causalChain = Throwables.getCausalChain(e);
|
||||||
|
if (causalChain.stream().anyMatch(IpVersionMismatchException.class::isInstance)) {
|
||||||
|
throw new IpAddressVersionMismatchException();
|
||||||
|
}
|
||||||
|
if (causalChain.stream().anyMatch(WrongProtocolVersionException.class::isInstance)) {
|
||||||
|
throw new UnimplementedProtocolVersionException();
|
||||||
|
}
|
||||||
|
if (causalChain.stream().anyMatch(UnknownCurrencyException.class::isInstance)) {
|
||||||
|
throw new UnknownCurrencyEppException();
|
||||||
|
}
|
||||||
|
throw new GenericXmlSyntaxErrorException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] marshalWithLenientRetry(EppOutput eppOutput) {
|
||||||
|
checkState(eppOutput != null);
|
||||||
|
// We need to marshal to a string instead of writing the response directly to the servlet's
|
||||||
|
// response writer, so that partial results don't get written on failure.
|
||||||
|
try {
|
||||||
|
return EppXmlTransformer.marshal(eppOutput, STRICT);
|
||||||
|
} catch (XmlException e) {
|
||||||
|
// We failed to marshal with validation. This is very bad, but we can potentially still send
|
||||||
|
// back slightly invalid xml, so try again without validation.
|
||||||
|
try {
|
||||||
|
byte[] lenient = EppXmlTransformer.marshal(eppOutput, LENIENT);
|
||||||
|
// Marshaling worked even though the results didn't validate against the schema.
|
||||||
|
logger.atSevere().withCause(e).log(
|
||||||
|
"Result marshaled but did not validate: %s", new String(lenient, UTF_8));
|
||||||
|
return lenient;
|
||||||
|
} catch (XmlException e2) {
|
||||||
|
throw new RuntimeException(e2); // Failing to marshal at all is not recoverable.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Registrar is not logged in. */
|
/** Registrar is not logged in. */
|
||||||
public static class NotLoggedInException extends CommandUseErrorException {
|
public static class NotLoggedInException extends CommandUseErrorException {
|
||||||
public NotLoggedInException() {
|
public NotLoggedInException() {
|
||||||
super("Registrar is not logged in.");
|
super("Registrar is not logged in.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** IP address version mismatch. */
|
||||||
|
public static class IpAddressVersionMismatchException extends ParameterValueRangeErrorException {
|
||||||
|
public IpAddressVersionMismatchException() {
|
||||||
|
super("IP adddress version mismatch");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unknown currency. */
|
||||||
|
static class UnknownCurrencyEppException extends ParameterValueRangeErrorException {
|
||||||
|
public UnknownCurrencyEppException() {
|
||||||
|
super("Unknown currency.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generic XML syntax error that can be thrown by any flow. */
|
||||||
|
public static class GenericXmlSyntaxErrorException extends SyntaxErrorException {
|
||||||
|
public GenericXmlSyntaxErrorException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
package google.registry.flows.domain;
|
package google.registry.flows.domain;
|
||||||
|
|
||||||
import static com.google.common.collect.Sets.union;
|
import static com.google.common.collect.Sets.union;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.flows.FlowUtils.unmarshalEpp;
|
||||||
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
|
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
|
||||||
import static google.registry.flows.ResourceFlowUtils.verifyExistence;
|
import static google.registry.flows.ResourceFlowUtils.verifyExistence;
|
||||||
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
|
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
|
||||||
|
@ -136,7 +136,7 @@ public final class DomainApplicationInfoFlow implements Flow {
|
||||||
if (Boolean.TRUE.equals(launchInfo.getIncludeMark())) { // Default to false.
|
if (Boolean.TRUE.equals(launchInfo.getIncludeMark())) { // Default to false.
|
||||||
for (EncodedSignedMark encodedMark : application.getEncodedSignedMarks()) {
|
for (EncodedSignedMark encodedMark : application.getEncodedSignedMarks()) {
|
||||||
try {
|
try {
|
||||||
marksBuilder.add(unmarshal(SignedMark.class, encodedMark.getBytes()).getMark());
|
marksBuilder.add(unmarshalEpp(SignedMark.class, encodedMark.getBytes()).getMark());
|
||||||
} catch (EppException e) {
|
} catch (EppException e) {
|
||||||
// This is a serious error; don't let the benign EppException propagate.
|
// This is a serious error; don't let the benign EppException propagate.
|
||||||
throw new IllegalStateException("Could not decode a stored encoded signed mark", e);
|
throw new IllegalStateException("Could not decode a stored encoded signed mark", e);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
package google.registry.flows.domain;
|
package google.registry.flows.domain;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.concat;
|
import static com.google.common.collect.Iterables.concat;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.flows.FlowUtils.unmarshalEpp;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import google.registry.flows.EppException;
|
import google.registry.flows.EppException;
|
||||||
|
@ -90,7 +90,7 @@ public final class DomainFlowTmchUtils {
|
||||||
|
|
||||||
SignedMark signedMark;
|
SignedMark signedMark;
|
||||||
try {
|
try {
|
||||||
signedMark = unmarshal(SignedMark.class, signedMarkData);
|
signedMark = unmarshalEpp(SignedMark.class, signedMarkData);
|
||||||
} catch (EppException e) {
|
} catch (EppException e) {
|
||||||
throw new SignedMarkParsingErrorException();
|
throw new SignedMarkParsingErrorException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ import org.joda.time.DateTime;
|
||||||
* hosts cannot have any. This flow allows creating a host name, and if necessary enqueues tasks to
|
* hosts cannot have any. This flow allows creating a host name, and if necessary enqueues tasks to
|
||||||
* update DNS.
|
* update DNS.
|
||||||
*
|
*
|
||||||
* @error {@link google.registry.flows.EppXmlTransformer.IpAddressVersionMismatchException}
|
* @error {@link google.registry.flows.FlowUtils.IpAddressVersionMismatchException}
|
||||||
* @error {@link google.registry.flows.exceptions.ResourceAlreadyExistsException}
|
* @error {@link google.registry.flows.exceptions.ResourceAlreadyExistsException}
|
||||||
* @error {@link HostFlowUtils.HostNameTooLongException}
|
* @error {@link HostFlowUtils.HostNameTooLongException}
|
||||||
* @error {@link HostFlowUtils.HostNameTooShallowException}
|
* @error {@link HostFlowUtils.HostNameTooShallowException}
|
||||||
|
@ -87,8 +87,13 @@ public final class HostCreateFlow implements TransactionalFlow {
|
||||||
@Inject HistoryEntry.Builder historyBuilder;
|
@Inject HistoryEntry.Builder historyBuilder;
|
||||||
@Inject DnsQueue dnsQueue;
|
@Inject DnsQueue dnsQueue;
|
||||||
@Inject EppResponse.Builder responseBuilder;
|
@Inject EppResponse.Builder responseBuilder;
|
||||||
@Inject @Config("contactAndHostRoidSuffix") String roidSuffix;
|
|
||||||
@Inject HostCreateFlow() {}
|
@Inject
|
||||||
|
@Config("contactAndHostRoidSuffix")
|
||||||
|
String roidSuffix;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HostCreateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final EppResponse run() throws EppException {
|
public final EppResponse run() throws EppException {
|
||||||
|
@ -126,17 +131,21 @@ public final class HostCreateFlow implements TransactionalFlow {
|
||||||
.setType(HistoryEntry.Type.HOST_CREATE)
|
.setType(HistoryEntry.Type.HOST_CREATE)
|
||||||
.setModificationTime(now)
|
.setModificationTime(now)
|
||||||
.setParent(Key.create(newHost));
|
.setParent(Key.create(newHost));
|
||||||
ImmutableSet<ImmutableObject> entitiesToSave = ImmutableSet.of(
|
ImmutableSet<ImmutableObject> entitiesToSave =
|
||||||
newHost,
|
ImmutableSet.of(
|
||||||
historyBuilder.build(),
|
newHost,
|
||||||
ForeignKeyIndex.create(newHost, newHost.getDeletionTime()),
|
historyBuilder.build(),
|
||||||
EppResourceIndex.create(Key.create(newHost)));
|
ForeignKeyIndex.create(newHost, newHost.getDeletionTime()),
|
||||||
|
EppResourceIndex.create(Key.create(newHost)));
|
||||||
if (superordinateDomain.isPresent()) {
|
if (superordinateDomain.isPresent()) {
|
||||||
entitiesToSave = union(
|
entitiesToSave =
|
||||||
entitiesToSave,
|
union(
|
||||||
superordinateDomain.get().asBuilder()
|
entitiesToSave,
|
||||||
.addSubordinateHost(command.getFullyQualifiedHostName())
|
superordinateDomain
|
||||||
.build());
|
.get()
|
||||||
|
.asBuilder()
|
||||||
|
.addSubordinateHost(command.getFullyQualifiedHostName())
|
||||||
|
.build());
|
||||||
// Only update DNS if this is a subordinate host. External hosts have no glue to write, so
|
// Only update DNS if this is a subordinate host. External hosts have no glue to write, so
|
||||||
// they are only written as NS records from the referencing domain.
|
// they are only written as NS records from the referencing domain.
|
||||||
dnsQueue.addHostRefreshTask(targetId);
|
dnsQueue.addHostRefreshTask(targetId);
|
||||||
|
|
|
@ -402,13 +402,5 @@ public final class EppResourceUtils {
|
||||||
return queryForLinkedDomains(key, now).limit(1).count() > 0;
|
return queryForLinkedDomains(key, now).limit(1).count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Exception to throw when failing to parse a repo id. */
|
|
||||||
public static class InvalidRepoIdException extends Exception {
|
|
||||||
|
|
||||||
public InvalidRepoIdException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private EppResourceUtils() {}
|
private EppResourceUtils() {}
|
||||||
}
|
}
|
||||||
|
|
95
java/google/registry/model/eppcommon/EppXmlTransformer.java
Normal file
95
java/google/registry/model/eppcommon/EppXmlTransformer.java
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
// 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.model.eppcommon;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import google.registry.model.ImmutableObject;
|
||||||
|
import google.registry.model.eppinput.EppInput;
|
||||||
|
import google.registry.model.eppoutput.EppOutput;
|
||||||
|
import google.registry.xml.ValidationMode;
|
||||||
|
import google.registry.xml.XmlException;
|
||||||
|
import google.registry.xml.XmlTransformer;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
/** {@link XmlTransformer} for marshalling to and from the Epp model classes. */
|
||||||
|
public class EppXmlTransformer {
|
||||||
|
|
||||||
|
// Hardcoded XML schemas, ordered with respect to dependency.
|
||||||
|
private static final ImmutableList<String> SCHEMAS = ImmutableList.of(
|
||||||
|
"eppcom.xsd",
|
||||||
|
"epp.xsd",
|
||||||
|
"contact.xsd",
|
||||||
|
"host.xsd",
|
||||||
|
"domain.xsd",
|
||||||
|
"rgp.xsd",
|
||||||
|
"secdns.xsd",
|
||||||
|
"fee06.xsd",
|
||||||
|
"fee11.xsd",
|
||||||
|
"fee12.xsd",
|
||||||
|
"metadata.xsd",
|
||||||
|
"mark.xsd",
|
||||||
|
"dsig.xsd",
|
||||||
|
"smd.xsd",
|
||||||
|
"launch.xsd",
|
||||||
|
"allocate.xsd",
|
||||||
|
"superuser.xsd",
|
||||||
|
"allocationToken-1.0.xsd");
|
||||||
|
|
||||||
|
private static final XmlTransformer INPUT_TRANSFORMER =
|
||||||
|
new XmlTransformer(SCHEMAS, EppInput.class);
|
||||||
|
|
||||||
|
private static final XmlTransformer OUTPUT_TRANSFORMER =
|
||||||
|
new XmlTransformer(SCHEMAS, EppOutput.class);
|
||||||
|
|
||||||
|
public static void validateOutput(String xml) throws XmlException {
|
||||||
|
OUTPUT_TRANSFORMER.validate(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmarshal bytes into Epp classes.
|
||||||
|
*
|
||||||
|
* @param clazz type to return, specified as a param to enforce typesafe generics
|
||||||
|
*/
|
||||||
|
public static <T> T unmarshal(Class<T> clazz, byte[] bytes) throws XmlException {
|
||||||
|
return INPUT_TRANSFORMER.unmarshal(clazz, new ByteArrayInputStream(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] marshal(
|
||||||
|
XmlTransformer transformer,
|
||||||
|
ImmutableObject root,
|
||||||
|
ValidationMode validation) throws XmlException {
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
transformer.marshal(root, byteArrayOutputStream, UTF_8, validation);
|
||||||
|
return byteArrayOutputStream.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] marshal(EppOutput root, ValidationMode validation) throws XmlException {
|
||||||
|
return marshal(OUTPUT_TRANSFORMER, root, validation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public static byte[] marshalInput(EppInput root, ValidationMode validation) throws XmlException {
|
||||||
|
return marshal(INPUT_TRANSFORMER, root, validation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public static void validateInput(String xml) throws XmlException {
|
||||||
|
INPUT_TRANSFORMER.validate(xml);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ import static com.google.common.base.Strings.emptyToNull;
|
||||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||||
import static com.google.common.collect.Iterables.transform;
|
import static com.google.common.collect.Iterables.transform;
|
||||||
import static com.google.common.io.BaseEncoding.base16;
|
import static com.google.common.io.BaseEncoding.base16;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.tools.CommandUtilities.addHeader;
|
import static google.registry.tools.CommandUtilities.addHeader;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
|
@ -34,7 +34,6 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.template.soy.data.SoyMapData;
|
import com.google.template.soy.data.SoyMapData;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.flows.EppException;
|
|
||||||
import google.registry.model.domain.DesignatedContact;
|
import google.registry.model.domain.DesignatedContact;
|
||||||
import google.registry.model.domain.DomainApplication;
|
import google.registry.model.domain.DomainApplication;
|
||||||
import google.registry.model.domain.DomainCommand;
|
import google.registry.model.domain.DomainCommand;
|
||||||
|
@ -46,6 +45,7 @@ import google.registry.model.eppinput.EppInput.ResourceCommandWrapper;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.model.smd.SignedMark;
|
import google.registry.model.smd.SignedMark;
|
||||||
import google.registry.tools.soy.DomainAllocateSoyInfo;
|
import google.registry.tools.soy.DomainAllocateSoyInfo;
|
||||||
|
import google.registry.xml.XmlException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -88,7 +88,7 @@ final class AllocateDomainCommand extends MutatingEppToolCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Extract the registration period from the XML used to create the domain application. */
|
/** Extract the registration period from the XML used to create the domain application. */
|
||||||
private static Period extractPeriodFromXml(byte[] xmlBytes) throws EppException {
|
private static Period extractPeriodFromXml(byte[] xmlBytes) throws XmlException {
|
||||||
EppInput eppInput = unmarshal(EppInput.class, xmlBytes);
|
EppInput eppInput = unmarshal(EppInput.class, xmlBytes);
|
||||||
return ((DomainCommand.Create)
|
return ((DomainCommand.Create)
|
||||||
((ResourceCommandWrapper) eppInput.getCommandWrapper().getCommand())
|
((ResourceCommandWrapper) eppInput.getCommandWrapper().getCommand())
|
||||||
|
@ -182,7 +182,7 @@ final class AllocateDomainCommand extends MutatingEppToolCommand {
|
||||||
"dsRecords", dsRecords,
|
"dsRecords", dsRecords,
|
||||||
"clTrid", clientTransactionId));
|
"clTrid", clientTransactionId));
|
||||||
applicationKeys.add(Key.create(application));
|
applicationKeys.add(Key.create(application));
|
||||||
} catch (EppException e) {
|
} catch (XmlException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
package google.registry.tools;
|
package google.registry.tools;
|
||||||
|
|
||||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.model.registry.Registries.assertTldExists;
|
import static google.registry.model.registry.Registries.assertTldExists;
|
||||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||||
|
@ -29,7 +29,6 @@ import com.google.common.base.Joiner;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
import com.googlecode.objectify.cmd.LoadType;
|
import com.googlecode.objectify.cmd.LoadType;
|
||||||
import com.googlecode.objectify.cmd.Query;
|
import com.googlecode.objectify.cmd.Query;
|
||||||
import google.registry.flows.EppException;
|
|
||||||
import google.registry.model.domain.DomainApplication;
|
import google.registry.model.domain.DomainApplication;
|
||||||
import google.registry.model.smd.EncodedSignedMark;
|
import google.registry.model.smd.EncodedSignedMark;
|
||||||
import google.registry.model.smd.SignedMark;
|
import google.registry.model.smd.SignedMark;
|
||||||
|
@ -39,6 +38,7 @@ import google.registry.tmch.TmchXmlSignature;
|
||||||
import google.registry.tools.params.PathParameter;
|
import google.registry.tools.params.PathParameter;
|
||||||
import google.registry.util.Clock;
|
import google.registry.util.Clock;
|
||||||
import google.registry.util.Idn;
|
import google.registry.util.Idn;
|
||||||
|
import google.registry.xml.XmlException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -132,7 +132,7 @@ final class GenerateApplicationsReportCommand implements CommandWithRemoteApi {
|
||||||
SignedMark signedMark;
|
SignedMark signedMark;
|
||||||
try {
|
try {
|
||||||
signedMark = unmarshal(SignedMark.class, signedMarkData);
|
signedMark = unmarshal(SignedMark.class, signedMarkData);
|
||||||
} catch (EppException e) {
|
} catch (XmlException e) {
|
||||||
return Optional.of(makeLine(domainApplication, "Unparseable SMD"));
|
return Optional.of(makeLine(domainApplication, "Unparseable SMD"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ java_library(
|
||||||
"//java/google/registry/config",
|
"//java/google/registry/config",
|
||||||
"//java/google/registry/dns",
|
"//java/google/registry/dns",
|
||||||
"//java/google/registry/export",
|
"//java/google/registry/export",
|
||||||
"//java/google/registry/flows",
|
|
||||||
"//java/google/registry/gcs",
|
"//java/google/registry/gcs",
|
||||||
"//java/google/registry/groups",
|
"//java/google/registry/groups",
|
||||||
"//java/google/registry/mapreduce",
|
"//java/google/registry/mapreduce",
|
||||||
|
@ -20,6 +19,7 @@ java_library(
|
||||||
"//java/google/registry/request",
|
"//java/google/registry/request",
|
||||||
"//java/google/registry/request/auth",
|
"//java/google/registry/request/auth",
|
||||||
"//java/google/registry/util",
|
"//java/google/registry/util",
|
||||||
|
"//java/google/registry/xml",
|
||||||
"//third_party/objectify:objectify-v4_1",
|
"//third_party/objectify:objectify-v4_1",
|
||||||
"@com_google_appengine_api_1_0_sdk",
|
"@com_google_appengine_api_1_0_sdk",
|
||||||
"@com_google_appengine_tools_appengine_gcs_client",
|
"@com_google_appengine_tools_appengine_gcs_client",
|
||||||
|
|
|
@ -17,7 +17,7 @@ package google.registry.tools.server;
|
||||||
import static com.google.common.base.Predicates.equalTo;
|
import static com.google.common.base.Predicates.equalTo;
|
||||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||||
import static com.google.common.collect.Maps.toMap;
|
import static com.google.common.collect.Maps.toMap;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
||||||
import static google.registry.util.DomainNameUtils.ACE_PREFIX;
|
import static google.registry.util.DomainNameUtils.ACE_PREFIX;
|
||||||
|
@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Multiset;
|
import com.google.common.collect.Multiset;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.cmd.Query;
|
import com.googlecode.objectify.cmd.Query;
|
||||||
import google.registry.flows.EppException;
|
|
||||||
import google.registry.model.domain.DomainCommand;
|
import google.registry.model.domain.DomainCommand;
|
||||||
import google.registry.model.domain.fee.FeeCreateCommandExtension;
|
import google.registry.model.domain.fee.FeeCreateCommandExtension;
|
||||||
import google.registry.model.domain.launch.LaunchCreateExtension;
|
import google.registry.model.domain.launch.LaunchCreateExtension;
|
||||||
|
@ -45,6 +44,7 @@ import google.registry.request.Action;
|
||||||
import google.registry.request.JsonActionRunner;
|
import google.registry.request.JsonActionRunner;
|
||||||
import google.registry.request.JsonActionRunner.JsonAction;
|
import google.registry.request.JsonActionRunner.JsonAction;
|
||||||
import google.registry.request.auth.Auth;
|
import google.registry.request.auth.Auth;
|
||||||
|
import google.registry.xml.XmlException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
@ -264,7 +264,7 @@ public class VerifyOteAction implements Runnable, JsonAction {
|
||||||
for (HistoryEntry historyEntry : query) {
|
for (HistoryEntry historyEntry : query) {
|
||||||
try {
|
try {
|
||||||
record(historyEntry);
|
record(historyEntry);
|
||||||
} catch (EppException e) {
|
} catch (XmlException e) {
|
||||||
throw new RuntimeException("Couldn't parse history entry " + Key.create(historyEntry), e);
|
throw new RuntimeException("Couldn't parse history entry " + Key.create(historyEntry), e);
|
||||||
}
|
}
|
||||||
// Break out early if all tests were passed.
|
// Break out early if all tests were passed.
|
||||||
|
@ -276,7 +276,7 @@ public class VerifyOteAction implements Runnable, JsonAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Interprets the data in the provided HistoryEntry and increments counters. */
|
/** Interprets the data in the provided HistoryEntry and increments counters. */
|
||||||
void record(final HistoryEntry historyEntry) throws EppException {
|
void record(final HistoryEntry historyEntry) throws XmlException {
|
||||||
byte[] xmlBytes = historyEntry.getXmlBytes();
|
byte[] xmlBytes = historyEntry.getXmlBytes();
|
||||||
// xmlBytes can be null on contact create and update for safe-harbor compliance.
|
// xmlBytes can be null on contact create and update for safe-harbor compliance.
|
||||||
final Optional<EppInput> eppInput =
|
final Optional<EppInput> eppInput =
|
||||||
|
|
|
@ -16,7 +16,7 @@ package google.registry.flows;
|
||||||
|
|
||||||
import static com.google.common.io.BaseEncoding.base64;
|
import static com.google.common.io.BaseEncoding.base64;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.EppXmlTransformer.marshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.LogsSubject.assertAboutLogs;
|
import static google.registry.testing.LogsSubject.assertAboutLogs;
|
||||||
import static google.registry.testing.TestDataHelper.loadFile;
|
import static google.registry.testing.TestDataHelper.loadFile;
|
||||||
|
|
|
@ -35,6 +35,7 @@ import google.registry.model.billing.BillingEvent.Flag;
|
||||||
import google.registry.model.billing.BillingEvent.OneTime;
|
import google.registry.model.billing.BillingEvent.OneTime;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
import google.registry.model.domain.DomainResource;
|
import google.registry.model.domain.DomainResource;
|
||||||
|
import google.registry.model.eppcommon.EppXmlTransformer;
|
||||||
import google.registry.model.ofy.Ofy;
|
import google.registry.model.ofy.Ofy;
|
||||||
import google.registry.model.registry.Registry;
|
import google.registry.model.registry.Registry;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
|
@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||||
import static com.google.common.collect.Sets.difference;
|
import static com.google.common.collect.Sets.difference;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.EppXmlTransformer.marshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.testing.DatastoreHelper.POLL_MESSAGE_ID_STRIPPER;
|
import static google.registry.testing.DatastoreHelper.POLL_MESSAGE_ID_STRIPPER;
|
||||||
import static google.registry.testing.DatastoreHelper.getPollMessages;
|
import static google.registry.testing.DatastoreHelper.getPollMessages;
|
||||||
|
|
|
@ -35,7 +35,7 @@ import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.flows.EppException;
|
import google.registry.flows.EppException;
|
||||||
import google.registry.flows.EppXmlTransformer.IpAddressVersionMismatchException;
|
import google.registry.flows.FlowUtils.IpAddressVersionMismatchException;
|
||||||
import google.registry.flows.ResourceFlowTestCase;
|
import google.registry.flows.ResourceFlowTestCase;
|
||||||
import google.registry.flows.exceptions.ResourceAlreadyExistsException;
|
import google.registry.flows.exceptions.ResourceAlreadyExistsException;
|
||||||
import google.registry.flows.host.HostCreateFlow.SubordinateHostMustHaveIpException;
|
import google.registry.flows.host.HostCreateFlow.SubordinateHostMustHaveIpException;
|
||||||
|
|
|
@ -45,7 +45,7 @@ public abstract class LoginFlowTestCase extends FlowTestCase<LoginFlow> {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void initRegistrar() {
|
public void initRegistrar() {
|
||||||
sessionMetadata.setClientId(null); // Don't implicitly log in (all other flows need to).
|
sessionMetadata.setClientId(null); // Don't implicitly log in (all other flows need to).
|
||||||
registrar = loadRegistrar("NewRegistrar");
|
registrar = loadRegistrar("NewRegistrar");
|
||||||
registrarBuilder = registrar.asBuilder();
|
registrarBuilder = registrar.asBuilder();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
import static google.registry.flows.EppXmlTransformer.marshalInput;
|
import static google.registry.model.eppcommon.EppXmlTransformer.marshalInput;
|
||||||
import static google.registry.xml.ValidationMode.STRICT;
|
import static google.registry.xml.ValidationMode.STRICT;
|
||||||
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
|
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
package google.registry.model.contact;
|
package google.registry.model.contact;
|
||||||
|
|
||||||
import static google.registry.flows.EppXmlTransformer.marshalInput;
|
import static google.registry.model.eppcommon.EppXmlTransformer.marshalInput;
|
||||||
import static google.registry.flows.EppXmlTransformer.validateInput;
|
import static google.registry.model.eppcommon.EppXmlTransformer.validateInput;
|
||||||
import static google.registry.xml.ValidationMode.LENIENT;
|
import static google.registry.xml.ValidationMode.LENIENT;
|
||||||
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
|
import static google.registry.xml.XmlTestUtils.assertXmlEquals;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
|
@ -12,11 +12,10 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
package google.registry.model.eppcommon;
|
||||||
package google.registry.flows;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.testing.JUnitBackports.assertThrows;
|
import static google.registry.testing.JUnitBackports.assertThrows;
|
||||||
import static google.registry.testing.TestDataHelper.loadBytes;
|
import static google.registry.testing.TestDataHelper.loadBytes;
|
||||||
|
|
||||||
|
@ -41,8 +40,6 @@ public class EppXmlTransformerTest extends ShardableTestCase {
|
||||||
public void testUnmarshalingWrongClassThrows() {
|
public void testUnmarshalingWrongClassThrows() {
|
||||||
assertThrows(
|
assertThrows(
|
||||||
ClassCastException.class,
|
ClassCastException.class,
|
||||||
() ->
|
() -> unmarshal(EppOutput.class, loadBytes(getClass(), "contact_info.xml").read()));
|
||||||
EppXmlTransformer.unmarshal(
|
|
||||||
EppOutput.class, loadBytes(getClass(), "contact_info.xml").read()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
14
javatests/google/registry/model/eppcommon/testdata/contact_info.xml
vendored
Normal file
14
javatests/google/registry/model/eppcommon/testdata/contact_info.xml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||||
|
<command>
|
||||||
|
<info>
|
||||||
|
<contact:info
|
||||||
|
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
|
||||||
|
<contact:id>sh8013</contact:id>
|
||||||
|
<contact:authInfo>
|
||||||
|
<contact:pw>2fooBAR</contact:pw>
|
||||||
|
</contact:authInfo>
|
||||||
|
</contact:info>
|
||||||
|
</info>
|
||||||
|
<clTRID>ABC-12345</clTRID>
|
||||||
|
</command>
|
||||||
|
</epp>
|
|
@ -16,15 +16,15 @@ package google.registry.model.eppinput;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.truth.Truth8.assertThat;
|
import static com.google.common.truth.Truth8.assertThat;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.testing.JUnitBackports.assertThrows;
|
import static google.registry.testing.JUnitBackports.assertThrows;
|
||||||
import static google.registry.testing.TestDataHelper.loadBytes;
|
import static google.registry.testing.TestDataHelper.loadBytes;
|
||||||
|
|
||||||
import google.registry.flows.EppException.SyntaxErrorException;
|
|
||||||
import google.registry.model.contact.ContactResourceTest;
|
import google.registry.model.contact.ContactResourceTest;
|
||||||
import google.registry.model.domain.DomainResourceTest;
|
import google.registry.model.domain.DomainResourceTest;
|
||||||
import google.registry.model.eppinput.EppInput.InnerCommand;
|
import google.registry.model.eppinput.EppInput.InnerCommand;
|
||||||
import google.registry.model.eppinput.EppInput.Login;
|
import google.registry.model.eppinput.EppInput.Login;
|
||||||
|
import google.registry.xml.XmlException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
@ -83,7 +83,7 @@ public class EppInputTest {
|
||||||
@Test
|
@Test
|
||||||
public void testUnmarshalling_loginTagInWrongCase_throws() {
|
public void testUnmarshalling_loginTagInWrongCase_throws() {
|
||||||
assertThrows(
|
assertThrows(
|
||||||
SyntaxErrorException.class,
|
XmlException.class,
|
||||||
() -> unmarshal(EppInput.class, loadBytes(getClass(), "login_wrong_case.xml").read()));
|
() -> unmarshal(EppInput.class, loadBytes(getClass(), "login_wrong_case.xml").read()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import google.registry.flows.EppXmlTransformer;
|
import google.registry.model.eppcommon.EppXmlTransformer;
|
||||||
import google.registry.model.eppcommon.StatusValue;
|
import google.registry.model.eppcommon.StatusValue;
|
||||||
import google.registry.model.eppinput.EppInput;
|
import google.registry.model.eppinput.EppInput;
|
||||||
import google.registry.model.eppinput.EppInput.ResourceCommandWrapper;
|
import google.registry.model.eppinput.EppInput.ResourceCommandWrapper;
|
||||||
|
|
|
@ -16,7 +16,7 @@ package google.registry.testing;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertAbout;
|
import static com.google.common.truth.Truth.assertAbout;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.EppXmlTransformer.marshal;
|
import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
|
||||||
|
|
||||||
import com.google.common.truth.FailureMetadata;
|
import com.google.common.truth.FailureMetadata;
|
||||||
import com.google.common.truth.SimpleSubjectBuilder;
|
import com.google.common.truth.SimpleSubjectBuilder;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
package google.registry.testing;
|
package google.registry.testing;
|
||||||
|
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.flows.FlowUtils.unmarshalEpp;
|
||||||
import static google.registry.testing.TestDataHelper.loadFile;
|
import static google.registry.testing.TestDataHelper.loadFile;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
|
@ -37,7 +37,12 @@ public class EppLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public EppInput getEpp() throws EppException {
|
public EppInput getEpp() throws EppException {
|
||||||
return unmarshal(EppInput.class, eppXml.getBytes(UTF_8));
|
/*
|
||||||
|
* TODO(b/120837374): we shouldn't use EppException in non-Flow tests. Find a way to use {@link
|
||||||
|
* google.registry.model.eppcommon.EppXmlTransformer#unmarshal(Class, byte[])} in those tests
|
||||||
|
* instead of {@link google.registry.flows.FlowUtils#unmarshalEpp(Class, byte[])}
|
||||||
|
*/
|
||||||
|
return unmarshalEpp(EppInput.class, eppXml.getBytes(UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEppXml() {
|
public String getEppXml() {
|
||||||
|
|
|
@ -16,12 +16,12 @@ package google.registry.tools;
|
||||||
|
|
||||||
import static com.google.common.io.BaseEncoding.base16;
|
import static com.google.common.io.BaseEncoding.base16;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
|
||||||
import static google.registry.flows.picker.FlowPicker.getFlowClass;
|
import static google.registry.flows.picker.FlowPicker.getFlowClass;
|
||||||
import static google.registry.model.domain.DesignatedContact.Type.ADMIN;
|
import static google.registry.model.domain.DesignatedContact.Type.ADMIN;
|
||||||
import static google.registry.model.domain.DesignatedContact.Type.BILLING;
|
import static google.registry.model.domain.DesignatedContact.Type.BILLING;
|
||||||
import static google.registry.model.domain.DesignatedContact.Type.TECH;
|
import static google.registry.model.domain.DesignatedContact.Type.TECH;
|
||||||
import static google.registry.model.domain.launch.ApplicationStatus.VALIDATED;
|
import static google.registry.model.domain.launch.ApplicationStatus.VALIDATED;
|
||||||
|
import static google.registry.model.eppcommon.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD;
|
import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.newDomainApplication;
|
import static google.registry.testing.DatastoreHelper.newDomainApplication;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue