Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Add the message producers and listeners

You will next add the code required to send and receive messages to the visits-service. The messaging-emulator will send a PetClinicMessageRequest to the visits-requests queue. The visits-service will need to listen to this queue and each time a VisitRequest message is submitted, it will create a new Visit for the pet ID referenced in the message. The visits-service will also send back a VisitResponse as a confirmation to the visits-confirmations queue. This is the queue the messaging-emulator is listening to.

Step by step guidance

  1. In the spring-petclinic-visits-service directory, create a new src/main/java/org/springframework/samples/petclinic/visits/entities subdirectory and add a VisitRequest.java class file containing the following code:

    package org.springframework.samples.petclinic.visits.entities;
       
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.AllArgsConstructor;
    import java.io.Serializable;
       
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class VisitRequest implements Serializable {
        private static final long serialVersionUID = -249974321255677286L;
       
        private Integer requestId;
        private Integer petId;
        private String message;
    }
    
  2. In the same directory, add a VisitResponse.java class containing the following code:

    package org.springframework.samples.petclinic.visits.entities;
    
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.AllArgsConstructor;
       
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class VisitResponse {
        Integer requestId;
        Boolean confirmed;
        String reason;
    }
    
  3. In the spring-petclinic-visits-service directory, create a new src/main/java/org/springframework/samples/petclinic/visits/config subdirectory and add a MessagingConfig.java class file containing the following code:

    package org.springframework.samples.petclinic.visits.config;
       
    import java.util.HashMap;
    import java.util.Map;
       
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
    import org.springframework.jms.support.converter.MessageConverter;
    import org.springframework.samples.petclinic.visits.entities.VisitRequest;
    import org.springframework.samples.petclinic.visits.entities.VisitResponse;
       
    @Configuration
    public class MessagingConfig {
       
        @Bean
        public MessageConverter jackson2Converter() {
            MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
       
            Map<String, Class<?>> typeMappings = new HashMap<String, Class<?>>();
            typeMappings.put("visitRequest", VisitRequest.class);
            typeMappings.put("visitResponse", VisitResponse.class);
            converter.setTypeIdMappings(typeMappings);
            converter.setTypeIdPropertyName("messageType");
            return converter;
        }
    }
    
  4. In the same directory, add a QueueConfig.java class file containing the following code:

    package org.springframework.samples.petclinic.visits.config;
       
    import org.springframework.beans.factory.annotation.Value;
       
    public class QueueConfig {
        @Value("${spring.jms.queue.visits-requests:visits-requests}")
        private String visitsRequestsQueue;
       
        @Value("${spring.jms.queue.visits-confirmations:visits-confirmations}")
        private String visitsResponsesQueue;
       
        public String getVisitsRequestsQueue() {
            return visitsRequestsQueue;
        }
       
        public String getVisitsResponsesQueue(){
            return visitsResponsesQueue;
        }
    }
    
  5. In the spring-petclinic-visits-service directory, create a new src/main/java/org/springframework/samples/petclinic/visits/service subdirectory and add a VisitsReceiver.java class file containing the following code:

    package org.springframework.samples.petclinic.visits.service;
       
    import java.util.Date;
       
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.samples.petclinic.visits.entities.VisitRequest;
    import org.springframework.samples.petclinic.visits.entities.VisitResponse;
    import org.springframework.samples.petclinic.visits.model.Visit;
    import org.springframework.samples.petclinic.visits.model.VisitRepository;
    import org.springframework.stereotype.Component;
       
    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
       
    @Component
    @Slf4j
    @RequiredArgsConstructor
    public class VisitsReceiver {
        private final VisitRepository visitsRepository;
       
        private final JmsTemplate jmsTemplate;
       
        @Value("${spring.jms.queue.visits-requests:visits-requests}")
        private String requestQueueName;
       
        @Value("${spring.jms.queue.visits-responses:visits-confirmations}")
        private String confirmationsQueueName;
       
        @JmsListener(destination = requestQueueName)
        void receiveVisitRequests(VisitRequest visitRequest) {
            log.info("Received message: {}", visitRequest.getMessage());
            try {
                Visit visit = new Visit(null, new Date(), visitRequest.getMessage(),
                    visitRequest.getPetId());
                visitsRepository.save(visit);
                jmsTemplate.convertAndSend(confirmationsQueueName, new VisitResponse(visitRequest.getRequestId(), true, "Your visit request    has been accepted"));
            } catch (Exception ex) {
                log.error("Error saving visit: {}", ex.getMessage());
                jmsTemplate.convertAndSend(confirmationsQueueName, new VisitResponse(visitRequest.getRequestId(), false, ex.getMessage()));
            }
        }
       
    }
    

    This VisitsReceiver service is listening to the visits-requests queue. Each time a message is present on the queue, it will dequeue this message and save a new Visit in the database. In the next step, you will verify it by having it sent a confirmation message to the visits-confirmations queue.

  6. Rebuild the spring-petclinic-visits-service microservice

    cd ..
    mvn clean package -DskipTests -rf :spring-petclinic-visits-service
    
  7. Navigate to the staging-acr directory, copy the jar file of the visit-service and recreate the container app.

    export APP_NAME="visits-service"
    cp ../spring-petclinic-$APP_NAME/target/spring-petclinic-$APP_NAME-$VERSION.jar spring-petclinic-$APP_NAME-$VERSION.jar
    sed -i "s|my-service|$APP_NAME|g" Dockerfile
       
    az containerapp update \
    --name $APP_NAME \
    --resource-group $RESOURCE_GROUP \
    --source .  \
    --set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "vets-service"}}' InstrumentationKey=$AI_CONNECTIONSTRING
       
    sed -i "s|$APP_NAME|my-service|g" Dockerfile
    rm spring-petclinic-$APP_NAME-$VERSION.jar
    
  8. To validate the resulting functionality, in the Azure Portal, navigate back to the page of the visits-requests queue of the Service Bus namespace you deployed earlier in this lab.

  9. On the Overview page of the visits-requests queue, verify that there are no active messages.

  10. In the web browser window, open another tab and navigate to the public endpoint of the api-gateway service.

  11. On the Welcome to Petclinic page, select Owners and, in the drop-down menu, select All.

  12. In the list of owners, select the first entry (George Franklin).

  13. On the Owner Information page, in the Pets and Visits section, verify the presence of an entry representing the message you submitted earlier in this lab.