mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
Add MR to expand billing events into OneTimes
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=124837292
This commit is contained in:
parent
7cf4ddce97
commit
2a83d122ef
6 changed files with 69 additions and 8 deletions
|
@ -265,6 +265,12 @@
|
|||
<url-pattern>/_dr/task/dnsRefreshForHostRename</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Mapreduce to expand recurring billing events into OneTimes. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/expandRecurringBillingEvents</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
|
|
|
@ -20,8 +20,6 @@ import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
|||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
|
@ -69,7 +67,12 @@ public class Cursor extends ImmutableObject {
|
|||
*/
|
||||
RDE_UPLOAD_SFTP(Registry.class),
|
||||
|
||||
/** Cursor for ensuring rolling transactional isolation of recurring billing expansion. */
|
||||
/**
|
||||
* Cursor for ensuring rolling transactional isolation of recurring billing expansion. The
|
||||
* value of this cursor represents the exclusive upper bound on the range of billing times
|
||||
* for which Recurring billing events have been expanded (i.e. the inclusive first billing time
|
||||
* for the next expansion job).
|
||||
*/
|
||||
RECURRING_BILLING(EntityGroupRoot.class);
|
||||
|
||||
/** See the definition of scope on {@link #getScopeClass}. */
|
||||
|
@ -120,16 +123,14 @@ public class Cursor extends ImmutableObject {
|
|||
}
|
||||
|
||||
/** Creates a unique key for a given scope and cursor type. */
|
||||
@VisibleForTesting
|
||||
static Key<Cursor> createKey(CursorType cursorType, ImmutableObject scope) {
|
||||
public static Key<Cursor> createKey(CursorType cursorType, ImmutableObject scope) {
|
||||
Key<? extends ImmutableObject> scopeKey = Key.create(scope);
|
||||
checkValidCursorTypeForScope(cursorType, scopeKey);
|
||||
return Key.create(getCrossTldKey(), Cursor.class, generateId(cursorType, scopeKey));
|
||||
}
|
||||
|
||||
/** Creates a unique key for a given global cursor type. */
|
||||
@VisibleForTesting
|
||||
static Key<Cursor> createGlobalKey(CursorType cursorType) {
|
||||
public static Key<Cursor> createGlobalKey(CursorType cursorType) {
|
||||
checkArgument(
|
||||
cursorType.getScopeClass().equals(EntityGroupRoot.class),
|
||||
"Cursor type is not a global cursor.");
|
||||
|
|
|
@ -14,11 +14,11 @@ java_library(
|
|||
"//java/com/google/common/net",
|
||||
"//java/google/registry/backup",
|
||||
"//java/google/registry/bigquery",
|
||||
"//java/google/registry/billing",
|
||||
"//java/google/registry/config",
|
||||
"//java/google/registry/cron",
|
||||
"//java/google/registry/dns",
|
||||
"//java/google/registry/dns/writer/api",
|
||||
"//java/google/registry/dns/writer/dnsupdate",
|
||||
"//java/google/registry/export",
|
||||
"//java/google/registry/export/sheet",
|
||||
"//java/google/registry/flows",
|
||||
|
@ -35,6 +35,7 @@ java_library(
|
|||
"//java/google/registry/util",
|
||||
"//third_party/java/bouncycastle",
|
||||
"//third_party/java/dagger",
|
||||
"//third_party/java/joda_time",
|
||||
"//third_party/java/jsr305_annotations",
|
||||
"//third_party/java/jsr330_inject",
|
||||
"//third_party/java/servlet/servlet_api",
|
||||
|
|
|
@ -15,14 +15,20 @@
|
|||
package google.registry.module.backend;
|
||||
|
||||
import static google.registry.model.registry.Registries.assertTldExists;
|
||||
import static google.registry.request.RequestParameters.extractOptionalDatetimeParameter;
|
||||
import static google.registry.request.RequestParameters.extractRequiredParameter;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
import google.registry.billing.ExpandRecurringBillingEventsAction;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.RequestParameters;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
|
@ -36,4 +42,11 @@ public class BackendModule {
|
|||
static String provideTld(HttpServletRequest req) {
|
||||
return assertTldExists(extractRequiredParameter(req, RequestParameters.PARAM_TLD));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("cursorTime")
|
||||
static Optional<DateTime> provideCursorTime(HttpServletRequest req) {
|
||||
return extractOptionalDatetimeParameter(
|
||||
req, ExpandRecurringBillingEventsAction.PARAM_CURSOR_TIME);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,6 +160,25 @@ public final class RequestParameters {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first request parameter associated with {@code name} parsed as an
|
||||
* <a href="https://goo.gl/pk5Q2k">ISO 8601</a> timestamp, e.g. {@code 1984-12-18TZ},
|
||||
* {@code 2000-01-01T16:20:00Z}.
|
||||
*
|
||||
* @throws BadRequestException if request parameter is present but not a valid {@link DateTime}.
|
||||
*/
|
||||
public static Optional<DateTime> extractOptionalDatetimeParameter(
|
||||
HttpServletRequest req, String name) {
|
||||
String stringParam = req.getParameter(name);
|
||||
try {
|
||||
return isNullOrEmpty(stringParam)
|
||||
? Optional.<DateTime>absent()
|
||||
: Optional.of(DateTime.parse(stringParam));
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new BadRequestException("Bad ISO 8601 timestamp: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first request parameter associated with {@code name} parsed as an optional
|
||||
* {@link InetAddress} (which might be IPv6).
|
||||
|
|
|
@ -17,6 +17,7 @@ package google.registry.request;
|
|||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.request.RequestParameters.extractBooleanParameter;
|
||||
import static google.registry.request.RequestParameters.extractEnumParameter;
|
||||
import static google.registry.request.RequestParameters.extractOptionalDatetimeParameter;
|
||||
import static google.registry.request.RequestParameters.extractOptionalParameter;
|
||||
import static google.registry.request.RequestParameters.extractRequiredDatetimeParameter;
|
||||
import static google.registry.request.RequestParameters.extractRequiredMaybeEmptyParameter;
|
||||
|
@ -184,6 +185,26 @@ public class RequestParametersTest {
|
|||
extractRequiredDatetimeParameter(req, "timeParam");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractOptionalDatetimeParameter_correctValue_works() throws Exception {
|
||||
when(req.getParameter("timeParam")).thenReturn("2015-08-27T13:25:34.123Z");
|
||||
assertThat(extractOptionalDatetimeParameter(req, "timeParam"))
|
||||
.hasValue(DateTime.parse("2015-08-27T13:25:34.123Z"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractOptionalDatetimeParameter_badValue_throwsBadRequest() throws Exception {
|
||||
when(req.getParameter("timeParam")).thenReturn("Tuesday at three o'clock");
|
||||
thrown.expect(BadRequestException.class, "timeParam");
|
||||
extractOptionalDatetimeParameter(req, "timeParam");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractOptionalDatetimeParameter_empty_returnsAbsent() throws Exception {
|
||||
when(req.getParameter("timeParam")).thenReturn("");
|
||||
assertThat(extractOptionalDatetimeParameter(req, "timeParam")).isAbsent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractRequiredDatetimeParameter_noValue_throwsBadRequest() throws Exception {
|
||||
thrown.expect(BadRequestException.class, "timeParam");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue