Skip to content

Commit 61e2e96

Browse files
authored
fix: Multiple REST transport related fixes (#997)
1) Stop failing for grpc+rest and rest transports in case if there are bidi- or client- streaming methods (generated a method throwing "Unimplemented" exception if called) 2) Make sure that the resource name suggested for wildcard resource names actually matches url pattern (most of the changes in goldens are caused by this change) 3) Fix the order of "actual" and "expected" in diff_gen_and_golden to match 4) Fix multipattern `of%Name` method resoluiton to make sure that the chosen pattern matches url pattern (the changes in `MessagingClient.golden` and related files are caused by this change). 5) Fix anonymous resource name class construction (add proper toString() method matching pattern) 6) Gracefully treat methods without http bindings as not supported in rest transport (instead of failing on generation)
1 parent d935654 commit 61e2e96

File tree

64 files changed

+1255
-251
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1255
-251
lines changed

scripts/diff_gen_and_golden.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ find src -type f -name 'PlaceholderFile.java' -delete
2323
find src -type d -empty -delete
2424
# This will not print diff_output to the console unless `--test_output=all` option
2525
# is enabled, it only emits the comparison results to the test.log.
26-
diff -ru src test/integration/goldens/${API_NAME}/src
27-
diff -ru samples test/integration/goldens/${API_NAME}/samples
26+
diff -ru test/integration/goldens/${API_NAME}/src src
27+
diff -ru test/integration/goldens/${API_NAME}/samples samples

src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java

+18-5
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ protected GapicClass generate(String className, GapicContext context, Service se
130130
return GapicClass.create(kind, classDef);
131131
}
132132

