-
Notifications
You must be signed in to change notification settings - Fork 330
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: add support for Firestore database id configuration #2164
Changes from 8 commits
dc88042
7cb9669
86892e6
0ca1e40
c873f8d
1a35d97
68bf732
3d00420
357373a
de8f9c2
55eb052
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
import com.google.api.gax.core.CredentialsProvider; | ||
import com.google.api.gax.core.NoCredentialsProvider; | ||
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; | ||
import com.google.api.gax.rpc.internal.Headers; | ||
import com.google.cloud.firestore.Firestore; | ||
import com.google.cloud.firestore.FirestoreOptions; | ||
import com.google.cloud.spring.autoconfigure.core.GcpContextAutoConfiguration; | ||
|
@@ -30,10 +31,15 @@ | |
import com.google.cloud.spring.data.firestore.mapping.FirestoreDefaultClassMapper; | ||
import com.google.cloud.spring.data.firestore.mapping.FirestoreMappingContext; | ||
import com.google.firestore.v1.FirestoreGrpc; | ||
import io.grpc.ClientInterceptor; | ||
import io.grpc.ManagedChannel; | ||
import io.grpc.ManagedChannelBuilder; | ||
import io.grpc.Metadata; | ||
import io.grpc.auth.MoreCallCredentials; | ||
import io.grpc.stub.MetadataUtils; | ||
import java.io.IOException; | ||
import java.net.URLEncoder; | ||
import java.nio.charset.StandardCharsets; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
import org.springframework.boot.autoconfigure.AutoConfigureAfter; | ||
|
@@ -61,6 +67,8 @@ public class GcpFirestoreAutoConfiguration { | |
|
||
private final String projectId; | ||
|
||
private final String databaseId; | ||
|
||
private final CredentialsProvider credentialsProvider; | ||
|
||
private final String hostPort; | ||
|
@@ -74,6 +82,7 @@ public class GcpFirestoreAutoConfiguration { | |
throws IOException { | ||
|
||
this.projectId = gcpFirestoreProperties.getResolvedProjectId(projectIdProvider); | ||
this.databaseId = gcpFirestoreProperties.getResolvedDatabaseId(); | ||
|
||
if (gcpFirestoreProperties.getEmulator().isEnabled()) { | ||
// if the emulator is enabled, create CredentialsProvider for this particular case. | ||
|
@@ -95,6 +104,7 @@ public FirestoreOptions firestoreOptions() { | |
return FirestoreOptions.getDefaultInstance().toBuilder() | ||
.setCredentialsProvider(this.credentialsProvider) | ||
.setProjectId(this.projectId) | ||
.setDatabaseId(databaseId) | ||
.setHeaderProvider(USER_AGENT_HEADER_PROVIDER) | ||
.setChannelProvider( | ||
InstantiatingGrpcChannelProvider.newBuilder().setEndpoint(this.hostPort).build()) | ||
|
@@ -150,12 +160,27 @@ public FirestoreTemplate firestoreTemplate( | |
firestoreMappingContext); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(name = "firestoreRoutingHeadersInterceptor") | ||
public ClientInterceptor firestoreRoutingHeadersInterceptor() { | ||
// add routing header for custom database id | ||
Metadata routingHeader = new Metadata(); | ||
Metadata.Key<String> key = | ||
Metadata.Key.of(Headers.DYNAMIC_ROUTING_HEADER_KEY, Metadata.ASCII_STRING_MARSHALLER); | ||
routingHeader.put(key, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may work for this specific case, but routing header config could change in the future. I'm not sure it works for all the new routing header configs either, but maybe those are not required. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, this integration was specifically made to support reactive, and I believe at the time GAPIC was not compatible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. My concern is that every time the backend makes the routing header required for a new RPC, or change how the routing header is constructed, we would have to come back and manually change it in spring-cloud-gcp. It may not in scope of this PR, can we investigate the possibility of switching to the GAPIC stubs? |
||
"project_id=" + URLEncoder.encode(projectId, StandardCharsets.US_ASCII) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use PercentEscaper in gax, which I think has slight advantage over the Java default one based on @lqiu96's investigation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switch to `PercentEscaper1. |
||
+ "&database_id=" + URLEncoder.encode(databaseId, StandardCharsets.US_ASCII)); | ||
return MetadataUtils.newAttachHeadersInterceptor(routingHeader); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(name = "firestoreManagedChannel") | ||
public ManagedChannel firestoreManagedChannel() { | ||
public ManagedChannel firestoreManagedChannel( | ||
ClientInterceptor firestoreRoutingHeadersInterceptor) { | ||
return ManagedChannelBuilder.forTarget( | ||
"dns:///" + GcpFirestoreAutoConfiguration.this.hostPort) | ||
.userAgent(USER_AGENT_HEADER_PROVIDER.getUserAgent()) | ||
.intercept(firestoreRoutingHeadersInterceptor) | ||
.build(); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
spring.cloud.gcp.firestore.project-id=spring-cloud-gcp-ci-firestore | ||
spring.cloud.gcp.firestore.project-id=spring-cloud-gcp-ci | ||
spring.cloud.gcp.firestore.database-id=firestoredb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Default value" column is missing.