Skip to content
This repository was archived by the owner on Jun 28, 2022. It is now read-only.

AutoValue LongRunningConfig; always use gapic config's polling settings #2698

Merged
merged 2 commits into from
Apr 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 106 additions & 77 deletions src/main/java/com/google/api/codegen/config/LongRunningConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.api.tools.framework.model.TypeRef;
import com.google.auto.value.AutoValue;
import com.google.longrunning.OperationInfo;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.threeten.bp.Duration;

Expand All @@ -32,10 +33,10 @@
public abstract class LongRunningConfig {

// Default values for LongRunningConfig fields.
static final int LRO_INITIAL_POLL_DELAY_MILLIS = 500;
static final Duration LRO_INITIAL_POLL_DELAY_MILLIS = Duration.ofMillis(500);
static final double LRO_POLL_DELAY_MULTIPLIER = 1.5;
static final int LRO_MAX_POLL_DELAY_MILLIS = 5000;
static final int LRO_TOTAL_POLL_TIMEOUT_MILLS = 300000;
static final Duration LRO_MAX_POLL_DELAY_MILLIS = Duration.ofMillis(5000);
static final Duration LRO_TOTAL_POLL_TIMEOUT_MILLS = Duration.ofMillis(300000);

/** Returns the message type returned from a completed operation. */
public abstract TypeModel getReturnType();
Expand All @@ -62,20 +63,18 @@ public abstract class LongRunningConfig {
static LongRunningConfig createLongRunningConfig(
Method method,
DiagCollector diagCollector,
LongRunningConfigProto longRunningConfigProto,
@Nonnull LongRunningConfigProto longRunningConfigProto,
ProtoParser protoParser) {
LongRunningConfig longRunningConfig =
createLongRunningConfigFromProtoFile(
method, diagCollector, longRunningConfigProto, protoParser);
if (longRunningConfig != null) {
return longRunningConfig;
}

if (!LongRunningConfigProto.getDefaultInstance().equals(longRunningConfigProto)) {
return LongRunningConfig.createLongRunningConfigFromGapicConfig(
if (protoParser.isProtoAnnotationsEnabled()) {
return createLongRunningConfigFromProtoFile(
method, diagCollector, longRunningConfigProto, protoParser);
} else {
if (longRunningConfigProto.equals(LongRunningConfigProto.getDefaultInstance())) {
return null;
}
return createLongRunningConfigFromGapicConfig(
method.getModel(), diagCollector, longRunningConfigProto);
}
return null;
}

private static String qualifyLroTypeName(
Expand All @@ -94,7 +93,7 @@ private static String qualifyLroTypeName(
private static LongRunningConfig createLongRunningConfigFromProtoFile(
Method method,
DiagCollector diagCollector,
LongRunningConfigProto longRunningConfigProto,
@Nonnull LongRunningConfigProto longRunningConfigProto,
ProtoParser protoParser) {
int preexistingErrors = diagCollector.getErrorCount();

Expand All @@ -110,13 +109,6 @@ private static LongRunningConfig createLongRunningConfigFromProtoFile(
String metadataTypeName =
qualifyLroTypeName(operationTypes.getMetadataType(), method, protoParser);

if (responseTypeName.equals(longRunningConfigProto.getReturnType())
&& metadataTypeName.equals(longRunningConfigProto.getMetadataType())) {
// GAPIC config refers to the same Long running config; so use its retry settings.
return LongRunningConfig.createLongRunningConfigFromGapicConfig(
method.getModel(), diagCollector, longRunningConfigProto);
}

TypeRef returnType = model.getSymbolTable().lookupType(responseTypeName);
TypeRef metadataType = model.getSymbolTable().lookupType(metadataTypeName);

Expand Down Expand Up @@ -152,18 +144,71 @@ private static LongRunningConfig createLongRunningConfigFromProtoFile(
return null;
}

// Use default retry settings.
Duration initialPollDelay = Duration.ofMillis(LRO_INITIAL_POLL_DELAY_MILLIS);
Duration maxPollDelay = Duration.ofMillis(LRO_MAX_POLL_DELAY_MILLIS);
Duration totalPollTimeout = Duration.ofMillis(LRO_TOTAL_POLL_TIMEOUT_MILLS);

return new AutoValue_LongRunningConfig(
ProtoTypeRef.create(returnType),
ProtoTypeRef.create(metadataType),
initialPollDelay,
LRO_POLL_DELAY_MULTIPLIER,
maxPollDelay,
totalPollTimeout);
LongRunningConfig.Builder builder =
getGapicConfigLroRetrySettingsOrDefault(diagCollector, longRunningConfigProto);

return builder
.setReturnType(ProtoTypeRef.create(returnType))
.setMetadataType(ProtoTypeRef.create(metadataType))
.build();
}

/**
* Creates an instance of LongRunningConfig.Builder based on a method's GAPIC config's LRO polling
* settings.
*/
private static LongRunningConfig.Builder getGapicConfigLroRetrySettingsOrDefault(
DiagCollector diagCollector, LongRunningConfigProto longRunningConfigProto) {
if (longRunningConfigProto.equals(LongRunningConfigProto.getDefaultInstance())) {
return newBuilder()
.setInitialPollDelay(LRO_INITIAL_POLL_DELAY_MILLIS)
.setPollDelayMultiplier(LRO_POLL_DELAY_MULTIPLIER)
.setMaxPollDelay(LRO_MAX_POLL_DELAY_MILLIS)
.setTotalPollTimeout(LRO_TOTAL_POLL_TIMEOUT_MILLS);
}

Duration initialPollDelay =
Duration.ofMillis(longRunningConfigProto.getInitialPollDelayMillis());
if (initialPollDelay.compareTo(Duration.ZERO) < 0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Initial poll delay must be provided and set to a positive number: '%s'",
longRunningConfigProto.getInitialPollDelayMillis()));
}

double pollDelayMultiplier = longRunningConfigProto.getPollDelayMultiplier();
if (pollDelayMultiplier < 1.0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Poll delay multiplier must be provided and be greater or equal than 1.0: '%s'",
longRunningConfigProto.getPollDelayMultiplier()));
}

Duration maxPollDelay = Duration.ofMillis(longRunningConfigProto.getMaxPollDelayMillis());
if (maxPollDelay.compareTo(initialPollDelay) < 0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Max poll delay must be provided and set be equal or greater than initial poll delay: '%s'",
longRunningConfigProto.getMaxPollDelayMillis()));
}

Duration totalPollTimeout =
Duration.ofMillis(longRunningConfigProto.getTotalPollTimeoutMillis());
if (totalPollTimeout.compareTo(maxPollDelay) < 0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Total poll timeout must be provided and be be equal or greater than max poll delay: '%s'",
longRunningConfigProto.getTotalPollTimeoutMillis()));
}
return newBuilder()
.setInitialPollDelay(initialPollDelay)
.setPollDelayMultiplier(pollDelayMultiplier)
.setMaxPollDelay(maxPollDelay)
.setTotalPollTimeout(totalPollTimeout);
}

