Create the Test Runner Microservice
Next, you will create the “Test Runner” microservice which you will use to simulate the ATM and Back Office. This service will send messages to the queues that you just created.
-
Create a new Java Project for the
transfer
service.In the Explorer of VS Code open
Java Project
and click the plus sign to add a Java Project to your workspace.Select Spring Boot Project.
Select Maven Project.
Specify
3.3.4
as the Spring Boot version.Use
com.example
as the Group Id.Enter
testrunner
as the Artifact Id.Use
JAR
as the Packaging Type.Select Java version
21
.Search for
Spring Web
and press EnterPress Enter to continue and create the Java Project
Select the
root
location for your project e.g. side by side with theaccount
project.When the project opens click Add to Workspace
-
Modify the
pom.xml
fileOpen the
pom.xml
file in thetestrunner
project. This service will use the “Web” Spring Boot Starter which will allow it to expose REST endpoints and make REST calls to other services. It also uses the two Oracle Spring Boot Starters for UCP and Wallet to access the database: Add the following to the pom.xml:<dependency> <groupId>com.oracle.database.spring</groupId> <artifactId>oracle-spring-boot-starter-aqjms</artifactId> <version>23.4.0</version> </dependency> <dependency> <groupId>com.oracle.database.spring</groupId> <artifactId>oracle-spring-boot-starter-wallet</artifactId> <type>pom</type> <version>23.4.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
-
Create the Spring Boot application YAML file
In the
testrunner
project, rename the file calledapplication.properties
toapplication.yaml
located in thesrc/main/resources
. This will be the Spring Boot application configuration file:spring: application: name: testrunner datasource: url: ${spring.datasource.url} username: ${spring.datasource.username} password: ${spring.datasource.password}
This is the Spring Boot application YAML file, which contains the configuration information for this service. In this case, you only need to provide the application name and the connection details for the database hosting the queues.
-
Create the main Spring Application class
In the
testrunner
directory, open the Java file calledTestrunnerApplication.java
and add this content. This is a standard Spring Boot main class, notice the@SpringBootApplication
annotation on the class. It also has the@EnableJms
annotation which tells Spring Boot to enable JMS functionality in this application. Themain
method is a normal Spring Boot main method:package com.example.testrunner; import jakarta.jms.ConnectionFactory; 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.core.JmsTemplate; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; @SpringBootApplication @EnableJms public class TestrunnerApplication { public static void main(String[] args) { SpringApplication.run(TestrunnerApplication.class, args); } // Serialize message content to json using TextMessage @Bean public MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_type"); return converter; } @Bean public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) { JmsTemplate jmsTemplate = new JmsTemplate(); jmsTemplate.setConnectionFactory(connectionFactory); jmsTemplate.setMessageConverter(jacksonJmsMessageConverter()); return jmsTemplate; } }
In addition to the standard parts of a Spring Boot application class, you will add two beans that will be needed in this service. First, you need a
MessageConverter
bean so that you can convert a Java object (POJO) into JSON format, and vice versa. This bean will be used to serialize and deserialize the objects you need to write onto the queues.The second bean you need is a
JmsTemplate
. This is a standard Spring JMS bean that is used to access JMS functionality. You will use this bean to enqueue messages. Notice that this bean is configured to use theMessageConverter
bean and that the JMSConnectionFactory
is injected. The Oracle Spring Boot Starter for AQ/JMS will create the JMSConnectionFactory
for you.Note: The Oracle Spring Boot Starter for AQ/JMS will also inject a JDBC
Connection
bean which shares the same database transaction with the JMSConnectionFactory
. This is not needed in this lab. The shared transaction enables you to write methods which can perform both JMS and JPA operations in an atomic transaction, which can be very helpful in some use cases and can dramatically reduce the amount of code needed to handle situations like duplicate message delivery or lost messages. -
Create the model classes
Create a new directory called
src/main/java/com/example/testrunner/model
and in this directory create two Java files. First,CheckDeposit.java
with this content. This class will be used to simulate the ATM sending the “deposit” notification:package com.example.testrunner.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class CheckDeposit { private long accountId; private long amount; }
Next,
Clearance.java
with this content. This class will be used to simulate the Back Office sending the “clearance” notification:package com.example.testrunner.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Clearance { private long journalId; }
-
Create the controller
Create a new directory called
src/main/java/com/example/testrunner/controller
and in this directory create a new Java file calledTestRunnerController.java
with the following content. This class will have theRestController
annotation so that it can expose REST APIs that you can call to trigger the simulation of the ATM and Back Office notifications. It will need theJmsTemplate
to access JMS functionality, this can be injected with theAutoWired
annotation. Create two methods, one to send each notification:package com.example.testrunner.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.jms.core.JmsTemplate; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.testrunner.model.CheckDeposit; import com.example.testrunner.model.Clearance; @RestController @RequestMapping("/api/v1/testrunner") public class TestRunnerController { @Autowired private JmsTemplate jmsTemplate; @PostMapping("/deposit") public ResponseEntity<CheckDeposit> depositCheck(@RequestBody CheckDeposit deposit) { jmsTemplate.convertAndSend("deposits", deposit); return new ResponseEntity<CheckDeposit>(deposit, HttpStatus.CREATED); } @PostMapping("/clear") public ResponseEntity<Clearance> clearCheck(@RequestBody Clearance clearance) { jmsTemplate.convertAndSend("clearances", clearance); return new ResponseEntity<Clearance>(clearance, HttpStatus.CREATED); } }
-
Build a JAR file for deployment
Run the following command to build the JAR file.
$ mvn clean package -DskipTests
The service is now ready to deploy to the backend.
-
Prepare the backend for deployment
The Oracle Backend for Microservices and AI admin service is not exposed outside the Kubernetes cluster by default. Oracle recommends using a kubectl port forwarding tunnel to establish a secure connection to the admin service.
Start a tunnel using this command in a new terminal window:
$ kubectl -n obaas-admin port-forward svc/obaas-admin 8080
Get the password for the
obaas-admin
user. Theobaas-admin
user is the equivalent of the admin or root user in the Oracle Backend for Microservices and AI backend.$ kubectl get secret -n azn-server oractl-passwords -o jsonpath='{.data.admin}' | base64 -d
Start the Oracle Backend for Microservices and AI CLI (oractl) in a new terminal window using this command:
$ oractl _ _ __ _ ___ / \ |_) _. _. (_ / | | \_/ |_) (_| (_| __) \_ |_ _|_ ======================================================================================== Application Name: Oracle Backend Platform :: Command Line Interface Application Version: (1.3.0) :: Spring Boot (v3.3.3) :: Ask for help: - Slack: https://oracledevs.slack.com/archives/C03ALDSV272 - email: obaas_ww@oracle.com oractl:>
Connect to the Oracle Backend for Microservices and AI admin service using the
connect
command. Enterobaas-admin
and the username and use the password you collected earlier.oractl> connect username: obaas-admin password: ************** Credentials successfully authenticated! obaas-admin -> welcome to OBaaS CLI. oractl:>
-
Create a binding for the Test Runner service
Create a binding so the Test Runner service can access the Oracle Autonomous Database as the
account
user. Run this command to create the binding, and type in the password for theaccount
user when prompted. The password isWelcome1234##
:oractl:> bind --app-name application --service-name testrunner --username account
-
Deploy the Test Runner service
You will now deploy your Test Runner service to the Oracle Backend for Microservices and AI using the CLI. Run this command to deploy your service, make sure you provide the correct path to your JAR file. Note that this command may take 1-3 minutes to complete:
oractl:> deploy --app-name application --service-name testrunner --artifact-path /path/to/testrunner-0.0.1-SNAPSHOT.jar --image-version 0.0.1 --java-version ghcr.io/oracle/graalvm-native-image-obaas:21 uploading: testrunner/target/testrunner-0.0.1-SNAPSHOT.jarbuilding and pushing image... creating deployment and service... successfully deployed oractl:>
You can close the port forwarding session for the CLI now (just type a Ctrl+C in its console window).
-
Check that the
testrunner
service is runningVerify that the testrunner application is up and running by running this command:
$ kubectl logs -n application svc/testrunner
The output should be similar to this, look for
Started TestrunnerApplication
2023-06-02 15:18:39.620 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1806 ms 2023-06-02 15:18:40.915 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2023-06-02 15:18:40.938 INFO 1 --- [ main] c.e.testrunner.TestrunnerApplication : Started TestrunnerApplication in 4.174 seconds (JVM running for 5.237)
-
Test the endpoints
The Test Runner service is not exposed outside your Kubernetes cluster, so you must create a port-forwarding tunnel to access it. Create a tunnel using this command:
$ kubectl -n application port-forward svc/testrunner 8084:8080
Call the deposit endpoint to send a deposit notification using this command:
$ curl -i -X POST -H 'Content-Type: application/json' -d '{"accountId": 2, "amount": 200}' http://localhost:8084/api/v1/testrunner/deposit HTTP/1.1 201 Date: Wed, 31 May 2023 15:11:55 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive {"accountId":2,"amount":200}
Call the clear endpoint to send a clearance notification using this command. Note that you can use any
journalId
since there is nothing receiving and processing these messages yet:$ curl -i -X POST -H 'Content-Type: application/json' -d '{"journalId": 4}' http://localhost:8084/api/v1/testrunner/clear HTTP/1.1 201 Date: Wed, 31 May 2023 15:12:54 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive {"journalId":4}
-
Verify the expected messages are on the queues
Connect to the database as the
account
(passwordWelcome12343##
) and issue this SQL statement to check the payloads of the messages on the deposits queue:SQL> select qt.user_data.text_vc from deposits_qt qt; USER_DATA.TEXT_VC _______________________________ {"accountId":2,"amount":200}
Issue this SQL statement to check the payloads of the messages on the clearances queue:
SQL> select qt.user_data.text_vc from clearances_qt qt; USER_DATA.TEXT_VC ____________________ {"journalId":4}
That completes the Test Runner service. Next, you will build the Check Processing service which will receive these messages and process them.