133+
protected boolean isSupportedMethod(Method method) {
134+
return true;
135+
}
136+
133137
private List<AnnotationNode> createClassAnnotations() {
134138
return Arrays.asList(
135139
AnnotationNode.builder()
@@ -225,6 +229,9 @@ private List<MethodDefinition> createTestMethods(
225229
Map<String, Message> messageTypes = context.messages();
226230
List<MethodDefinition> javaMethods = new ArrayList<>();
227231
for (Method method : service.methods()) {
232+
if (!isSupportedMethod(method)) {
233+
continue;
234+
}
228235
Service matchingService = service;
229236
if (method.isMixin()) {
230237
int dotIndex = method.mixedInApiName().lastIndexOf(".");
@@ -388,7 +395,8 @@ private MethodDefinition createRpcTestMethod(
388395
DefaultValueComposer.createSimpleMessageBuilderValue(
389396
messageTypes.get(methodOutputType.reference().fullName()),
390397
resourceNames,
391-
messageTypes);
398+
messageTypes,
399+
method.httpBindings());
392400
} else {
393401
// Wrap this in a field so we don't have to split the helper into lots of different methods,
394402
// or duplicate it for VariableExpr.
@@ -461,9 +469,14 @@ private MethodDefinition createRpcTestMethod(
461469
if (getTransportContext().useValuePatterns() && method.hasHttpBindings()) {
462470
pathParamValuePatterns = method.httpBindings().getPathParametersValuePatterns();
463471
}
472+
464473
Expr valExpr =
465474
DefaultValueComposer.createSimpleMessageBuilderValue(
466-
requestMessage, resourceNames, messageTypes, pathParamValuePatterns);
475+
requestMessage,
476+
resourceNames,
477+
messageTypes,
478+
pathParamValuePatterns,
479+
method.httpBindings());
467480
methodExprs.add(
468481
AssignmentExpr.builder()
469482
.setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build())
@@ -482,7 +495,7 @@ private MethodDefinition createRpcTestMethod(
482495
argExprs.add(varExpr);
483496
Expr valExpr =
484497
DefaultValueComposer.createMethodArgValue(
485-
methodArg, resourceNames, messageTypes, valuePatterns);
498+
methodArg, resourceNames, messageTypes, valuePatterns, method.httpBindings());
486499
methodExprs.add(
487500
AssignmentExpr.builder()
488501
.setVariableExpr(varExpr.toBuilder().setIsDecl(true).build())
@@ -770,7 +783,7 @@ protected List<Statement> createRpcExceptionTestStatements(
770783
}
771784
Expr valExpr =
772785
DefaultValueComposer.createSimpleMessageBuilderValue(
773-
requestMessage, resourceNames, messageTypes, valuePatterns);
786+
requestMessage, resourceNames, messageTypes, valuePatterns, method.httpBindings());
774787
tryBodyExprs.add(
775788
AssignmentExpr.builder()
776789
.setVariableExpr(varExpr.toBuilder().setIsDecl(true).build())
@@ -789,7 +802,7 @@ protected List<Statement> createRpcExceptionTestStatements(
789802
argVarExprs.add(varExpr);
790803
Expr valExpr =
791804
DefaultValueComposer.createMethodArgValue(
792-
methodArg, resourceNames, messageTypes, valuePatterns);
805+
methodArg, resourceNames, messageTypes, valuePatterns, method.httpBindings());
793806
tryBodyExprs.add(
794807
AssignmentExpr.builder()
795808
.setVariableExpr(varExpr.toBuilder().setIsDecl(true).build())

src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ public GapicClass generate(GapicContext context, Service service) {
217217
return GapicClass.create(kind, classDef);
218218
}
219219

220+
protected boolean isSupportedMethod(Method method) {
221+
return true;
222+
}
223+
220224
protected abstract Statement createMethodDescriptorVariableDecl(
221225
Service service,
222226
Method protoMethod,
@@ -299,6 +303,7 @@ protected List<Statement> createMethodDescriptorVariableDecls(
299303
Map<String, VariableExpr> protoMethodNameToDescriptorVarExprs,
300304
Map<String, Message> messageTypes) {
301305
return service.methods().stream()
306+
.filter(this::isSupportedMethod)
302307
.map(
303308
m ->
304309
createMethodDescriptorVariableDecl(
@@ -323,6 +328,7 @@ private static List<Statement> createClassMemberFieldDeclarations(
323328
protected Map<String, VariableExpr> createProtoMethodNameToDescriptorClassMembers(
324329
Service service, Class<?> descriptorClass) {
325330
return service.methods().stream()
331+
.filter(this::isSupportedMethod)
326332
.collect(
327333
Collectors.toMap(
328334
Method::name,
@@ -354,6 +360,9 @@ private Map<String, VariableExpr> createCallableClassMembers(
354360
Map<String, VariableExpr> callableClassMembers = new LinkedHashMap<>();
355361
// Using a for-loop because the output cardinality is not a 1:1 mapping to the input set.
356362
for (Method protoMethod : service.methods()) {
363+
if (!isSupportedMethod(protoMethod)) {
364+
continue;
365+
}
357366
String javaStyleProtoMethodName = JavaStyle.toLowerCamelCase(protoMethod.name());
358367
String callableName = String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
359368
callableClassMembers.put(
@@ -643,6 +652,7 @@ protected List<MethodDefinition> createConstructorMethods(
643652
// Transport settings local variables.
644653
Map<String, VariableExpr> javaStyleMethodNameToTransportSettingsVarExprs =
645654
service.methods().stream()
655+
.filter(this::isSupportedMethod)
646656
.collect(
647657
Collectors.toMap(
648658
m -> JavaStyle.toLowerCamelCase(m.name()),
@@ -666,6 +676,7 @@ protected List<MethodDefinition> createConstructorMethods(
666676

667677
secondCtorExprs.addAll(
668678
service.methods().stream()
679+
.filter(this::isSupportedMethod)
669680
.map(
670681
m ->
671682
createTransportSettingsInitExpr(
@@ -1035,7 +1046,9 @@ private List<MethodDefinition> createStubOverrideMethods(
10351046
}
10361047

10371048
private boolean checkOperationPollingMethod(Service service) {
1038-
return service.methods().stream().anyMatch(Method::isOperationPollingMethod);
1049+
return service.methods().stream()
1050+
.filter(this::isSupportedMethod)
1051+
.anyMatch(Method::isOperationPollingMethod);
10391052
}
10401053

10411054
protected List<MethodDefinition> createLongRunningClientGetters() {
@@ -1073,6 +1086,7 @@ private TypeStore createDynamicTypes(Service service, String stubPakkage) {
10731086
typeStore.putAll(
10741087
service.pakkage(),
10751088
service.methods().stream()
1089+
.filter(this::isSupportedMethod)
10761090
.filter(Method::isPaged)
10771091
.map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name()))
10781092
.collect(Collectors.toList()),

src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java

+62-26
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.api.generator.engine.ast.VariableExpr;
3333
import com.google.api.generator.gapic.composer.resourcename.ResourceNameTokenizer;
3434
import com.google.api.generator.gapic.model.Field;
35+
import com.google.api.generator.gapic.model.HttpBindings;
3536
import com.google.api.generator.gapic.model.Message;
3637
import com.google.api.generator.gapic.model.MethodArgument;
3738
import com.google.api.generator.gapic.model.ResourceName;
@@ -65,7 +66,8 @@ public static Expr createMethodArgValue(
6566
MethodArgument methodArg,
6667
Map<String, ResourceName> resourceNames,
6768
Map<String, Message> messageTypes,
68-
Map<String, String> valuePatterns) {
69+
Map<String, String> valuePatterns,
70+
HttpBindings bindings) {
6971
if (methodArg.isResourceNameHelper()) {
7072
Preconditions.checkState(
7173
methodArg.field().hasResourceReference(),
@@ -84,7 +86,8 @@ public static Expr createMethodArgValue(
8486
resourceName,
8587
methodArg.field().resourceReference().isChildType(),
8688
resourceNames.values().stream().collect(Collectors.toList()),
87-
methodArg.field().name());
89+
methodArg.field().name(),
90+
bindings);
8891

8992
if (!methodArg.isResourceNameHelper() && methodArg.field().hasResourceReference()) {
9093
defValue =
@@ -156,7 +159,7 @@ public static Expr createValue(
156159
Message nestedMessage = messageTypes.get(field.type().reference().fullName());
157160
if (nestedMessage != null) {
158161
return createSimpleMessageBuilderValue(
159-
nestedMessage, resourceNames, messageTypes, nestedValuePatterns);
162+
nestedMessage, resourceNames, messageTypes, nestedValuePatterns, null);
160163
}
161164
}
162165

@@ -209,8 +212,10 @@ public static Expr createResourceHelperValue(
209212
ResourceName resourceName,
210213
boolean isChildType,
211214
List<ResourceName> resnames,
212-
String fieldOrMessageName) {
213-
return createResourceHelperValue(resourceName, isChildType, resnames, fieldOrMessageName, true);
215+
String fieldOrMessageName,
216+
HttpBindings bindings) {
217+
return createResourceHelperValue(
218+
resourceName, isChildType, resnames, fieldOrMessageName, true, bindings);
214219
}
215220

216221
private static Optional<ResourceName> findParentResource(
@@ -239,7 +244,8 @@ static Expr createResourceHelperValue(
239244
boolean isChildType,
240245
List<ResourceName> resnames,
241246
String fieldOrMessageName,
242-
boolean allowAnonResourceNameClass) {
247+
boolean allowAnonResourceNameClass,
248+
HttpBindings bindings) {
243249

244250
if (isChildType) {
245251
resourceName = findParentResource(resourceName, resnames).orElse(resourceName);
@@ -249,13 +255,15 @@ static Expr createResourceHelperValue(
249255
List<ResourceName> unexaminedResnames = new ArrayList<>(resnames);
250256
for (ResourceName resname : resnames) {
251257
unexaminedResnames.remove(resname);
252-
if (!resname.isOnlyWildcard()) {
253-
return createResourceHelperValue(resname, false, unexaminedResnames, fieldOrMessageName);
258+
if (!resname.isOnlyWildcard()
259+
&& (bindings == null || resname.getMatchingPattern(bindings) != null)) {
260+
return createResourceHelperValue(
261+
resname, false, unexaminedResnames, fieldOrMessageName, null);
254262
}
255263
}
256264

257265
return allowAnonResourceNameClass
258-
? createAnonymousResourceNameClassValue(fieldOrMessageName)
266+
? createAnonymousResourceNameClassValue(fieldOrMessageName, bindings)
259267
: ValueExpr.withValue(
260268
StringObjectValue.withValue(
261269
String.format("%s%s", fieldOrMessageName, fieldOrMessageName.hashCode())));
@@ -272,15 +280,22 @@ static Expr createResourceHelperValue(
272280
if (containsOnlyDeletedTopic) {
273281
ofMethodName = "ofDeletedTopic";
274282
} else {
275-
for (String pattern : resourceName.patterns()) {
276-
if (pattern.equals(ResourceNameConstants.WILDCARD_PATTERN)
277-
|| pattern.equals(ResourceNameConstants.DELETED_TOPIC_LITERAL)) {
278-
continue;
283+
String matchingPattern = null;
284+
if (bindings != null) {
285+
matchingPattern = resourceName.getMatchingPattern(bindings);
286+
}
287+
if (matchingPattern == null) {
288+
for (String pattern : resourceName.patterns()) {
289+
if (pattern.equals(ResourceNameConstants.WILDCARD_PATTERN)
290+
|| pattern.equals(ResourceNameConstants.DELETED_TOPIC_LITERAL)) {
291+
continue;
292+
}
293+
matchingPattern = pattern;
294+
break;
279295
}
280-
patternPlaceholderTokens.addAll(
281-
ResourceNameTokenizer.parseTokenHierarchy(Arrays.asList(pattern)).get(0));
282-
break;
283296
}
297+
patternPlaceholderTokens.addAll(
298+
ResourceNameTokenizer.parseTokenHierarchy(Arrays.asList(matchingPattern)).get(0));
284299
}
285300

286301
boolean hasOnePattern = resourceName.patterns().size() == 1;
@@ -312,16 +327,20 @@ static Expr createResourceHelperValue(
312327
}
313328

314329
public static Expr createSimpleMessageBuilderValue(
315-
Message message, Map<String, ResourceName> resourceNames, Map<String, Message> messageTypes) {
330+
Message message,
331+
Map<String, ResourceName> resourceNames,
332+
Map<String, Message> messageTypes,
333+
HttpBindings bindings) {
316334
return createSimpleMessageBuilderValue(
317-
message, resourceNames, messageTypes, Collections.emptyMap());
335+
message, resourceNames, messageTypes, Collections.emptyMap(), bindings);
318336
}
319337

320338
public static Expr createSimpleMessageBuilderValue(
321339
Message message,
322340
Map<String, ResourceName> resourceNames,
323341
Map<String, Message> messageTypes,
324-
Map<String, String> valuePatterns) {
342+
Map<String, String> valuePatterns,
343+
HttpBindings bindings) {
325344
MethodInvocationExpr builderExpr =
326345
MethodInvocationExpr.builder()
327346
.setStaticReferenceType(message.type())
@@ -350,7 +369,8 @@ public static Expr createSimpleMessageBuilderValue(
350369
field.resourceReference().isChildType(),
351370
resourceNames.values().stream().collect(Collectors.toList()),
352371
message.name(),
353-
/* allowAnonResourceNameClass = */ false);
372+
/* allowAnonResourceNameClass = */ false,
373+
bindings);
354374
defaultExpr =
355375
MethodInvocationExpr.builder()
356376
.setExprReferenceExpr(defaultExpr)
@@ -507,7 +527,8 @@ public static Expr createSimplePagedResponseValue(
507527
}
508528

509529
@VisibleForTesting
510-
static AnonymousClassExpr createAnonymousResourceNameClassValue(String fieldOrMessageName) {
530+
static AnonymousClassExpr createAnonymousResourceNameClassValue(
531+
String fieldOrMessageName, HttpBindings matchedBindings) {
511532
TypeNode stringMapType =
512533
TypeNode.withReference(
513534
ConcreteReference.builder()
@@ -525,12 +546,18 @@ static AnonymousClassExpr createAnonymousResourceNameClassValue(String fieldOrMe
525546
// fieldValuesMap.put("resource", "resource-12345");
526547
// return fieldValuesMap;
527548
// }
549+
550+
String toStringValue = String.format("%s%s", fieldOrMessageName, fieldOrMessageName.hashCode());
551+
if (matchedBindings != null) {
552+
Map<String, String> valuePatterns = matchedBindings.getPathParametersValuePatterns();
553+
toStringValue =
554+
constructValueMatchingPattern(fieldOrMessageName, valuePatterns.get(fieldOrMessageName));
555+
}
556+
528557
VariableExpr fieldValuesMapVarExpr =
529558
VariableExpr.withVariable(
530559
Variable.builder().setType(stringMapType).setName("fieldValuesMap").build());
531-
StringObjectValue fieldOrMessageStringValue =
532-
StringObjectValue.withValue(
533-
String.format("%s%s", fieldOrMessageName, fieldOrMessageName.hashCode()));
560+
StringObjectValue fieldOrMessageStringValue = StringObjectValue.withValue(toStringValue);
534561

535562
List<Expr> bodyExprs =
536563
Arrays.asList(
@@ -586,15 +613,24 @@ static AnonymousClassExpr createAnonymousResourceNameClassValue(String fieldOrMe
586613
.build())
587614
.build();
588615

616+
MethodDefinition toStringMethod =
617+
MethodDefinition.builder()
618+
.setIsOverride(true)
619+
.setScope(ScopeNode.PUBLIC)
620+
.setReturnType(TypeNode.STRING)
621+
.setName("toString")
622+
.setReturnExpr(ValueExpr.withValue(StringObjectValue.withValue(toStringValue)))
623+
.build();
624+
589625
return AnonymousClassExpr.builder()
590626
.setType(
591627
TypeNode.withReference(
592628
ConcreteReference.withClazz(com.google.api.resourcenames.ResourceName.class)))
593-
.setMethods(Arrays.asList(getFieldValuesMapMethod, getFieldValueMethod))
629+
.setMethods(Arrays.asList(getFieldValuesMapMethod, getFieldValueMethod, toStringMethod))
594630
.build();
595631
}
596632

597-
private static String constructValueMatchingPattern(String fieldName, String pattern) {
633+
public static String constructValueMatchingPattern(String fieldName, String pattern) {
598634
if (pattern == null || pattern.isEmpty()) {
599635
return fieldName + fieldName.hashCode();
600636
}

src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,8 @@ protected MethodDefinition createStreamingRpcTestMethod(
551551
DefaultValueComposer.createSimpleMessageBuilderValue(
552552
messageTypes.get(methodOutputType.reference().fullName()),
553553
resourceNames,
554-
messageTypes);
554+
messageTypes,
555+
method.httpBindings());
555556
} else {
556557
// Wrap this in a field so we don't have to split the helper into lots of different methods,
557558
// or duplicate it for VariableExpr.
@@ -608,7 +609,7 @@ protected MethodDefinition createStreamingRpcTestMethod(
608609
Preconditions.checkNotNull(requestMessage);
609610
Expr valExpr =
610611
DefaultValueComposer.createSimpleMessageBuilderValue(
611-
requestMessage, resourceNames, messageTypes);
612+
requestMessage, resourceNames, messageTypes, method.httpBindings());
612613
methodExprs.add(
613614
AssignmentExpr.builder()
614615
.setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build())
@@ -881,7 +882,7 @@ protected List<Statement> createStreamingRpcExceptionTestStatements(
881882
Preconditions.checkNotNull(requestMessage);
882883
Expr valExpr =
883884
DefaultValueComposer.createSimpleMessageBuilderValue(
884-
requestMessage, resourceNames, messageTypes);
885+
requestMessage, resourceNames, messageTypes, method.httpBindings());
885886

886887
List<Statement> statements = new ArrayList<>();
887888
statements.add(

0 commit comments

Comments
 (0)