Google Pub/Sub | Spring Cloud GCP | Publishing by enabling ordering key

683 views Asked by At

I want to publish a message with ordering enabled via pubSubTemplate. On building PubsubMessage and publishing it via pubSubTemplate I am getting java.lang.IllegalStateException: Cannot publish a message with an ordering key when message ordering is not enabled in the Publisher client. Please create a Publisher client with setEnableMessageOrdering(true) in the builder.

I am using Spring Cloud GCP starters dependencies for integration with Google Pub/Sub.

<dependencies>
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
  </dependency>
</dependencies>

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-gcp-dependencies</artifactId>
           <version>1.2.3.RELEASE</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement> 

I am using PubSubTemplate to publish the messages. Here is the definition of PubSubTemplate.

  @Bean
  public Credentials credentials() throws IOException {
    return GoogleCredentials.fromStream(Files.newInputStream(Paths.get(credentialsFilePath)));
  }

  @Bean
  public PublisherFactory publisherFactory(Credentials credentials) {
    return new DefaultPublisherFactory(() -> projectId);
  }

  @Bean
  public SubscriberFactory subscriberFactory(Credentials credentials) {
    return new DefaultSubscriberFactory(() -> projectId);
  }

  @Bean
  public PubSubTemplate pubSubTemplate(
      PublisherFactory publisherFactory, SubscriberFactory subscriberFactory) {
    return new PubSubTemplate(publisherFactory, subscriberFactory);
  }
1

There are 1 answers

0
Rishabh Rastogi On BEST ANSWER

Looks like, I was using the older dependencies which didn't support publishing via PubSubTemplate by enabling Ordering Key.

On updating dependencies as below, I'm able to achieve it.

<dependency>
  <groupId>com.google.cloud</groupId>
  <artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>

<dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>spring-cloud-gcp-dependencies</artifactId>
        <version>3.5.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

Ordering can be enabled at PublisherFactory level which is used to define PubSubTemplate bean like below -

  @Bean
  public PublisherFactory publisherFactory(Credentials credentials) {
    DefaultPublisherFactory factory = new DefaultPublisherFactory(() -> projectId);
    factory.setEnableMessageOrdering(true);
    factory.setCredentialsProvider(FixedCredentialsProvider.create(credentials));
    return factory;
  }

  @Bean
  public PubSubTemplate pubSubTemplate(
      PublisherFactory publisherFactory, SubscriberFactory subscriberFactory) {
    return new PubSubTemplate(publisherFactory, subscriberFactory);
  }

Now, messages can be sent by passing orderingKey in PubSubMessage object.

    pubSubTemplate.publish(topic,PubsubMessage.newBuilder()
        .setData(ByteString.copyFromUtf8(payload))
        .setOrderingKey(orderingKey)
        .build());