Skip to content

Commit 102e0db

Browse files
authored
Backport: Refactor ItTwoDomainLoadBalancer class for separate LoadBalancers to release/3.3 (#2752)
* Backport: Refactor ItTwoDomainLoadBalancer class for separate LoadBalancers to release/3.3
1 parent 158b085 commit 102e0db

File tree

10 files changed

+2697
-2299
lines changed

10 files changed

+2697
-2299
lines changed
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
// Copyright (c) 2022, Oracle and/or its affiliates.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
4+
package oracle.weblogic.kubernetes;
5+
6+
import java.nio.file.Path;
7+
import java.util.ArrayList;
8+
import java.util.Collections;
9+
import java.util.LinkedHashMap;
10+
import java.util.List;
11+
import java.util.concurrent.Callable;
12+
13+
import io.kubernetes.client.custom.Quantity;
14+
import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
15+
import io.kubernetes.client.openapi.models.V1PersistentVolume;
16+
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim;
17+
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaimSpec;
18+
import io.kubernetes.client.openapi.models.V1PersistentVolumeSpec;
19+
import io.kubernetes.client.openapi.models.V1ResourceRequirements;
20+
import oracle.weblogic.kubernetes.annotations.IntegrationTest;
21+
import oracle.weblogic.kubernetes.annotations.Namespaces;
22+
import oracle.weblogic.kubernetes.logging.LoggingFacade;
23+
import org.junit.jupiter.api.BeforeAll;
24+
import org.junit.jupiter.api.DisplayName;
25+
import org.junit.jupiter.api.MethodOrderer;
26+
import org.junit.jupiter.api.Test;
27+
import org.junit.jupiter.api.TestMethodOrder;
28+
29+
import static java.nio.file.Paths.get;
30+
import static oracle.weblogic.kubernetes.TestConstants.APACHE_IMAGE;
31+
import static oracle.weblogic.kubernetes.TestConstants.APACHE_RELEASE_NAME;
32+
import static oracle.weblogic.kubernetes.TestConstants.KIND_REPO;
33+
import static oracle.weblogic.kubernetes.TestConstants.MII_BASIC_IMAGE_NAME;
34+
import static oracle.weblogic.kubernetes.TestConstants.MII_BASIC_IMAGE_TAG;
35+
import static oracle.weblogic.kubernetes.TestConstants.OCIR_PASSWORD;
36+
import static oracle.weblogic.kubernetes.TestConstants.OCIR_REGISTRY;
37+
import static oracle.weblogic.kubernetes.TestConstants.OCIR_USERNAME;
38+
import static oracle.weblogic.kubernetes.TestConstants.PV_ROOT;
39+
import static oracle.weblogic.kubernetes.actions.TestActions.dockerLogin;
40+
import static oracle.weblogic.kubernetes.actions.TestActions.dockerPull;
41+
import static oracle.weblogic.kubernetes.actions.TestActions.dockerPush;
42+
import static oracle.weblogic.kubernetes.actions.TestActions.dockerTag;
43+
import static oracle.weblogic.kubernetes.actions.TestActions.getServiceNodePort;
44+
import static oracle.weblogic.kubernetes.utils.CommonLBTestUtils.buildAndDeployClusterviewApp;
45+
import static oracle.weblogic.kubernetes.utils.CommonLBTestUtils.createMultipleDomainsSharingPVUsingWlstAndVerify;
46+
import static oracle.weblogic.kubernetes.utils.CommonLBTestUtils.verifyClusterLoadbalancing;
47+
import static oracle.weblogic.kubernetes.utils.CommonMiiTestUtils.createMiiDomainAndVerify;
48+
import static oracle.weblogic.kubernetes.utils.CommonTestUtils.testUntil;
49+
import static oracle.weblogic.kubernetes.utils.ImageUtils.createSecretForBaseImages;
50+
import static oracle.weblogic.kubernetes.utils.LoadBalancerUtils.installAndVerifyApache;
51+
import static oracle.weblogic.kubernetes.utils.OperatorUtils.installAndVerifyOperator;
52+
import static oracle.weblogic.kubernetes.utils.PersistentVolumeUtils.createPVPVCAndVerify;
53+
import static oracle.weblogic.kubernetes.utils.ThreadSafeLogger.getLogger;
54+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
55+
import static org.junit.jupiter.api.Assertions.assertNotNull;
56+
57+
/**
58+
* Test Apache load balancer handles traffic to one or two backend Weblogic domains.
59+
* It contains two usecases.
60+
* One is configuring the Apache webtier as a load balancer for a WebLogic domain using the default configuration.
61+
* Another is configuring the Apache webtier as a load balancer for multiple WebLogic domains
62+
* using a custom configuration.
63+
*/
64+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
65+
@DisplayName("Verify Apache load balancer handles traffic to one or two backend Weblogic domains")
66+
@IntegrationTest
67+
class ItLBTwoDomainsApache {
68+
69+
private static final int numberOfDomains = 2;
70+
private static final String wlSecretName = "weblogic-credentials";
71+
private static final String apachePvcName = "apache-custom-file-pvc";
72+
private static final String apachePvName = "apache-custom-file-pv";
73+
74+
private static List<String> domainUids = new ArrayList<>();
75+
private static String miiDomainUid = null;
76+
private static String domainNamespace = null;
77+
private static String apacheNamespace = null;
78+
private static LoggingFacade logger = null;
79+
private static String kindRepoApacheImage = APACHE_IMAGE;
80+
81+
// domain constants
82+
private static final int replicaCount = 2;
83+
private static final int MANAGED_SERVER_PORT = 7100;
84+
private static final int ADMIN_SERVER_PORT = 7001;
85+
private static final String clusterName = "cluster-1";
86+
87+
/**
88+
* Assigns unique namespaces for operator and domains.
89+
* Pull WebLogic image if running tests in Kind cluster.
90+
* Installs operator and create domain.
91+
*
92+
* @param namespaces injected by JUnit
93+
*/
94+
@BeforeAll
95+
public static void initAll(@Namespaces(3) List<String> namespaces) {
96+
logger = getLogger();
97+
logger.info("Assign a unique namespace for operator");
98+
assertNotNull(namespaces.get(0), "Namespace is null");
99+
String opNamespace = namespaces.get(0);
100+
101+
// get unique domain namespaces
102+
logger.info("Get unique namespaces for WebLogic domain1 and domain2");
103+
assertNotNull(namespaces.get(1), "Namespace list is null");
104+
domainNamespace = namespaces.get(1);
105+
106+
// get a unique Apache namespace
107+
logger.info("Assign a unique namespace for Apache");
108+
assertNotNull(namespaces.get(1), "Namespace list is null");
109+
apacheNamespace = namespaces.get(2);
110+
111+
// set the service account name for the operator
112+
String opServiceAccount = opNamespace + "-sa";
113+
114+
// install and verify operator with REST API
115+
installAndVerifyOperator(opNamespace, opServiceAccount, true, 0, domainNamespace, apacheNamespace);
116+
117+
// create pull secrets for WebLogic image when running in non Kind Kubernetes cluster
118+
// this secret is used only for non-kind cluster
119+
createSecretForBaseImages(domainNamespace);
120+
121+
for (int i = 1; i <= numberOfDomains; i++) {
122+
domainUids.add("wls-apache-domain-" + i);
123+
}
124+
125+
if (KIND_REPO != null) {
126+
// The kind clusters can't pull Apache webtier image from OCIR using the image pull secret.
127+
// Try the following instead:
128+
// 1. docker login
129+
// 2. docker pull
130+
// 3. docker tag with the KIND_REPO value
131+
// 4. docker push to KIND_REPO
132+
testUntil(
133+
() -> dockerLogin(OCIR_REGISTRY, OCIR_USERNAME, OCIR_PASSWORD),
134+
logger,
135+
"docker login to be successful");
136+
137+
testUntil(
138+
pullImageFromOcirAndPushToKind(APACHE_IMAGE),
139+
logger,
140+
"pullImageFromOcirAndPushToKind for image {0} to be successful",
141+
APACHE_IMAGE);
142+
}
143+
144+
// create one domain with model-in-image type in apache namespace for Apache default configuration usecase
145+
miiDomainUid = "wls-domain1";
146+
createMiiDomainAndVerify(
147+
apacheNamespace,
148+
miiDomainUid,
149+
MII_BASIC_IMAGE_NAME + ":" + MII_BASIC_IMAGE_TAG,
150+
miiDomainUid + "-admin-server",
151+
miiDomainUid + "-managed-server",
152+
replicaCount);
153+
154+
// create two domains with domain-on-pv type in domain namespace for Apache custom configuration usecase
155+
createMultipleDomainsSharingPVUsingWlstAndVerify(
156+
domainNamespace, wlSecretName, ItLBTwoDomainsApache.class.getSimpleName(), numberOfDomains, domainUids,
157+
replicaCount, clusterName, ADMIN_SERVER_PORT, MANAGED_SERVER_PORT);
158+
159+
// build and deploy app to be used by Apache custom sample
160+
buildAndDeployClusterviewApp(domainNamespace, domainUids);
161+
// build and deploy app to be used by Apache default sample
162+
buildAndDeployClusterviewApp(apacheNamespace, Collections.singletonList(miiDomainUid));
163+
164+
// install Apache ingress controller for all test cases using Apache
165+
installApacheIngressController();
166+
}
167+
168+
/**
169+
* Verify Apache load balancer default sample through HTTP channel.
170+
* Configure the Apache webtier as a load balancer for a WebLogic domain using the default configuration.
171+
* It only support HTTP protocol.
172+
* For details, please see
173+
* https://github.com/oracle/weblogic-kubernetes-operator/tree/master/kubernetes/samples/charts/apache-samples/default-sample
174+
*/
175+
@Test
176+
@DisplayName("verify Apache load balancer default sample through HTTP channel")
177+
void testApacheLoadBalancingDefaultSample() {
178+
// verify Apache default sample
179+
logger.info("Verifying Apache default sample");
180+
int httpNodePort = getApacheNodePort(apacheNamespace, "http");
181+
verifyClusterLoadbalancing(miiDomainUid, "", "http", httpNodePort, replicaCount, false, "/weblogic");
182+
}
183+
184+
/**
185+
* Verify Apache load balancer custom sample through HTTP and HTTPS channel.
186+
* Configure the Apache webtier as a load balancer for multiple WebLogic domains using a custom configuration.
187+
* Create a custom Apache plugin configuration file named custom_mod_wl_apache.conf in a directory specified
188+
* in helm chart parameter volumePath.
189+
* For more details, please check:
190+
* https://github.com/oracle/weblogic-kubernetes-operator/tree/master/kubernetes/samples/charts/apache-samples/custom-sample
191+
*/
192+
@Test
193+
@DisplayName("verify Apache load balancer custom sample through HTTP and HTTPS channel")
194+
void testApacheLoadBalancingCustomSample() {
195+
// verify Apache custom sample
196+
logger.info("Verifying Apache custom sample");
197+
for (int i = 1; i <= numberOfDomains; i++) {
198+
int httpNodePort = getApacheNodePort(domainNamespace, "http");
199+
verifyClusterLoadbalancing(domainUids.get(i - 1), "", "http", httpNodePort, replicaCount,
200+
false, "/weblogic" + i);
201+
202+
int httpsNodePort = getApacheNodePort(domainNamespace, "https");
203+
verifyClusterLoadbalancing(domainUids.get(i - 1), "", "https", httpsNodePort, replicaCount,
204+
false, "/weblogic" + i);
205+
}
206+
}
207+
208+
private static void installApacheIngressController() {
209+
// install and verify Apache for default configuration
210+
logger.info("Installing Apache controller using helm");
211+
assertDoesNotThrow(() ->
212+
installAndVerifyApache(apacheNamespace, kindRepoApacheImage, 0, 0, 8001, miiDomainUid));
213+
214+
// install and verify Apache for custom configuration
215+
LinkedHashMap<String, String> clusterNamePortMap = new LinkedHashMap<>();
216+
for (int i = 0; i < numberOfDomains; i++) {
217+
clusterNamePortMap.put(domainUids.get(i) + "-cluster-cluster-1", "" + MANAGED_SERVER_PORT);
218+
}
219+
createPVPVCForApacheCustomConfiguration(domainNamespace);
220+
assertDoesNotThrow(() ->
221+
installAndVerifyApache(domainNamespace, kindRepoApacheImage, 0, 0, MANAGED_SERVER_PORT, domainUids.get(0),
222+
apachePvcName, "apache-sample-host", ADMIN_SERVER_PORT, clusterNamePortMap));
223+
}
224+
225+
private static Callable<Boolean> pullImageFromOcirAndPushToKind(String apacheImage) {
226+
return (() -> {
227+
kindRepoApacheImage = KIND_REPO + apacheImage.substring(OCIR_REGISTRY.length() + 1);
228+
logger.info("pulling image {0} from OCIR, tag it as image {1} and push to KIND repo",
229+
apacheImage, kindRepoApacheImage);
230+
return dockerPull(apacheImage) && dockerTag(apacheImage, kindRepoApacheImage) && dockerPush(kindRepoApacheImage);
231+
});
232+
}
233+
234+
/**
235+
* Create PV and PVC for Apache custom configuration file in specified namespace.
236+
* @param apacheNamespace namespace in which to create PVC
237+
*/
238+
private static void createPVPVCForApacheCustomConfiguration(String apacheNamespace) {
239+
Path pvHostPath = get(PV_ROOT, ItLBTwoDomainsApache.class.getSimpleName(), "apache-persistentVolume");
240+
241+
V1PersistentVolume v1pv = new V1PersistentVolume()
242+
.spec(new V1PersistentVolumeSpec()
243+
.addAccessModesItem("ReadWriteMany")
244+
.storageClassName("apache-storage-class")
245+
.volumeMode("Filesystem")
246+
.putCapacityItem("storage", Quantity.fromString("1Gi"))
247+
.persistentVolumeReclaimPolicy("Retain"))
248+
.metadata(new V1ObjectMetaBuilder()
249+
.withName(apachePvName)
250+
.build()
251+
.putLabelsItem("apacheLabel", "apache-custom-config"));
252+
253+
V1PersistentVolumeClaim v1pvc = new V1PersistentVolumeClaim()
254+
.spec(new V1PersistentVolumeClaimSpec()
255+
.addAccessModesItem("ReadWriteMany")
256+
.storageClassName("apache-storage-class")
257+
.volumeName(apachePvName)
258+
.resources(new V1ResourceRequirements()
259+
.putRequestsItem("storage", Quantity.fromString("1Gi"))))
260+
.metadata(new V1ObjectMetaBuilder()
261+
.withName(apachePvcName)
262+
.withNamespace(apacheNamespace)
263+
.build()
264+
.putLabelsItem("apacheLabel", "apache-custom-config"));
265+
266+
String labelSelector = String.format("apacheLabel in (%s)", "apache-custom-config");
267+
createPVPVCAndVerify(v1pv, v1pvc, labelSelector, apacheNamespace,
268+
"apache-storage-class", pvHostPath);
269+
}
270+
271+
private static int getApacheNodePort(String namespace, String channelName) {
272+
String apacheServiceName = APACHE_RELEASE_NAME + "-" + namespace.substring(3) + "-apache-webtier";
273+
274+
// get Apache service NodePort
275+
int apacheNodePort = assertDoesNotThrow(() ->
276+
getServiceNodePort(namespace, apacheServiceName, channelName),
277+
"Getting Apache service NodePort failed");
278+
logger.info("NodePort for {0} is: {1} :", apacheServiceName, apacheNodePort);
279+
return apacheNodePort;
280+
}
281+
282+
}

0 commit comments

Comments
 (0)