Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(spring): use shared configuration #1071

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,12 @@ private static void writeSpringAdditionalMetadataJson(GapicContext context, JarO

@VisibleForTesting
static String buildPomString(GapicContext context) {
String pakkageName = Utils.getPackageName(context);
pakkageName = pakkageName.replace('.', '-');
String clientLibraryShortName = Utils.getLibName(context);
String clientLibraryGroupId = "{{client-library-group-id}}";
String clientLibraryName = "{{client-library-artifact-id}}";
String clientLibraryVersion = "{{client-library-version}}";

String springStarterArtifactId = pakkageName + "-spring-starter";
String springStarterArtifactId = clientLibraryName + "-spring-starter";
String springStarterVersion = "{{starter-version}}";
String springStarterName = "Spring Boot Starter - " + clientLibraryShortName;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,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;
Expand All @@ -34,6 +35,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;
Expand All @@ -52,6 +54,7 @@
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.common.base.CaseFormat;
Expand Down Expand Up @@ -155,41 +158,91 @@ private static List<Statement> createMemberVariables(

Statement loggerStatement =
LoggerUtils.getLoggerDeclarationExpr(serviceName + "AutoConfig", types);
return Arrays.asList(clientPropertiesStatement, loggerStatement);
Statement globalPropertiesStatement =
GlobalPropertiesUtils.getGlobalPropertiesDeclaration(types);
return Arrays.asList(clientPropertiesStatement, globalPropertiesStatement, loggerStatement);
}

private static MethodDefinition createConstructor(
String serviceName, String className, Map<String, TypeNode> types, Expr thisExpr) {
VariableExpr propertiesVarExpr =
/// constructor
// VariableExpr credentialsProviderBuilderVarExpr =
// VariableExpr.withVariable(
// Variable.builder()
// .setName("coreCredentialsProvider")
// .setType(types.get("CredentialsProvider"))
// .build());
//
// VariableExpr coreProjectIdProviderVarExpr =
// VariableExpr.withVariable(
// Variable.builder()
// .setName("coreProjectIdProvider")
// .setType(types.get("GcpProjectIdProvider"))
// .build());
diegomarquezp marked this conversation as resolved.
Show resolved Hide resolved

VariableExpr clientPropertiesVarExpr =
VariableExpr.withVariable(
Variable.builder()
.setName("clientProperties")
.setType(types.get(serviceName + "Properties"))
.build());
VariableExpr globalPropertiesVarExpr =
VariableExpr.withVariable(
Variable.builder()
.setName("globalProperties")
.setType(types.get("GlobalProperties"))
.build());
// Variable projectIdProviderVar =
// Variable.builder()
// .setName("projectIdProvider")
// .setType(types.get("GcpProjectIdProvider"))
// .build();
diegomarquezp marked this conversation as resolved.
Show resolved Hide resolved
Variable clientPropertiesVar =
Variable.builder()
.setName("clientProperties")
.setType(types.get(serviceName + "Properties"))
.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();
}

Expand Down Expand Up @@ -244,10 +297,26 @@ private static List<AnnotationNode> createClassAnnotations(
AnnotationNode.builder()
.setType(types.get("EnableConfigurationProperties"))
.setDescription(
VariableExpr.builder()
.setVariable(
Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build())
.setStaticReferenceType(types.get(service.name() + "Properties"))
ArrayExpr.builder()
.setType(TypeNode.createArrayTypeOf(TypeNode.CLASS_OBJECT))
.addExpr(
VariableExpr.builder()
.setVariable(
Variable.builder()
.setType(TypeNode.CLASS_OBJECT)
.setName("class")
.build())
.setStaticReferenceType(types.get(service.name() + "Properties"))
.build())
.addExpr(
VariableExpr.builder()
.setVariable(
Variable.builder()
.setType(TypeNode.CLASS_OBJECT)
.setName("class")
.build())
.setStaticReferenceType(types.get("GlobalProperties"))
.build())
.build())
.build();

Expand All @@ -265,11 +334,19 @@ private static MethodDefinition createCredentialsProviderBeanMethod(
Map<String, TypeNode> 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<Statement> bodyStatements = new ArrayList<>();
Variable globalPropertiesVar =
Variable.builder()
.setName("GlobalProperties")
.setType(types.get("GlobalProperties"))
.build();
Variable clientPropertiesVar =
Variable.builder()
.setName("clientProperties")
Expand All @@ -281,7 +358,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()
Expand All @@ -290,6 +372,46 @@ private static MethodDefinition createCredentialsProviderBeanMethod(
.build())
.setType(types.get("CredentialsProvider"))
.build();
CastExpr globalCredentialsCastExpr =
CastExpr.builder()
.setExpr(
NewObjectExpr.builder()
.setType(types.get("DefaultCredentialsProvider"))
.setArguments(thisGlobalProperties)
.build())
.setType(types.get("CredentialsProvider"))
.build();
ExprStatement clientCredentialsReturnExpr =
ExprStatement.withExpr(ReturnExpr.withExpr(clientCastExpr));
Expr clientPropertiesGetCredentials =
MethodInvocationExpr.builder()
.setExprReferenceExpr(thisClientProperties)
.setMethodName("getCredentials")
.setReturnType(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(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)
Expand All @@ -298,11 +420,10 @@ private static MethodDefinition createCredentialsProviderBeanMethod(
.setScope(ScopeNode.PUBLIC)
.setReturnType(types.get("CredentialsProvider"))
.setAnnotations(
Arrays.asList(
AnnotationNode.withType(types.get("Bean")),
AnnotationNode.withType(types.get("ConditionalOnMissingBean"))))
Arrays.asList(AnnotationNode.withType(types.get("Bean")), conditionalOnMissingBeanExpr))
.setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(IOException.class)))
.setReturnExpr(castExpr)
.setBody(bodyStatements)
.setReturnExpr(globalCredentialsCastExpr)
.build();
}

Expand Down Expand Up @@ -1038,6 +1159,7 @@ private static Map<String, TypeNode> createDynamicTypes(Service service, String
typeMap.put("Qualifier", qualifier);
typeMap.put("Log", LoggerUtils.getLoggerType());
typeMap.put("LogFactory", LoggerUtils.getLoggerFactoryType());
typeMap.put("GlobalProperties", GlobalPropertiesUtils.getGlobalPropertiesType());
diegomarquezp marked this conversation as resolved.
Show resolved Hide resolved

return typeMap;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
diegomarquezp marked this conversation as resolved.
Show resolved Hide resolved
public static final String GLOBAL_PROPERTIES_PAKKAGE_NAME = "com.google.cloud.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<String, TypeNode> 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ 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.global.GlobalProperties;
import com.google.cloud.spring.core.Credentials;
import com.google.cloud.spring.core.DefaultCredentialsProvider;
import com.google.showcase.v1beta1.EchoClient;
import com.google.showcase.v1beta1.EchoSettings;
Expand Down Expand Up @@ -60,23 +62,29 @@ 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(EchoSpringAutoConfig.class);

protected EchoSpringAutoConfiguration(EchoSpringProperties clientProperties) {
protected EchoSpringAutoConfiguration(
EchoSpringProperties clientProperties, GlobalProperties globalProperties) {
this.clientProperties = clientProperties;
this.globalProperties = globalProperties;
}

/**
* Obtains the default credentials provider. The used key will be obtained from Spring Boot
* configuration data files.
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnMissingBean(name = "echoCredentials")
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));
diegomarquezp marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
Loading