11
11
import java .util .ArrayList ;
12
12
import java .util .Arrays ;
13
13
import java .util .Collections ;
14
+ import java .util .HashMap ;
14
15
import java .util .List ;
16
+ import java .util .Map ;
15
17
16
18
import io .kubernetes .client .openapi .models .V1EnvVar ;
17
19
import io .kubernetes .client .openapi .models .V1HTTPIngressPath ;
30
32
import oracle .weblogic .kubernetes .actions .impl .Cluster ;
31
33
import oracle .weblogic .kubernetes .actions .impl .NginxParams ;
32
34
import oracle .weblogic .kubernetes .actions .impl .Service ;
35
+ import oracle .weblogic .kubernetes .actions .impl .primitive .Command ;
36
+ import oracle .weblogic .kubernetes .actions .impl .primitive .CommandParams ;
33
37
import oracle .weblogic .kubernetes .actions .impl .primitive .WitParams ;
34
38
import oracle .weblogic .kubernetes .annotations .IntegrationTest ;
35
39
import oracle .weblogic .kubernetes .annotations .Namespaces ;
40
44
import org .junit .jupiter .api .DisplayName ;
41
45
import org .junit .jupiter .api .Tag ;
42
46
import org .junit .jupiter .api .Test ;
47
+ import org .junit .jupiter .api .condition .DisabledIfEnvironmentVariable ;
43
48
44
49
import static java .net .InetAddress .getLocalHost ;
45
50
import static oracle .weblogic .kubernetes .TestConstants .ADMIN_PASSWORD_DEFAULT ;
77
82
import static oracle .weblogic .kubernetes .utils .CommonTestUtils .testUntil ;
78
83
import static oracle .weblogic .kubernetes .utils .DomainUtils .createDomainAndVerify ;
79
84
import static oracle .weblogic .kubernetes .utils .FileUtils .copyFileToPod ;
85
+ import static oracle .weblogic .kubernetes .utils .FileUtils .generateFileFromTemplate ;
80
86
import static oracle .weblogic .kubernetes .utils .ImageUtils .createTestRepoSecret ;
81
87
import static oracle .weblogic .kubernetes .utils .LoadBalancerUtils .createIngressAndRetryIfFail ;
82
88
import static oracle .weblogic .kubernetes .utils .LoadBalancerUtils .installAndVerifyNginx ;
@@ -118,6 +124,7 @@ class ItCrossDomainTransactionSecurity {
118
124
private static String domain2ManagedServerPrefix = domainUid2 + "-managed-server" ;
119
125
private static LoggingFacade logger = null ;
120
126
private static int replicaCount = 2 ;
127
+ private static String clusterName = "cluster-2" ;
121
128
private static int t3ChannelPort1 = getNextFreePort ();
122
129
private static int t3ChannelPort2 = getNextFreePort ();
123
130
private static String domain1AdminExtSvcRouteHost = null ;
@@ -126,6 +133,11 @@ class ItCrossDomainTransactionSecurity {
126
133
private static String nginxNamespace = null ;
127
134
private static NginxParams nginxHelmParams = null ;
128
135
private static int nginxNodePort ;
136
+ private static Path tlsCertFile ;
137
+ private static Path tlsKeyFile ;
138
+ private static Path jksTrustFile ;
139
+ private static String tlsSecretName = domainUid2 + "-test-tls-secret" ;
140
+ private static String hostAddress = K8S_NODEPORT_HOST ;
129
141
130
142
131
143
@@ -135,7 +147,7 @@ class ItCrossDomainTransactionSecurity {
135
147
* JUnit engine parameter resolution mechanism
136
148
*/
137
149
@ BeforeAll
138
- public static void initAll (@ Namespaces (3 ) List <String > namespaces ) {
150
+ public static void initAll (@ Namespaces (3 ) List <String > namespaces ) throws UnknownHostException {
139
151
logger = getLogger ();
140
152
141
153
// get a new unique opNamespace
@@ -152,6 +164,7 @@ public static void initAll(@Namespaces(3) List<String> namespaces) {
152
164
assertNotNull (namespaces .get (2 ), "Namespace list is null" );
153
165
nginxNamespace = namespaces .get (2 );
154
166
167
+
155
168
// Create the repo secret to pull the image
156
169
// this secret is used only for non-kind cluster
157
170
createTestRepoSecret (domainNamespace );
@@ -167,25 +180,6 @@ public static void initAll(@Namespaces(3) List<String> namespaces) {
167
180
168
181
buildDomains ();
169
182
170
- }
171
-
172
- /**
173
- * Configure two domains d1 and d2 with CrossDomainSecurityEnabled set to true
174
- * On both domains create a user (cross-domain) with group CrossDomainConnectors
175
- * Add required Credential Mapping
176
- * Deploy a JSP on d1's admin server that takes 2 parameteers
177
- * a. The tx aaction b. the d2's cluster service url
178
- * Starts a User transcation
179
- * Send 10 messgaes to a distributed destination (jms.testUniformQueue) on d2 that has 2 members
180
- * Send a message to local destination (jms.admin.adminQueue) on d1
181
- * Commit/rollback the transation
182
- * Receive the messages from the distributed destination (jms.testUniformQueue) on d2
183
- * Receive the message from the local destination (jms.admin.adminQueue) on d1
184
- */
185
- @ Test
186
- @ DisplayName ("Check cross domain transaction works" )
187
- void testCrossDomainTransactionCommitSecurityEnable () throws UnknownHostException {
188
-
189
183
logger .info ("2 domains with crossDomainSecurity enabled start up!" );
190
184
int domain1AdminServiceNodePort
191
185
= getServiceNodePort (domainNamespace , getExternalServicePodName (domain1AdminServerPodName ), "default" );
@@ -212,7 +206,25 @@ void testCrossDomainTransactionCommitSecurityEnable() throws UnknownHostExceptio
212
206
}
213
207
logger .info ("hostHeader1 for domain1 is: " + hostHeader1 );
214
208
logger .info ("hostAndPort1 for domain1 is: " + hostAndPort1 );
209
+ }
215
210
211
+ /**
212
+ * Configure two domains d1 and d2 with CrossDomainSecurityEnabled set to true
213
+ * On both domains create a user (cross-domain) with group CrossDomainConnectors
214
+ * Add required Credential Mapping
215
+ * Deploy a JSP on d1's admin server that takes 2 parameteers
216
+ * a. The tx action b. the d2's cluster service url
217
+ * Starts a User transcation
218
+ * Using t3 send 10 messgaes to a distributed destination (jms.testUniformQueue) on d2 that has 2 members
219
+ * Using t3 Send a message to local destination (jms.admin.adminQueue) on d1
220
+ * Commit/rollback the transation
221
+ * Using t3 receive the messages from the distributed destination (jms.testUniformQueue) on d2
222
+ * Using t3 receive the message from the local destination (jms.admin.adminQueue) on d1
223
+ */
224
+ @ Test
225
+ @ DisplayName ("Check cross domain transaction works" )
226
+ void testCrossDomainTxWithCrossDomainSecurityEnabled () throws UnknownHostException {
227
+
216
228
// build the standalone JMS Client on Admin pod
217
229
String destLocation = "/u01/JmsSendReceiveClient.java" ;
218
230
assertDoesNotThrow (() -> copyFileToPod (domainNamespace ,
@@ -294,6 +306,122 @@ void testCrossDomainTransactionCommitSecurityEnable() throws UnknownHostExceptio
294
306
"Wait for JMS Client to send/recv msg" );
295
307
}
296
308
309
+ /**
310
+ * Configure two domains d1 and d2 with CrossDomainSecurityEnabled set to true
311
+ * On both domains create a user (cross-domain) with group CrossDomainConnectors
312
+ * Add required Credential Mapping
313
+ * Deploy a JSP on d1's admin server that takes 2 parameteers
314
+ * a. The tx action b. the d2's cluster service url
315
+ * Starts a User transcation
316
+ * Using t3s send 10 messgaes to a distributed destination (jms.testUniformQueue) on d2 that has 2 members
317
+ * Using t3s Send a message to local destination (jms.admin.adminQueue) on d1
318
+ * Commit/rollback the transation
319
+ * Using t3s receive the messages from the distributed destination (jms.testUniformQueue) on d2
320
+ * Using t3s Receive the message from the local destination (jms.admin.adminQueue) on d1
321
+ */
322
+ @ Test
323
+ @ DisplayName ("Check cross domain transaction works when SSL enabled" )
324
+ @ DisabledIfEnvironmentVariable (named = "OKE_CLUSTER" , matches = "true" )
325
+ void testCrossDomainTxWithCrossDomainSecurityAndSSLEnabled () throws UnknownHostException {
326
+
327
+ // Create SSL certificate and key using openSSL with SAN extension
328
+ createCertKeyFiles (hostAddress );
329
+ // Create kubernates secret using genereated certificate and key
330
+ createSecretWithTLSCertKey (tlsSecretName );
331
+ // Import the tls certificate into a JKS truststote to be used while
332
+ // running the standalone client.
333
+ importKeytoTrustStore ();
334
+
335
+ //In a UserTransaction send 10 msg to remote udq and 1 msg to local queue and commit the tx
336
+ StringBuffer curlCmd1 = new StringBuffer ("curl -skg --show-error --noproxy '*' " );
337
+ if (TestConstants .KIND_CLUSTER
338
+ && !TestConstants .WLSIMG_BUILDER .equals (TestConstants .WLSIMG_BUILDER_DEFAULT )) {
339
+ curlCmd1 .append (" -H 'host: " + hostHeader1 + "' " );
340
+ }
341
+ String url1 = "\" http://" + hostAndPort1
342
+ + "/sample_war/dtx.jsp?remoteurl=t3s://domain2-cluster-cluster-2:8500&action=commit\" " ;
343
+ curlCmd1 .append (url1 );
344
+ logger .info ("Executing curl command: {0}" , curlCmd1 );
345
+ assertTrue (getCurlResult (curlCmd1 .toString ()).contains ("Message sent in a commit User Transation" ),
346
+ "Didn't send expected msg " );
347
+
348
+ //receive msg from the udq that has 2 memebers
349
+ StringBuffer curlCmd2 = new StringBuffer ("curl -j --show-error --noproxy '*' " );
350
+ if (TestConstants .KIND_CLUSTER
351
+ && !TestConstants .WLSIMG_BUILDER .equals (TestConstants .WLSIMG_BUILDER_DEFAULT )) {
352
+ curlCmd2 .append (" -H 'host: " + hostHeader1 + "' " );
353
+ }
354
+ String url2 = "\" http://" + hostAndPort1
355
+ + "/sample_war/get.jsp?remoteurl="
356
+ + "t3s://domain2-cluster-cluster-2:8500&action=recv&dest=jms.testUniformQueue\" " ;
357
+ curlCmd2 .append (url2 );
358
+ logger .info ("Executing curl command: {0}" , curlCmd2 );
359
+ for (int i = 0 ; i < 2 ; i ++) {
360
+ assertTrue (getCurlResult (curlCmd2 .toString ()).contains ("Total Message(s) Received : 5" ),
361
+ "Didn't receive expected msg count from remote queue" );
362
+ }
363
+
364
+ // receive 1 msg from the local queue
365
+ logger .info ("Receiving 1 msg from the local queue" );
366
+ StringBuffer curlCmdx = new StringBuffer ("curl -j --show-error --noproxy '*' " );
367
+ if (TestConstants .KIND_CLUSTER
368
+ && !TestConstants .WLSIMG_BUILDER .equals (TestConstants .WLSIMG_BUILDER_DEFAULT )) {
369
+ curlCmdx .append (" -H 'host: " + hostHeader1 + "' " );
370
+ }
371
+ String urlx = "\" http://" + hostAndPort1
372
+ + "/sample_war/get.jsp?remoteurl="
373
+ + "t3s://domain1-admin-server:7002&action=recv&dest=jms.admin.adminQueue\" " ;
374
+ curlCmdx .append (urlx );
375
+ logger .info ("Executing curl command for local queue: {0}" , curlCmdx );
376
+ assertTrue (getCurlResult (curlCmdx .toString ()).contains ("Total Message(s) Received : 1" ),
377
+ "Didn't receive expected msg count from local queue" );
378
+
379
+ //In a UserTransaction send 10 msg to remote udq and 1 msg to local queue and rollback the tx
380
+ StringBuffer curlCmd3 = new StringBuffer ("curl -skg --show-error --noproxy '*' " );
381
+ if (TestConstants .KIND_CLUSTER
382
+ && !TestConstants .WLSIMG_BUILDER .equals (TestConstants .WLSIMG_BUILDER_DEFAULT )) {
383
+ curlCmd3 .append (" -H 'host: " + hostHeader1 + "' " );
384
+ }
385
+ String url3 = "\" http://" + hostAndPort1
386
+ + "/sample_war/dtx.jsp?remoteurl=t3s://domain2-cluster-cluster-2:8500&action=rollback\" " ;
387
+ curlCmd3 .append (url3 );
388
+ logger .info ("Executing curl command: {0}" , curlCmd3 );
389
+ assertTrue (getCurlResult (curlCmd3 .toString ()).contains ("Message sent in a rolled-back User Transation" ),
390
+ "Didn't send expected msg " );
391
+
392
+ //receive 0 msg from the udq that has 2 memebers
393
+ StringBuffer curlCmd4 = new StringBuffer ("curl -j --show-error --noproxy '*' " );
394
+ if (TestConstants .KIND_CLUSTER
395
+ && !TestConstants .WLSIMG_BUILDER .equals (TestConstants .WLSIMG_BUILDER_DEFAULT )) {
396
+ curlCmd4 .append (" -H 'host: " + hostHeader1 + "' " );
397
+ }
398
+ String url4 = "\" http://" + hostAndPort1
399
+ + "/sample_war/get.jsp?remoteurl="
400
+ + "t3s://domain2-cluster-cluster-2:8500&action=recv&dest=jms.testUniformQueue\" " ;
401
+ curlCmd4 .append (url4 );
402
+ logger .info ("Executing curl command: {0}" , curlCmd4 );
403
+ for (int i = 0 ; i < 2 ; i ++) {
404
+ assertTrue (getCurlResult (curlCmd4 .toString ()).contains ("Total Message(s) Received : 0" ),
405
+ "Didn't receive expected msg count from remote queue" );
406
+ }
407
+
408
+ // receive 0 msg from the local queue
409
+ logger .info ("Receiving 0 msg from the local queue" );
410
+ StringBuffer curlCmdy = new StringBuffer ("curl -j --show-error --noproxy '*' " );
411
+ if (TestConstants .KIND_CLUSTER
412
+ && !TestConstants .WLSIMG_BUILDER .equals (TestConstants .WLSIMG_BUILDER_DEFAULT )) {
413
+ curlCmdy .append (" -H 'host: " + hostHeader1 + "' " );
414
+ }
415
+ String urly = "\" http://" + hostAndPort1
416
+ + "/sample_war/get.jsp?remoteurl="
417
+ + "t3s://domain1-admin-server:7002&action=recv&dest=jms.admin.adminQueue\" " ;
418
+ curlCmdy .append (urly );
419
+ logger .info ("Executing curl command for local queue: {0}" , curlCmdy );
420
+ assertTrue (getCurlResult (curlCmdx .toString ()).contains ("Total Message(s) Received : 0" ),
421
+ "Didn't receive expected msg count from local queue" );
422
+
423
+ }
424
+
297
425
private static String createAuxImage (String imageName , String imageTag , List <String > wdtModelFile ,
298
426
String wdtVariableFile ) {
299
427
@@ -630,5 +758,63 @@ private static void createNginxIngressPathRoutingRules() {
630
758
assertTrue (callWebAppAndWaitTillReady (curlCmd , 60 ));
631
759
}
632
760
761
+ // Create and display SSL certificate and key using openSSL with SAN extension
762
+ private static void createCertKeyFiles (String cn ) {
763
+
764
+ Map <String , String > sanConfigTemplateMap = new HashMap <>();
765
+ sanConfigTemplateMap .put ("INGRESS_HOST" , hostAddress );
766
+
767
+ Path srcFile = Paths .get (RESOURCE_DIR ,
768
+ "tunneling" , "san.config.template.txt" );
769
+ Path targetFile = assertDoesNotThrow (
770
+ () -> generateFileFromTemplate (srcFile .toString (),
771
+ "san.config.txt" , sanConfigTemplateMap ));
772
+ logger .info ("Generated SAN config file {0}" , targetFile );
773
+
774
+ tlsKeyFile = Paths .get (RESULTS_ROOT , domainNamespace + "-tls.key" );
775
+ tlsCertFile = Paths .get (RESULTS_ROOT , domainNamespace + "-tls.cert" );
776
+ String opcmd = "openssl req -x509 -nodes -days 365 -newkey rsa:2048 "
777
+ + "-keyout " + tlsKeyFile + " -out " + tlsCertFile
778
+ + " -subj \" /CN=" + cn + "\" -extensions san"
779
+ + " -config " + Paths .get (RESULTS_ROOT , "san.config.txt" );
780
+ assertTrue (
781
+ Command .withParams (new CommandParams ()
782
+ .command (opcmd )).execute (), "openssl req command fails" );
783
+
784
+ String opcmd2 = "openssl x509 -in " + tlsCertFile + " -noout -text " ;
785
+ assertTrue (
786
+ Command .withParams (new CommandParams ()
787
+ .command (opcmd2 )).execute (), "openssl list command fails" );
788
+ }
789
+
790
+ // Import the certificate into a JKS TrustStore to be used while running
791
+ // external JMS client to send message to WebLogic.
792
+ private static void importKeytoTrustStore () {
793
+
794
+ jksTrustFile = Paths .get (RESULTS_ROOT , domainNamespace + "-trust.jks" );
795
+ String keycmd = "keytool -import -file " + tlsCertFile
796
+ + " --keystore " + jksTrustFile
797
+ + " -storetype jks -storepass password -noprompt " ;
798
+ assertTrue (
799
+ Command .withParams (new CommandParams ()
800
+ .command (keycmd )).execute (), "keytool import command fails" );
801
+
802
+ String keycmd2 = "keytool -list -keystore " + jksTrustFile
803
+ + " -storepass password -noprompt" ;
804
+ assertTrue (
805
+ Command .withParams (new CommandParams ()
806
+ .command (keycmd2 )).execute (), "keytool list command fails" );
807
+ }
808
+
809
+ // Create kubernetes secret from the ssl key and certificate
810
+ private static void createSecretWithTLSCertKey (String tlsSecretName ) {
811
+ String kcmd = KUBERNETES_CLI + " create secret tls " + tlsSecretName + " --key "
812
+ + tlsKeyFile + " --cert " + tlsCertFile + " -n " + domainNamespace ;
813
+ assertTrue (
814
+ Command .withParams (new CommandParams ()
815
+ .command (kcmd )).execute (), KUBERNETES_CLI + " create secret command fails" );
816
+ }
817
+
818
+
633
819
}
634
820
0 commit comments