├── README.md ├── docker-compose.yml ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── javatechie │ │ ├── SpringPulsarDemoApplication.java │ │ ├── consumer │ │ └── EventConsumer.java │ │ ├── controller │ │ └── EventController.java │ │ ├── dto │ │ └── Customer.java │ │ └── producer │ │ └── EventPublisher.java └── resources │ ├── application.properties │ └── application.yml └── test └── java └── com └── javatechie └── SpringPulsarDemoApplicationTests.java /README.md: -------------------------------------------------------------------------------- 1 | # springboot-apache-pulsar 2 | 3 | 4 | ### Create Admin user : 5 | 6 | ``` 7 | CSRF_TOKEN=$(curl http://localhost:7750/pulsar-manager/csrf-token) 8 | 9 | curl \ 10 | -H "X-XSRF-TOKEN: $CSRF_TOKEN" \ 11 | -H "Cookie: XSRF-TOKEN=$CSRF_TOKEN;" \ 12 | -H "Content-Type: application/json" \ 13 | -X PUT http://localhost:7750/pulsar-manager/users/superuser \ 14 | -d '{"name": "admin", "password": "apachepulsar", "description": "test", "email": "username@test.org"}' 15 | ``` 16 | 17 | ### Apache Pulsar archtecture 18 | 19 | ![Screenshot 2024-03-14 at 9 44 01 PM](https://github.com/Java-Techie-jt/springboot-apache-pulsar/assets/25712816/63daeb90-f6f6-4328-8b21-49f0bdfdee01) 20 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | 3 | services: 4 | pulsar: 5 | image: "apachepulsar/pulsar:2.10.1" 6 | command: bin/pulsar standalone 7 | environment: 8 | PULSAR_MEM: "-Xms512m -Xmx512m -XX:MaxDirectMemorySize=1g" 9 | ports: 10 | - "6650:6650" 11 | - "8080:8080" 12 | restart: unless-stopped 13 | networks: 14 | - pulsar_network 15 | 16 | pulsar-manager: 17 | image: "apachepulsar/pulsar-manager:v0.2.0" 18 | ports: 19 | - "9527:9527" 20 | - "7750:7750" 21 | depends_on: 22 | - pulsar 23 | environment: 24 | SPRING_CONFIGURATION_FILE: /pulsar-manager/pulsar-manager/application.properties 25 | networks: 26 | - pulsar_network 27 | 28 | networks: 29 | pulsar_network: 30 | name: pulsar_network 31 | driver: bridge -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.3 9 | 10 | 11 | com.javatechie 12 | spring-pulsar-demo 13 | 0.0.1-SNAPSHOT 14 | spring-pulsar-demo 15 | Demo project for Spring Boot 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-pulsar 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | true 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-test 37 | test 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-maven-plugin 46 | 47 | 48 | 49 | org.projectlombok 50 | lombok 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/SpringPulsarDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.javatechie; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.pulsar.annotation.EnablePulsar; 6 | 7 | @SpringBootApplication 8 | @EnablePulsar 9 | public class SpringPulsarDemoApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringPulsarDemoApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/consumer/EventConsumer.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.consumer; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.javatechie.dto.Customer; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.apache.pulsar.client.api.SubscriptionType; 8 | import org.apache.pulsar.common.schema.SchemaType; 9 | import org.springframework.pulsar.annotation.PulsarListener; 10 | import org.springframework.stereotype.Service; 11 | 12 | @Service 13 | @Slf4j 14 | public class EventConsumer { 15 | 16 | 17 | @PulsarListener( 18 | topics = "${spring.pulsar.producer.topic-name1}", 19 | subscriptionName = "my-subscription", 20 | subscriptionType = SubscriptionType.Shared 21 | ) 22 | public void consumeTextEvent(String msg) { 23 | log.info("EventConsumer:: consumeTextEvent consumed events {}", msg); 24 | } 25 | 26 | 27 | @PulsarListener( 28 | topics = "${spring.pulsar.producer.topic-name2}", 29 | subscriptionName = "my-subscription", 30 | schemaType = SchemaType.JSON, 31 | subscriptionType = SubscriptionType.Shared 32 | ) 33 | public void consumeRawEvent(Customer customer) throws JsonProcessingException { 34 | log.info("EventConsumer:: consumeTextEvent consumed events {}", new ObjectMapper().writeValueAsString(customer)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/controller/EventController.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.controller; 2 | 3 | import com.javatechie.dto.Customer; 4 | import com.javatechie.producer.EventPublisher; 5 | import org.apache.pulsar.client.api.PulsarClientException; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | @RestController 10 | @RequestMapping("/producer") 11 | public class EventController { 12 | 13 | 14 | @Autowired 15 | private EventPublisher publisher; 16 | 17 | @GetMapping("/text/{message}") 18 | public String sendTextEvent(@PathVariable String message) throws PulsarClientException { 19 | publisher.publishPlainMessage(message); 20 | return "message published !"; 21 | } 22 | 23 | @PostMapping("/raw") 24 | public String sendRawEvent(@RequestBody Customer customer) throws PulsarClientException { 25 | publisher.publishRawMessage(customer); 26 | return "Custom object published !"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/dto/Customer.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class Customer { 11 | 12 | private int id; 13 | private String name; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/producer/EventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.producer; 2 | 3 | import com.javatechie.dto.Customer; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.apache.pulsar.client.api.PulsarClientException; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.pulsar.core.PulsarTemplate; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service 12 | @Slf4j 13 | public class EventPublisher { 14 | 15 | 16 | @Value("${spring.pulsar.producer.topic-name1}") 17 | private String topicName1; 18 | 19 | @Value("${spring.pulsar.producer.topic-name2}") 20 | private String topicName2; 21 | 22 | @Autowired 23 | private PulsarTemplate template; 24 | 25 | public void publishPlainMessage(String message) throws PulsarClientException { 26 | template.send(topicName1, message); 27 | log.info("EventPublisher::publishPlainMessage publish the event {}", message); 28 | } 29 | 30 | 31 | public void publishRawMessage(Customer customer) throws PulsarClientException { 32 | template.send(topicName2, customer); 33 | log.info("EventPublisher::publishRawMessage publish the event {}", customer.getName()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-pulsar-demo 2 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9191 3 | 4 | spring: 5 | pulsar: 6 | client: 7 | service-url: pulsar://localhost:6650 8 | producer: 9 | topic-name1: jt-plain-topic 10 | topic-name2: jt-raw-topic 11 | consumer: 12 | subscription: 13 | name: my-subscription 14 | defaults: 15 | type-mappings: 16 | - messageType: com.javatechie.dto.Customer 17 | schema-info: 18 | schema-type: JSON -------------------------------------------------------------------------------- /src/test/java/com/javatechie/SpringPulsarDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.javatechie; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringPulsarDemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------