// Copyright 2018 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.batch; import static google.registry.flows.async.AsyncFlowEnqueuer.PARAM_REQUESTED_TIME; import static google.registry.flows.async.AsyncFlowEnqueuer.PARAM_RESAVE_TIMES; import static google.registry.flows.async.AsyncFlowEnqueuer.PARAM_RESOURCE_KEY; import static google.registry.model.ofy.ObjectifyService.ofy; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.flogger.FluentLogger; import com.googlecode.objectify.Key; import google.registry.flows.async.AsyncFlowEnqueuer; import google.registry.model.EppResource; import google.registry.model.ImmutableObject; import google.registry.request.Action; import google.registry.request.Action.Method; import google.registry.request.Parameter; import google.registry.request.Response; import google.registry.request.auth.Auth; import javax.inject.Inject; import org.joda.time.DateTime; /** * An action that re-saves a given entity, typically after a certain amount of time has passed. * *

{@link EppResource}s will be projected forward to the current time. */ @Action(path = "/_dr/task/resaveEntity", auth = Auth.AUTH_INTERNAL_OR_ADMIN, method = Method.POST) public class ResaveEntityAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private final Key resourceKey; private final DateTime requestedTime; private final ImmutableSortedSet resaveTimes; private final AsyncFlowEnqueuer asyncFlowEnqueuer; private final Response response; @Inject ResaveEntityAction( @Parameter(PARAM_RESOURCE_KEY) Key resourceKey, @Parameter(PARAM_REQUESTED_TIME) DateTime requestedTime, @Parameter(PARAM_RESAVE_TIMES) ImmutableSet resaveTimes, AsyncFlowEnqueuer asyncFlowEnqueuer, Response response) { this.resourceKey = resourceKey; this.requestedTime = requestedTime; this.resaveTimes = ImmutableSortedSet.copyOf(resaveTimes); this.asyncFlowEnqueuer = asyncFlowEnqueuer; this.response = response; } @Override public void run() { logger.atInfo().log( "Re-saving entity %s which was enqueued at %s.", resourceKey, requestedTime); ofy().transact(() -> { ImmutableObject entity = ofy().load().key(resourceKey).now(); ofy().save().entity( (entity instanceof EppResource) ? ((EppResource) entity).cloneProjectedAtTime(ofy().getTransactionTime()) : entity ); if (!resaveTimes.isEmpty()) { asyncFlowEnqueuer.enqueueAsyncResave(entity, requestedTime, resaveTimes); } }); response.setPayload("Entity re-saved."); } }