mirror of
https://github.com/google/nomulus.git
synced 2025-05-02 21:17:50 +02:00
These are needed by Datastore export management actions. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=224242281
218 lines
6.4 KiB
Java
218 lines
6.4 KiB
Java
// 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.export.datastore;
|
|
|
|
import static com.google.common.base.Preconditions.checkState;
|
|
|
|
import com.google.api.client.json.GenericJson;
|
|
import com.google.api.client.util.Key;
|
|
import com.google.common.base.Strings;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import google.registry.export.datastore.DatastoreAdmin.Get;
|
|
import google.registry.util.Clock;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import javax.annotation.Nullable;
|
|
import org.joda.time.DateTime;
|
|
import org.joda.time.Duration;
|
|
|
|
/**
|
|
* Model object that describes the details of an export or import operation in Cloud Datastore.
|
|
*
|
|
* <p>{@link Operation} instances are parsed from the JSON payload in Datastore response messages.
|
|
*/
|
|
public class Operation extends GenericJson {
|
|
|
|
private static final String STATE_SUCCESS = "SUCCESSFUL";
|
|
private static final String STATE_PROCESSING = "PROCESSING";
|
|
|
|
@Key private String name;
|
|
@Key private Metadata metadata;
|
|
@Key private boolean done;
|
|
|
|
/** For JSON deserialization. */
|
|
public Operation() {}
|
|
|
|
/** Returns the name of this operation, which may be used in a {@link Get} request. */
|
|
public String getName() {
|
|
checkState(name != null, "Name must not be null.");
|
|
return name;
|
|
}
|
|
|
|
public boolean isDone() {
|
|
return done;
|
|
}
|
|
|
|
private String getState() {
|
|
return getMetadata().getCommonMetadata().getState();
|
|
}
|
|
|
|
public boolean isSuccessful() {
|
|
return getState().equals(STATE_SUCCESS);
|
|
}
|
|
|
|
public boolean isProcessing() {
|
|
return getState().equals(STATE_PROCESSING);
|
|
}
|
|
|
|
public Duration getRunningTime(Clock clock) {
|
|
return new Duration(
|
|
getStartTime(), getMetadata().getCommonMetadata().getEndTime().orElse(clock.nowUtc()));
|
|
}
|
|
|
|
public DateTime getStartTime() {
|
|
return getMetadata().getCommonMetadata().getStartTime();
|
|
}
|
|
|
|
public ImmutableSet<String> getKinds() {
|
|
return ImmutableSet.copyOf(getMetadata().getEntityFilter().getKinds());
|
|
}
|
|
|
|
/**
|
|
* Returns the URL to the GCS folder that holds the exported data. This folder is created by
|
|
* Datastore and is under the {@code outputUrlPrefix} set to {@linkplain
|
|
* DatastoreAdmin#export(String, List) the export request}.
|
|
*/
|
|
public String getExportFolderUrl() {
|
|
return getMetadata().getOutputUrlPrefix();
|
|
}
|
|
|
|
/**
|
|
* Returns the last segment of the {@linkplain #getExportFolderUrl() export folder URL} which can
|
|
* be used as unique identifier of this export operation. This is a better ID than the {@linkplain
|
|
* #getName() operation name}, which is opaque.
|
|
*/
|
|
public String getExportId() {
|
|
String exportFolderUrl = getExportFolderUrl();
|
|
return exportFolderUrl.substring(exportFolderUrl.lastIndexOf('/') + 1);
|
|
}
|
|
|
|
public String getProgress() {
|
|
StringBuilder result = new StringBuilder();
|
|
Progress progress = getMetadata().getProgressBytes();
|
|
if (progress != null) {
|
|
result.append(
|
|
String.format(" [%s/%s bytes]", progress.workCompleted, progress.workEstimated));
|
|
}
|
|
progress = getMetadata().getProgressEntities();
|
|
if (progress != null) {
|
|
result.append(
|
|
String.format(" [%s/%s entities]", progress.workCompleted, progress.workEstimated));
|
|
}
|
|
if (result.length() == 0) {
|
|
return "Progress: N/A";
|
|
}
|
|
return "Progress:" + result;
|
|
}
|
|
|
|
private Metadata getMetadata() {
|
|
checkState(metadata != null, "Response metadata missing.");
|
|
return metadata;
|
|
}
|
|
|
|
/** Models the common metadata properties of all operations. */
|
|
public static class CommonMetadata extends GenericJson {
|
|
|
|
@Key private String startTime;
|
|
@Key @Nullable private String endTime;
|
|
@Key private String operationType;
|
|
@Key private String state;
|
|
|
|
public CommonMetadata() {}
|
|
|
|
String getOperationType() {
|
|
checkState(!Strings.isNullOrEmpty(operationType), "operationType may not be null or empty");
|
|
return operationType;
|
|
}
|
|
|
|
String getState() {
|
|
checkState(!Strings.isNullOrEmpty(state), "state may not be null or empty");
|
|
return state;
|
|
}
|
|
|
|
DateTime getStartTime() {
|
|
checkState(startTime != null, "StartTime missing.");
|
|
return DateTime.parse(startTime);
|
|
}
|
|
|
|
Optional<DateTime> getEndTime() {
|
|
return Optional.ofNullable(endTime).map(DateTime::parse);
|
|
}
|
|
}
|
|
|
|
/** Models the metadata of a Cloud Datatore export or import operation. */
|
|
public static class Metadata extends GenericJson {
|
|
@Key("common")
|
|
private CommonMetadata commonMetadata;
|
|
|
|
@Key private Progress progressEntities;
|
|
@Key private Progress progressBytes;
|
|
@Key private EntityFilter entityFilter;
|
|
@Key private String outputUrlPrefix;
|
|
|
|
public Metadata() {}
|
|
|
|
CommonMetadata getCommonMetadata() {
|
|
checkState(commonMetadata != null, "CommonMetadata field is null.");
|
|
return commonMetadata;
|
|
}
|
|
|
|
public Progress getProgressEntities() {
|
|
return progressEntities;
|
|
}
|
|
|
|
public Progress getProgressBytes() {
|
|
return progressBytes;
|
|
}
|
|
|
|
public EntityFilter getEntityFilter() {
|
|
return entityFilter;
|
|
}
|
|
|
|
public String getOutputUrlPrefix() {
|
|
checkState(!Strings.isNullOrEmpty(outputUrlPrefix), "outputUrlPrefix");
|
|
return outputUrlPrefix;
|
|
}
|
|
}
|
|
|
|
/** Progress of an export or import operation. */
|
|
public static class Progress extends GenericJson {
|
|
@Key private long workCompleted;
|
|
@Key private long workEstimated;
|
|
|
|
public Progress() {}
|
|
|
|
long getWorkCompleted() {
|
|
return workCompleted;
|
|
}
|
|
|
|
public long getWorkEstimated() {
|
|
return workEstimated;
|
|
}
|
|
}
|
|
|
|
/** List of {@link Operation Operations}. */
|
|
public static class OperationList extends GenericJson {
|
|
@Key private List<Operation> operations;
|
|
|
|
/** For JSON deserialization. */
|
|
public OperationList() {}
|
|
|
|
ImmutableList<Operation> toList() {
|
|
return ImmutableList.copyOf(operations);
|
|
}
|
|
}
|
|
}
|