Local pubsub emulator via docker compose && Spring Boot

Docker compose

How to run local pubsub inside docker? Here is a docker compose file that will:

  • pull in the google/cloud-sdk:emulators image
  • initialize the project with id test-project-id
  • create topic with name test-v1-topic
  • create subscription with name test-v1-subscription
version: '3.8'

services:
  pubsub-emulator:
    image: google/cloud-sdk:emulators
    container_name: pubsub-emulator
    ports:
      - "8085:8085"
    command: gcloud beta emulators pubsub start --host-port=0.0.0.0:8085 --project=test-project-id
    environment:
      - PUBSUB_EMULATOR_HOST=localhost:8085
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8085 || exit 1"]
      interval: 10s
      retries: 3

  setup-pubsub:
    image: google/cloud-sdk:emulators
    depends_on:
      - pubsub-emulator
    entrypoint: >
      /bin/bash -c "
      until curl -s http://pubsub-emulator:8085; do sleep 1; done;
      export PUBSUB_EMULATOR_HOST=pubsub-emulator:8085;
      curl -X PUT http://pubsub-emulator:8085/v1/projects/test-project-id/topics/test-v1-topic;
      curl -X PUT http://pubsub-emulator:8085/v1/projects/test-project-id/subscriptions/test-v1-subscription -H 'Content-Type: application/json' -d '{
        \"topic\": \"projects/test-project-id/topics/test-v1-topic\"
      }'
      "

Just run with

docker-compose up

Spring Boot

Maven dependency

		<!-- https://mvnrepository.com/artifact/com.google.cloud/spring-cloud-gcp-starter-pubsub -->
		<dependency>
			<groupId>com.google.cloud</groupId>
			<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
			<version>5.5.1</version>
		</dependency>

application.properties

# application.properties
spring.cloud.gcp.pubsub.emulator-host=localhost:8085
spring.cloud.gcp.project-id=test-project-id

# pubsub.topic=test-v1-topic
# pubsub.subscription=test-v1-subscription

Test publisher

@RestController
@RequiredArgsConstructor
public class PublisherController {
    private final PubSubTemplate pubSubTemplate;


    @PostMapping("/publish")
    public String publishMessage(@RequestParam("message") String message) {
        pubSubTemplate.publish("test-v1-topic", message);
        return "Message published successfully.";
    }

}

Test receiver

@Service
public class PubSubSubscriberService {

    private final PubSubTemplate pubSubTemplate;

    public PubSubSubscriberService(PubSubTemplate pubSubTemplate) {
        this.pubSubTemplate = pubSubTemplate;
        subscribeToTopic("test-v1-subscription");
    }

    public void subscribeToTopic(String subscriptionName) {
        pubSubTemplate.subscribe(subscriptionName, this::messageReceiver);
    }

    private void messageReceiver(BasicAcknowledgeablePubsubMessage message) {
        System.out.println("Message received: " + message.getPubsubMessage().getData().toStringUtf8());
        // Acknowledge the message
        message.ack();
    }
}

Github here github.

Leave a comment