如何在应用程序开始时不需要服务帐户凭据json的情况下将消息发布到google pub / sub?

How to publish a message to google pub/sub without the need of service account credentials json required at the start of the application?

提问人:Lakshmi Pravallika 提问时间:5/6/2023 更新时间:5/11/2023 访问量:438

问:

我构建了一个 gradle 应用程序,它将消息发布到 google pub/sub。我已经在 GCP 上创建了一个服务帐户并下载了凭据 json 文件。我已经在 GCP 上创建了主题和订阅,在订阅中,我已将我的服务帐户名称添加为主体,并赋予了发布/订阅编辑角色。 这是我的 gradle 应用程序详细信息。

Gradle 依赖:implementation group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-pubsub',version: '1.2.8.RELEASE'

实现'org.springframework.cloud:spring-cloud-gcp-starter:1.2.0.RELEASE'

application.yaml: 弹簧: 配置 文件: 活动:myEnv 应用: 名称:pubsub 云: GCP: 项目 ID:project_id 凭据: 位置: classpath:credentials.json

我已将此credentials.json放在 src/main/resources 中。

这是我的服务类。

public String publishMessageToPubSub() throws IOException, InterruptedException, ExecutionException {
        String response = "Success";
        Publisher publisher = null;
        boolean isShutdown = false;
        try {           
                    
            //pubsubProperties.getGcp_config() : This piece of code is getting the credJsonString from AWS paramstore
            InputStream inputStream = new ByteArrayInputStream(pubsubProperties.getGcp_config().getBytes());

            CredentialsProvider credentialsProvider = FixedCredentialsProvider
                    .create(GoogleCredentials.fromStream(inputStream));

            ProjectTopicName topic = ProjectTopicName.of("project_id","topic_id");

            publisher = Publisher.newBuilder(topic).setCredentialsProvider(credentialsProvider).build();

            String messageToBePublished = "Hello World";

            byte[] encodedBytes = Base64.getEncoder().encode(messageToBePublished.getBytes());
            String encodedMessage = new String(encodedBytes);

            ByteString data = ByteString.copyFromUtf8(encodedMessage);
            PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(data).build();

            ApiFuture<String> messageIdFuture = publisher.publish(pubsubMessage);
            String messageId = null;

            try {
                messageId = messageIdFuture.get();
                log.info("Message Published Successfully with message Id : " + messageId);
            } catch (Exception e) {
                
                throw e;
            }

            publisher.shutdown();
            isShutdown = true;
        } catch (HttpStatusCodeException ioe) {
            throw ioe;
        } catch (Exception e) {
            throw e;
        } finally {
            if (publisher != null && !isShutdown) {
                // When finished with the publisher, shutdown to free up resources.
                publisher.shutdown();
                publisher.awaitTermination(1, TimeUnit.MINUTES);
            }
        }
    

        return response;
    }

此代码工作正常,消息在 GCP 中发布,而credentials.json文件位于 src/main/resources 中。

出于安全考虑,我们不能将此文件放在 github 中,并且此应用程序将通过 Jenkins 管道进行部署,并将 git 分支带到 ECS 集群。 但是,如果文件不存在,则应用程序未启动,并且在执行 run 方法后立即引发以下错误。

java.io.IOException:应用程序缺省凭证不可用。如果在 Google Compute Engine 中运行,则它们可用。否则,必须定义指向定义凭据的文件的环境变量GOOGLE_APPLICATION_CREDENTIALS。有关详细信息,请参阅 https://developers.google.com/accounts/docs/application-default-credentials

它需要spring.cloud.gcp.project-id和spring.cloud.gcp.credentials.location属性,并试图查找credentials.json的位置,并使用内容来实例化一些PubSub类。

并将此 java 应用程序部署到 ECS 集群。

请向我建议一种不需要credentials.json路径来启动应用程序的方法,因为我可以设法获取 json 的内容以在代码中创建 GoogleCredentials。 或者是否有任何其他不需要credentials.json文件的身份验证方式。

java spring-boot google-cloud-pubsub asynccallback

评论

0赞 tushar 7/19/2023
你找到任何解决方案了吗?不暴露credentials.json

答:

0赞 Sneha Mule 5/11/2023 #1

您需要在项目中添加服务帐户(将从 pubsub 读取消息的应用程序)。并向该服务帐号添加 gcp 发布者访问权限。

因此,您可以在没有凭据的情况下在 tipic 上发布