【问题标题】:Close GCP SecretManagerServiceClient after getting secrets from it从 GCP SecretManagerServiceClient 获取秘密后关闭它
【发布时间】:2024-05-02 23:05:03
【问题描述】:

如何在下面的代码中关闭客户端:

object GoogleSecret {
    def apply(
            project: String,
            version: String = SecretVersion,
            credentials: CredentialsProvider = defaultProvider
        ): Try[SecretService] = Try {
            require(project != null && project.nonEmpty, "project is null or empty")

            val settings = SecretManagerServiceSettings.newBuilder
                    .setCredentialsProvider(credentialsProvider)
                    .build()
            val client = SecretManagerServiceClient.create(settings)
        
            logger.info(s"connected to project: $project")
        
            secrets => secrets.flatMap {
                secret =>
                    logger.debug(s"getting secret: $secret")
                    try {
                        val value = client
                            .accessSecretVersion(SecretVersionName.of(project, secret, version))
                            .getPayload
                            .getData
                            .toStringUtf8
                        Some(secret -> value)
                    } catch {
                        case e: Throwable => {
                            logger.error(s"google error ($secret): ${e.getMessage}")
                            client.shutdown()
                            client.awaitTermination(30, TimeUnit.SECONDS)
                            client.close()
                            None
                        }
                    }
            }.toMap
}

上述方法创建了一个客户端连接到 GCP Secret Manager,以获取秘密值,但我有一些问题:

  1. 这个片段应该做什么:
secrets => secrets.flatMap {
            secret =>
                logger.debug(s"getting secret: $secret")
                try {
                    val value = client
                        .accessSecretVersion(SecretVersionName.of(project, secret, version))
                        .getPayload
                        .getData
                        .toStringUtf8
                    Some(secret -> value)
                } catch {
                    case e: Throwable => {
                        logger.error(s"google error ($secret): ${e.getMessage}")
                        client.shutdown()
                        client.awaitTermination(30, TimeUnit.SECONDS)
                        client.close()
                        None
                    }
                }
        }.toMap
  1. 如何转换代码以返回 Map[String, String] 中的机密值,并关闭客户端连接(类似这样):

def apply(
        project: String,
        version: String = SecretVersion,
        credentials: CredentialsProvider = defaultProvider
    ): Try[SecretService] = Try {
.
.
.
some code with the solution
.
.
.
    client.shutdown()
    client.awaitTermination(30, TimeUnit.SECONDS)
    client.close()
    secrets
}

提前致谢;)

【问题讨论】:

  • 您可能想看看像 cats-effectZIO 这样的效果系统,它们提供了一种更安全的资源管理方式。跨度>

标签: scala scala-collections


【解决方案1】:

如果我理解正确的话,你拿到地图后需要关闭客户端

val client = SecretManagerServiceClient.create(settings)
// TODO: Set the type of the secrets parameter
val result = (secrets: ???) => { secrets.flatMap 
  ... 
  }.toMap
}

client.shutdown()
client.awaitTermination(30, TimeUnit.SECONDS)
client.close()

return result

这里,result 是您要返回的函数句柄

但是,请记住,如果您到达异常块,客户端可能已经关闭

你也可以

  1. 将客户端传递给函数,而不是项目详细信息。函数调用后关闭客户端
  2. 从函数定义中删除Try,并实际处理异常或在成功时关闭客户端,然后返回Some[Map]

【讨论】:

  • 感谢您的帮助,但是,不起作用,我收到此错误:[error] val result = secrets => secrets.flatMap { [error] ^ [error] 发现一个错误 [error] ( Compile / compileIncremental) 编译失败
  • 你可能需要像val result = (secrets: List[String]) => { secrets.flatMap { secret => }.toMap }这样的东西