1010import java .util .ArrayList ;
1111import java .util .Arrays ;
1212import java .util .Collections ;
13+ import java .util .HashMap ;
1314import java .util .List ;
15+ import java .util .Map ;
1416import java .util .Properties ;
1517
18+ import io .kubernetes .client .custom .V1Patch ;
1619import io .kubernetes .client .openapi .ApiException ;
20+ import io .kubernetes .client .openapi .models .V1ConfigMap ;
21+ import io .kubernetes .client .openapi .models .V1ObjectMeta ;
22+ import oracle .weblogic .domain .ClusterResource ;
1723import oracle .weblogic .domain .DomainCreationImage ;
1824import oracle .weblogic .domain .DomainResource ;
1925import oracle .weblogic .kubernetes .actions .impl .primitive .HelmParams ;
2228import oracle .weblogic .kubernetes .annotations .Namespaces ;
2329import oracle .weblogic .kubernetes .logging .LoggingFacade ;
2430import oracle .weblogic .kubernetes .utils .ExecResult ;
31+ import org .awaitility .core .ConditionFactory ;
2532import org .junit .jupiter .api .BeforeAll ;
2633import org .junit .jupiter .api .DisplayName ;
2734import org .junit .jupiter .api .MethodOrderer ;
4249import static oracle .weblogic .kubernetes .TestConstants .OPERATOR_RELEASE_NAME ;
4350import static oracle .weblogic .kubernetes .TestConstants .TEST_IMAGES_REPO_SECRET_NAME ;
4451import static oracle .weblogic .kubernetes .actions .ActionConstants .MODEL_DIR ;
52+ import static oracle .weblogic .kubernetes .actions .TestActions .createConfigMap ;
4553import static oracle .weblogic .kubernetes .actions .TestActions .deletePod ;
4654import static oracle .weblogic .kubernetes .actions .TestActions .getOperatorPodName ;
55+ import static oracle .weblogic .kubernetes .actions .TestActions .patchDomainCustomResource ;
56+ import static oracle .weblogic .kubernetes .actions .TestActions .patchDomainResourceWithNewIntrospectVersion ;
4757import static oracle .weblogic .kubernetes .utils .AuxiliaryImageUtils .createAndPushAuxiliaryImage ;
58+ import static oracle .weblogic .kubernetes .utils .ClusterUtils .createClusterAndVerify ;
59+ import static oracle .weblogic .kubernetes .utils .ClusterUtils .createClusterResource ;
4860import static oracle .weblogic .kubernetes .utils .CommonTestUtils .addSccToDBSvcAccount ;
61+ import static oracle .weblogic .kubernetes .utils .CommonTestUtils .checkPodReadyAndServiceExists ;
62+ import static oracle .weblogic .kubernetes .utils .CommonTestUtils .createCustomConditionFactory ;
4963import static oracle .weblogic .kubernetes .utils .CommonTestUtils .getNextFreePort ;
5064import static oracle .weblogic .kubernetes .utils .CommonTestUtils .getUniqueName ;
5165import static oracle .weblogic .kubernetes .utils .CommonTestUtils .testUntil ;
6377import static oracle .weblogic .kubernetes .utils .FmwUtils .verifyDomainReady ;
6478import static oracle .weblogic .kubernetes .utils .ImageUtils .createBaseRepoSecret ;
6579import static oracle .weblogic .kubernetes .utils .ImageUtils .createTestRepoSecret ;
80+ import static oracle .weblogic .kubernetes .utils .JobUtils .getIntrospectJobName ;
6681import static oracle .weblogic .kubernetes .utils .OKDUtils .createRouteForOKD ;
6782import static oracle .weblogic .kubernetes .utils .OperatorUtils .installAndVerifyOperator ;
6883import static oracle .weblogic .kubernetes .utils .PodUtils .checkPodDoesNotExist ;
84+ import static oracle .weblogic .kubernetes .utils .PodUtils .checkPodExists ;
6985import static oracle .weblogic .kubernetes .utils .PodUtils .checkPodLogContains ;
7086import static oracle .weblogic .kubernetes .utils .PodUtils .getExternalServicePodName ;
7187import static oracle .weblogic .kubernetes .utils .SecretUtils .createOpsswalletFileSecretWithoutFile ;
@@ -697,6 +713,126 @@ void testFmwDomainOnPVwithProvidedOpss() {
697713 }
698714 }
699715
716+ /**
717+ * User creates RCU, Operate creates PV/PVC and FMW domain.
718+ * Add a cluster to the domain and update the introspectVersion to trigger the introspection
719+ * Verify Operator starts the servers in the new cluster.
720+ */
721+ @ Test
722+ @ Order (8 )
723+ @ DisplayName ("Create a FMW domain on PV with adding new cluster" )
724+ void testFmwDomainOnPvUserWithAddedCluster () {
725+ String domainUid = "jrfdomainonpv-userrcu7" ;
726+ String adminSecretName = domainUid + "-weblogic-credentials" ;
727+ String rcuaccessSecretName = domainUid + "-rcu-credentials" ;
728+ String opsswalletpassSecretName = domainUid + "-opss-wallet-password-secret" ;
729+ String configMapName = domainUid + "-configmap" ;
730+ String cluster2Res = domainUid + "-cluster-2" ;
731+ String cluster2Name = "cluster-2" ;
732+ int replicaCluster2 = 2 ;
733+ String managedServer2Prefix = domainUid + "-c2-managed-server" ;
734+ final String pvName = getUniqueName (domainUid + "-pv-" );
735+ final String pvcName = getUniqueName (domainUid + "-pvc-" );
736+
737+ //create RCU schema
738+ assertDoesNotThrow (() -> createRcuSchema (FMWINFRA_IMAGE_TO_USE_IN_SPEC , RCUSCHEMAPREFIX + "7" ,
739+ dbUrl , dbNamespace ), "create RCU schema failed" );
740+
741+ // create a model property file
742+ File fmwModelPropFile = createWdtPropertyFile (domainUid , RCUSCHEMAPREFIX + "7" );
743+
744+ // Create the repo secret to pull the image
745+ // this secret is used only for non-kind cluster
746+ createTestRepoSecret (domainNamespace );
747+
748+ // create secret for admin credentials
749+ logger .info ("Create secret for admin credentials" );
750+ assertDoesNotThrow (() -> createSecretWithUsernamePassword (
751+ adminSecretName ,
752+ domainNamespace ,
753+ ADMIN_USERNAME_DEFAULT ,
754+ ADMIN_PASSWORD_DEFAULT ),
755+ String .format ("createSecret failed for %s" , adminSecretName ));
756+
757+ // create RCU access secret
758+ logger .info ("Creating RCU access secret: {0}, with prefix: {1}, dbUrl: {2}, schemapassword: {3})" ,
759+ rcuaccessSecretName , RCUSCHEMAPREFIX + "7" , RCUSCHEMAPASSWORD , dbUrl );
760+ assertDoesNotThrow (() -> createRcuAccessSecret (
761+ rcuaccessSecretName ,
762+ domainNamespace ,
763+ RCUSCHEMAPREFIX + "7" ,
764+ RCUSCHEMAPASSWORD ,
765+ dbUrl ),
766+ String .format ("createSecret failed for %s" , rcuaccessSecretName ));
767+
768+ logger .info ("Create OPSS wallet password secret" );
769+ assertDoesNotThrow (() -> createOpsswalletpasswordSecret (
770+ opsswalletpassSecretName ,
771+ domainNamespace ,
772+ ADMIN_PASSWORD_DEFAULT ),
773+ String .format ("createSecret failed for %s" , opsswalletpassSecretName ));
774+
775+ DomainCreationImage domainCreationImage = createImage (fmwModelFile ,fmwModelPropFile ,"jrf7" );
776+ List <DomainCreationImage > domainCreationImages7 = new ArrayList <>();
777+ domainCreationImages7 .add (domainCreationImage );
778+
779+ logger .info ("create WDT configMap with extra cluster" );
780+ createModelConfigMap (domainUid ,configMapName );
781+
782+ // create a domain custom resource configuration object
783+ logger .info ("Creating domain custom resource with pvName: {0}" , pvName );
784+ DomainResource domain = createDomainResourceSimplifyJrfPv (
785+ domainUid , domainNamespace , adminSecretName ,
786+ TEST_IMAGES_REPO_SECRET_NAME ,
787+ rcuaccessSecretName ,
788+ opsswalletpassSecretName , null ,
789+ pvName , pvcName , domainCreationImages7 , configMapName );
790+
791+ createDomainAndVerify (domain , domainNamespace );
792+
793+ // verify that all servers in the original cluster-1 are ready
794+ verifyDomainReady (domainNamespace , domainUid , replicaCount , "nosuffix" );
795+
796+ // create and deploy cluster resource
797+ ClusterResource cluster2 = createClusterResource (
798+ cluster2Res , cluster2Name , domainNamespace , replicaCluster2 );
799+ logger .info ("Creating ClusterResource {0} in namespace {1}" ,cluster2Res , domainNamespace );
800+ createClusterAndVerify (cluster2 );
801+
802+ logger .info ("Patch domain resource by adding cluster cluster-2" );
803+ String patchStr
804+ = "["
805+ + "{\" op\" : \" add\" ,\" path\" : \" /spec/clusters/-\" , \" value\" : {\" name\" : \" " + cluster2Res + "\" }"
806+ + "}]" ;
807+ logger .info ("Updating domain configuration using patch string: {0}\n " , patchStr );
808+ V1Patch patch2 = new V1Patch (patchStr );
809+ assertTrue (patchDomainCustomResource (domainUid , domainNamespace , patch2 , V1Patch .PATCH_FORMAT_JSON_PATCH ),
810+ "Failed to patch domain" );
811+
812+ patchDomainResourceWithNewIntrospectVersion (domainUid , domainNamespace );
813+
814+ ConditionFactory customConditionFactory = createCustomConditionFactory (0 , 1 , 5 );
815+
816+ //verify the introspector pod is created and runs
817+ String introspectPodNameBase2 = getIntrospectJobName (domainUid );
818+ checkPodExists (customConditionFactory , introspectPodNameBase2 , domainUid , domainNamespace );
819+ checkPodDoesNotExist (introspectPodNameBase2 , domainUid , domainNamespace );
820+
821+ // verify managed server pods from cluster-2 are created
822+ for (int i = 1 ; i <= replicaCluster2 ; i ++) {
823+ logger .info ("Wait for managed pod {0} to be ready in namespace {1}" ,
824+ managedServer2Prefix + i , domainNamespace );
825+ checkPodReadyAndServiceExists (managedServer2Prefix + i , domainUid , domainNamespace );
826+ }
827+
828+ // delete the domain
829+ deleteDomainResource (domainNamespace , domainUid );
830+ //delete the rcu pod
831+ assertDoesNotThrow (() -> deletePod ("rcu" , dbNamespace ),
832+ "Got exception while deleting server " + "rcu" );
833+ checkPodDoesNotExist ("rcu" , null , dbNamespace );
834+
835+ }
700836
701837 private DomainCreationImage createImage (String fmwModelFile , File fmwModelPropFile , String imageTagPrefix ) {
702838
@@ -788,5 +924,44 @@ private void verifyPodWithExpectedErrorMsg(String expectedErrorMsg, String podNa
788924 "Checking operator log containing the expected error msg {0}:" ,
789925 expectedErrorMsg );
790926 }
927+
928+ // create a ConfigMap with a model that adds a cluster
929+ private static void createModelConfigMap (String domainid , String cfgMapName ) {
930+ String yamlString = "topology:\n "
931+ + " Cluster:\n "
932+ + " 'cluster-2':\n "
933+ + " Server:\n "
934+ + " 'c2-managed-server1':\n "
935+ + " Cluster: 'cluster-2' \n "
936+ + " ListenPort : 8001 \n "
937+ + " 'c2-managed-server2':\n "
938+ + " Cluster: 'cluster-2' \n "
939+ + " ListenPort : 8001 \n "
940+ + " 'c2-managed-server3':\n "
941+ + " Cluster: 'cluster-2' \n "
942+ + " ListenPort : 8001 \n "
943+ + " 'c2-managed-server4':\n "
944+ + " Cluster: 'cluster-2' \n "
945+ + " ListenPort : 8001 \n "
946+ + " 'c2-managed-server5':\n "
947+ + " Cluster: 'cluster-2' \n "
948+ + " ListenPort : 8001 \n " ;
949+
950+ Map <String , String > labels = new HashMap <>();
951+ labels .put ("weblogic.domainUid" , domainid );
952+ Map <String , String > data = new HashMap <>();
953+ data .put ("model.cluster.yaml" , yamlString );
954+
955+ V1ConfigMap configMap = new V1ConfigMap ()
956+ .data (data )
957+ .metadata (new V1ObjectMeta ()
958+ .labels (labels )
959+ .name (cfgMapName )
960+ .namespace (domainNamespace ));
961+ boolean cmCreated = assertDoesNotThrow (() -> createConfigMap (configMap ),
962+ String .format ("Can't create ConfigMap %s" , cfgMapName ));
963+ assertTrue (cmCreated , String .format ("createConfigMap failed %s" , cfgMapName ));
964+ }
965+
791966
792967}
0 commit comments