簡體   English   中英

如何使用 Spring Boot、R2DBC 和 TestContainers(Spanner 模擬器)為 Spanner 集成測試提供憑據

[英]How to provide credentials for Spanner integration tests with Spring Boot, R2DBC and TestContainers (Spanner Emulator)

這是執行集成測試的錯誤:

com.google.cloud.spanner.SpannerException: 
UNAUTHENTICATED: com.google.api.gax.rpc.UnauthenticatedException: io.grpc.StatusRuntimeException: 
UNAUTHENTICATED: Request is missing required authentication credential. 
Expected OAuth 2 access token, login cookie or other valid authentication credential. 
See https://developers.google.com/identity/sign-in/web/devconsole-project.

代碼(為了更容易和更快的復制而簡化):

@ExtendWith(SpringExtension.class)
@SpringBootTest
@ActiveProfiles("it")
@DirtiesContext
public class SpannerIT {

    static final String PROJECT_ID = "emulator-config";
    static final String INSTANCE_ID = "test-instance";
    static final String DATABASE_NAME = "test-database";

    static SpannerEmulatorContainer spannerContainer;

    @Autowired
    private R2dbcEntityTemplate template;

    @DynamicPropertySource
    static void properties(DynamicPropertyRegistry r) {
        r.add("spring.cloud.gcp.spanner.emulator-host", spannerContainer::getEmulatorGrpcEndpoint);
        r.add("spring.r2dbc.url", () -> "r2dbc:cloudspanner://" + spannerContainer.getEmulatorHttpEndpoint() +
            "/projects/" + PROJECT_ID + "/instances/" + INSTANCE_ID + "/databases/" + DATABASE_NAME);
    }

    @BeforeAll
    public static void beforeAll() {
        spannerContainer = new SpannerEmulatorContainer(
            DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator").withTag("1.4.1"));
        spannerContainer.start();
    }

    @AfterAll
    public static void afterAll() {
        spannerContainer.stop();
    }

    @Test
    void test() {
        StepVerifier.create(
                template.select(Query.query(CriteriaDefinition.empty()), SomeClazz.class)
            )
            .verifyComplete();

    }

    @Data
    @Table("test")
    public class SomeClazz {

        @Column("column")
        private String column;
    }
}

和配置(application-it.yml):

spring:
  cloud:
    gcp:
      spanner:
        project-id: emulator-config

  r2dbc:
    url: overwritten_in_tests
    properties:
      usePlainText: true
      autoConfigEmulator: true

通過將usePlainText設置為 r2dbc URL 理論上我們應該繞過憑據問題。 憑據提供程序已正確配置為NoCredentials ( SpannerConnectionFactoryProvider#extractCredentials )。

Github repo 完整代碼:
https://github.com/magiccrafter/spanner-spring-boot-r2jdbc-app

您收到的錯誤實際上是在暗示您的憑據選項正在運行,但有些東西正在嘗試在沒有憑據的情況下連接到 Cloud Spanner(或其他一些雲產品)。 模擬器通常不會返回Unauthenticated錯誤,因為它不需要任何憑據。 你能檢查一下:

  1. 在所有情況下,您的測試實際上都在嘗試連接到模擬器端點,而不是真正的 Cloud Spanner。
  2. 您的測試不會意外地嘗試使用NoCredentials訪問其他一些雲產品。

感謝elefeint的提示:

您還必須設置環境變量 export SPANNER_EMULATOR_HOST=localhost:9010,以便 Spanner 客戶端庫選擇非生產主機,類似於 jdbc 驅動程序。

Upvote #200 允許以編程方式自定義模擬器。

有關詳細信息,請查看Github 問題 #200

這是我想出的解決方法,可以在集成測試運行之前繞過對 SPANNER_EMULATOR_HOST 環境變量的要求:

@Testcontainers
@ExtendWith(SystemStubsExtension.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest
@ActiveProfiles("it")
@DirtiesContext
public class SpannerIT {

    static final String PROJECT_ID = "nv-local";
    static final String INSTANCE_ID = "test-instance";
    static final String DATABASE_NAME = "trades";

    @Container
    private static final SpannerEmulatorContainer spannerContainer =
        new SpannerEmulatorContainer(
            DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator").withTag("1.4.1"));

    @SystemStub
    private static EnvironmentVariables environmentVariables;

    @Autowired
    ConnectionFactory connectionFactory;

    @DynamicPropertySource
    static void properties(DynamicPropertyRegistry r) {
        environmentVariables.set("SPANNER_EMULATOR_HOST", spannerContainer.getEmulatorGrpcEndpoint());
        r.add("spring.r2dbc.url", () -> "r2dbc:cloudspanner://" +
            "/projects/" + PROJECT_ID + "/instances/" + INSTANCE_ID + "/databases/" + DATABASE_NAME);
    }

這樣,我們就可以在 Testcontainers 中擁有 Spanner 模擬器,而無需單獨啟動 Spanner 模擬器並映射具體端口。 完整的源代碼可以在這里找到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM