Spring Boot ActiveMQ Integration - Sinhala Guide | ස්ප්‍රින් බූට් සමග ActiveMQ

Spring Boot ActiveMQ Integration - Sinhala Guide | ස්ප්‍රින් බූට් සමග ActiveMQ

ආයුබෝවන් යාළුවනේ!

කොහොමද ඉතින් ඔයාලා හැමෝටම? අද අපි කතා කරන්න යන්නේ ඔයාලා software development වලදී අහලා ඇති, දැකලා ඇති, සමහරවිට පාවිච්චි කරලාත් ඇති, message queuing කියන concept එක ගැන. විශේෂයෙන්ම අපි බලමු Spring Boot එක්ක ActiveMQ කොහොමද පාවිච්චි කරන්නේ කියලා. ඔයාලා RabbitMQ වගේ ඒවා පාවිච්චි කරලා ඇති, අද අපි බලමු ඒකට හොඳ alternative එකක් විදිහට ActiveMQ සෙට් වෙන්නේ කොහොමද කියලා.

අපි දන්නවා දැන් distributed systems, microservices කියන ඒවා මාරම ජනප්‍රියයි. මේ වගේ systems වල services අතර communicate කරන්න, ඒ වගේම background tasks manage කරන්න message queues නැතුවම බෑ. දත්ත එක service එකකින් තවත් service එකකට විශ්වාසනීයව යවන්න, process වෙන්න වෙලාවක් ගන්න tasks perform කරන්න, load එක distribute කරන්න මේවා මාරම උදව් වෙනවා. ඉතින්, ActiveMQ කියන්නේ මේ වගේ දේවල් වලට තියෙන powerful, open-source solution එකක්.

මේ ලිපියෙන් අපි step-by-step බලමු Spring Boot project එකකට ActiveMQ එකතු කරගෙන, messages යවන්නෙයි, ගන්නෙයි කොහොමද කියලා. ඒ වගේම RabbitMQ වලට වඩා ActiveMQ වලට මාරු වෙද්දි බලන්න ඕන දේවල් ගැනත් පොඩ්ඩක් කතා කරමු. එහෙනම්, වැඩේට බහිමු!

ActiveMQ කියන්නේ මොකද්ද? (What is ActiveMQ?)

හරි, මුලින්ම බලමු මේ ActiveMQ කියන්නේ හරියටම මොකද්ද කියලා. Apache ActiveMQ කියන්නේ open-source, multi-protocol, Java-based message broker එකක්. සරලව කිව්වොත්, මේක තමා messages ටික manage කරන්නේ – එක තැනකින් එන messages අරගෙන, ඒවා යවන්න ඕන තැනට delivery කරන එක. මේක තමයි JMS (Java Message Service) standard එක full support කරන ජනප්‍රියම message brokers අතරින් එකක්.

ActiveMQ පාවිච්චි කරන්නේ ඇයි? (Why use ActiveMQ?)

  • Asynchronous Communication (අසමමුහුර්ත සන්නිවේදනය): Services එකිනෙකාට messages යවන්නේ බලාගෙන ඉන්නේ නැතුව. ඒ කියන්නේ, service A එකෙන් message එකක් යැව්වට පස්සේ, ඒක delivery වෙනකම් බලාගෙන ඉන්නේ නැතුව තමන්ගේ වැඩ කරගෙන යනවා. මේක system එකේ responsiveness එකයි, scalability එකයි වැඩි කරනවා.
  • Decoupling (වෙන් කිරීම): Producer (message එක යවන කෙනා) සහ Consumer (message එක ගන්න කෙනා) එකිනෙකාගෙන් වෙන් කරනවා. ඒ කියන්නේ, producer දන්නේ නෑ consumer කවුද කියලා, consumer දන්නෙත් නෑ producer කවුද කියලා. මේකෙන් system එකේ maintainability එකයි, flexibility එකයි වැඩි වෙනවා.
  • Reliability (විශ්වාසනීයත්වය): Messages අතරමග නැති වෙන්නේ නැතුව ගමනාන්තයටම යනවා කියලා ActiveMQ වගබලා ගන්නවා. Durable subscriptions, persistent messages වගේ features මේකට උදව් වෙනවා.
  • Scalability (ප්‍රසාරණය වීමේ හැකියාව): Workload එක වැඩි වෙද්දී ActiveMQ cluster කරන්න පුළුවන්, ඒ කියන්නේ servers කිහිපයක් එකතු කරලා work එක බෙදාගන්න පුළුවන්.
  • JMS Support: Java applications වලට JMS standard එක හරහා ActiveMQ එක්ක පහසුවෙන් communicate කරන්න පුළුවන්. මේකෙන් ඔයාලට vendor lock-in නැතුව වෙනත් JMS brokers වලට මාරු වෙන්නත් පුළුවන්.

