diff --git a/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItCrossDomainTransaction.java b/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItCrossDomainTransaction.java index ad86fb2e4aa..585d354a1c7 100644 --- a/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItCrossDomainTransaction.java +++ b/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItCrossDomainTransaction.java @@ -32,12 +32,12 @@ import oracle.weblogic.kubernetes.annotations.Namespaces; import oracle.weblogic.kubernetes.assertions.TestAssertions; import oracle.weblogic.kubernetes.logging.LoggingFacade; -import oracle.weblogic.kubernetes.utils.BuildApplication; import oracle.weblogic.kubernetes.utils.ExecResult; import org.awaitility.core.ConditionFactory; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @@ -57,6 +57,7 @@ import static oracle.weblogic.kubernetes.actions.TestActions.createDomainCustomResource; import static oracle.weblogic.kubernetes.actions.TestActions.getServiceNodePort; import static oracle.weblogic.kubernetes.assertions.TestAssertions.domainExists; +import static oracle.weblogic.kubernetes.utils.BuildApplication.buildApplication; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkPodExists; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkPodReady; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkServiceExists; @@ -71,9 +72,12 @@ import static oracle.weblogic.kubernetes.utils.DbUtils.getDBNodePort; import static oracle.weblogic.kubernetes.utils.DbUtils.startOracleDB; import static oracle.weblogic.kubernetes.utils.ExecCommand.exec; +import static oracle.weblogic.kubernetes.utils.FileUtils.copyFolder; +import static oracle.weblogic.kubernetes.utils.FileUtils.replaceStringInFile; import static oracle.weblogic.kubernetes.utils.ThreadSafeLogger.getLogger; import static org.awaitility.Awaitility.with; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -92,15 +96,19 @@ public class ItCrossDomainTransaction { private static final String PROPS_TEMP_DIR = RESULTS_ROOT + "/crossdomaintransactiontemp"; private static final String WDT_MODEL_FILE_JMS = "model-cdt-jms.yaml"; private static final String WDT_MODEL_FILE_JDBC = "model-cdt-jdbc.yaml"; + private static final String WDT_MODEL_FILE_JMS2 = "model2-cdt-jms.yaml"; private static String opNamespace = null; private static String domain1Namespace = null; private static String domain2Namespace = null; private static ConditionFactory withStandardRetryPolicy = null; - private String domainUid1 = "domain1"; - private String domainUid2 = "domain2"; - private final String domain1AdminServerPodName = domainUid1 + "-admin-server"; + private static String domainUid1 = "domain1"; + private static String domainUid2 = "domain2"; + private static int domain1AdminServiceNodePort = -1; + private static int admin2ServiceNodePort = -1; + private static String domain1AdminServerPodName = domainUid1 + "-admin-server"; private final String domain1ManagedServerPrefix = domainUid1 + "-managed-server"; + private static String domain2AdminServerPodName = domainUid2 + "-admin-server"; private final String domain2ManagedServerPrefix = domainUid2 + "-managed-server"; private static final String ORACLEDBURLPREFIX = "oracledb."; private static final String ORACLEDBSUFFIX = ".svc.cluster.local:1521/devpdb.k8s"; @@ -146,7 +154,7 @@ public static void initAll(@Namespaces(3) List namespaces) { logger.info("DB Node Port = {0}", dbNodePort); // Now that we got the namespaces for both the domains, we need to update the model properties - // file with the namespaces. For cross domain transaction to work, we need to have the externalDNSName + // file with the namespaces. For a cross-domain transaction to work, we need to have the externalDNSName // set in the config file. Cannot set this after the domain is up since a server restart is // required for this to take effect. So, copying the property file to RESULT_ROOT and updating the // property file @@ -155,6 +163,7 @@ public static void initAll(@Namespaces(3) List namespaces) { // install and verify operator installAndVerifyOperator(opNamespace, domain1Namespace, domain2Namespace); + buildApplicationsAndDomains(); } private static void updatePropertyFile() { @@ -196,23 +205,10 @@ private static void addToPropertyFile(String propFileName, String domainNamespac out.close(); } - /* - * This test verifies cross domain transaction is successful. domain in image using wdt is used - * to create 2 domains in different namespaces. An app is deployed to both the domains and the servlet - * is invoked which starts a transaction that spans both domains. - * The application consists of a servlet front-end and a remote object that defines a method to register - * a simple javax.transaction.Synchronization object. When the servlet is invoked, a global transaction - * is started, and the specified list of server URLs is used to look up the remote object and register - * a Synchronization object on each server. Finally, the transaction is committed. If the server - * listen-addresses are resolvable between the transaction participants, then the transaction should - * complete successfully - */ - @Test - @DisplayName("Check cross domain transaction works") - public void testCrossDomainTransaction() { + private static void buildApplicationsAndDomains() { //build application archive - Path distDir = BuildApplication.buildApplication(Paths.get(APP_DIR, "txforward"), null, null, + Path distDir = buildApplication(Paths.get(APP_DIR, "txforward"), null, null, "build", domain1Namespace); logger.info("distDir is {0}", distDir.toString()); assertTrue(Paths.get(distDir.toString(), @@ -222,7 +218,7 @@ public void testCrossDomainTransaction() { logger.info("Application is in {0}", appSource); //build application archive - distDir = BuildApplication.buildApplication(Paths.get(APP_DIR, "cdtservlet"), null, null, + distDir = buildApplication(Paths.get(APP_DIR, "cdtservlet"), null, null, "build", domain1Namespace); logger.info("distDir is {0}", distDir.toString()); assertTrue(Paths.get(distDir.toString(), @@ -231,6 +227,42 @@ public void testCrossDomainTransaction() { String appSource1 = distDir.toString() + "/cdttxservlet.war"; logger.info("Application is in {0}", appSource1); + //build application archive for JMS Send/Receive + distDir = buildApplication(Paths.get(APP_DIR, "jmsservlet"), null, null, + "build", domain1Namespace); + logger.info("distDir is {0}", distDir.toString()); + assertTrue(Paths.get(distDir.toString(), + "jmsservlet.war").toFile().exists(), + "Application archive is not available"); + String appSource2 = distDir.toString() + "/jmsservlet.war"; + logger.info("Application is in {0}", appSource2); + + Path mdbSrcDir = Paths.get(APP_DIR, "mdbtopic"); + Path mdbDestDir = Paths.get(PROPS_TEMP_DIR, "mdbtopic"); + + assertDoesNotThrow(() -> copyFolder( + mdbSrcDir.toString(), mdbDestDir.toString()), + "Could not copy mdbtopic application directory"); + + Path template = Paths.get(PROPS_TEMP_DIR, + "mdbtopic/src/application/MdbTopic.java"); + + // Add the domain2 namespace decorated URL to the providerURL of MDB + // so that it can communicate with remote destination on domain2 + assertDoesNotThrow(() -> replaceStringInFile( + template.toString(), "domain2-namespace", domain2Namespace), + "Could not modify the domain2Namespace in MDB Template file"); + + //build application archive for MDB + distDir = buildApplication(Paths.get(PROPS_TEMP_DIR, "mdbtopic"), null, null, + "build", domain1Namespace); + logger.info("distDir is {0}", distDir.toString()); + assertTrue(Paths.get(distDir.toString(), + "mdbtopic.jar").toFile().exists(), + "Application archive is not available"); + String appSource3 = distDir.toString() + "/mdbtopic.jar"; + logger.info("Application is in {0}", appSource3); + // create admin credential secret for domain1 logger.info("Create admin credential secret for domain1"); String domain1AdminSecretName = domainUid1 + "-weblogic-credentials"; @@ -250,7 +282,7 @@ public void testCrossDomainTransaction() { MODEL_DIR + "/" + WDT_MODEL_FILE_DOMAIN1, MODEL_DIR + "/" + WDT_MODEL_FILE_JMS); - final List appSrcDirList1 = Arrays.asList(appSource, appSource1); + final List appSrcDirList1 = Arrays.asList(appSource, appSource1, appSource2, appSource3); logger.info("Creating image with model file and verify"); String domain1Image = createImageAndVerify( @@ -263,6 +295,7 @@ public void testCrossDomainTransaction() { // build the model file list for domain2 final List modelListDomain2 = Arrays.asList( MODEL_DIR + "/" + WDT_MODEL_FILE_DOMAIN2, + MODEL_DIR + "/" + WDT_MODEL_FILE_JMS2, MODEL_DIR + "/" + WDT_MODEL_FILE_JDBC); final List appSrcDirList2 = Collections.singletonList(appSource); @@ -280,14 +313,42 @@ public void testCrossDomainTransaction() { //create domain2 createDomain(domainUid2, domain2Namespace, domain2AdminSecretName, domain2Image); - logger.info("Getting admin server external service node port"); - int adminServiceNodePort = assertDoesNotThrow( + logger.info("Getting admin server external service node port(s)"); + domain1AdminServiceNodePort = assertDoesNotThrow( () -> getServiceNodePort(domain1Namespace, getExternalServicePodName(domain1AdminServerPodName), "default"), "Getting admin server node port failed"); + assertNotEquals(-1, domain1AdminServiceNodePort, "admin server default node port is not valid"); + + admin2ServiceNodePort = assertDoesNotThrow( + () -> getServiceNodePort(domain2Namespace, getExternalServicePodName(domain2AdminServerPodName), "default"), + "Getting admin server node port failed"); + assertNotEquals(-1, admin2ServiceNodePort, "admin server default node port is not valid"); + } + + /* + * This test verifies a cross-domain transaction in non-istio environment. + * domain-in-image using wdt is used to create 2 domains in different + * namespaces. An app is deployed to both the domains and the servlet + * is invoked which starts a transaction that spans both domains. + * The application consists of + * (a) servlet + * (b) a remote object that defines a method to register a + * simple javax.transaction.Synchronization object. + * When the servlet is invoked, a global transaction is started, and the + * specified list of server URLs is used to look up the remote objects and + * register a Synchronization object on each server. + * Finally, the transaction is committed. + * If the server listen-addresses are resolvable between the transaction + * participants, then the transaction should complete successfully + */ + @Order(1) + @Test + @DisplayName("Check cross domain transaction works") + public void testCrossDomainTransaction() { String curlRequest = String.format("curl -v --show-error --noproxy '*' " + "http://%s:%s/TxForward/TxForward?urls=t3://%s.%s:7001,t3://%s1.%s:8001,t3://%s1.%s:8001,t3://%s2.%s:8001", - K8S_NODEPORT_HOST, adminServiceNodePort, domain1AdminServerPodName, domain1Namespace, + K8S_NODEPORT_HOST, domain1AdminServiceNodePort, domain1AdminServerPodName, domain1Namespace, domain1ManagedServerPrefix, domain1Namespace, domain2ManagedServerPrefix, domain2Namespace, domain2ManagedServerPrefix, domain2Namespace); @@ -300,28 +361,26 @@ public void testCrossDomainTransaction() { logger.info("curl command returned {0}", result.toString()); assertTrue(result.stdout().contains("Status=Committed"), "crossDomainTransaction failed"); } - } /* - * This test verifies cross domain transaction is successful and able to re-establish connection when - * one domain is shutdown. Domain in image with wdt is used to create 2 domains in different namespaces. - * A servlet is deployed to the admin server of domain1. This servlet starts a transaction with - * TMAfterTLogBeforeCommitExit transaction property set. The servlet inserts data into oracleDB table and - * sends a message to a JMS queue as part of a same transaction.The coordinator (server in domain2) - * should exit before commit and the domain1 admin server should be able to re-establish connection - * with domain2 and the transaction should commit. + * This test verifies a cross-domain transaction with re-connection. + * It makes sure the disitibuted transaction is completed successfully + * when a coordinator server is re-started after writing to transcation log + * A servlet is deployed to the admin server of domain1. + * The servlet starts a transaction with TMAfterTLogBeforeCommitExit + * transaction property set. The servlet inserts data into an Oracle DB + * table and sends a message to a JMS queue as part of the same transaction. + * The coordinator (server in domain2) should exit before commit and the + * domain1 admin server should be able to re-establish the connection with + * domain2 and the transaction should commit. * */ + @Order(2) @Test @DisplayName("Check cross domain transaction with TMAfterTLogBeforeCommitExit property commits") public void testCrossDomainTransactionWithFailInjection() { - logger.info("Getting admin server external service node port"); - int domain1AdminServiceNodePort = assertDoesNotThrow( - () -> getServiceNodePort(domain1Namespace, domain1AdminServerPodName + "-external", "default"), - "Getting admin server node port failed"); - String curlRequest = String.format("curl -v --show-error --noproxy '*' " + "http://%s:%s/cdttxservlet/cdttxservlet?namespaces=%s,%s", K8S_NODEPORT_HOST, domain1AdminServiceNodePort, domain1Namespace, domain2Namespace); @@ -336,10 +395,76 @@ public void testCrossDomainTransactionWithFailInjection() { assertTrue(result.stdout().contains("Status=SUCCESS"), "crossDomainTransaction with TMAfterTLogBeforeCommitExit failed"); } + } + + /* + * This test verifies cross-domain MessageDrivenBean communication + * A transacted MDB on Domain D1 listen on a replicated Distributed Topic + * on Domain D2. + * The MDB is deployed to cluster on domain D1 with MessagesDistributionMode + * set to One-Copy-Per-Server. The OnMessage() routine sends a message to + * local queue on receiving the message. + * An application servlet is deployed to Administration Server on D1 which + * send/receive message from a JMS destination based on a given URL. + * (a) app servlet send message to Distributed Topic on D2 + * (b) mdb puts a message into local Queue for each received message + * (c) make sure local Queue gets 2X times messages sent to Distributed Topic + * Since the MessagesDistributionMode is set to One-Copy-Per-Server and + * targeted to a cluster of two servers, onMessage() will be triggered + * for both instance of MDB for a message sent to Distributed Topic + */ + @Order(3) + @Test + @DisplayName("Check cross domain transcated MDB communication ") + public void testCrossDomainTranscatedMDB() { + + String curlRequest = String.format("curl -v --show-error --noproxy '*' " + + "\"http://%s:%s/jmsservlet/jmstest?" + + "url=t3://domain2-cluster-cluster-1.%s:8001&" + + "cf=jms.ClusterConnectionFactory&" + + "action=send&" + + "dest=jms/testCdtUniformTopic\"", + K8S_NODEPORT_HOST, domain1AdminServiceNodePort, domain2Namespace); + + ExecResult result = null; + logger.info("curl command {0}", curlRequest); + result = assertDoesNotThrow( + () -> exec(curlRequest, true)); + if (result.exitValue() == 0) { + logger.info("\n HTTP response is \n " + result.stdout()); + logger.info("curl command returned {0}", result.toString()); + assertTrue(result.stdout().contains("Sent (10) message"), + "Can not send message to remote Distributed Topic"); + } + assertTrue(checkLocalQueue(), + "Expected number of message not found in Accounting Queue"); + } + + private boolean checkLocalQueue() { + String curlString = String.format("curl -v --show-error --noproxy '*' " + + "\"http://%s:%s/jmsservlet/jmstest?" + + "url=t3://localhost:7001&" + + "action=receive&dest=jms.testAccountingQueue\"", + K8S_NODEPORT_HOST, domain1AdminServiceNodePort); + + logger.info("curl command {0}", curlString); + + withStandardRetryPolicy + .conditionEvaluationListener( + condition -> logger.info("Waiting for local queue to be updated " + + "(elapsed time {0} ms, remaining time {1} ms)", + condition.getElapsedTimeInMS(), + condition.getRemainingTimeInMS())) + .until(assertDoesNotThrow(() -> { + return () -> { + return exec(new String(curlString), true).stdout().contains("Messages are distributed"); + }; + })); + return true; } - private void createDomain(String domainUid, String domainNamespace, String adminSecretName, + private static void createDomain(String domainUid, String domainNamespace, String adminSecretName, String domainImage) { // admin/managed server name here should match with model yaml in WDT_MODEL_FILE final String adminServerPodName = domainUid + "-admin-server"; @@ -418,7 +543,7 @@ private void createDomain(String domainUid, String domainNamespace, String admin } } - private void createDomainResource(String domainUid, String domNamespace, String adminSecretName, + private static void createDomainResource(String domainUid, String domNamespace, String adminSecretName, String repoSecretName, int replicaCount, String domainImage) { logger.info("Image to be used is {0}", domainImage); // create the domain CR diff --git a/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItIstioCrossDomainTransaction.java b/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItIstioCrossDomainTransaction.java index ae34e9a17f8..d822b626fb8 100644 --- a/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItIstioCrossDomainTransaction.java +++ b/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItIstioCrossDomainTransaction.java @@ -32,7 +32,6 @@ import oracle.weblogic.kubernetes.annotations.IntegrationTest; import oracle.weblogic.kubernetes.annotations.Namespaces; import oracle.weblogic.kubernetes.logging.LoggingFacade; -import oracle.weblogic.kubernetes.utils.BuildApplication; import oracle.weblogic.kubernetes.utils.ExecResult; import org.awaitility.core.ConditionFactory; import org.junit.jupiter.api.BeforeAll; @@ -59,6 +58,7 @@ import static oracle.weblogic.kubernetes.actions.TestActions.addLabelsToNamespace; import static oracle.weblogic.kubernetes.actions.TestActions.createDomainCustomResource; import static oracle.weblogic.kubernetes.assertions.TestAssertions.domainExists; +import static oracle.weblogic.kubernetes.utils.BuildApplication.buildApplication; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkAppUsingHostHeader; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkPodReady; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkServiceExists; @@ -73,6 +73,8 @@ import static oracle.weblogic.kubernetes.utils.DbUtils.getDBNodePort; import static oracle.weblogic.kubernetes.utils.DbUtils.startOracleDB; import static oracle.weblogic.kubernetes.utils.ExecCommand.exec; +import static oracle.weblogic.kubernetes.utils.FileUtils.copyFolder; +import static oracle.weblogic.kubernetes.utils.FileUtils.replaceStringInFile; import static oracle.weblogic.kubernetes.utils.IstioUtils.deployHttpIstioGatewayAndVirtualservice; import static oracle.weblogic.kubernetes.utils.IstioUtils.getIstioHttpIngressPort; import static oracle.weblogic.kubernetes.utils.ThreadSafeLogger.getLogger; @@ -97,23 +99,25 @@ public class ItIstioCrossDomainTransaction { private static final String PROPS_TEMP_DIR = RESULTS_ROOT + "/istiocrossdomaintransactiontemp"; private static final String WDT_MODEL_FILE_JMS = "model-cdt-jms.yaml"; private static final String WDT_MODEL_FILE_JDBC = "model-cdt-jdbc.yaml"; + private static final String WDT_MODEL_FILE_JMS2 = "model2-cdt-jms.yaml"; private static String opNamespace = null; private static String domain1Namespace = null; private static String domain2Namespace = null; private static ConditionFactory withStandardRetryPolicy = null; - private String domainUid1 = "domain1"; - private String domainUid2 = "domain2"; - private final String domain1AdminServerPodName = domainUid1 + "-admin-server"; + private static String domainUid1 = "domain1"; + private static String domainUid2 = "domain2"; + private static String domain1AdminServerPodName = domainUid1 + "-admin-server"; private final String domain1ManagedServerPrefix = domainUid1 + "-managed-server"; + private static String domain2AdminServerPodName = domainUid2 + "-admin-server"; private final String domain2ManagedServerPrefix = domainUid2 + "-managed-server"; - private String clusterName = "cluster-1"; + private static String clusterName = "cluster-1"; private static final String ORACLEDBURLPREFIX = "oracledb."; private static final String ORACLEDBSUFFIX = ".svc.cluster.local:1521/devpdb.k8s"; private static LoggingFacade logger = null; static String dbUrl; static int dbNodePort; - int istioIngressPort; + static int istioIngressPort; /** * Install Operator. @@ -170,6 +174,8 @@ public static void initAll(@Namespaces(3) List namespaces) { // install and verify operator installAndVerifyOperator(opNamespace, domain1Namespace, domain2Namespace); + buildApplicationsAndDomains(); + } private static void updatePropertyFile() { @@ -211,24 +217,10 @@ private static void addToPropertyFile(String propFileName, String domainNamespac out.close(); } - /* - * This test verifies cross domain transaction is successful. domain in image using wdt is used - * to create 2 domains in different namespaces. An app is deployed to both the domains and the servlet - * is invoked which starts a transaction that spans both domains. - * The application consists of a servlet front-end and a remote object that defines a method to register - * a simple javax.transaction.Synchronization object. When the servlet is invoked, a global transaction - * is started, and the specified list of server URLs is used to look up the remote object and register - * a Synchronization object on each server. Finally, the transaction is committed. If the server - * listen-addresses are resolvable between the transaction participants, then the transaction should - * complete successfully. - */ - @Test - @Order(1) - @DisplayName("Check cross domain transaction with istio works") - public void testIstioCrossDomainTransaction() { + private static void buildApplicationsAndDomains() { - //build application archive - txforward - Path distDir = BuildApplication.buildApplication(Paths.get(APP_DIR, "txforward"), null, null, + //build application archive + Path distDir = buildApplication(Paths.get(APP_DIR, "txforward"), null, null, "build", domain1Namespace); logger.info("distDir is {0}", distDir.toString()); assertTrue(Paths.get(distDir.toString(), @@ -237,8 +229,8 @@ public void testIstioCrossDomainTransaction() { String appSource = distDir.toString() + "/txforward.ear"; logger.info("Application is in {0}", appSource); - //build application archive - cdttxservlet - distDir = BuildApplication.buildApplication(Paths.get(APP_DIR, "cdtservlet"), null, null, + //build application archive + distDir = buildApplication(Paths.get(APP_DIR, "cdtservlet"), null, null, "build", domain1Namespace); logger.info("distDir is {0}", distDir.toString()); assertTrue(Paths.get(distDir.toString(), @@ -247,6 +239,41 @@ public void testIstioCrossDomainTransaction() { String appSource1 = distDir.toString() + "/cdttxservlet.war"; logger.info("Application is in {0}", appSource1); + //build application archive for JMS Send/Receive + distDir = buildApplication(Paths.get(APP_DIR, "jmsservlet"), null, null, + "build", domain1Namespace); + logger.info("distDir is {0}", distDir.toString()); + assertTrue(Paths.get(distDir.toString(), + "jmsservlet.war").toFile().exists(), + "Application archive is not available"); + String appSource2 = distDir.toString() + "/jmsservlet.war"; + logger.info("Application is in {0}", appSource2); + + Path mdbSrcDir = Paths.get(APP_DIR, "mdbtopic"); + Path mdbDestDir = Paths.get(PROPS_TEMP_DIR, "mdbtopic"); + + assertDoesNotThrow(() -> copyFolder( + mdbSrcDir.toString(), mdbDestDir.toString()), + "Could not copy mdbtopic application directory"); + + Path template = Paths.get(PROPS_TEMP_DIR, + "mdbtopic/src/application/MdbTopic.java"); + + // Add the domain2 namespace decorated URL to the providerURL of MDB + // so that it can communicate with remote destination on domain2 + assertDoesNotThrow(() -> replaceStringInFile( + template.toString(), "domain2-namespace", domain2Namespace), + "Could not modify the domain2Namespace in MDB Template file"); + + //build application archive for MDB + distDir = buildApplication(Paths.get(PROPS_TEMP_DIR, "mdbtopic"), null, null, + "build", domain1Namespace); + logger.info("distDir is {0}", distDir.toString()); + assertTrue(Paths.get(distDir.toString(), + "mdbtopic.jar").toFile().exists(), + "Application archive is not available"); + String appSource3 = distDir.toString() + "/mdbtopic.jar"; + logger.info("Application is in {0}", appSource3); // create admin credential secret for domain1 logger.info("Create admin credential secret for domain1"); @@ -267,7 +294,7 @@ public void testIstioCrossDomainTransaction() { MODEL_DIR + "/" + WDT_MODEL_FILE_DOMAIN1, MODEL_DIR + "/" + WDT_MODEL_FILE_JMS); - final List appSrcDirList1 = Arrays.asList(appSource, appSource1); + final List appSrcDirList1 = Arrays.asList(appSource, appSource1, appSource2, appSource3); logger.info("Creating image with model file and verify"); String domain1Image = createImageAndVerify( @@ -280,6 +307,7 @@ public void testIstioCrossDomainTransaction() { // build the model file list for domain2 final List modelListDomain2 = Arrays.asList( MODEL_DIR + "/" + WDT_MODEL_FILE_DOMAIN2, + MODEL_DIR + "/" + WDT_MODEL_FILE_JMS2, MODEL_DIR + "/" + WDT_MODEL_FILE_JDBC); final List appSrcDirList2 = Collections.singletonList(appSource); @@ -328,6 +356,30 @@ public void testIstioCrossDomainTransaction() { logger.info("Skipping WebLogic console in WebLogic slim image"); } + } + + + /* + * Test verifies a cross-domain transaction in a istio enabled environment. + * domain-in-image using wdt is used to create 2 domains in different + * namespaces. An app is deployed to both the domains and the servlet + * is invoked which starts a transaction that spans both domains. + * The application consists of + * (a) servlet + * (b) a remote object that defines a method to register a + * simple javax.transaction.Synchronization object. + * When the servlet is invoked, a global transaction is started, and the + * specified list of server URLs is used to look up the remote objects and + * register a Synchronization object on each server. + * Finally, the transaction is committed. + * If the server listen-addresses are resolvable between the transaction + * participants, then the transaction should complete successfully + */ + @Order(1) + @Test + @DisplayName("Check cross domain transaction with istio works") + public void testIstioCrossDomainTransaction() { + String curlRequest = String.format("curl -v --show-error --noproxy '*' " + "-H 'host:domain1-" + domain1Namespace + ".org' " + "http://%s:%s/TxForward/TxForward?urls=t3://%s.%s:7001,t3://%s1.%s:8001,t3://%s1.%s:8001,t3://%s2.%s:8001", @@ -350,17 +402,19 @@ public void testIstioCrossDomainTransaction() { } /* - * This test verifies cross domain transaction with Istio is successful and able to re-establish connection when - * one domain is shutdown. Domain in image with wdt is used to create 2 domains in different namespaces. - * A servlet is deployed to the admin server of domain1. This servlet starts a transaction with - * TMAfterTLogBeforeCommitExit transaction property set. The servlet then inserts data into oracleDB table and - * sends a message to a JMS queue as part of a same transaction. The coordinator (server in domain2) - * should exit before commit and the domain1 admin server should be able to re-establish connection - * with domain2 and the transaction should commit. + * Test verifies a cross-domain transaction with re-connection is istio env. + * It makes sure the disitibuted transaction is completed successfully + * when a coordinator server is re-started after writing to transcation log + * A servlet is deployed to the admin server of domain1. + * The servlet starts a transaction with TMAfterTLogBeforeCommitExit + * transaction property set. The servlet inserts data into an Oracle DB + * table and sends a message to a JMS queue as part of the same transaction. + * The coordinator (server in domain2) should exit before commit and the + * domain1 admin server should be able to re-establish the connection with + * domain2 and the transaction should commit. */ - - @Test @Order(2) + @Test @DisplayName("Check cross domain transaction with istio and with TMAfterTLogBeforeCommitExit property commits") public void testIstioCrossDomainTransactionWithFailInjection() { @@ -379,10 +433,78 @@ public void testIstioCrossDomainTransactionWithFailInjection() { assertTrue(result.stdout().contains("Status=SUCCESS"), "crossDomainTransaction with TMAfterTLogBeforeCommitExit failed"); } + } + + /* + * Test verifies cross-domain MessageDrivenBean communication in istio env. + * A transacted MDB on Domain D1 listen on a replicated Distributed Topic + * on Domain D2. + * The MDB is deployed to cluster on domain D1 with MessagesDistributionMode + * set to One-Copy-Per-Server. The OnMessage() routine sends a message to + * local queue on receiving the message. + * An application servlet is deployed to Administration Server on D1 which + * send/receive message from a JMS destination based on a given URL. + * (a) app servlet send message to Distributed Topic on D2 + * (b) mdb puts a message into local Queue for each received message + * (c) make sure local Queue gets 2X times messages sent to Distributed Topic + * Since the MessagesDistributionMode is set to One-Copy-Per-Server and + * targeted to a cluster of two servers, onMessage() will be triggered + * for both instance of MDB for a message sent to Distributed Topic + */ + @Order(3) + @Test + @DisplayName("Check cross domain transcated MDB communication with istio") + public void testIstioCrossDomainTranscatedMDB() { + + String curlRequest = String.format("curl -v --show-error --noproxy '*' " + + "-H 'host:domain1-" + domain1Namespace + ".org' " + + "\"http://%s:%s/jmsservlet/jmstest?" + + "url=t3://domain2-cluster-cluster-1.%s:8001&" + + "cf=jms.ClusterConnectionFactory&" + + "action=send&" + + "dest=jms/testCdtUniformTopic\"", + K8S_NODEPORT_HOST, istioIngressPort, domain2Namespace); + + ExecResult result = null; + logger.info("curl command {0}", curlRequest); + result = assertDoesNotThrow( + () -> exec(curlRequest, true)); + if (result.exitValue() == 0) { + logger.info("\n HTTP response is \n " + result.stdout()); + logger.info("curl command returned {0}", result.toString()); + assertTrue(result.stdout().contains("Sent (10) message"), + "Can not send message to remote Distributed Topic"); + } + assertTrue(checkLocalQueue(), + "Expected number of message not found in Accounting Queue"); } - private void createDomain(String domainUid, String domainNamespace, String adminSecretName, + private boolean checkLocalQueue() { + String curlString = String.format("curl -v --show-error --noproxy '*' " + + "-H 'host:domain1-" + domain1Namespace + ".org' " + + "\"http://%s:%s/jmsservlet/jmstest?" + + "url=t3://localhost:7001&" + + "action=receive&dest=jms.testAccountingQueue\"", + K8S_NODEPORT_HOST, istioIngressPort); + + logger.info("curl command {0}", curlString); + withStandardRetryPolicy + .conditionEvaluationListener( + condition -> logger.info("Waiting for local queue to be updated " + + "(elapsed time {0} ms, remaining time {1} ms)", + condition.getElapsedTimeInMS(), + condition.getRemainingTimeInMS())) + .until(assertDoesNotThrow(() -> { + return () -> { + return exec(new String(curlString), true).stdout().contains("Messages are distributed"); + }; + })); + return true; + } + + + private static void createDomain(String domainUid, String domainNamespace, String adminSecretName, String domainImage) { // admin/managed server name here should match with model yaml in WDT_MODEL_FILE final String adminServerPodName = domainUid + "-admin-server"; @@ -434,7 +556,7 @@ private void createDomain(String domainUid, String domainNamespace, String admin } - private void createDomainResource(String domainUid, String domNamespace, String adminSecretName, + private static void createDomainResource(String domainUid, String domNamespace, String adminSecretName, String repoSecretName, int replicaCount, String domainImage) { // create the domain CR Domain domain = new Domain() diff --git a/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/AppBuilder.java b/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/AppBuilder.java index c615fe39ed9..cea32e7f8ce 100644 --- a/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/AppBuilder.java +++ b/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/AppBuilder.java @@ -109,7 +109,7 @@ public boolean buildCoherence() { copyFolder(APP_DIR + "/" + item, ARCHIVE_SRC_DIR); } } catch (IOException ioe) { - getLogger().info("Failed to get the directory " + ARCHIVE_DIR + " ready", ioe); + getLogger().severe("Failed to get the directory " + ARCHIVE_DIR + " ready", ioe); return false; } @@ -245,7 +245,7 @@ public boolean archiveApp() { checkDirectory(appDir); for (String appSrcFile : srcFiles) { if (appSrcFile.length() > 0) { - getLogger().info("copy {0]} to {1} ", appSrcFile, appDir); + getLogger().info("copy {0} to {1} ", appSrcFile, appDir); String fileName = appSrcFile.substring(appSrcFile.lastIndexOf("/") + 1); Files.copy(Paths.get(appSrcFile), Paths.get(appDir + "/" + fileName), StandardCopyOption.REPLACE_EXISTING); diff --git a/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/primitive/Kubernetes.java b/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/primitive/Kubernetes.java index a9d1a9222e5..ef623ef6d78 100644 --- a/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/primitive/Kubernetes.java +++ b/integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/primitive/Kubernetes.java @@ -2006,6 +2006,9 @@ public static V1Service getNamespacedService(String namespace, String serviceNam * @return node port if service and channel is found, otherwise -1 */ public static int getServiceNodePort(String namespace, String serviceName, String channelName) { + LoggingFacade logger = getLogger(); + logger.info("Retrieving Service NodePort for service [{0}] in namespace [{1}] for channel [{2}]", + serviceName, namespace, channelName); V1Service service = getNamespacedService(namespace, serviceName); if (service != null) { V1ServicePort port = service.getSpec().getPorts().stream().filter( diff --git a/integration-tests/src/test/java/oracle/weblogic/kubernetes/utils/CommonTestUtils.java b/integration-tests/src/test/java/oracle/weblogic/kubernetes/utils/CommonTestUtils.java index 981822148f4..60a38dd85cd 100644 --- a/integration-tests/src/test/java/oracle/weblogic/kubernetes/utils/CommonTestUtils.java +++ b/integration-tests/src/test/java/oracle/weblogic/kubernetes/utils/CommonTestUtils.java @@ -2050,7 +2050,7 @@ public static String createImageAndVerify(String imageNameBase, boolean buildCoherence = false; for (String appSrcDir : appSrcDirList) { - if (appSrcDir.contains(".war") || appSrcDir.contains(".ear")) { + if (appSrcDir.contains(".war") || appSrcDir.contains(".ear") || appSrcDir.contains(".jar")) { //remove from build buildAppDirList.remove(appSrcDir); archiveAppsList.add(appSrcDir); diff --git a/integration-tests/src/test/resources/apps/cdtservlet/build.xml b/integration-tests/src/test/resources/apps/cdtservlet/build.xml index 57d3febe783..3cf3d0c41f3 100644 --- a/integration-tests/src/test/resources/apps/cdtservlet/build.xml +++ b/integration-tests/src/test/resources/apps/cdtservlet/build.xml @@ -15,7 +15,7 @@ - + @@ -24,15 +24,16 @@ - - + destdir="${tempdir}"> - - - + + + + + + - \ No newline at end of file + diff --git a/integration-tests/src/test/resources/apps/cdtservlet/descriptors/web.xml b/integration-tests/src/test/resources/apps/cdtservlet/descriptors/web.xml deleted file mode 100644 index fead481767b..00000000000 --- a/integration-tests/src/test/resources/apps/cdtservlet/descriptors/web.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - cdttxservlet - application.CdtTxServlet - - - cdttxservlet - /cdttxservlet - - \ No newline at end of file diff --git a/integration-tests/src/test/resources/apps/cdtservlet/src/application/CdtTxServlet.java b/integration-tests/src/test/resources/apps/cdtservlet/src/application/CdtTxServlet.java index 8f9bcbef3a7..9f8a2d8cd62 100644 --- a/integration-tests/src/test/resources/apps/cdtservlet/src/application/CdtTxServlet.java +++ b/integration-tests/src/test/resources/apps/cdtservlet/src/application/CdtTxServlet.java @@ -28,8 +28,15 @@ import weblogic.transaction.TransactionHelper; import weblogic.transaction.TransactionManager; +import javax.servlet.*; +import javax.servlet.annotation.*; +import javax.servlet.http.*; + import static java.lang.Thread.sleep; +@WebServlet(name="cdttxservlet", urlPatterns={"/cdttxservlet"}, + initParams={ @WebInitParam(name="simpleParam", value="paramValue") } ) + public class CdtTxServlet extends HttpServlet { private static final long serialVersionUID = 1L; private TransactionManager tm = (TransactionManager) diff --git a/integration-tests/src/test/resources/apps/jmsservlet/build.xml b/integration-tests/src/test/resources/apps/jmsservlet/build.xml new file mode 100644 index 00000000000..2c3e1cf0d38 --- /dev/null +++ b/integration-tests/src/test/resources/apps/jmsservlet/build.xml @@ -0,0 +1,38 @@ + + + + + ant script to build the jms servlet to send/receive message + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration-tests/src/test/resources/apps/jmsservlet/src/application/JmsServlet.java b/integration-tests/src/test/resources/apps/jmsservlet/src/application/JmsServlet.java new file mode 100644 index 00000000000..86f6be2bb2a --- /dev/null +++ b/integration-tests/src/test/resources/apps/jmsservlet/src/application/JmsServlet.java @@ -0,0 +1,164 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +package application; + +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.annotation.WebInitParam; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServlet; +import java.text.SimpleDateFormat; +import java.text.DateFormat; + +import java.util.Hashtable; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.JMSConsumer; +import javax.jms.JMSContext; +import javax.jms.JMSException; +import javax.jms.JMSProducer; +import javax.jms.MessageConsumer; +import javax.jms.JMSRuntimeException; +import javax.jms.Message; + +import javax.transaction.UserTransaction; +import weblogic.transaction.TransactionHelper; + +@WebServlet(name="JmsServlet", urlPatterns={"/jmstest"}, + initParams={ @WebInitParam(name="simpleParam", value="paramValue") } ) + +public class JmsServlet extends HttpServlet { + + protected void doGet(HttpServletRequest request, + HttpServletResponse response) + throws ServletException, IOException { + response.setContentType("text/plain"); + PrintWriter out = response.getWriter(); + String action = ""; + String destination = ""; + String cfactory = "weblogic.jms.ConnectionFactory"; + String url = "t3://localhost:7001"; + String host = "localhost"; + String port = "7001"; + int scount = 10; + int rcount = 20; + + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + java.util.Date date = new java.util.Date(); + + try { + + action = request.getParameter("action"); + out.println("Action ["+action+"]"); + + destination = request.getParameter("dest"); + out.println("Destination ["+destination+"]"); + + if (request.getParameter("host") != null ) + host = request.getParameter("host"); + + if (request.getParameter("port") != null ) + port = request.getParameter("port"); + + url = "t3://"+host+":"+port; + + // Override if url parameter is provided + if (request.getParameter("url") != null ) + url = request.getParameter("url"); + + out.println("Url ["+url+"]"); + + if (request.getParameter("cf") != null ) + cfactory = request.getParameter("cf"); + + out.println("ConnectionFactory ["+cfactory+"]"); + + if (request.getParameter("scount") != null ) + scount = Integer.parseInt(request.getParameter("scount")); + + if (request.getParameter("rcount") != null ) + scount = Integer.parseInt(request.getParameter("rcount")); + + Hashtable h = new Hashtable(); + h.put(Context.INITIAL_CONTEXT_FACTORY, + "weblogic.jndi.WLInitialContextFactory"); + h.put(Context.PROVIDER_URL,url); + h.put(Context.SECURITY_PRINCIPAL, "weblogic"); + h.put(Context.SECURITY_CREDENTIALS, "welcome1"); + Context cxt = null; + cxt = new InitialContext(h); + out.println("Got Initial Context from " + url); + Destination d = (Destination)cxt.lookup(destination); + out.println("Destination Lookup Successful "); + ConnectionFactory qcf= (ConnectionFactory)cxt.lookup(cfactory); + out.println("ConnectionFactory Lookup Successful"); + + JMSContext context = qcf.createContext(); + + if ( action.equals("send") ) { + out.println("Sending ("+scount+") message to ["+destination+"]"); + String msg = "["+dateFormat.format(date)+"] Welcome to WebLogic Kubenates Operator"; + for ( int i=0; i + + + + ant script to build the cdttx servlet + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration-tests/src/test/resources/apps/mdbtopic/src/application/MdbTopic.java b/integration-tests/src/test/resources/apps/mdbtopic/src/application/MdbTopic.java new file mode 100644 index 00000000000..e2d4684fb16 --- /dev/null +++ b/integration-tests/src/test/resources/apps/mdbtopic/src/application/MdbTopic.java @@ -0,0 +1,102 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +package application; + +import java.text.SimpleDateFormat; +import java.text.DateFormat; + +import java.util.Hashtable; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import javax.jms.Destination; +import javax.jms.ConnectionFactory; +import javax.jms.JMSContext; +import javax.jms.Message; +import javax.jms.TextMessage; +import javax.jms.JMSConsumer; +import javax.jms.JMSProducer; +import javax.jms.MessageListener; + +import javax.ejb.MessageDriven; +import javax.ejb.ActivationConfigProperty; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; + +import weblogic.javaee.MessageDestinationConfiguration; +import weblogic.javaee.TransactionIsolation; +import weblogic.javaee.TransactionTimeoutSeconds; + +import weblogic.management.jmx.MBeanServerInvocationHandler; +import weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean; +import weblogic.management.mbeanservers.runtime.RuntimeServiceMBean; +import weblogic.management.runtime.DomainRuntimeMBean; +import weblogic.management.runtime.ServerRuntimeMBean; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +@MessageDriven( + activationConfig = { + @ActivationConfigProperty(propertyName="destinationType", + propertyValue="javax.jms.Topic"), + @ActivationConfigProperty(propertyName="topicMessagesDistributionMode", + propertyValue="One-Copy-Per-Server") + }, + mappedName = "jms/testCdtUniformTopic" +) + +@MessageDestinationConfiguration( + connectionFactoryJNDIName="weblogic.jms.XAConnectionFactory", + providerURL="t3://domain2-cluster-cluster-1.domain2-namespace:8001") + +@TransactionAttribute(value = TransactionAttributeType.REQUIRED) + + public class MdbTopic implements MessageListener { + + public void onMessage (Message msg) { + try { + + MBeanServer localMBeanServer; + ServerRuntimeMBean serverRuntime; + RuntimeServiceMBean runtimeService; + MBeanServer domainMBeanServer; + DomainRuntimeServiceMBean domainRuntimeServiceMbean; + DomainRuntimeMBean domainRuntime; + + localMBeanServer = (MBeanServer) + (new InitialContext()).lookup("java:comp/env/jmx/runtime"); + + ObjectName runtimeserviceObjectName = new ObjectName(RuntimeServiceMBean.OBJECT_NAME); + runtimeService = (RuntimeServiceMBean) MBeanServerInvocationHandler + .newProxyInstance(localMBeanServer, runtimeserviceObjectName); + serverRuntime = runtimeService.getServerRuntime(); + System.out.println(" MDB is activated on Server " + serverRuntime.getName()); + + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + java.util.Date date = new java.util.Date(); + TextMessage tmsg = (TextMessage) msg; + System.out.println("["+dateFormat.format(date)+"] Got message :" + tmsg.getText() ); + Hashtable h = new Hashtable(); + h.put(Context.INITIAL_CONTEXT_FACTORY, + "weblogic.jndi.WLInitialContextFactory"); + h.put(Context.PROVIDER_URL,"t3://domain1-admin-server:7001"); + h.put(Context.SECURITY_PRINCIPAL, "weblogic"); + h.put(Context.SECURITY_CREDENTIALS, "welcome1"); + Context cxt = new InitialContext(h); + + ConnectionFactory + cf=(ConnectionFactory)cxt.lookup("weblogic.jms.ConnectionFactory"); + Destination rq=(Destination)cxt.lookup("jms.testAccountingQueue"); + JMSContext context = cf.createContext(); + tmsg = context.createTextMessage("(On Server) " + serverRuntime.getName()); + context.createProducer().send(rq,tmsg); + System.out.println("["+dateFormat.format(date)+"] message added to [@FWD_DEST_URL@]"); + } catch (Exception e) { + e.printStackTrace (); + } + } + + } diff --git a/integration-tests/src/test/resources/apps/txforward/build.xml b/integration-tests/src/test/resources/apps/txforward/build.xml index b862c385a3f..3cc079778c4 100644 --- a/integration-tests/src/test/resources/apps/txforward/build.xml +++ b/integration-tests/src/test/resources/apps/txforward/build.xml @@ -64,7 +64,6 @@ - diff --git a/integration-tests/src/test/resources/istio/istio-cdt-http-template-service.yaml b/integration-tests/src/test/resources/istio/istio-cdt-http-template-service.yaml index 66dff5160b7..f8733128486 100644 --- a/integration-tests/src/test/resources/istio/istio-cdt-http-template-service.yaml +++ b/integration-tests/src/test/resources/istio/istio-cdt-http-template-service.yaml @@ -34,6 +34,8 @@ spec: prefix: /TxForward - uri: prefix: /cdttxservlet + - uri: + prefix: /jmsservlet - port: 7001 route: - destination: diff --git a/integration-tests/src/test/resources/wdt-models/model-cdt-jms.yaml b/integration-tests/src/test/resources/wdt-models/model-cdt-jms.yaml index 8aed3ce5cd8..8983ac4f147 100644 --- a/integration-tests/src/test/resources/wdt-models/model-cdt-jms.yaml +++ b/integration-tests/src/test/resources/wdt-models/model-cdt-jms.yaml @@ -12,8 +12,24 @@ resources: PersistentStore: 'TestCdtFileStore' InsertionPausedAtStartup: false MessageCompressionOptions: GZIP_DEFAULT_COMPRESSION + TestAdminJmsServer: + ProductionPausedAtStartup: false + ConsumptionPausedAtStartup: false + Target: 'admin-server' + InsertionPausedAtStartup: false + MessageCompressionOptions: GZIP_DEFAULT_COMPRESSION JMSSystemResource: + TestAdminJmsModule: + Target: 'admin-server' + SubDeployment: + TestAdminSubDeployment: + Target: TestAdminJmsServer + JmsResource: + Queue: + testAccountingQueue: + SubDeploymentName: TestAdminSubDeployment + JNDIName: jms.testAccountingQueue TestCdtJmsModule: Target: 'cluster-1' SubDeployment: @@ -23,4 +39,11 @@ resources: UniformDistributedQueue: testCdtUniformQueue: SubDeploymentName: TestCdtSubDeployment - JNDIName: jms/testCdtUniformQueue \ No newline at end of file + JNDIName: jms/testCdtUniformQueue + ConnectionFactory: + ClusterConnectionFactory: + JNDIName: jms.ClusterConnectionFactory + DefaultTargetingEnabled: true + LoadBalancingParams: + ServerAffinityEnabled: false + LoadBalancingEnabled: true diff --git a/integration-tests/src/test/resources/wdt-models/model-crossdomaintransaction-domain1.yaml b/integration-tests/src/test/resources/wdt-models/model-crossdomaintransaction-domain1.yaml index 63717213027..be809dc6451 100644 --- a/integration-tests/src/test/resources/wdt-models/model-crossdomaintransaction-domain1.yaml +++ b/integration-tests/src/test/resources/wdt-models/model-crossdomaintransaction-domain1.yaml @@ -36,4 +36,12 @@ appDeployments: cdttxservlet: SourcePath: "wlsdeploy/applications/cdttxservlet.war" ModuleType: war - Target: 'admin-server' \ No newline at end of file + Target: 'admin-server' + jmservlet: + SourcePath: "wlsdeploy/applications/jmsservlet.war" + ModuleType: war + Target: 'admin-server' + mdbtopic: + SourcePath: "wlsdeploy/applications/mdbtopic.jar" + ModuleType: jar + Target: 'cluster-1' diff --git a/integration-tests/src/test/resources/wdt-models/model2-cdt-jms.yaml b/integration-tests/src/test/resources/wdt-models/model2-cdt-jms.yaml new file mode 100644 index 00000000000..874e61ee360 --- /dev/null +++ b/integration-tests/src/test/resources/wdt-models/model2-cdt-jms.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +resources: + FileStore: + TestCdtFileStore: + Target: 'cluster-1' + JMSServer: + TestCdtJmsServer: + ProductionPausedAtStartup: false + ConsumptionPausedAtStartup: false + Target: 'cluster-1' + PersistentStore: 'TestCdtFileStore' + InsertionPausedAtStartup: false + MessageCompressionOptions: GZIP_DEFAULT_COMPRESSION + + JMSSystemResource: + TestCdtJmsModule: + Target: 'cluster-1' + SubDeployment: + TestCdtSubDeployment: + Target: TestCdtJmsServer + JmsResource: + UniformDistributedTopic: + testCdtUniformTopic: + SubDeploymentName: TestCdtSubDeployment + JNDIName: jms.testCdtUniformTopic + ForwardingPolicy: Partitioned + ConnectionFactory: + ClusterConnectionFactory: + JNDIName: jms.ClusterConnectionFactory + DefaultTargetingEnabled: true + LoadBalancingParams: + ServerAffinityEnabled: false + LoadBalancingEnabled: true