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
-
In the
spring-petclinic-visits-service
directory, create a newsrc/main/java/org/springframework/samples/petclinic/visits/entities
subdirectory and add aVisitRequest.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; }
-
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; }
-
In the
spring-petclinic-visits-service
directory, create a newsrc/main/java/org/springframework/samples/petclinic/visits/config
subdirectory and add aMessagingConfig.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.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("QueueConfig") public QueueConfig queueConfig() { return new QueueConfig(); } @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; } }
-
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; } }
-
In the
spring-petclinic-visits-service
directory, create a newsrc/main/java/org/springframework/samples/petclinic/visits/service
subdirectory and add aVisitsReceiver.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 = "#{@QueueConfig.visitsRequestsQueue}") 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 thevisits-requests
queue. Each time a message is present on the queue, it will dequeue this message and save a newVisit
in the database. In the next step, you will verify it by having it sent a confirmation message to thevisits-confirmations
queue. -
Rebuild the spring-petclinic-visits-service microservice
cd .. mvn clean package -DskipTests -rf :spring-petclinic-visits-service
-
Navigate to the
staging-acr
directory, copy the jar file of the visit-service and update 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 SERVICEBUS_NAMESPACE=$SERVICEBUS_NAMESPACE CLIENT_ID=$CLIENT_ID sed -i "s|$APP_NAME|my-service|g" Dockerfile rm spring-petclinic-$APP_NAME-$VERSION.jar
-
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. -
On the Overview page of the
visits-requests
queue, verify that there are no active messages. -
In the web browser window, open another tab and navigate to the public endpoint of the
api-gateway
service. -
On the Welcome to Petclinic page, select Owners and, in the drop-down menu, select All.
-
In the list of owners, select the first entry (George Franklin).
-
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.