ActiveMQ වල ප්‍රධාන messaging models දෙකක් තියෙනවා:

  1. Point-to-Point (Queues): මේකේදී message එකක් යන්නේ එක consumer කෙනෙක්ට විතරයි. ඒ කියන්නේ, message එකක් queue එකකට දැම්මම, ඒක ගන්න පුළුවන් එක consumer කෙනෙක්ට විතරයි. (e.g., Task processing)
  2. Publish/Subscribe (Topics): මේකේදී message එකක් යවපු ගමන් ඒ topic එකට subscribe කරලා ඉන්න හැම consumer කෙනෙක්ටම ඒ message එක ලැබෙනවා. (e.g., Real-time notifications)

හරි, දැන් ActiveMQ ගැන මූලික අවබෝධයක් තියෙන නිසා, අපි බලමු මේක Spring Boot project එකකට සෙට් කරගන්නේ කොහොමද කියලා.

Spring Boot Project එකක් හදමු (Let's Create a Spring Boot Project)

වැඩේ පටන් ගන්න කලින් අපිට ඕන වෙනවා Spring Boot project එකක්. මේක හදාගන්න ලේසිම විදිය තමයි Spring Initializr පාවිච්චි කරන එක. ඔයාලට පුළුවන් මේ steps ටික follow කරන්න:

  1. start.spring.io එකට යන්න.
  2. Project: Maven Project (නැත්නම් Gradle)
  3. Language: Java
  4. Spring Boot: Latest Stable Version එක (දැනට 3.x.x වගේ එකක් වෙයි)
  5. Group: com.example
  6. Artifact: spring-boot-activemq-example
  7. Name: spring-boot-activemq-example
  8. Package name: com.example.springbootactivemqexample
  9. Packaging: Jar
  10. Java: 17 (නැත්නම් ඔයාලට අවශ්‍ය version එක)
  11. Dependencies: මෙතනදී අපි "Spring Web" සහ "Spring for Apache ActiveMQ" කියන dependencies දෙක search කරලා add කරගන්න ඕනේ. (RabbitMQ project එකක නම් "Spring AMQP" add කරලා තියෙන්නේ, මේකෙන් අපිට ActiveMQ වලට මාරු වෙන්න පුළුවන්.)
  12. දැන් Generate button එක click කරලා project එක download කරගන්න.

Download කරපු `.zip` file එක extract කරලා, ඔයාලා පාවිච්චි කරන IDE (IntelliJ IDEA, VS Code, Eclipse) එකට import කරගන්න. දැන් අපිට Spring Boot project එක සෙට් වෙලා තියෙන්නේ ActiveMQ එක්ක වැඩ කරන්න.

ActiveMQ Server එකක් සෙට් කරමු

අපේ Spring Boot application එක ActiveMQ එක්ක කතා කරන්න නම්, ActiveMQ server එකක් run වෙලා තියෙන්න ඕනේ. මේක ඔයාලගේ local machine එකේම run කරන්න පුළුවන්. ActiveMQ server එක download කරගන්න පුළුවන් Apache ActiveMQ වෙබ්සයිට් එකෙන්. Download කරලා extract කරාට පස්සේ, `bin` folder එක ඇතුලේ තියෙන `activemq` (Linux/macOS) නැත්නම් `activemq.bat` (Windows) file එක run කරන්න. සාමාන්‍යයෙන් මේක `tcp://localhost:61616` port එකේ run වෙයි. ඒ වගේම `http://localhost:8161/admin` වලට ගිහින් username එක `admin` සහ password එක `admin` දීලා ActiveMQ web console එකට ලොග් වෙලා broker එකේ තත්වය බලන්නත් පුළුවන්.

ActiveMQ එක්ක සම්බන්ධ වෙමු (Connecting with ActiveMQ)

Spring Boot project එකයි ActiveMQ server එකයි ලෑස්ති කරගත්තු නිසා, දැන් අපිට පුළුවන් ActiveMQ එක්ක සම්බන්ධ වෙන්න. මේකට අපි `application.properties` (නැත්නම් `application.yml`) file එකේ ActiveMQ connection details ටික define කරන්න ඕනේ.

application.properties Configuration

ඔයාලගේ `src/main/resources` folder එකේ තියෙන `application.properties` file එකට මේ settings ටික add කරන්න:

# ActiveMQ Broker URL
spring.activemq.broker-url=tcp://localhost:61616
# ActiveMQ Credentials (change if you have different ones)
spring.activemq.user=admin
spring.activemq.password=admin
# Enable Pub/Sub domain for topics (optional, default is false for queues)
spring.jms.pub-sub-domain=true

මේ codes වලින් කරන්නේ:

  • `spring.activemq.broker-url`: ActiveMQ server එක run වෙන URL එක. Default එක `tcp://localhost:61616`. ඔයාලා වෙන server එකක් පාවිච්චි කරනවා නම් ඒකේ IP address එකයි port එකයි දෙන්න ඕනේ.
  • `spring.activemq.user` සහ `spring.activemq.password`: ActiveMQ broker එකට authenticate වෙන්න ඕන credentials. Default admin user එක `admin`, password එකත් `admin`. Security considerations වලදී මේවා වෙනස් කරන්න අමතක කරන්න එපා.
  • `spring.jms.pub-sub-domain`: මේක `true` කරොත් Spring Boot JMS template එක by default topics එක්ක වැඩ කරන්න configure වෙනවා. `false` (default) වුනොත් queues එක්ක. අපි queues සහ topics දෙකම පාවිච්චි කරන නිසා මේක `true` කරලා, topics වලට වෙනම `JmsListenerContainerFactory` එකක් හදමු.

මේ settings ටික දැම්මම Spring Boot auto-configuration එකෙන් ActiveMQ connection factory එක හදලා දෙනවා. අපිට ඒ ගැන කරදර වෙන්න දෙයක් නෑ. නියමයි නේද?

JMS Template සහ JmsListener

Spring Boot JMS වලදී, messages යවන්න අපි JmsTemplate එක පාවිච්චි කරනවා, messages ගන්න අපි @JmsListener annotation එක පාවිච්චි කරනවා.

JmsTemplate: Spring Framework එකෙන් provide කරන utility class එකක්. මේකෙන් අපිට JMS broker එකට messages යවන්න, receive කරන්න, convert කරන්න වගේ දේවල් පහසුවෙන් කරන්න පුළුවන්. Spring Boot auto-configuration එකෙන් මේ JmsTemplate එක බීන් (bean) එකක් විදිහට register කරන නිසා, අපිට කෙලින්ම අපේ services වලට inject කරලා පාවිච්චි කරන්න පුළුවන්.

@JmsListener: මේක Spring Boot එකෙන් දෙන annotation එකක්. මේක අපි අපේ consumer methods උඩ දැම්මම, ඒ method එකට අදාල queue එකට නැත්නම් topic එකට messages ආවම ඒ methods automatically trigger වෙනවා. RabbitMQ වලදී `@RabbitListener` වගේම මේකත් වැඩ කරනවා.

Producer සහ Consumer හදමු (Let's Create a Producer and Consumer)

දැන් අපි බලමු කොහොමද message එකක් යවන (Producer) service එකකුයි, message එකක් ගන්න (Consumer) service එකකුයි හදාගන්නේ කියලා. මේකෙන් අපිට පුළුවන් messages ActiveMQ හරහා යවන එකයි, ගන්න එකයි practice කරන්න.

1. Message Producer Service එක (JmsProducerService.java)

මුලින්ම අපි `com.example.springbootactivemqexample.producer` package එකක් හදලා ඒක ඇතුලේ `JmsProducerService.java` කියන class එක හදමු:

package com.example.springbootactivemqexample.producer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;

@Service // Spring Bean එකක් විදිහට define කරනවා
public class JmsProducerService {

    @Autowired // JmsTemplate එක inject කරගන්නවා
    private JmsTemplate jmsTemplate;

    /**
     *  Queue එකකට හෝ Topic එකකට message එකක් යවන method එක.
     * @param destinationName - Queue එකේ හෝ Topic එකේ නම
     * @param message - යවන්න ඕන message එක (String)
     */
    public void sendMessage(String destinationName, String message) {
        System.out.println("Sending message to " + destinationName + ": " + message);
        // jmsTemplate.convertAndSend() method එකෙන් message එක යවනවා
        // මේකෙන් String එකක් වුනත් object එකක් වුනත් යවන්න පුළුවන්, JMS format එකට convert කරලා
        jmsTemplate.convertAndSend(destinationName, message);
        System.out.println("Message sent successfully!");
    }

    /**
     *  ගොඩක් වෙලාවට Queues වලට පාවිච්චි වෙනවා.
     * @param queueName - Queue එකේ නම
     * @param message - යවන්න ඕන message එක
     */
    public void sendToQueue(String queueName, String message) {
        System.out.println("Sending message to queue " + queueName + ": " + message);
        jmsTemplate.convertAndSend(queueName, message);
    }

    /**
     *  Topics වලට පාවිච්චි වෙනවා (publish/subscribe).
     *  Topics වලට යවන messages ගන්න නම් pub-sub-domain=true configuration එක අවශ්‍යයි.
     * @param topicName - Topic එකේ නම
     * @param message - යවන්න ඕන message එක
     */
    public void sendToTopic(String topicName, String message) {
        System.out.println("Sending message to topic " + topicName + ": " + message);
        // jmsTemplate.setPubSubDomain(true); // If you want to force pub-sub on template level
        jmsTemplate.convertAndSend(topicName, message);
    }
}

මේ `JmsProducerService` එකේ තියෙන්නේ `JmsTemplate` එක පාවිච්චි කරලා message එකක් `destinationName` එකට යවන simple method එකක්. `destinationName` කියන්නේ queue එකක නමක් වෙන්නත් පුළුවන්, topic එකක නමක් වෙන්නත් පුළුවන්.

2. Message Consumer Service එක (JmsConsumerService.java)

ඊළඟට අපි `com.example.springbootactivemqexample.consumer` package එකක් හදලා ඒක ඇතුලේ `JmsConsumerService.java` කියන class එක හදමු. මේකෙන් අපි messages receive කරගන්නේ:

package com.example.springbootactivemqexample.consumer;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component // Spring Bean එකක් විදිහට define කරනවා
public class JmsConsumerService {

    /**
     *  'my-queue' කියන Queue එකෙන් messages receive කරන method එක.
     *  @JmsListener annotation එකෙන් කියන්නේ මේ method එකට messages එන්නේ කොහෙන්ද කියලා.
     * @param message - ලැබුණු message එක
     */
    @JmsListener(destination = "my-queue")
    public void receiveQueueMessage(String message) {
        System.out.println("Received message from my-queue: " + message);
        // මෙතනදී ඔයාලට පුළුවන් ලැබුණු message එක process කරන්න.
        // උදා: database එකට save කරන්න, වෙන service එකකට යවන්න
    }

    /**
     *  'my-topic' කියන Topic එකෙන් messages receive කරන method එක.
     *  topics වලට messages receive කරනවා නම්, ඒකට වෙනම jmsListenerContainerFactory එකක් ඕන වෙනවා
     *  pub-sub-domain=true කියලා configure කරපු.
     * @param message - ලැබුණු message එක
     */
    @JmsListener(destination = "my-topic", containerFactory = "jmsListenerContainerFactory")
    public void receiveTopicMessage(String message) {
        System.out.println("Received message from my-topic: " + message);
        // Topic messages process කරන්න.
    }
}

`@JmsListener` annotation එකේ `destination` attribute එකෙන් අපි කියනවා මේ method එක listen කරන්නේ මොන queue එකටද නැත්නම් මොන topic එකටද කියලා. `containerFactory` attribute එක අපි පාවිච්චි කරන්නේ `my-topic` වගේ topic එකකට listen කරනවා නම්, මොකද ඒකට වෙනම pub-sub-domain enable කරපු factory එකක් අවශ්‍ය වෙනවා.

3. Spring Boot Application එක (SpringBootActivemqApplication.java)

දැන් අපි අපේ main application class එක edit කරලා, producer එක පාවිච්චි කරලා messages යවමු, ඒ වගේම topic listener එකට අවශ්‍ය වෙන factory එකත් configure කරමු:

package com.example.springbootactivemqexample;

import com.example.springbootactivemqexample.producer.JmsProducerService;
import jakarta.jms.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;

@SpringBootApplication
@EnableJms // JMS listeners enable කරන්න මේක අනිවාර්යයි!
public class SpringBootActivemqApplication implements CommandLineRunner {

    @Autowired
    private JmsProducerService producerService;

    public static void main(String[] args) {
        SpringApplication.run(SpringBootActivemqApplication.class, args);
    }

    /**
     *  Application එක start වුණාම run වෙන method එකක්.
     *  අපිට මෙතනින් messages ටිකක් යවලා බලන්න පුළුවන්.
     */
    @Override
    public void run(String... args) throws Exception {
        System.out.println("Application started. Sending messages...");
        // Queue එකකට messages යවමු
        producerService.sendToQueue("my-queue", "Hello from Spring Boot to Queue!");
        producerService.sendToQueue("my-queue", "This is another message for the queue!");

        // Topic එකකට messages යවමු
        producerService.sendToTopic("my-topic", "News update for all subscribers!");
        producerService.sendToTopic("my-topic", "Emergency alert to topic!");

        System.out.println("Messages sent. Check console for received messages.");
    }

    /**
     *  Topic listeners වලට අවශ්‍ය JMS Listener Container Factory එක configure කරනවා.
     *  'spring.jms.pub-sub-domain=true' තිබ්බත්, topic listen කරන්න මේ bean එක අවශ්‍ය වෙනවා.
     */
    @Bean
    public JmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setPubSubDomain(true); // Pub/Sub domain එක enable කරනවා
        // මේ factory එකට වෙනත් settings දාන්නත් පුළුවන්, e.g., concurrency, message converter
        return factory;
    }
}

මෙතන `SpringBootActivemqApplication` class එකට `CommandLineRunner` interface එක implement කරලා, `run` method එක ඇතුලේ අපි test messages ටිකක් යවනවා. ඒ වගේම `jmsListenerContainerFactory` කියන Bean එක අපි හදලා තියෙනවා `my-topic` එකට listen කරන්න පුළුවන් වෙන විදියට (pub/sub domain enable කරලා).

දැන් වැඩේ Run කරමු!

දැන් ඔයාලට පුළුවන් මේ Spring Boot application එක run කරන්න. IDE එකෙන් හෝ Maven command එකකින් (`mvn spring-boot:run`) run කරන්න. ActiveMQ server එක run වෙලා තියෙනවාද කියලත් confirm කරගන්න අමතක කරන්න එපා. Output එකේ `Sending message...` සහ `Received message...` කියන ලයින්ස් ඔයාලට බලාගන්න පුළුවන් වෙයි. නියමයි නේද? ඔයාලා දැන් Spring Boot එක්ක ActiveMQ පාවිච්චි කරලා messages යවන්නයි, ගන්නයි ඉගෙනගෙන ඉවරයි!

RabbitMQ වෙනුවට ActiveMQ:

ඔයාලා RabbitMQ project එකක ඉඳන් ActiveMQ වලට මාරු වෙනවා නම්, වෙනස්කම් ටිකක් තියෙනවා. RabbitMQ වලදී අපි `spring-boot-starter-amqp` dependency එක පාවිච්චි කරලා, `@RabbitListener` annotation එකෙන් messages receive කරා. configuration වලදී broker URL එක `spring.rabbitmq.host`, `spring.rabbitmq.port` වගේ properties වලින් define කරා. ActiveMQ වලදී අපි `spring-boot-starter-activemq` පාවිච්චි කරලා, `@JmsListener` annotation එකෙන් messages receive කරනවා. Configuration වලදී `spring.activemq.broker-url` වගේ properties පාවිච්චි කරනවා. අනිත් concept එක Message Producer/Consumer වගේමයි, implementation එක විතරයි වෙනස් වෙන්නේ. ඉතින්, බය වෙන්න එපා, වැඩේ ලේසියෙන් කරගන්න පුළුවන්!

ප්‍රායෝගික උපදෙස් සහ උපක්‍රම (Practical Tips & Tricks)

මූලික දේවල් ඉගෙනගත්තා වගේම, production environment එකක ActiveMQ පාවිච්චි කරද්දී දැනගෙන ඉන්න ඕන තවත් වැදගත් දේවල් කිහිපයක් තියෙනවා:

1. Error Handling සහ Dead-Letter Queues (DLQ)

සමහර වෙලාවට messages process කරද්දී errors එන්න පුළුවන්. ඒ වගේ වෙලාවට message එක process කරන්න බැරි වෙන්න පුළුවන්. ActiveMQ වලදී මේ වගේ messages dead-letter queue එකකට (DLQ) යවන්න පුළුවන්. මේකෙන් අපිට පසුව මේ messages examine කරලා, error එක fix කරලා ආයෙත් process කරන්න පුළුවන්. ActiveMQ default configuration එකේදී DLQ එකක් automatically handle කරනවා (e.g., `ActiveMQ.DLQ`). ඔයාලට පුළුවන් `errorHandler` වගේ දේවල් පාවිච්චි කරලා custom error handling logic එකක් ලියන්න.

// Custom Error Handler for JMS Listeners
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ErrorHandler;

@Configuration
public class JmsConfig {

    @Bean
    public ErrorHandler myJmsErrorHandler() {
        return new ErrorHandler() {
            @Override
            public void handleError(Throwable t) {
                System.err.println("JMS Error occurred: " + t.getMessage());
                // Log the error, send alert, move to DLQ manually etc.
            }
        };
    }
}
// Use the custom error handler in your JmsListenerContainerFactory
// DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// factory.setErrorHandler(myJmsErrorHandler());

2. Persistent Messages (ස්ථිර පණිවිඩ)

ActiveMQ server එක restart වුනොත් messages නැති වෙන්න බෑ කියලා sure කරගන්න නම්, messages persistent කරන්න ඕනේ. Default configuration එකේදී queues වලට යවන messages persist වෙනවා. Topics වලට යවන messages durable subscriptions නැත්නම් restart වෙද්දී නැති වෙන්න පුළුවන්. Durable subscriptions හදාගන්න නම්, consumer එක client ID එකක් දීලා `setDurableSubscription(true)` කියලා specify කරන්න ඕනේ.

@Bean
public JmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setPubSubDomain(true);
    factory.setClientId("my-unique-client-id"); // අනිවාර්යයි durable subscriptions වලට
    factory.setSubscriptionDurability("DurableTopicSubscription"); // නමක් දෙන්න
    return factory;
}

