diff --git a/src/main/java/com/google/api/generator/spring/composer/SpringAutoConfigClassComposer.java b/src/main/java/com/google/api/generator/spring/composer/SpringAutoConfigClassComposer.java index 6ba7d06dd0..2b67625693 100644 --- a/src/main/java/com/google/api/generator/spring/composer/SpringAutoConfigClassComposer.java +++ b/src/main/java/com/google/api/generator/spring/composer/SpringAutoConfigClassComposer.java @@ -22,6 +22,7 @@ import com.google.api.gax.rpc.TransportChannelProvider; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.ArithmeticOperationExpr; +import com.google.api.generator.engine.ast.ArrayExpr; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.CastExpr; import com.google.api.generator.engine.ast.ClassDefinition; @@ -35,6 +36,7 @@ import com.google.api.generator.engine.ast.NewObjectExpr; import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.RelationalOperationExpr; +import com.google.api.generator.engine.ast.ReturnExpr; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.Statement; import com.google.api.generator.engine.ast.StringObjectValue; @@ -53,8 +55,10 @@ import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.spring.composer.comment.SpringAutoconfigCommentComposer; +import com.google.api.generator.spring.utils.GlobalPropertiesUtils; import com.google.api.generator.spring.utils.LoggerUtils; import com.google.api.generator.spring.utils.Utils; +import com.google.cloud.spring.core.Credentials; import com.google.cloud.spring.core.DefaultCredentialsProvider; import com.google.common.base.CaseFormat; import com.google.common.base.Joiner; @@ -164,41 +168,71 @@ private static List createMemberVariables( Statement loggerStatement = LoggerUtils.getLoggerDeclarationExpr( Utils.getServiceAutoConfigurationClassName(service), types); - return Arrays.asList(clientPropertiesStatement, loggerStatement); + Statement globalPropertiesStatement = + GlobalPropertiesUtils.getGlobalPropertiesDeclaration(types); + return Arrays.asList(clientPropertiesStatement, globalPropertiesStatement, loggerStatement); } private static MethodDefinition createConstructor( Service service, String className, Map types, Expr thisExpr) { - VariableExpr propertiesVarExpr = + VariableExpr clientPropertiesVarExpr = VariableExpr.withVariable( Variable.builder() .setName("clientProperties") .setType(types.get(Utils.getServicePropertiesClassName(service))) .build()); + VariableExpr globalPropertiesVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setName("globalProperties") + .setType(types.get("GlobalProperties")) + .build()); Variable clientPropertiesVar = Variable.builder() .setName("clientProperties") .setType(types.get(Utils.getServicePropertiesClassName(service))) .build(); + Variable globalPropertiesVar = + Variable.builder() + .setName("globalProperties") + .setType(types.get("GlobalProperties")) + .build(); // this.clientProperties = clientProperties; - AssignmentExpr thisPropertiesAssignmentExpr = + AssignmentExpr thisClientPropertiesAssignmentExpr = AssignmentExpr.builder() .setVariableExpr( VariableExpr.withVariable(clientPropertiesVar) .toBuilder() .setExprReferenceExpr(thisExpr) .build()) - .setValueExpr(propertiesVarExpr) + .setValueExpr(clientPropertiesVarExpr) .build(); - ExprStatement thisPropertiesAssignmentStatement = - ExprStatement.withExpr(thisPropertiesAssignmentExpr); + ExprStatement thisClientPropertiesAssignmentStatement = + ExprStatement.withExpr(thisClientPropertiesAssignmentExpr); + + AssignmentExpr thisGlobalPropertiesAssignmentExpr = + AssignmentExpr.builder() + .setVariableExpr( + VariableExpr.withVariable(globalPropertiesVar) + .toBuilder() + .setExprReferenceExpr(thisExpr) + .build()) + .setValueExpr(globalPropertiesVarExpr) + .build(); + ExprStatement thisGlobalPropertiesAssignmentStatement = + ExprStatement.withExpr(thisGlobalPropertiesAssignmentExpr); return MethodDefinition.constructorBuilder() .setScope(ScopeNode.PROTECTED) .setReturnType(types.get(className)) - .setArguments(Arrays.asList(propertiesVarExpr.toBuilder().setIsDecl(true).build())) - .setBody(Arrays.asList(thisPropertiesAssignmentStatement)) + .setArguments( + Arrays.asList( + clientPropertiesVarExpr.toBuilder().setIsDecl(true).build(), + globalPropertiesVarExpr.toBuilder().setIsDecl(true).build())) + .setBody( + Arrays.asList( + thisClientPropertiesAssignmentStatement, thisGlobalPropertiesAssignmentStatement)) .build(); } @@ -253,10 +287,27 @@ private static List createClassAnnotations( AnnotationNode.builder() .setType(STATIC_TYPES.get("EnableConfigurationProperties")) .setDescription( - VariableExpr.builder() - .setVariable( - Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) - .setStaticReferenceType(types.get(Utils.getServicePropertiesClassName(service))) + ArrayExpr.builder() + .setType(TypeNode.createArrayTypeOf(TypeNode.CLASS_OBJECT)) + .addExpr( + VariableExpr.builder() + .setVariable( + Variable.builder() + .setType(TypeNode.CLASS_OBJECT) + .setName("class") + .build()) + .setStaticReferenceType( + types.get(Utils.getServicePropertiesClassName(service))) + .build()) + .addExpr( + VariableExpr.builder() + .setVariable( + Variable.builder() + .setType(TypeNode.CLASS_OBJECT) + .setName("class") + .build()) + .setStaticReferenceType(types.get("GlobalProperties")) + .build()) .build()) .build(); @@ -274,11 +325,19 @@ private static MethodDefinition createCredentialsProviderBeanMethod( Map types, Expr thisExpr) { // @Bean - // @ConditionalOnMissingBean + // @ConditionalOnMissingBean(name = "[serviceName]ServiceCredentials") // public CredentialsProvider languageServiceCredentials() throws IOException { - // return new DefaultCredentialsProvider(this.clientProperties); + // if (this.clientProperties.getCredentials().hasKey()) { + // return new DefaultCredentialsProvider(this.clientProperties); + // } + // return new DefaultCredentialsProvider(this.globalProperties); // } - + List bodyStatements = new ArrayList<>(); + Variable globalPropertiesVar = + Variable.builder() + .setName("globalProperties") + .setType(types.get("GlobalProperties")) + .build(); Variable clientPropertiesVar = Variable.builder() .setName("clientProperties") @@ -290,7 +349,12 @@ private static MethodDefinition createCredentialsProviderBeanMethod( .toBuilder() .setExprReferenceExpr(thisExpr) .build(); - CastExpr castExpr = + VariableExpr thisGlobalProperties = + VariableExpr.withVariable(globalPropertiesVar) + .toBuilder() + .setExprReferenceExpr(thisExpr) + .build(); + CastExpr clientCastExpr = CastExpr.builder() .setExpr( NewObjectExpr.builder() @@ -299,6 +363,46 @@ private static MethodDefinition createCredentialsProviderBeanMethod( .build()) .setType(STATIC_TYPES.get("CredentialsProvider")) .build(); + CastExpr globalCredentialsCastExpr = + CastExpr.builder() + .setExpr( + NewObjectExpr.builder() + .setType(STATIC_TYPES.get("DefaultCredentialsProvider")) + .setArguments(thisGlobalProperties) + .build()) + .setType(STATIC_TYPES.get("CredentialsProvider")) + .build(); + ExprStatement clientCredentialsReturnExpr = + ExprStatement.withExpr(ReturnExpr.withExpr(clientCastExpr)); + Expr clientPropertiesGetCredentials = + MethodInvocationExpr.builder() + .setExprReferenceExpr(thisClientProperties) + .setMethodName("getCredentials") + .setReturnType(STATIC_TYPES.get("Credentials")) + .build(); + Expr clientPropertiesCredentialsHasKey = + MethodInvocationExpr.builder() + .setExprReferenceExpr(clientPropertiesGetCredentials) + .setMethodName("hasKey") + .setReturnType(TypeNode.BOOLEAN) + .build(); + IfStatement clientCredentialsIfStatement = + createIfStatement( + clientPropertiesCredentialsHasKey, Arrays.asList(clientCredentialsReturnExpr), null); + bodyStatements.add(clientCredentialsIfStatement); + + // @ConditionalOnMissingBean(name = "[serviceName]ServiceCredentials") + AnnotationNode conditionalOnMissingBeanExpr = + AnnotationNode.builder() + .setType(STATIC_TYPES.get("ConditionalOnMissingBean")) + .addDescription( + AssignmentExpr.builder() + .setVariableExpr( + VariableExpr.withVariable( + Variable.builder().setName("name").setType(TypeNode.STRING).build())) + .setValueExpr(ValueExpr.withValue(StringObjectValue.withValue(methodName))) + .build()) + .build(); return MethodDefinition.builder() .setName(methodName) @@ -311,7 +415,8 @@ private static MethodDefinition createCredentialsProviderBeanMethod( AnnotationNode.withType(STATIC_TYPES.get("Bean")), AnnotationNode.withType(STATIC_TYPES.get("ConditionalOnMissingBean")))) .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(IOException.class))) - .setReturnExpr(castExpr) + .setBody(bodyStatements) + .setReturnExpr(globalCredentialsCastExpr) .build(); } @@ -901,7 +1006,8 @@ private static Map createStaticTypes() { Qualifier.class, DefaultCredentialsProvider.class, HeaderProvider.class, - Collections.class); + Collections.class, + Credentials.class); Map concreteClazzesMap = concreteClazzes.stream() .collect( @@ -955,6 +1061,7 @@ private static Map createDynamicTypes(Service service, String typeMap.put("ServiceClient", serviceClient); typeMap.put("ServiceSettings", serviceSettings); typeMap.put("ServiceSettingsBuilder", serviceSettingsBuilder); + typeMap.put("GlobalProperties", GlobalPropertiesUtils.getGlobalPropertiesType()); return typeMap; } diff --git a/src/main/java/com/google/api/generator/spring/utils/GlobalPropertiesUtils.java b/src/main/java/com/google/api/generator/spring/utils/GlobalPropertiesUtils.java new file mode 100644 index 0000000000..7ddde96bed --- /dev/null +++ b/src/main/java/com/google/api/generator/spring/utils/GlobalPropertiesUtils.java @@ -0,0 +1,55 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.api.generator.spring.utils; + +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.VaporReference; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import java.util.Map; + +public class GlobalPropertiesUtils { + public static final String GLOBAL_PROPERTIES_CLAZZ_NAME = "GlobalProperties"; + public static final String GLOBAL_PROPERTIES_PAKKAGE_NAME = "com.google.cloud.spring.global"; + + public static TypeNode getGlobalPropertiesType() { + TypeNode loggerType = + TypeNode.withReference( + VaporReference.builder() + .setName(GLOBAL_PROPERTIES_CLAZZ_NAME) + .setPakkage(GLOBAL_PROPERTIES_PAKKAGE_NAME) + .build()); + return loggerType; + } + + public static Statement getGlobalPropertiesDeclaration(Map types) { + Variable globalPropertiesVar = + Variable.builder() + .setName("globalProperties") + .setType(types.get("GlobalProperties")) + .build(); + return ExprStatement.withExpr( + VariableExpr.builder() + .setVariable(globalPropertiesVar) + .setScope(ScopeNode.PRIVATE) + .setIsStatic(false) + .setIsFinal(true) + .setIsDecl(true) + .build()); + } +} diff --git a/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationFull.golden b/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationFull.golden index 57e37709a5..b973414fc1 100644 --- a/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationFull.golden +++ b/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationFull.golden @@ -22,7 +22,9 @@ import com.google.api.gax.core.ExecutorProvider; import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.spring.core.Credentials; import com.google.cloud.spring.core.DefaultCredentialsProvider; +import com.google.cloud.spring.global.GlobalProperties; import com.google.showcase.v1beta1.EchoClient; import com.google.showcase.v1beta1.EchoSettings; import java.io.IOException; @@ -60,13 +62,16 @@ import org.threeten.bp.Duration; @ConditionalOnProperty( value = "com.google.showcase.v1beta1.spring.auto.echo.enabled", matchIfMissing = false) -@EnableConfigurationProperties(EchoSpringProperties.class) +@EnableConfigurationProperties({EchoSpringProperties.class, GlobalProperties.class}) public class EchoSpringAutoConfiguration { private final EchoSpringProperties clientProperties; + private final GlobalProperties globalProperties; private static final Log LOGGER = LogFactory.getLog(EchoSpringAutoConfiguration.class); - protected EchoSpringAutoConfiguration(EchoSpringProperties clientProperties) { + protected EchoSpringAutoConfiguration( + EchoSpringProperties clientProperties, GlobalProperties globalProperties) { this.clientProperties = clientProperties; + this.globalProperties = globalProperties; } /** @@ -76,7 +81,10 @@ public class EchoSpringAutoConfiguration { @Bean @ConditionalOnMissingBean public CredentialsProvider echoCredentials() throws IOException { - return ((CredentialsProvider) new DefaultCredentialsProvider(this.clientProperties)); + if (this.clientProperties.getCredentials().hasKey()) { + return ((CredentialsProvider) new DefaultCredentialsProvider(this.clientProperties)); + } + return ((CredentialsProvider) new DefaultCredentialsProvider(this.globalProperties)); } /** diff --git a/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpc.golden b/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpc.golden index be43d1f5ba..4464a4ab01 100644 --- a/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpc.golden +++ b/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpc.golden @@ -5,7 +5,9 @@ import com.google.api.gax.core.ExecutorProvider; import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.spring.core.Credentials; import com.google.cloud.spring.core.DefaultCredentialsProvider; +import com.google.cloud.spring.global.GlobalProperties; import com.google.showcase.v1beta1.EchoClient; import com.google.showcase.v1beta1.EchoSettings; import java.io.IOException; @@ -40,13 +42,16 @@ import org.threeten.bp.Duration; @ConditionalOnProperty( value = "com.google.showcase.v1beta1.spring.auto.echo.enabled", matchIfMissing = false) -@EnableConfigurationProperties(EchoSpringProperties.class) +@EnableConfigurationProperties({EchoSpringProperties.class, GlobalProperties.class}) public class EchoSpringAutoConfiguration { private final EchoSpringProperties clientProperties; + private final GlobalProperties globalProperties; private static final Log LOGGER = LogFactory.getLog(EchoSpringAutoConfiguration.class); - protected EchoSpringAutoConfiguration(EchoSpringProperties clientProperties) { + protected EchoSpringAutoConfiguration( + EchoSpringProperties clientProperties, GlobalProperties globalProperties) { this.clientProperties = clientProperties; + this.globalProperties = globalProperties; } /** @@ -56,7 +61,10 @@ public class EchoSpringAutoConfiguration { @Bean @ConditionalOnMissingBean public CredentialsProvider echoCredentials() throws IOException { - return ((CredentialsProvider) new DefaultCredentialsProvider(this.clientProperties)); + if (this.clientProperties.getCredentials().hasKey()) { + return ((CredentialsProvider) new DefaultCredentialsProvider(this.clientProperties)); + } + return ((CredentialsProvider) new DefaultCredentialsProvider(this.globalProperties)); } /** diff --git a/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpcRest.golden b/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpcRest.golden index 9028ac55ed..9ce9e54996 100644 --- a/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpcRest.golden +++ b/src/test/java/com/google/api/generator/spring/composer/goldens/EchoSpringAutoConfigurationGrpcRest.golden @@ -6,7 +6,9 @@ import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.spring.core.Credentials; import com.google.cloud.spring.core.DefaultCredentialsProvider; +import com.google.cloud.spring.global.GlobalProperties; import com.google.showcase.v1beta1.EchoClient; import com.google.showcase.v1beta1.EchoSettings; import java.io.IOException; @@ -41,13 +43,16 @@ import org.threeten.bp.Duration; @ConditionalOnProperty( value = "com.google.showcase.v1beta1.spring.auto.echo.enabled", matchIfMissing = false) -@EnableConfigurationProperties(EchoSpringProperties.class) +@EnableConfigurationProperties({EchoSpringProperties.class, GlobalProperties.class}) public class EchoSpringAutoConfiguration { private final EchoSpringProperties clientProperties; + private final GlobalProperties globalProperties; private static final Log LOGGER = LogFactory.getLog(EchoSpringAutoConfiguration.class); - protected EchoSpringAutoConfiguration(EchoSpringProperties clientProperties) { + protected EchoSpringAutoConfiguration( + EchoSpringProperties clientProperties, GlobalProperties globalProperties) { this.clientProperties = clientProperties; + this.globalProperties = globalProperties; } /** @@ -57,7 +62,10 @@ public class EchoSpringAutoConfiguration { @Bean @ConditionalOnMissingBean public CredentialsProvider echoCredentials() throws IOException { - return ((CredentialsProvider) new DefaultCredentialsProvider(this.clientProperties)); + if (this.clientProperties.getCredentials().hasKey()) { + return ((CredentialsProvider) new DefaultCredentialsProvider(this.clientProperties)); + } + return ((CredentialsProvider) new DefaultCredentialsProvider(this.globalProperties)); } /**