/** Creates an instance of LongRunningConfig based on LongRunningConfigProto. */
Expand Down Expand Up @@ -205,54 +250,38 @@ private static LongRunningConfig createLongRunningConfigFromGapicConfig(
longRunningConfigProto.getMetadataType()));
}

Duration initialPollDelay =
Duration.ofMillis(longRunningConfigProto.getInitialPollDelayMillis());
if (initialPollDelay.compareTo(Duration.ZERO) < 0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Initial poll delay must be provided and set to a positive number: '%s'",
longRunningConfigProto.getInitialPollDelayMillis()));
if (diagCollector.getErrorCount() - preexistingErrors > 0) {
return null;
}

double pollDelayMultiplier = longRunningConfigProto.getPollDelayMultiplier();
if (pollDelayMultiplier <= 1.0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Poll delay multiplier must be provided and be greater or equal than 1.0: '%s'",
longRunningConfigProto.getPollDelayMultiplier()));
}
LongRunningConfig.Builder builder =
getGapicConfigLroRetrySettingsOrDefault(diagCollector, longRunningConfigProto);

Duration maxPollDelay = Duration.ofMillis(longRunningConfigProto.getMaxPollDelayMillis());
if (maxPollDelay.compareTo(initialPollDelay) < 0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Max poll delay must be provided and set be equal or greater than initial poll delay: '%s'",
longRunningConfigProto.getMaxPollDelayMillis()));
}
return builder
.setReturnType(ProtoTypeRef.create(returnType))
.setMetadataType(ProtoTypeRef.create(metadataType))
.build();
}

Duration totalPollTimeout =
Duration.ofMillis(longRunningConfigProto.getTotalPollTimeoutMillis());
if (totalPollTimeout.compareTo(maxPollDelay) < 0) {
diagCollector.addDiag(
Diag.error(
SimpleLocation.TOPLEVEL,
"Total poll timeout must be provided and be be equal or greater than max poll delay: '%s'",
longRunningConfigProto.getTotalPollTimeoutMillis()));
}
private static Builder newBuilder() {
return new AutoValue_LongRunningConfig.Builder();
}