3. Transaction Management (ගනුදෙනු කළමනාකරණය)

සමහර වෙලාවට ඔයාලට message එකක් receive කරලා, database එකක data update කරලා, ඊට පස්සේ තව message එකක් send කරන්න වගේ දේවල් එක transaction එකක් විදිහට කරන්න ඕනේ වෙන්න පුළුවන්. මේ වගේ වෙලාවට Spring Framework එකේ `@Transactional` annotation එක පාවිච්චි කරන්න පුළුවන්. Spring Boot එකෙන් JMS transactions support කරනවා.

import org.springframework.transaction.annotation.Transactional;

@JmsListener(destination = "my-queue")
@Transactional // Method එකේ operations එක transaction එකක් විදිහට run වෙනවා
public void receiveAndProcessTransactionalMessage(String message) {
    System.out.println("Processing transactional message: " + message);
    // Database update operations
    // ...
    // Send another message (if needed within the same transaction)
    // jmsTemplate.convertAndSend("another-queue", "Processed: " + message);
}

4. Monitoring සහ Administration

ActiveMQ broker එකේ performance එකයි, message flowsයි monitor කරන එක මාරම වැදගත්. ActiveMQ වලට තියෙනවා web console එකක් (`http://localhost:8161/admin`). මේකෙන් queues, topics, connections, pending messages වගේ හැම දෙයක්ම බලාගන්න පුළුවන්. ඒ වගේම JMX (Java Management Extensions) හරහා monitoring tools වලට data expose කරනවා.

