From f8b7a0a47e17e6b7ce0d0f1affb2690c361a2a06 Mon Sep 17 00:00:00 2001 From: Andy Tael Date: Thu, 31 Oct 2024 12:42:57 -0500 Subject: [PATCH] Updates to the TxEventQ Java sample (#980) * Updates --- code-teq/javaTeq/README.md | 12 ++++ code-teq/javaTeq/pom.xml | 59 +++++------------ .../{ConsumeTEQ.java => ConsumeTxEventQ.java} | 50 +++++++------- .../java/com/oracle/example/CreateTEQ.java | 56 ---------------- .../com/oracle/example/CreateTxEventQ.java | 65 +++++++++++++++++++ .../java/com/oracle/example/PublishTEQ.java | 63 ------------------ .../com/oracle/example/PublishTxEventQ.java | 65 +++++++++++++++++++ code-teq/javaTeq/user_perm.sql | 13 ++++ 8 files changed, 197 insertions(+), 186 deletions(-) create mode 100644 code-teq/javaTeq/README.md rename code-teq/javaTeq/src/main/java/com/oracle/example/{ConsumeTEQ.java => ConsumeTxEventQ.java} (55%) delete mode 100644 code-teq/javaTeq/src/main/java/com/oracle/example/CreateTEQ.java create mode 100644 code-teq/javaTeq/src/main/java/com/oracle/example/CreateTxEventQ.java delete mode 100644 code-teq/javaTeq/src/main/java/com/oracle/example/PublishTEQ.java create mode 100644 code-teq/javaTeq/src/main/java/com/oracle/example/PublishTxEventQ.java create mode 100644 code-teq/javaTeq/user_perm.sql diff --git a/code-teq/javaTeq/README.md b/code-teq/javaTeq/README.md new file mode 100644 index 000000000..bec0e79e3 --- /dev/null +++ b/code-teq/javaTeq/README.md @@ -0,0 +1,12 @@ +# Transactional Event Queues (TxEventQ) example in Java + +Transactional Event Queues (TxEventQ) is a messaging platform built into Oracle Database that is used for application workflows, microservices, and event-triggered actions. + +## Setup +1. Install an Oracle Database 23ai. +1. Execute the `user_perm.sql` as the `SYS` or `SYSTEM` user. + +## Test +1. Create the TxEventQ by running the `CreateTxEventQ` class. +1. Publish a message to the TxEventQ by running the `PublishTxEventQ` class. +1. Consume the published message by running the `ConsumeTXEventQ` class. diff --git a/code-teq/javaTeq/pom.xml b/code-teq/javaTeq/pom.xml index 3fe958954..9c5b422cc 100644 --- a/code-teq/javaTeq/pom.xml +++ b/code-teq/javaTeq/pom.xml @@ -1,5 +1,5 @@ - + + + com.oracle.database.messaging + aqapi-jakarta + 23.3.1.0 + - javax.transaction - javax.transaction-api - 1.2 + jakarta.transaction + jakarta.transaction-api + 2.0.1 - com.oracle.database.jdbc - ojdbc8 - 19.3.0.0 + com.oracle.database.jdbc + ojdbc11 + 23.5.0.24.07 com.oracle.database.messaging aqapi - 21.3.0.0 + 23.3.0.0 - javax.jms - javax.jms-api - 2.0.1 - - - javax.transaction - jta - 1.1 + jakarta.jms + jakarta.jms-api + 3.1.0 - - - - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - - - exec - - - - - java - - -Doracle.jdbc.fanEnabled=false - -classpath - - com.oracle.example.ConsumeTEQ - - - - - - diff --git a/code-teq/javaTeq/src/main/java/com/oracle/example/ConsumeTEQ.java b/code-teq/javaTeq/src/main/java/com/oracle/example/ConsumeTxEventQ.java similarity index 55% rename from code-teq/javaTeq/src/main/java/com/oracle/example/ConsumeTEQ.java rename to code-teq/javaTeq/src/main/java/com/oracle/example/ConsumeTxEventQ.java index eb66d2bf7..ef3ba8d79 100644 --- a/code-teq/javaTeq/src/main/java/com/oracle/example/ConsumeTEQ.java +++ b/code-teq/javaTeq/src/main/java/com/oracle/example/ConsumeTxEventQ.java @@ -1,4 +1,4 @@ -// Copyright (c) 2022, Oracle and/or its affiliates. +// Copyright (c) 2022, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. // This is an example of how to consume a message from a TEQ using Java. @@ -6,47 +6,49 @@ package com.oracle.example; +import java.sql.Connection; import java.sql.SQLException; -import javax.jms.JMSException; -import javax.jms.Session; -import javax.jms.Topic; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSession; +import jakarta.jms.JMSException; +import jakarta.jms.Session; +import jakarta.jms.Topic; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; import oracle.AQ.AQException; -import oracle.jms.AQjmsFactory; -import oracle.jms.AQjmsSession; -import oracle.jms.AQjmsTextMessage; -import oracle.jms.AQjmsTopicSubscriber; -import oracle.ucp.jdbc.PoolDataSource; -import oracle.ucp.jdbc.PoolDataSourceFactory; +import oracle.jakarta.jms.AQjmsFactory; +import oracle.jakarta.jms.AQjmsSession; +import oracle.jakarta.jms.AQjmsTextMessage; +import oracle.jakarta.jms.AQjmsTopicSubscriber; +import oracle.jdbc.pool.OracleDataSource; -public class ConsumeTEQ { +public class ConsumeTxEventQ { - private static String username = "pdbadmin"; - private static String url = "jdbc:oracle:thin:@//localhost:1521/pdb1"; - private static String topicName = "my_teq"; + private static final String username = "testuser"; + private static final String url = "jdbc:oracle:thin:@//localhost:1521/freepdb1"; + private static final String password = "Welcome12345"; + private static final String topicName = "my_jms_teq"; public static void main(String[] args) throws AQException, SQLException, JMSException { - // create a topic session - PoolDataSource ds = PoolDataSourceFactory.getPoolDataSource(); - ds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); + // Create DB connection + OracleDataSource ds = new OracleDataSource(); ds.setURL(url); ds.setUser(username); - ds.setPassword(System.getenv("DB_PASSWORD")); + ds.setPassword(password); + Connection con = ds.getConnection(); + if (con != null) { + System.out.println("Connected!"); + } // create a JMS topic connection and session TopicConnectionFactory tcf = AQjmsFactory.getTopicConnectionFactory(ds); TopicConnection conn = tcf.createTopicConnection(); conn.start(); - TopicSession session = - (AQjmsSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE); + var session = (AQjmsSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE); // create a subscriber on the topic - Topic topic = ((AQjmsSession) session).getTopic(username, topicName); + Topic topic = session.getTopic(username, topicName); AQjmsTopicSubscriber subscriber = (AQjmsTopicSubscriber) session.createDurableSubscriber(topic, "my_subscriber"); diff --git a/code-teq/javaTeq/src/main/java/com/oracle/example/CreateTEQ.java b/code-teq/javaTeq/src/main/java/com/oracle/example/CreateTEQ.java deleted file mode 100644 index 203b8cee4..000000000 --- a/code-teq/javaTeq/src/main/java/com/oracle/example/CreateTEQ.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2022, Oracle and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -// This is an example of how to create a TEQ using Java. -// Please see the Maven POM file for dependencies. - -package com.oracle.example; - -import java.sql.SQLException; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Session; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSession; - -import oracle.AQ.AQException; -import oracle.AQ.AQQueueTableProperty; -import oracle.jms.AQjmsDestination; -import oracle.jms.AQjmsFactory; -import oracle.jms.AQjmsSession; -import oracle.ucp.jdbc.PoolDataSource; -import oracle.ucp.jdbc.PoolDataSourceFactory; - -public class CreateTEQ { - - private static String username = "pdbadmin"; - private static String url = "jdbc:oracle:thin:@//localhost:1521/pdb1"; - - public static void main(String[] args) throws AQException, SQLException, JMSException { - - // create a topic session - PoolDataSource ds = PoolDataSourceFactory.getPoolDataSource(); - ds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); - ds.setURL(url); - ds.setUser(username); - ds.setPassword(System.getenv("DB_PASSWORD")); - - TopicConnectionFactory tcf = AQjmsFactory.getTopicConnectionFactory(ds); - TopicConnection conn = tcf.createTopicConnection(); - conn.start(); - TopicSession session = (AQjmsSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE); - - // create properties - AQQueueTableProperty props = new AQQueueTableProperty("SYS.AQ$_JMS_TEXT_MESAGE"); - props.setMultiConsumer(true); - props.setPayloadType("SYS.AQ$_JMS_TEXT_MESSAGE"); - - // create queue table, topic and start it - Destination myTeq = ((AQjmsSession) session).createJMSTransactionalEventQueue("my_jms_teq", true); - ((AQjmsDestination) myTeq).start(session, true, true); - - } - -} \ No newline at end of file diff --git a/code-teq/javaTeq/src/main/java/com/oracle/example/CreateTxEventQ.java b/code-teq/javaTeq/src/main/java/com/oracle/example/CreateTxEventQ.java new file mode 100644 index 000000000..8c0b62929 --- /dev/null +++ b/code-teq/javaTeq/src/main/java/com/oracle/example/CreateTxEventQ.java @@ -0,0 +1,65 @@ +// Copyright (c) 2022, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +// This is an example of how to create a TEQ using Java. +// Please see the Maven POM file for dependencies. + +package com.oracle.example; + +import java.sql.SQLException; + +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Session; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; + +import oracle.AQ.AQException; +import oracle.AQ.AQQueueTableProperty; +import oracle.jakarta.jms.AQjmsDestination; +import oracle.jakarta.jms.AQjmsFactory; +import oracle.jakarta.jms.AQjmsSession; + +import oracle.jdbc.pool.OracleDataSource; +import java.sql.Connection; + +public class CreateTxEventQ { + + private static final String username = "testuser"; + private static final String url = "jdbc:oracle:thin:@//localhost:1521/freepdb1"; + private static final String password = "Welcome12345"; + private static final String topicName = "my_jms_teq"; + + public static void main(String[] args) throws AQException, SQLException, JMSException { + + // Create DB connection + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + ds.setUser(username); + ds.setPassword(password); + Connection con = ds.getConnection(); + if (con != null) { + System.out.println("Connected!"); + } + + // create a topic session + TopicConnectionFactory tcf = AQjmsFactory.getTopicConnectionFactory(ds); + TopicConnection conn = tcf.createTopicConnection(); + conn.start(); + AQjmsSession session = (AQjmsSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE); + + // create properties + AQQueueTableProperty props = new AQQueueTableProperty("SYS.AQ$_JMS_TEXT_MESSAGE"); + props.setMultiConsumer(true); + props.setPayloadType("SYS.AQ$_JMS_TEXT_MESSAGE"); + + // create queue table, topic and start it + Destination myTeq = session.createJMSTransactionalEventQueue(topicName, true); + ((AQjmsDestination) myTeq).start(session, true, true); + + if (con != null && !con.isClosed()) { + con.close(); + } + } + +} \ No newline at end of file diff --git a/code-teq/javaTeq/src/main/java/com/oracle/example/PublishTEQ.java b/code-teq/javaTeq/src/main/java/com/oracle/example/PublishTEQ.java deleted file mode 100644 index 18bf64ea1..000000000 --- a/code-teq/javaTeq/src/main/java/com/oracle/example/PublishTEQ.java +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2022, Oracle and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -// This is an example of how to publish a message onto a TEQ using Java. -// Please see the Maven POM file for dependencies. - -package com.oracle.example; - -import java.sql.SQLException; - -import javax.jms.JMSException; -import javax.jms.Session; -import javax.jms.Topic; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSession; - -import oracle.AQ.AQException; -import oracle.jms.AQjmsAgent; -import oracle.jms.AQjmsFactory; -import oracle.jms.AQjmsSession; -import oracle.jms.AQjmsTextMessage; -import oracle.jms.AQjmsTopicPublisher; -import oracle.ucp.jdbc.PoolDataSource; -import oracle.ucp.jdbc.PoolDataSourceFactory; - -public class PublishTEQ { - - private static String username = "pdbadmin"; - private static String url = "jdbc:oracle:thin:@//localhost:1521/pdb1"; - private static String topicName = "my_teq"; - - public static void main(String[] args) throws AQException, SQLException, JMSException { - - // create a topic session - PoolDataSource ds = PoolDataSourceFactory.getPoolDataSource(); - ds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); - ds.setURL(url); - ds.setUser(username); - ds.setPassword(System.getenv("DB_PASSWORD")); - - // create a JMS topic connection and session - TopicConnectionFactory tcf = AQjmsFactory.getTopicConnectionFactory(ds); - TopicConnection conn = tcf.createTopicConnection(); - conn.start(); - TopicSession session = - (AQjmsSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE); - - // publish message - Topic topic = ((AQjmsSession) session).getTopic(username, topicName); - AQjmsTopicPublisher publisher = (AQjmsTopicPublisher) session.createPublisher(topic); - - AQjmsTextMessage message = (AQjmsTextMessage) session.createTextMessage("hello from java"); - publisher.publish(message, new AQjmsAgent[] { new AQjmsAgent("my_subscription", null) }); - session.commit(); - - // clean up - publisher.close(); - session.close(); - conn.close(); - } - -} \ No newline at end of file diff --git a/code-teq/javaTeq/src/main/java/com/oracle/example/PublishTxEventQ.java b/code-teq/javaTeq/src/main/java/com/oracle/example/PublishTxEventQ.java new file mode 100644 index 000000000..9fb2f3923 --- /dev/null +++ b/code-teq/javaTeq/src/main/java/com/oracle/example/PublishTxEventQ.java @@ -0,0 +1,65 @@ +// Copyright (c) 2022, 2024, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +// This is an example of how to publish a message onto a TEQ using Java. +// Please see the Maven POM file for dependencies. + +package com.oracle.example; + +import java.sql.Connection; +import java.sql.SQLException; + +import jakarta.jms.JMSException; +import jakarta.jms.Session; +import jakarta.jms.Topic; +import jakarta.jms.TopicConnection; +import jakarta.jms.TopicConnectionFactory; + +import oracle.AQ.AQException; +import oracle.jakarta.jms.AQjmsAgent; +import oracle.jakarta.jms.AQjmsFactory; +import oracle.jakarta.jms.AQjmsSession; +import oracle.jakarta.jms.AQjmsTextMessage; +import oracle.jakarta.jms.AQjmsTopicPublisher; +import oracle.jdbc.pool.OracleDataSource; + +public class PublishTxEventQ { + + private static final String username = "testuser"; + private static final String url = "jdbc:oracle:thin:@//localhost:1521/freepdb1"; + private static final String password = "Welcome12345"; + private static final String topicName = "my_jms_teq"; + + public static void main(String[] args) throws AQException, SQLException, JMSException { + + // Create DB connection + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + ds.setUser(username); + ds.setPassword(password); + Connection con = ds.getConnection(); + if (con != null) { + System.out.println("Connected!"); + } + + // create a JMS topic connection and session + TopicConnectionFactory tcf = AQjmsFactory.getTopicConnectionFactory(ds); + TopicConnection conn = tcf.createTopicConnection(); + conn.start(); + var session = (AQjmsSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE); + + // publish message + Topic topic = session.getTopic(username, topicName); + AQjmsTopicPublisher publisher = (AQjmsTopicPublisher) session.createPublisher(topic); + + AQjmsTextMessage message = (AQjmsTextMessage) session.createTextMessage("hello from java"); + publisher.publish(message, new AQjmsAgent[] { new AQjmsAgent("my_subscription", null) }); + session.commit(); + + // clean up + publisher.close(); + session.close(); + conn.close(); + } + +} \ No newline at end of file diff --git a/code-teq/javaTeq/user_perm.sql b/code-teq/javaTeq/user_perm.sql new file mode 100644 index 000000000..f1259e664 --- /dev/null +++ b/code-teq/javaTeq/user_perm.sql @@ -0,0 +1,13 @@ +-- Copyright (c) 2022, 2024, Oracle and/or its affiliates. +-- Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +-- This must be executed as SYS +create user testuser identified by Welcome12345; +grant resource, connect, unlimited tablespace to testuser; +grant aq_user_role to testuser; +grant execute on dbms_aq to testuser; +grant execute on dbms_aqadm to testuser; +grant execute ON dbms_aqin TO testuser; +grant execute ON dbms_aqjms TO testuser; +grant execute on dbms_teqk to testuser; +commit; \ No newline at end of file