diff --git a/integration-tests/src/test/java/oracle/weblogic/domain/ServerPod.java b/integration-tests/src/test/java/oracle/weblogic/domain/ServerPod.java index 74b1d9ebe1d..8e4239394b8 100644 --- a/integration-tests/src/test/java/oracle/weblogic/domain/ServerPod.java +++ b/integration-tests/src/test/java/oracle/weblogic/domain/ServerPod.java @@ -368,7 +368,7 @@ public ServerPod addCommonMountsItem(CommonMount commonMountsItem) { return this; } - List getCommonMounts() { + public List getCommonMounts() { return this.commonMounts; } diff --git a/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItMiiCommonMount.java b/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItMiiCommonMount.java index 526d673656a..32c45548d2a 100644 --- a/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItMiiCommonMount.java +++ b/integration-tests/src/test/java/oracle/weblogic/kubernetes/ItMiiCommonMount.java @@ -7,9 +7,13 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.time.OffsetDateTime; import java.util.Collections; import java.util.List; +import java.util.Map; +import io.kubernetes.client.custom.V1Patch; +import oracle.weblogic.domain.CommonMount; import oracle.weblogic.domain.Domain; import oracle.weblogic.kubernetes.actions.impl.primitive.Command; import oracle.weblogic.kubernetes.actions.impl.primitive.CommandParams; @@ -43,18 +47,25 @@ import static oracle.weblogic.kubernetes.actions.TestActions.defaultAppParams; import static oracle.weblogic.kubernetes.actions.TestActions.deleteImage; import static oracle.weblogic.kubernetes.actions.TestActions.dockerPush; +import static oracle.weblogic.kubernetes.actions.TestActions.getDomainCustomResource; import static oracle.weblogic.kubernetes.actions.TestActions.getServiceNodePort; +import static oracle.weblogic.kubernetes.actions.TestActions.patchDomainCustomResource; +import static oracle.weblogic.kubernetes.assertions.TestAssertions.verifyRollingRestartOccurred; import static oracle.weblogic.kubernetes.utils.CommonMiiTestUtils.createDomainResource; +import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkSystemResourceConfig; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.checkSystemResourceConfiguration; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.createDomainAndVerify; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.createOcirRepoSecret; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.createSecretWithUsernamePassword; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.getExternalServicePodName; +import static oracle.weblogic.kubernetes.utils.CommonTestUtils.getPodsWithTimeStamps; import static oracle.weblogic.kubernetes.utils.CommonTestUtils.installAndVerifyOperator; +import static oracle.weblogic.kubernetes.utils.FileUtils.replaceStringInFile; import static oracle.weblogic.kubernetes.utils.FileUtils.unzipWDTInstallationFile; 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.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -69,6 +80,12 @@ public class ItMiiCommonMount { private String domainUid = "domain1"; private static String miiCMImage1 = MII_COMMONMOUNT_IMAGE_NAME + ":" + MII_BASIC_IMAGE_TAG + "1"; private static String miiCMImage2 = MII_COMMONMOUNT_IMAGE_NAME + ":" + MII_BASIC_IMAGE_TAG + "2"; + private static String miiCMImage3 = MII_COMMONMOUNT_IMAGE_NAME + ":" + MII_BASIC_IMAGE_TAG + "3"; + private static Map podsWithTimeStamps = null; + private final String adminServerPodName = domainUid + "-admin-server"; + private final String managedServerPrefix = domainUid + "-managed-server"; + private final int replicaCount = 2; + ConditionFactory withStandardRetryPolicy = with().pollDelay(0, SECONDS) .and().with().pollInterval(10, SECONDS) @@ -87,7 +104,7 @@ public static void initAll(@Namespaces(2) List namespaces) { assertNotNull(namespaces.get(0), "Namespace list is null"); opNamespace = namespaces.get(0); - logger.info("Creating unique namespace for Domain"); + logger.info("Creating unique namespace for Domain1"); assertNotNull(namespaces.get(1), "Namespace list is null"); domainNamespace = namespaces.get(1); @@ -106,9 +123,6 @@ public static void initAll(@Namespaces(2) List namespaces) { public void testCreateDomainUsingMultipleCommonMounts() { // admin/managed server name here should match with model yaml - final String adminServerPodName = domainUid + "-admin-server"; - final String managedServerPrefix = domainUid + "-managed-server"; - final int replicaCount = 2; final String commonMountVolumeName = "commonMountsVolume1"; final String commonMountPath = "/common"; @@ -140,6 +154,10 @@ public void testCreateDomainUsingMultipleCommonMounts() { Paths.get(MODEL_DIR, MII_BASIC_WDT_MODEL_FILE), Paths.get(modelsPath1.toString(), MII_BASIC_WDT_MODEL_FILE), StandardCopyOption.REPLACE_EXISTING)); + assertDoesNotThrow(() -> Files.copy( + Paths.get(MODEL_DIR, "multi-model-one-ds.20.yaml"), + Paths.get(modelsPath1.toString(), "multi-model-one-ds.20.yaml"), + StandardCopyOption.REPLACE_EXISTING)); // build app assertTrue(buildAppArchive(defaultAppParams() @@ -200,7 +218,8 @@ public void testCreateDomainUsingMultipleCommonMounts() { // create domain and verify its running logger.info("Creating domain {0} with common mount images {1} {2} in namespace {3}", domainUid, miiCMImage1, miiCMImage2, domainNamespace); - createDomainAndVerify(domainUid, domainCR, domainNamespace, adminServerPodName, managedServerPrefix, replicaCount); + createDomainAndVerify(domainUid, domainCR, domainNamespace, + adminServerPodName, managedServerPrefix, replicaCount); // check configuration for JMS int adminServiceNodePort @@ -211,6 +230,122 @@ public void testCreateDomainUsingMultipleCommonMounts() { logger.info("Found the JMSSystemResource configuration"); } + /** + * Reuse created a domain with datasource using common mount containing the DataSource, + * verify the domain is running and JDBC DataSource resource is added. + * Patch domain with updated JDBC URL info and verify the update. + */ + @Test + @Order(2) + @DisplayName("Test to update data source url in the domain using common mount") + public void testUpdateDataSourceInDomainUsingCommonMount1() { + + Path multipleCMPath1 = Paths.get(RESULTS_ROOT, "multiplecmimage1"); + Path modelsPath1 = Paths.get(multipleCMPath1.toString(), "models"); + + + // create stage dir for common mount with image3 + // replace DataSource URL info in the model file + assertDoesNotThrow(() -> replaceStringInFile(Paths.get(modelsPath1.toString(), + "/multi-model-one-ds.20.yaml").toString(), "xxx.xxx.x.xxx:1521", + "localhost:7001"),"Can't replace datasource url in the model file"); + assertDoesNotThrow(() -> replaceStringInFile(Paths.get(modelsPath1.toString(), + "/multi-model-one-ds.20.yaml").toString(), "ORCLCDB", + "dbsvc"),"Can't replace datasource url in the model file"); + + // create image3 with model and wdt installation files + createCommonMountImage(multipleCMPath1.toString(), + Paths.get(RESOURCE_DIR, "commonmount", "Dockerfile").toString(), miiCMImage3); + + // push image3 to repo for multi node cluster + if (!DOMAIN_IMAGES_REPO.isEmpty()) { + logger.info("docker push image {0} to registry {1}", miiCMImage3, DOMAIN_IMAGES_REPO); + assertTrue(dockerPush(miiCMImage3), String.format("docker push failed for image %s", miiCMImage3)); + } + + // check configuration for DataSource in the running domain + int adminServiceNodePort + = getServiceNodePort(domainNamespace, getExternalServicePodName(adminServerPodName), "default"); + assertNotEquals(-1, adminServiceNodePort, "admin server default node port is not valid"); + assertTrue(checkSystemResourceConfig(adminServiceNodePort, + "JDBCSystemResources/TestDataSource/JDBCResource/JDBCDriverParams", + "jdbc:oracle:thin:@\\/\\/xxx.xxx.x.xxx:1521\\/ORCLCDB"),"Can't find expected URL configuration for DataSource"); + + logger.info("Found the DataResource configuration"); + + patchDomainWithCMImageAndVerify(miiCMImage1, miiCMImage3, domainUid, domainNamespace); + + assertTrue(checkSystemResourceConfig(adminServiceNodePort, + "JDBCSystemResources/TestDataSource/JDBCResource/JDBCDriverParams", + "jdbc:oracle:thin:@\\/\\/localhost:7001\\/dbsvc"), "Can't find expected URL configuration for DataSource"); + + logger.info("Found the DataResource configuration"); + } + + private static void patchDomainWithCMImageAndVerify(String oldImageName, String newImageName, + String domainUid, String domainNamespace) { + String adminServerPodName = domainUid + "-admin-server"; + String managedServerPrefix = domainUid + "-managed-server"; + Domain domain1 = assertDoesNotThrow(() -> getDomainCustomResource(domainUid, domainNamespace), + String.format("getDomainCustomResource failed with ApiException when tried to get domain %s in namespace %s", + domainUid, domainNamespace)); + assertNotNull(domain1, "Got null domain resource "); + assertNotNull(domain1.getSpec().getServerPod().getCommonMounts(), domain1 + "/spec/serverPod/commonMounts is null"); + List commonMountList = domain1.getSpec().getServerPod().getCommonMounts(); + assertFalse(commonMountList.isEmpty(), "CommonMount list is empty"); + String searchString; + int index = 0; + + CommonMount cmMount = commonMountList.stream() + .filter(commonMount -> oldImageName.equals(commonMount.getImage())) + .findAny() + .orElse(null); + assertNotNull(cmMount, "Can't find common Mount with Image name " + oldImageName + + "can't patch domain " + domainUid); + + index = commonMountList.indexOf(cmMount); + searchString = "\"/spec/serverPod/commonMounts/" + index + "/image\""; + StringBuffer patchStr = new StringBuffer("[{"); + patchStr.append("\"op\": \"replace\",") + .append(" \"path\": " + searchString + ",") + .append(" \"value\": \"" + newImageName + "\"") + .append(" }]"); + logger.info("Common Mount patch string: " + patchStr); + + //get current timestamp before domain rolling restart to verify domain roll events + podsWithTimeStamps = getPodsWithTimeStamps(domainNamespace, adminServerPodName, + managedServerPrefix, 2); + V1Patch patch = new V1Patch((patchStr).toString()); + + boolean cmPatched = assertDoesNotThrow(() -> + patchDomainCustomResource(domainUid, domainNamespace, patch, "application/json-patch+json"), + "patchDomainCustomResource(Common Mount) failed "); + assertTrue(cmPatched, "patchDomainCustomResource(common Mount) failed"); + + domain1 = assertDoesNotThrow(() -> getDomainCustomResource(domainUid, domainNamespace), + String.format("getDomainCustomResource failed with ApiException when tried to get domain %s in namespace %s", + domainUid, domainNamespace)); + assertNotNull(domain1, "Got null domain resource after patching"); + assertNotNull(domain1.getSpec(), domain1 + " /spec/serverPod is null"); + assertNotNull(domain1.getSpec().getServerPod(), domain1 + " /spec/serverPod is null"); + assertNotNull(domain1.getSpec().getServerPod().getCommonMounts(), domain1 + "/spec/serverPod/commonMounts is null"); + + //verify the new CommonMount image in the new patched domain + commonMountList = domain1.getSpec().getServerPod().getCommonMounts(); + + String cmImage = commonMountList.get(index).getImage(); + logger.info("In the new patched domain imageValue is: {0}", cmImage); + assertTrue(cmImage.equalsIgnoreCase(newImageName), "common mount image was not updated" + + " in the new patched domain"); + + // verify the server pods are rolling restarted and back to ready state + logger.info("Verifying rolling restart occurred for domain {0} in namespace {1}", + domainUid, domainNamespace); + + assertTrue(verifyRollingRestartOccurred(podsWithTimeStamps, 1, domainNamespace), + String.format("Rolling restart failed for domain %s in namespace %s", domainUid, domainNamespace)); + } + /** * Cleanup images. */ @@ -223,6 +358,10 @@ public void tearDownAll() { if (miiCMImage2 != null) { deleteImage(miiCMImage2); } + + if (miiCMImage3 != null) { + deleteImage(miiCMImage3); + } } private void createCommonMountImage(String stageDirPath, String dockerFileLocation, String cmImage) { @@ -234,5 +373,4 @@ private void createCommonMountImage(String stageDirPath, String dockerFileLocati .command(cmdToExecute)) .execute(), String.format("Failed to execute", cmdToExecute)); } - }