Skip to content
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
16 changes: 16 additions & 0 deletions rules_java_gapic/java_gapic.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

load("@com_google_api_codegen//rules_gapic:gapic.bzl", "proto_custom_library", "unzipped_srcjar")

SERVICE_YAML_ALLOWLIST = ["cloudkms"]
NO_GRPC_CONFIG_ALLOWLIST = ["library"]

def _java_gapic_postprocess_srcjar_impl(ctx):
Expand Down Expand Up @@ -123,6 +124,7 @@ def java_gapic_library(
srcs,
grpc_service_config = None,
gapic_yaml = None,
service_yaml = None,
deps = [],
test_deps = [],
**kwargs):
Expand All @@ -138,6 +140,20 @@ def java_gapic_library(
if gapic_yaml:
file_args_dict[gapic_yaml] = "gapic-config"

# Check the allow-list.
# TODO: Open this up after mixins are published, and gate on
# the allowlisted "mixed-in" APIs present in Java.
if service_yaml:
service_yaml_in_allowlist = False
for keyword in SERVICE_YAML_ALLOWLIST:
if keyword in service_yaml:
service_yaml_in_allowlist = True
break
if service_yaml_in_allowlist:
file_args_dict[service_yaml] = "gapic-service-config"
else:
fail("Service.yaml is no longer supported in the Java microgenerator")

srcjar_name = name + "_srcjar"
raw_srcjar_name = srcjar_name + "_raw"
output_suffix = ".srcjar"
Expand Down
31 changes: 19 additions & 12 deletions src/main/java/com/google/api/generator/gapic/composer/Composer.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class Composer {
public static List<GapicClass> composeServiceClasses(GapicContext context) {
Expand All @@ -44,9 +43,10 @@ public static List<GapicClass> composeServiceClasses(GapicContext context) {
availableResourceNames.put(resourceName.resourceTypeString(), resourceName);
}
for (Service service : context.services()) {
clazzes.addAll(
generateServiceClasses(
service, context.serviceConfig(), availableResourceNames, context.messages()));
clazzes.addAll(generateServiceClasses(service, context, availableResourceNames));
}
for (Service mixinService : context.mixinServices()) {
clazzes.addAll(generateMockClasses(mixinService, availableResourceNames, context.messages()));
}
clazzes.addAll(generateResourceNameHelperClasses(context.helperResourceNames()));
return addApacheLicense(clazzes);
Expand All @@ -58,13 +58,14 @@ public static GapicPackageInfo composePackageInfo(GapicContext context) {

public static List<GapicClass> generateServiceClasses(
@Nonnull Service service,
@Nullable GapicServiceConfig serviceConfig,
@Nonnull Map<String, ResourceName> resourceNames,
@Nonnull Map<String, Message> messageTypes) {
GapicContext context,
@Nonnull Map<String, ResourceName> resourceNames) {
List<GapicClass> clazzes = new ArrayList<>();
clazzes.addAll(generateStubClasses(service, serviceConfig, messageTypes, resourceNames));
clazzes.addAll(generateClientSettingsClasses(service, messageTypes, resourceNames));
clazzes.addAll(generateMocksAndTestClasses(service, resourceNames, messageTypes));
clazzes.addAll(
generateStubClasses(service, context.serviceConfig(), context.messages(), resourceNames));
clazzes.addAll(generateClientSettingsClasses(service, context.messages(), resourceNames));
clazzes.addAll(generateMockClasses(service, resourceNames, context.messages()));
clazzes.addAll(generateTestClasses(service, context, resourceNames));
// TODO(miraleung): Generate test classes.
return clazzes;
}
Expand Down Expand Up @@ -100,13 +101,19 @@ public static List<GapicClass> generateClientSettingsClasses(
return clazzes;
}

public static List<GapicClass> generateMocksAndTestClasses(
public static List<GapicClass> generateMockClasses(
Service service, Map<String, ResourceName> resourceNames, Map<String, Message> messageTypes) {
List<GapicClass> clazzes = new ArrayList<>();
clazzes.add(MockServiceClassComposer.instance().generate(service, messageTypes));
clazzes.add(MockServiceImplClassComposer.instance().generate(service, messageTypes));
return clazzes;
}

public static List<GapicClass> generateTestClasses(
Service service, GapicContext context, Map<String, ResourceName> resourceNames) {
List<GapicClass> clazzes = new ArrayList<>();
clazzes.add(
ServiceClientTestClassComposer.instance().generate(service, resourceNames, messageTypes));
ServiceClientTestClassComposer.instance().generate(service, context, resourceNames));
return clazzes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,10 @@ private static EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod)
}

private static String getProtoRpcFullMethodName(Service protoService, Method protoMethod) {
if (protoMethod.isMixin()) {
return String.format("%s/%s", protoMethod.mixedInApiName(), protoMethod.name());
}

if (!REROUTE_TO_GRPC_INTERFACE_SERVICE_ALLOWLIST.contains(protoService.protoPakkage())
|| !REROUTE_TO_GRPC_INTERFACE_IAM_METHOD_ALLOWLIST.contains(protoMethod.name())) {
return String.format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ private static MethodDefinition createResetMethod() {

private static List<MethodDefinition> createProtoMethodOverrides(Service service) {
return service.methods().stream()
.filter(m -> !m.isMixin()) // Mixin APIs will get their own generated mocks.
.map(m -> createGenericProtoMethodOverride(m))
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import com.google.api.generator.gapic.model.Field;
import com.google.api.generator.gapic.model.GapicClass;
import com.google.api.generator.gapic.model.GapicClass.Kind;
import com.google.api.generator.gapic.model.GapicContext;
import com.google.api.generator.gapic.model.Message;
import com.google.api.generator.gapic.model.Method;
import com.google.api.generator.gapic.model.MethodArgument;
Expand All @@ -82,6 +83,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -134,13 +136,20 @@ public static ServiceClientTestClassComposer instance() {
}

public GapicClass generate(
Service service, Map<String, ResourceName> resourceNames, Map<String, Message> messageTypes) {
Service service, GapicContext context, Map<String, ResourceName> resourceNames) {
Map<String, Message> messageTypes = context.messages();
String pakkage = service.pakkage();
TypeStore typeStore = createDynamicTypes(service);
TypeStore typeStore = new TypeStore();
addDynamicTypes(service, typeStore);
for (Service mixinService : context.mixinServices()) {
addDynamicTypes(mixinService, typeStore);
}

String className = ClassNames.getServiceClientTestClassName(service);
GapicClass.Kind kind = Kind.MAIN;

Map<String, VariableExpr> classMemberVarExprs = createClassMemberVarExprs(service, typeStore);
Map<String, VariableExpr> classMemberVarExprs =
createClassMemberVarExprs(service, context, typeStore);

ClassDefinition classDef =
ClassDefinition.builder()
Expand All @@ -150,8 +159,7 @@ public GapicClass generate(
.setName(className)
.setStatements(createClassMemberFieldDecls(classMemberVarExprs))
.setMethods(
createClassMethods(
service, classMemberVarExprs, typeStore, resourceNames, messageTypes))
createClassMethods(service, context, classMemberVarExprs, typeStore, resourceNames))
.build();
return GapicClass.create(kind, classDef);
}
Expand All @@ -165,13 +173,18 @@ private static List<AnnotationNode> createClassAnnotations() {
}

private static Map<String, VariableExpr> createClassMemberVarExprs(
Service service, TypeStore typeStore) {
Service service, GapicContext context, TypeStore typeStore) {
BiFunction<String, TypeNode, VariableExpr> varExprFn =
(name, type) ->
VariableExpr.withVariable(Variable.builder().setName(name).setType(type).build());
Map<String, TypeNode> fields = new LinkedHashMap<>();
fields.put(
getMockServiceVarName(service), typeStore.get(ClassNames.getMockServiceClassName(service)));
for (Service mixinService : context.mixinServices()) {
fields.put(
getMockServiceVarName(mixinService),
typeStore.get(ClassNames.getMockServiceClassName(mixinService)));
}
fields.put(SERVICE_HELPER_VAR_NAME, FIXED_TYPESTORE.get("MockServiceHelper"));
fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service)));
fields.put(CHANNEL_PROVIDER_VAR_NAME, FIXED_TYPESTORE.get("LocalChannelProvider"));
Expand All @@ -195,36 +208,50 @@ private static List<Statement> createClassMemberFieldDecls(

private static List<MethodDefinition> createClassMethods(
Service service,
GapicContext context,
Map<String, VariableExpr> classMemberVarExprs,
TypeStore typeStore,
Map<String, ResourceName> resourceNames,
Map<String, Message> messageTypes) {
Map<String, ResourceName> resourceNames) {
List<MethodDefinition> javaMethods = new ArrayList<>();
javaMethods.addAll(createTestAdminMethods(service, classMemberVarExprs, typeStore));
javaMethods.addAll(
createTestMethods(service, classMemberVarExprs, resourceNames, messageTypes));
javaMethods.addAll(createTestAdminMethods(service, context, classMemberVarExprs, typeStore));
javaMethods.addAll(createTestMethods(service, context, classMemberVarExprs, resourceNames));
return javaMethods;
}

private static List<MethodDefinition> createTestAdminMethods(
Service service, Map<String, VariableExpr> classMemberVarExprs, TypeStore typeStore) {
Service service,
GapicContext context,
Map<String, VariableExpr> classMemberVarExprs,
TypeStore typeStore) {
List<MethodDefinition> javaMethods = new ArrayList<>();
javaMethods.add(createStartStaticServerMethod(service, classMemberVarExprs));
javaMethods.add(createStartStaticServerMethod(service, context, classMemberVarExprs));
javaMethods.add(createStopServerMethod(service, classMemberVarExprs));
javaMethods.add(createSetUpMethod(service, classMemberVarExprs, typeStore));
javaMethods.add(createTearDownMethod(service, classMemberVarExprs));
return javaMethods;
}

private static MethodDefinition createStartStaticServerMethod(
Service service, Map<String, VariableExpr> classMemberVarExprs) {
VariableExpr mockServiceVarExpr = classMemberVarExprs.get(getMockServiceVarName(service));
Service service, GapicContext context, Map<String, VariableExpr> classMemberVarExprs) {
VariableExpr serviceHelperVarExpr = classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME);
Expr initMockServiceExpr =
AssignmentExpr.builder()
.setVariableExpr(mockServiceVarExpr)
.setValueExpr(NewObjectExpr.builder().setType(mockServiceVarExpr.type()).build())
.build();
Function<Service, VariableExpr> serviceToVarExprFn =
s -> classMemberVarExprs.get(getMockServiceVarName(s));
Function<Service, Expr> serviceToVarInitExprFn =
s -> {
VariableExpr mockServiceVarExpr = serviceToVarExprFn.apply(s);
return AssignmentExpr.builder()
.setVariableExpr(mockServiceVarExpr)
.setValueExpr(NewObjectExpr.builder().setType(mockServiceVarExpr.type()).build())
.build();
};
List<Expr> varInitExprs = new ArrayList<>();
List<Expr> mockServiceVarExprs = new ArrayList<>();
varInitExprs.add(serviceToVarInitExprFn.apply(service));
mockServiceVarExprs.add(serviceToVarExprFn.apply(service));
for (Service mixinService : context.mixinServices()) {
varInitExprs.add(serviceToVarInitExprFn.apply(mixinService));
mockServiceVarExprs.add(serviceToVarExprFn.apply(mixinService));
}

MethodInvocationExpr firstArg =
MethodInvocationExpr.builder()
Expand All @@ -242,7 +269,7 @@ private static MethodDefinition createStartStaticServerMethod(
.setStaticReferenceType(FIXED_TYPESTORE.get("Arrays"))
.setGenerics(Arrays.asList(FIXED_TYPESTORE.get("MockGrpcService").reference()))
.setMethodName("asList")
.setArguments(Arrays.asList(mockServiceVarExpr))
.setArguments(mockServiceVarExprs)
.build();

Expr initServiceHelperExpr =
Expand All @@ -260,6 +287,8 @@ private static MethodDefinition createStartStaticServerMethod(
.setExprReferenceExpr(serviceHelperVarExpr)
.setMethodName("start")
.build();
varInitExprs.add(initServiceHelperExpr);
varInitExprs.add(startServiceHelperExpr);

return MethodDefinition.builder()
.setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass"))))
Expand All @@ -268,10 +297,7 @@ private static MethodDefinition createStartStaticServerMethod(
.setReturnType(TypeNode.VOID)
.setName("startStaticServer")
.setBody(
Arrays.asList(initMockServiceExpr, initServiceHelperExpr, startServiceHelperExpr)
.stream()
.map(e -> ExprStatement.withExpr(e))
.collect(Collectors.toList()))
varInitExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()))
.build();
}

Expand Down Expand Up @@ -412,17 +438,35 @@ private static MethodDefinition createTearDownMethod(

private static List<MethodDefinition> createTestMethods(
Service service,
GapicContext context,
Map<String, VariableExpr> classMemberVarExprs,
Map<String, ResourceName> resourceNames,
Map<String, Message> messageTypes) {
Map<String, ResourceName> resourceNames) {
Map<String, Message> messageTypes = context.messages();
List<MethodDefinition> javaMethods = new ArrayList<>();
for (Method method : service.methods()) {
Service matchingService = service;
if (method.isMixin()) {
int dotIndex = method.mixedInApiName().lastIndexOf(".");
String mixinServiceName = method.mixedInApiName().substring(dotIndex + 1);
String mixinServiceProtoPackage = method.mixedInApiName().substring(0, dotIndex);
Optional<Service> mixinServiceOpt =
context.mixinServices().stream()
.filter(
s ->
s.name().equals(mixinServiceName)
&& s.protoPakkage().equals(mixinServiceProtoPackage))
.findFirst();
if (mixinServiceOpt.isPresent()) {
matchingService = mixinServiceOpt.get();
}
}

// Ignore variants for streaming methods as well.
if (method.methodSignatures().isEmpty() || !method.stream().equals(Method.Stream.NONE)) {
javaMethods.add(
createRpcTestMethod(
method,
service,
matchingService,
Collections.emptyList(),
0,
true,
Expand All @@ -432,7 +476,7 @@ private static List<MethodDefinition> createTestMethods(
javaMethods.add(
createRpcExceptionTestMethod(
method,
service,
matchingService,
Collections.emptyList(),
0,
classMemberVarExprs,
Expand All @@ -443,7 +487,7 @@ private static List<MethodDefinition> createTestMethods(
javaMethods.add(
createRpcTestMethod(
method,
service,
matchingService,
method.methodSignatures().get(i),
i,
false,
Expand All @@ -453,7 +497,7 @@ private static List<MethodDefinition> createTestMethods(
javaMethods.add(
createRpcExceptionTestMethod(
method,
service,
matchingService,
method.methodSignatures().get(i),
i,
classMemberVarExprs,
Expand Down Expand Up @@ -1715,15 +1759,13 @@ private static Map<String, TypeNode> createDefaultMethodNamesToTypes() {
return javaMethodNameToReturnType;
}

private static TypeStore createDynamicTypes(Service service) {
TypeStore typeStore = new TypeStore();
private static void addDynamicTypes(Service service, TypeStore typeStore) {
typeStore.putAll(
service.pakkage(),
Arrays.asList(
ClassNames.getMockServiceClassName(service),
ClassNames.getServiceClientClassName(service),
ClassNames.getServiceSettingsClassName(service)));

// Pagination types.
typeStore.putAll(
service.pakkage(),
Expand All @@ -1733,7 +1775,6 @@ private static TypeStore createDynamicTypes(Service service) {
.collect(Collectors.toList()),
true,
ClassNames.getServiceClientClassName(service));
return typeStore;
}

private static TypeNode getOperationCallSettingsType(Method protoMethod) {
Expand Down
Loading