nl.topicus.jdbc.shaded.com.google.cloud.spanner.Operation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spanner-jdbc Show documentation
Show all versions of spanner-jdbc Show documentation
JDBC Driver for Google Cloud Spanner
/*
* Copyright 2017 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in nl.topicus.jdbc.shaded.com.liance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.nl.topicus.jdbc.shaded.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 nl.topicus.jdbc.shaded.com.google.cloud.spanner;
import nl.topicus.jdbc.shaded.com.google.api.core.ApiClock;
import nl.topicus.jdbc.shaded.com.google.api.core.CurrentMillisClock;
import nl.topicus.jdbc.shaded.com.google.cloud.WaitForOption;
import nl.topicus.jdbc.shaded.com.google.cloud.WaitForOption.CheckingPeriod;
import nl.topicus.jdbc.shaded.com.google.cloud.WaitForOption.Timeout;
import nl.topicus.jdbc.shaded.com.google.cloud.spanner.spi.v1.SpannerRpc;
import nl.topicus.jdbc.shaded.com.google.nl.topicus.jdbc.shaded.com.on.annotations.VisibleForTesting;
import nl.topicus.jdbc.shaded.com.google.longrunning.Operation.ResultCase;
import nl.topicus.jdbc.shaded.com.google.protobuf.Any;
import nl.topicus.jdbc.shaded.com.google.rpc.Status;
import nl.topicus.jdbc.shaded.javax.annotation.Nullable;
/** Represents a long running operation. */
// TODO(user): Implement other operations on Operation.
public class Operation {
static interface Parser {
R parseResult(Any response);
M parseMetadata(Any metadata);
}
private final M metadata;
private final R result;
private final SpannerException exception;
private final boolean isDone;
private final SpannerRpc rpc;
private final String name;
private final Parser parser;
private final ApiClock clock;
@VisibleForTesting
Operation(
SpannerRpc rpc,
String name,
@Nullable M metadata,
@Nullable R result,
@Nullable SpannerException exception,
boolean isDone,
Parser parser,
ApiClock clock) {
this.rpc = rpc;
this.name = name;
this.metadata = metadata;
this.result = result;
this.exception = exception;
this.isDone = isDone;
this.parser = parser;
this.clock = clock;
}
private static Operation failed(
SpannerRpc rpc, String name, Status status, M metadata, Parser parser, ApiClock clock) {
SpannerException e =
SpannerExceptionFactory.newSpannerException(
ErrorCode.fromRpcStatus(status), status.getMessage(), null);
return new Operation(rpc, name, metadata, null, e, true, parser, clock);
}
private static Operation successful(
SpannerRpc rpc, String name, M metadata, R result, Parser parser, ApiClock clock) {
return new Operation<>(rpc, name, metadata, result, null, true, parser, clock);
}
private static Operation pending(
SpannerRpc rpc, String name, M metadata, Parser parser, ApiClock clock) {
return new Operation<>(rpc, name, metadata, null, null, false, parser, clock);
}
static Operation create(
SpannerRpc rpc, nl.topicus.jdbc.shaded.com.google.longrunning.Operation proto, Parser parser) {
return Operation.create(rpc, proto, parser, CurrentMillisClock.getDefaultClock());
}
static Operation create(
SpannerRpc rpc, nl.topicus.jdbc.shaded.com.google.longrunning.Operation proto, Parser parser, ApiClock clock) {
M metadata = proto.hasMetadata() ? parser.parseMetadata(proto.getMetadata()) : null;
String name = proto.getName();
if (proto.getDone()) {
if (proto.getResultCase() == ResultCase.ERROR) {
return Operation.failed(rpc, name, proto.getError(), metadata, parser, clock);
} else {
return Operation.successful(
rpc, name, metadata, parser.parseResult(proto.getResponse()), parser, clock);
}
} else {
return Operation.pending(rpc, name, metadata, parser, clock);
}
}
/** Fetches the current status of this operation. */
public Operation reload() throws SpannerException {
if (isDone) {
return this;
}
nl.topicus.jdbc.shaded.com.google.longrunning.Operation proto = rpc.getOperation(name);
return Operation.create(rpc, proto, parser);
}
/**
* Blocks till the operation is nl.topicus.jdbc.shaded.com.lete or maximum time, if specified, has elapsed.
*
* @return null if operation is not found otherwise the current operation.
*/
public Operation waitFor(WaitForOption... options) throws SpannerException {
if (isDone) {
return this;
}
long timeoutMillis = Timeout.getOrDefault(options).getTimeoutMillis();
boolean hasTimeout = timeoutMillis != -1;
CheckingPeriod period = CheckingPeriod.getOrDefault(options);
long startMillis = clock.millisTime();
while (true) {
try {
nl.topicus.jdbc.shaded.com.google.longrunning.Operation proto = rpc.getOperation(name);
if (proto.getDone()) {
return Operation.create(rpc, proto, parser);
}
long elapsed = clock.millisTime() - startMillis;
if (hasTimeout && elapsed >= timeoutMillis) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.DEADLINE_EXCEEDED, "Operation did not nl.topicus.jdbc.shaded.com.lete in the given time");
}
} catch (SpannerException e) {
if (e.getErrorCode() == ErrorCode.NOT_FOUND) {
return null;
}
if (!e.isRetryable()) {
throw e;
}
}
try {
period.getUnit().sleep(period.getPeriod());
} catch (InterruptedException e) {
throw SpannerExceptionFactory.propagateInterrupt(e);
}
}
}
/**
* Returns the metadata returned by the last refersh of this operation. Returns null if no
* metadata was returned or if this operation has not been refereshed.
*/
public M getMetadata() {
return metadata;
}
/** Returns true if the operation is done. */
public boolean isDone() {
return isDone;
}
/**
* Returns result of the operation if the operation is nl.topicus.jdbc.shaded.com.lete and had a result. Returns null if
* the operation is not nl.topicus.jdbc.shaded.com.lete or did not have a result.
*
* @throws SpannerException if the operation failed.
*/
public R getResult() throws SpannerException {
if (exception != null) {
throw exception;
}
return result;
}
/** Returns the name of the operation. */
public String getName() {
return name;
}
/** Returns true if the operation nl.topicus.jdbc.shaded.com.leted sucessfully. */
public boolean isSuccessful() {
return isDone && exception == null;
}
}