@Override public OperationFuture<Empty, UpdateDatabaseDdlMetadata> updateDatabaseDdl( String databaseName, Iterable<String> updateDatabaseStatements, @Nullable String updateId) throws SpannerException { UpdateDatabaseDdlRequest request = UpdateDatabaseDdlRequest.newBuilder() .setDatabase(databaseName) .addAllStatements(updateDatabaseStatements) .setOperationId(MoreObjects.firstNonNull(updateId, "")) .build(); GrpcCallContext context = newCallContext(null, databaseName); OperationCallable<UpdateDatabaseDdlRequest, Empty, UpdateDatabaseDdlMetadata> callable = databaseAdminStub.updateDatabaseDdlOperationCallable(); OperationFuture<Empty, UpdateDatabaseDdlMetadata> operationFuture = callable.futureCall(request, context); try { operationFuture.getInitialFuture().get(); } catch (InterruptedException e) { throw newSpannerException(e); } catch (ExecutionException e) { Throwable t = e.getCause(); if (t instanceof AlreadyExistsException) { String operationName = OPERATION_NAME_TEMPLATE.instantiate("database", databaseName, "operation", updateId); return callable.resumeFutureCall(operationName, context); } } return operationFuture; }
/** * Creates a new {@link OperationFuture} to watch an operation that has been initiated previously. * Note: This is not type-safe at static time; the result type can only be checked once the * operation finishes. * * @param operationName The name of the operation to resume. * @return {@link OperationFuture} for the call result. */ public OperationFuture<ResponseT, MetadataT> resumeFutureCall(String operationName) { return resumeFutureCall(operationName, null); }
/** * Creates a new {@link OperationFuture} to watch an operation that has been initiated previously. * Note: This is not type-safe at static time; the result type can only be checked once the * operation finishes. * * @param operationName The name of the operation to resume. * @return {@link OperationFuture} for the call result. */ public OperationFuture<ResponseT, MetadataT> resumeFutureCall(String operationName) { return resumeFutureCall(operationName, null); }
@Override public OperationFuture<ResponseT, MetadataT> resumeFutureCall( String operationName, ApiCallContext thisCallContext) { return OperationCallable.this.resumeFutureCall( operationName, defaultCallContext.merge(thisCallContext)); }
@Override public OperationFuture<ResponseT, MetadataT> resumeFutureCall( String operationName, ApiCallContext thisCallContext) { return OperationCallable.this.resumeFutureCall( operationName, defaultCallContext.merge(thisCallContext)); }
@Override public OperationFuture<Empty, UpdateDatabaseDdlMetadata> updateDatabaseDdl( String databaseName, Iterable<String> updateDatabaseStatements, @Nullable String updateId) throws SpannerException { UpdateDatabaseDdlRequest request = UpdateDatabaseDdlRequest.newBuilder() .setDatabase(databaseName) .addAllStatements(updateDatabaseStatements) .setOperationId(MoreObjects.firstNonNull(updateId, "")) .build(); GrpcCallContext context = newCallContext(null, databaseName); OperationCallable<UpdateDatabaseDdlRequest, Empty, UpdateDatabaseDdlMetadata> callable = databaseAdminStub.updateDatabaseDdlOperationCallable(); OperationFuture<Empty, UpdateDatabaseDdlMetadata> operationFuture = callable.futureCall(request, context); try { operationFuture.getInitialFuture().get(); } catch (InterruptedException e) { throw newSpannerException(e); } catch (ExecutionException e) { Throwable t = e.getCause(); if (t instanceof AlreadyExistsException) { String operationName = OPERATION_NAME_TEMPLATE.instantiate("database", databaseName, "operation", updateId); return callable.resumeFutureCall(operationName, context); } } return operationFuture; }
@Test public void callResume() throws Exception { ApiCallContext defaultCallContext = FakeCallContext.createDefault(); OperationStashCallable stashCallable = new OperationStashCallable(); OperationCallable<Integer, String, Long> callable = stashCallable.withDefaultCallContext(defaultCallContext); OperationFuture<String, Long> operationFuture = callable.futureCall(45); String response = callable.resumeFutureCall(operationFuture.getName()).get(); Truth.assertThat(response).isEqualTo("45"); Truth.assertThat(stashCallable.getResumeContext()).isSameAs(defaultCallContext); }
@Test public void testResumeFutureCall() throws Exception { String opName = "testResumeFutureCall"; Color resp = getColor(0.5f); Currency meta = Currency.getInstance("UAH"); OperationSnapshot resultOperation = getOperation(opName, resp, null, meta, true); LongRunningClient longRunningClient = mockGetOperation(StatusCode.Code.OK, resultOperation); ClientContext mockContext = getClientContext(new FakeChannel(), executor); OperationCallable<Integer, Color, Currency> callable = FakeCallableFactory.createOperationCallable( getUnexpectedStartCallable(), callSettings, mockContext, longRunningClient); OperationFuture<Color, Currency> future = callable.resumeFutureCall(opName); assertFutureSuccessMetaSuccess(opName, future, resp, meta); assertThat(executor.getIterationsCount()).isEqualTo(0); }
@Test public void callResumeWithContext() throws Exception { FakeChannel channel = new FakeChannel(); Credentials credentials = Mockito.mock(Credentials.class); ApiCallContext context = FakeCallContext.createDefault().withChannel(channel).withCredentials(credentials); OperationStashCallable stashCallable = new OperationStashCallable(); OperationCallable<Integer, String, Long> callable = stashCallable.withDefaultCallContext(FakeCallContext.createDefault()); OperationFuture<String, Long> operationFuture = callable.futureCall(45); String response = callable.resumeFutureCall(operationFuture.getName(), context).get(); Truth.assertThat(response).isEqualTo("45"); FakeCallContext actualContext = (FakeCallContext) stashCallable.getResumeContext(); Truth.assertThat(actualContext.getChannel()).isSameAs(channel); Truth.assertThat(actualContext.getCredentials()).isSameAs(credentials); }