use of com.google.firestore.v1.Document.Builder in project beam by apache.
the class BaseFirestoreV1WriteFnTest method endToEnd_deadlineExceededOnAnIndividualWriteResultsInThrottling.
@Test
public final void endToEnd_deadlineExceededOnAnIndividualWriteResultsInThrottling() throws Exception {
final long totalDocCount = 1_000_000;
final int numWorkers = 100;
final long docCount = totalDocCount / numWorkers;
LOG.info("docCount = {}", docCount);
RpcQosOptions options = rpcQosOptions.toBuilder().withHintMaxNumWorkers(numWorkers).withSamplePeriod(Duration.standardMinutes(10)).withReportDiagnosticMetrics().build();
LOG.debug("options = {}", options);
FirestoreStatefulComponentFactory ff = mock(FirestoreStatefulComponentFactory.class);
when(ff.getFirestoreStub(any())).thenReturn(stub);
Random random = new Random(12345);
TestClock clock = new TestClock(Instant.EPOCH, Duration.standardSeconds(1));
Sleeper sleeper = millis -> clock.setNext(advanceClockBy(Duration.millis(millis)));
RpcQosImpl qos = new RpcQosImpl(options, random, sleeper, metricsFixture.counterFactory, metricsFixture.distributionFactory);
RpcQos qosSpy = mock(RpcQos.class, invocation -> {
Method method = invocation.getMethod();
LOG.debug("method = {}", method);
Method actualMethod = qos.getClass().getMethod(method.getName(), method.getParameterTypes());
return actualMethod.invoke(qos, invocation.getArguments());
});
when(ff.getRpcQos(options)).thenReturn(qosSpy);
int defaultDocumentWriteLatency = 30;
final AtomicLong writeCounter = new AtomicLong();
when(processContext.element()).thenAnswer(invocation -> newWrite(writeCounter.getAndIncrement()));
when(callable.call(any())).thenAnswer(new Answer<BatchWriteResponse>() {
private final Random rand = new Random(84572908);
private final Instant threshold = Instant.ofEpochMilli(Duration.standardMinutes(20).getMillis());
@Override
public BatchWriteResponse answer(InvocationOnMock invocation) throws Throwable {
BatchWriteRequest request = invocation.getArgument(0, BatchWriteRequest.class);
LOG.debug("request = {}", request);
long requestDurationMs = 0;
BatchWriteResponse.Builder builder = BatchWriteResponse.newBuilder();
for (Write ignored : request.getWritesList()) {
builder.addWriteResults(WriteResult.newBuilder().build());
if (clock.prev.isBefore(threshold)) {
requestDurationMs += defaultDocumentWriteLatency;
builder.addStatus(STATUS_OK);
} else {
int latency = rand.nextInt(1500);
LOG.debug("latency = {}", latency);
if (latency > 300) {
builder.addStatus(STATUS_DEADLINE_EXCEEDED);
} else {
builder.addStatus(STATUS_OK);
}
requestDurationMs += latency;
}
}
clock.setNext(advanceClockBy(Duration.millis(requestDurationMs)));
return builder.build();
}
});
LOG.info("### parameters: {defaultDocumentWriteLatency: {}, rpcQosOptions: {}}", defaultDocumentWriteLatency, options);
FnT fn = getFn(clock, ff, options, metricsFixture.counterFactory, metricsFixture.distributionFactory);
fn.setup();
fn.startBundle(startBundleContext);
while (writeCounter.get() < docCount) {
fn.processElement(processContext, window);
}
fn.finishBundle(finishBundleContext);
LOG.info("writeCounter = {}", writeCounter.get());
LOG.info("clock.prev = {}", clock.prev);
MyDistribution qosAdaptiveThrottlerThrottlingMs = metricsFixture.distributions.get("qos_adaptiveThrottler_throttlingMs");
assertNotNull(qosAdaptiveThrottlerThrottlingMs);
List<Long> updateInvocations = qosAdaptiveThrottlerThrottlingMs.updateInvocations;
assertFalse(updateInvocations.isEmpty());
}
use of com.google.firestore.v1.Document.Builder in project spring-cloud-gcp by spring-cloud.
the class PartTreeFirestoreQuery method createBuilderWithFilter.
private StructuredQuery.Builder createBuilderWithFilter(Object[] parameters) {
StructuredQuery.Builder builder = StructuredQuery.newBuilder();
Iterator it = Arrays.asList(parameters).iterator();
StructuredQuery.CompositeFilter.Builder compositeFilter = StructuredQuery.CompositeFilter.newBuilder();
compositeFilter.setOp(StructuredQuery.CompositeFilter.Operator.AND);
this.tree.getParts().forEach(part -> {
StructuredQuery.FieldReference fieldReference = StructuredQuery.FieldReference.newBuilder().setFieldPath(buildName(part)).build();
StructuredQuery.Filter.Builder filter = StructuredQuery.Filter.newBuilder();
if (part.getType() == Part.Type.IS_NULL) {
filter.getUnaryFilterBuilder().setField(fieldReference).setOp(StructuredQuery.UnaryFilter.Operator.IS_NULL);
} else {
if (!it.hasNext()) {
throw new FirestoreDataException("Too few parameters are provided for query method: " + getQueryMethod().getName());
}
Object value = it.next();
filter.getFieldFilterBuilder().setField(fieldReference).setOp(getOperator(part, value)).setValue(this.classMapper.toFirestoreValue(value));
}
compositeFilter.addFilters(filter.build());
});
builder.setWhere(StructuredQuery.Filter.newBuilder().setCompositeFilter(compositeFilter.build()));
return builder;
}
use of com.google.firestore.v1.Document.Builder in project spring-cloud-gcp by spring-cloud.
the class PartTreeFirestoreQuery method execute.
@Override
public Object execute(Object[] parameters) {
StructuredQuery.Builder builder = createBuilderWithFilter(parameters);
// Handle Pageable parameters.
if (!getQueryMethod().getParameters().isEmpty()) {
ParameterAccessor paramAccessor = new ParametersParameterAccessor(getQueryMethod().getParameters(), parameters);
Pageable pageable = paramAccessor.getPageable();
if (pageable != null && pageable.isPaged()) {
builder.setOffset((int) Math.min(Integer.MAX_VALUE, pageable.getOffset()));
builder.setLimit(Int32Value.newBuilder().setValue(pageable.getPageSize()));
}
Sort sort = paramAccessor.getSort();
if (sort != null) {
builder.addAllOrderBy(createFirestoreSortOrders(sort));
}
}
if (this.tree.isCountProjection()) {
return this.reactiveOperations.count(this.persistentEntity.getType(), builder);
} else {
return this.reactiveOperations.execute(builder, this.persistentEntity.getType());
}
}
use of com.google.firestore.v1.Document.Builder in project spring-cloud-gcp by spring-cloud.
the class FirestoreTemplate method createUpdateWrite.
private <T> Write createUpdateWrite(T entity) {
Builder builder = Write.newBuilder();
if (getIdValue(entity) == null) {
builder.setCurrentDocument(Precondition.newBuilder().setExists(false).build());
}
String resourceName = buildResourceName(entity);
Document document = getClassMapper().entityToDocument(entity, resourceName);
return builder.setUpdate(document).build();
}
use of com.google.firestore.v1.Document.Builder in project beam by apache.
the class BaseFirestoreV1WriteFnTest method endToEnd_maxBatchSizeRespected.
@Test
public final void endToEnd_maxBatchSizeRespected() throws Exception {
Instant enqueue0 = Instant.ofEpochMilli(0);
Instant enqueue1 = Instant.ofEpochMilli(1);
Instant enqueue2 = Instant.ofEpochMilli(2);
Instant enqueue3 = Instant.ofEpochMilli(3);
Instant enqueue4 = Instant.ofEpochMilli(4);
Instant group1Rpc1Start = Instant.ofEpochMilli(5);
Instant group1Rpc1End = Instant.ofEpochMilli(6);
Instant enqueue5 = Instant.ofEpochMilli(7);
Instant finalFlush = Instant.ofEpochMilli(8);
Instant group2Rpc1Start = Instant.ofEpochMilli(9);
Instant group2Rpc1End = Instant.ofEpochMilli(10);
Write write0 = newWrite(0);
Write write1 = newWrite(1);
Write write2 = newWrite(2);
Write write3 = newWrite(3);
Write write4 = newWrite(4);
Write write5 = newWrite(5);
int maxValuesPerGroup = 5;
BatchWriteRequest.Builder builder = BatchWriteRequest.newBuilder().setDatabase("projects/testing-project/databases/(default)");
BatchWriteRequest expectedGroup1Request = builder.build().toBuilder().addWrites(write0).addWrites(write1).addWrites(write2).addWrites(write3).addWrites(write4).build();
BatchWriteRequest expectedGroup2Request = builder.build().toBuilder().addWrites(write5).build();
BatchWriteResponse group1Response = BatchWriteResponse.newBuilder().addStatus(STATUS_OK).addStatus(STATUS_OK).addStatus(STATUS_OK).addStatus(STATUS_OK).addStatus(STATUS_OK).build();
BatchWriteResponse group2Response = BatchWriteResponse.newBuilder().addStatus(STATUS_OK).build();
RpcQosOptions options = rpcQosOptions.toBuilder().withBatchMaxCount(maxValuesPerGroup).build();
FlushBuffer<Element<Write>> flushBuffer = spy(newFlushBuffer(options));
FlushBuffer<Element<Write>> flushBuffer2 = spy(newFlushBuffer(options));
when(processContext.element()).thenReturn(write0, write1, write2, write3, write4, write5);
when(rpcQos.newWriteAttempt(any())).thenReturn(attempt, attempt, attempt, attempt, attempt, attempt2, attempt2, attempt2).thenThrow(new IllegalStateException("too many attempts"));
when(attempt.awaitSafeToProceed(any())).thenReturn(true);
when(attempt2.awaitSafeToProceed(any())).thenReturn(true);
when(attempt.<Write, Element<Write>>newFlushBuffer(enqueue0)).thenReturn(newFlushBuffer(options));
when(attempt.<Write, Element<Write>>newFlushBuffer(enqueue1)).thenReturn(newFlushBuffer(options));
when(attempt.<Write, Element<Write>>newFlushBuffer(enqueue2)).thenReturn(newFlushBuffer(options));
when(attempt.<Write, Element<Write>>newFlushBuffer(enqueue3)).thenReturn(newFlushBuffer(options));
when(attempt.<Write, Element<Write>>newFlushBuffer(enqueue4)).thenReturn(flushBuffer);
when(callable.call(expectedGroup1Request)).thenReturn(group1Response);
when(attempt2.<Write, Element<Write>>newFlushBuffer(enqueue5)).thenReturn(newFlushBuffer(options));
when(attempt2.<Write, Element<Write>>newFlushBuffer(finalFlush)).thenReturn(flushBuffer2);
when(callable.call(expectedGroup2Request)).thenReturn(group2Response);
runFunction(getFn(clock, ff, options, CounterFactory.DEFAULT, DistributionFactory.DEFAULT), maxValuesPerGroup + 1);
verify(attempt, times(1)).recordRequestStart(group1Rpc1Start, 5);
verify(attempt, times(1)).recordWriteCounts(group1Rpc1End, 5, 0);
verify(attempt, times(1)).completeSuccess();
verify(attempt2, times(1)).recordRequestStart(group2Rpc1Start, 1);
verify(attempt2, times(1)).recordWriteCounts(group2Rpc1End, 1, 0);
verify(attempt2, times(1)).completeSuccess();
verify(callable, times(1)).call(expectedGroup1Request);
verify(callable, times(1)).call(expectedGroup2Request);
verifyNoMoreInteractions(callable);
verify(flushBuffer, times(maxValuesPerGroup)).offer(any());
verify(flushBuffer2, times(1)).offer(any());
}
Aggregations