if (diagCollector.getErrorCount() - preexistingErrors > 0) {
return null;
}
@AutoValue.Builder
abstract static class Builder {

public abstract Builder setReturnType(TypeModel val);

public abstract Builder setMetadataType(TypeModel val);

public abstract Builder setInitialPollDelay(Duration val);

public abstract Builder setPollDelayMultiplier(double val);

public abstract Builder setMaxPollDelay(Duration val);

public abstract Builder setTotalPollTimeout(Duration val);

return new AutoValue_LongRunningConfig(
ProtoTypeRef.create(returnType),
ProtoTypeRef.create(metadataType),
initialPollDelay,
pollDelayMultiplier,
maxPollDelay,
totalPollTimeout);
public abstract LongRunningConfig build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public static void startUp() {

@Test
public void testCreateLROWithoutGapicConfig() {
Mockito.when(protoParser.isProtoAnnotationsEnabled()).thenReturn(true);
DiagCollector diagCollector = new BoundedDiagCollector();
LongRunningConfig longRunningConfig =
LongRunningConfig.createLongRunningConfig(
Expand All @@ -120,19 +121,20 @@ public void testCreateLROWithoutGapicConfig() {
ProtoTypeRef returnTypeModel = (ProtoTypeRef) longRunningConfig.getReturnType();
assertThat(returnTypeModel.getProtoType()).isEqualTo(annotationsReturnType);

assertThat(longRunningConfig.getInitialPollDelay().toMillis())
assertThat(longRunningConfig.getInitialPollDelay())
.isEqualTo(LongRunningConfig.LRO_INITIAL_POLL_DELAY_MILLIS);
assertThat(longRunningConfig.getMaxPollDelay().toMillis())
assertThat(longRunningConfig.getMaxPollDelay())
.isEqualTo(LongRunningConfig.LRO_MAX_POLL_DELAY_MILLIS);
assertThat(longRunningConfig.getPollDelayMultiplier())
.isEqualTo(LongRunningConfig.LRO_POLL_DELAY_MULTIPLIER);
assertThat(longRunningConfig.getTotalPollTimeout().toMillis())
assertThat(longRunningConfig.getTotalPollTimeout())
.isEqualTo(LongRunningConfig.LRO_TOTAL_POLL_TIMEOUT_MILLS);
}

@Test
public void testCreateLROWithGapicConfigOnly() {
DiagCollector diagCollector = new BoundedDiagCollector();
Mockito.when(protoParser.isProtoAnnotationsEnabled()).thenReturn(false);

// simpleMethod has no LRO proto annotations.
// lroConfigProtoWithPollSettings contains LRO settings.
Expand Down Expand Up @@ -160,6 +162,7 @@ public void testCreateLROWithGapicConfigOnly() {
@Test
public void testCreateLROWithAnnotationsOverridingGapicConfig() {
DiagCollector diagCollector = new BoundedDiagCollector();
Mockito.when(protoParser.isProtoAnnotationsEnabled()).thenReturn(true);

// lroAnnotatedMethod contains different settings than that in lroConfigProtoWithPollSettings.
LongRunningConfig longRunningConfig =
Expand All @@ -169,24 +172,25 @@ public void testCreateLROWithAnnotationsOverridingGapicConfig() {
assertThat(diagCollector.getErrorCount()).isEqualTo(0);
assertThat(longRunningConfig).isNotNull();

// Assert that proto annotations settings take precendence over gapic config.
// Assert that proto annotations settings take precendence over gapic config for
// return and metadata types.
ProtoTypeRef metadataTypeModel = (ProtoTypeRef) longRunningConfig.getMetadataType();
assertThat(metadataTypeModel.getProtoType()).isEqualTo(annotationsMetadataType);
ProtoTypeRef returnTypeModel = (ProtoTypeRef) longRunningConfig.getReturnType();
assertThat(returnTypeModel.getProtoType()).isEqualTo(annotationsReturnType);

// Assert that GAPIC config timeout values are used.
assertThat(longRunningConfig.getInitialPollDelay().toMillis())
.isEqualTo(LongRunningConfig.LRO_INITIAL_POLL_DELAY_MILLIS);
assertThat(longRunningConfig.getMaxPollDelay().toMillis())
.isEqualTo(LongRunningConfig.LRO_MAX_POLL_DELAY_MILLIS);
assertThat(longRunningConfig.getPollDelayMultiplier())
.isEqualTo(LongRunningConfig.LRO_POLL_DELAY_MULTIPLIER);
.isEqualTo(TEST_INITIAL_POLL_DELAY);
assertThat(longRunningConfig.getMaxPollDelay().toMillis()).isEqualTo(TEST_MAX_POLL_DELAY);
assertThat(longRunningConfig.getPollDelayMultiplier()).isEqualTo(TEST_POLL_DELAY_MULTIPLIER);
assertThat(longRunningConfig.getTotalPollTimeout().toMillis())
.isEqualTo(LongRunningConfig.LRO_TOTAL_POLL_TIMEOUT_MILLS);
.isEqualTo(TEST_TOTAL_POLL_TIMEOUT);
}

@Test
public void testCreateSameLROFromProtoFileAndGapicConfig() {
Mockito.when(protoParser.isProtoAnnotationsEnabled()).thenReturn(true);
// Given a Protobuf LRO method annotated with the same Return and Metadata Type
// as in the GAPIC config, use the GAPIC config settings.
DiagCollector diagCollector = new BoundedDiagCollector();
Expand Down