5. Message Converters

අපේ උදාහරණයේදී අපි String messages යැව්වේ. හැබැයි, complex Java objects යවන්න ඕන නම්, අපිට Message Converters පාවිච්චි කරන්න පුළුවන් (e.g., `MappingJackson2MessageConverter` for JSON conversion). මේකෙන් object එක automatically JMS message format එකට convert කරලා යවනවා.

import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageType;

@Bean
public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT); // Convert to Text message with JSON payload
    converter.setTypeIdPropertyName("_type"); // Add type information
    return converter;
}

// Then set this converter to your JmsTemplate and JmsListenerContainerFactory
// jmsTemplate.setMessageConverter(jacksonJmsMessageConverter());
// factory.setMessageConverter(jacksonJmsMessageConverter());

අවසාන වශයෙන් (Conclusion)

හරි යාළුවනේ, ඔයාලා දැන් ActiveMQ එක්ක Spring Boot පාවිච්චි කරලා robust messaging solutions හදාගන්න අවශ්‍ය මූලික දැනුම ලබාගෙන ඉවරයි. අපි මේ ලිපියෙන් ActiveMQ කියන්නේ මොකද්ද, ඒකේ වාසි මොනවද, Spring Boot project එකකට ActiveMQ add කරන්නේ කොහොමද, producer සහ consumer services ලියන්නේ කොහොමද කියලා විස්තරාත්මකව කතා කළා. ඒ වගේම RabbitMQ project එකක් ActiveMQ වලට migrate කරද්දී බලන්න ඕන දේවල් සහ production එකට යද්දී අවශ්‍ය වෙන advanced tips & tricks කිහිපයකුත් කතා කරා.

ActiveMQ කියන්නේ powerful සහ flexible message broker එකක්. විශේෂයෙන්ම JMS standard එක එක්ක වැඩ කරනවා නම් මේක මාරම පහසුයි. ඔයාලට මේක distributed systems, event-driven architectures වගේ දේවල් වලට සාර්ථකව පාවිච්චි කරන්න පුළුවන්.

දැන් ඉතින්, තියෙන්නේ මේ කාරණා ඔයාලගේම project එකක් හදලා practice කරන එක තමයි. code එක ලියලා බලන්න, ActiveMQ console එකට ගිහින් messages flow වෙන හැටි බලන්න. මොකද, theory එක ඉගෙනගත්තට වඩා practice කරන එකෙන් තමයි හොඳටම වැඩේ ගොඩ දාගන්න පුළුවන්.

මේ ලිපිය ගැන මොනවා හරි ප්‍රශ්න තියෙනවා නම්, නැත්නම් ඔයාලගේ අත්දැකීම් බෙදාගන්න ඕන නම්, පහලින් comment එකක් දාන්න. අපි ඊළඟ ලිපියෙන් තවත් අලුත් දෙයක් අරගෙන එන්නම්! එතකම්, happy coding!

ඔබට සුබ දවසක්!