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

Use NoCredentialsProvider when firestore emulator enabled. #555

Merged
merged 5 commits into from
Aug 9, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.IOException;

import com.google.api.gax.core.CredentialsProvider;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.FirestoreOptions;
Expand Down Expand Up @@ -81,9 +82,15 @@ public class GcpFirestoreAutoConfiguration {
? gcpFirestoreProperties.getProjectId()
: projectIdProvider.getProjectId();

this.credentialsProvider = (gcpFirestoreProperties.getCredentials().hasKey()
? new DefaultCredentialsProvider(gcpFirestoreProperties)
: credentialsProvider);
if (gcpFirestoreProperties.getEmulator().isEnabled()) {
// if the emulator is enabled, create CredentialsProvider for this particular case.
this.credentialsProvider = NoCredentialsProvider.create();
}
else {
this.credentialsProvider = (gcpFirestoreProperties.getCredentials().hasKey()
? new DefaultCredentialsProvider(gcpFirestoreProperties)
: credentialsProvider);
}

this.hostPort = gcpFirestoreProperties.getHostPort();
this.firestoreRootPath = String.format(ROOT_PATH_FORMAT, this.projectId);
Expand All @@ -109,6 +116,10 @@ public Firestore firestore(FirestoreOptions firestoreOptions) {
return firestoreOptions.getService();
}

CredentialsProvider getCredentialsProvider() {
return credentialsProvider;
}

/**
* The Firestore reactive template and data repositories support auto-configuration.
*/
Expand Down Expand Up @@ -160,4 +171,5 @@ public ManagedChannel firestoreManagedChannel() {
.build();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ public class GcpFirestoreProperties implements CredentialsSupplier {
*/
private String hostPort = "firestore.googleapis.com:443";

@NestedConfigurationProperty
private FirestoreEmulatorProperties emulator = new FirestoreEmulatorProperties();

@Override
public Credentials getCredentials() {
return this.credentials;
Expand All @@ -65,4 +68,29 @@ public String getHostPort() {
public void setHostPort(String hostPort) {
this.hostPort = hostPort;
}

public FirestoreEmulatorProperties getEmulator() {
return emulator;
}

public void setEmulator(FirestoreEmulatorProperties emulator) {
this.emulator = emulator;
}

public static class FirestoreEmulatorProperties {

/**
* Enables autoconfiguration to use the Firestore emulator.
* If this is set to true, then you should set the spring.cloud.gcp.firestore.host-port to the host:port of your locally running emulator instance
*/
private boolean enabled = false;
meltsufin marked this conversation as resolved.
Show resolved Hide resolved

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2017-2020 the original author or authors.
*
* 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
*
* https://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.cloud.spring.autoconfigure.firestore;

import com.google.api.gax.core.CredentialsProvider;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.auth.Credentials;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.FirestoreOptions;
import com.google.cloud.spring.autoconfigure.core.GcpContextAutoConfiguration;
import org.junit.jupiter.api.Test;

import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

/**
* Tests for the Firestore emulator config.
*
* @author Gary Wong
*/
class GcpFirestoreEmulatorAutoConfigurationTests {

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
GcpContextAutoConfiguration.class,
GcpFirestoreEmulatorAutoConfiguration.class,
GcpFirestoreAutoConfiguration.class));

@Test
void testEmulatorEnabledConfig() {
this.contextRunner.withPropertyValues(
"spring.cloud.gcp.firestore.projectId=test-project",
"spring.cloud.gcp.firestore.emulator.enabled=true",
"spring.cloud.gcp.firestore.host-port=localhost:8080"
).run(context -> {
CredentialsProvider defaultCredentialsProvider = context.getBean(CredentialsProvider.class);
assertThat(defaultCredentialsProvider).isNotInstanceOf(NoCredentialsProvider.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we're missing the assertion on the actual Firestore credentials provider which this PR is all about.
I think you'll need to add a package-private getter for the credentialsProvider in GcpFirestoreAutoConfiguration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, added assertion on the new commit to make sure the GcpFirestoreAutoConfiguration did change to NoCredentialsProvider when emulator enabled.


GcpFirestoreAutoConfiguration firestoreAutoConfiguration = context.getBean(GcpFirestoreAutoConfiguration.class);
assertThat(firestoreAutoConfiguration.getCredentialsProvider()).isInstanceOf(NoCredentialsProvider.class);

FirestoreOptions datastoreOptions = context.getBean(Firestore.class).getOptions();
assertThat(datastoreOptions.getProjectId()).isEqualTo("test-project");

InstantiatingGrpcChannelProvider channelProvider = (InstantiatingGrpcChannelProvider) datastoreOptions.getTransportChannelProvider();
assertThat(channelProvider.getEndpoint()).isEqualTo("localhost:8080");
});
}

@Test
void testDefaultConfig() {
CredentialsProvider mockedCredentialsProvider = () -> mock(Credentials.class);

this.contextRunner.withPropertyValues(
"spring.cloud.gcp.firestore.projectId=test-project"
).withBean("mockedCredentialsProvider", CredentialsProvider.class, () -> mockedCredentialsProvider)
.run(context -> {
GcpFirestoreProperties gcpFirestoreProperties = context.getBean(GcpFirestoreProperties.class);
assertThat(gcpFirestoreProperties.getEmulator().isEnabled()).isFalse();

GcpFirestoreAutoConfiguration firestoreAutoConfiguration = context.getBean(GcpFirestoreAutoConfiguration.class);
assertThat(firestoreAutoConfiguration.getCredentialsProvider()).isEqualTo(mockedCredentialsProvider);

FirestoreOptions datastoreOptions = context.getBean(Firestore.class).getOptions();
assertThat(datastoreOptions.getProjectId()).isEqualTo("test-project");

InstantiatingGrpcChannelProvider channelProvider = (InstantiatingGrpcChannelProvider) datastoreOptions.getTransportChannelProvider();
assertThat(channelProvider.getEndpoint()).isEqualTo("firestore.googleapis.com:443");
});
}
}