Close GCP SecretManagerServiceClient after getting secrets from it

434 Views Asked by At

How can I close the client in the following code:

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
}

the above method create a client to connect to GCP Secret Manager, to get secrets values, but i have some questions:

  1. this fragment what is supposed to do :
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. How i can tranform the code to return the secrets values in a Map[String, String], and close the client connection (something like that):

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
}

Thanks in advance ;)

1

There are 1 best solutions below

2
OneCricketeer On BEST ANSWER

If I understand correctly, you'll need to close the client after you get the map

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

Here, the result is a function handle, that you're returning

However, keep in mind that the client may already have been closed, if you ever reach the exception block

Alternatively, you can

  1. Pass a client to the function, not the project details. Close the client after your function call
  2. Remove the Try from the function definition, and actually handle the exceptions or close the client upon a Success, then return Some[Map]