Skip to content

Commit 9005e90

Browse files
authored
OWLS-86407 - Fixed the logic to start clustered managed server pods when admin server pod not running (#2093)
* OWLS-86407 - Fixed logic to start clustered managed server pods when admin server pod is not running * minor change * Add a unit test case for OWLS-86407 * changes to address PR review comments. * PR review comments. * Remove redundant condition. * Refactoring change as per the review comment. * Chnaged method name to be consistent.
1 parent aa033a0 commit 9005e90

File tree

4 files changed

+94
-11
lines changed

4 files changed

+94
-11
lines changed

operator/src/main/java/oracle/kubernetes/operator/helpers/DomainPresenceInfo.java

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import static java.lang.System.lineSeparator;
3636
import static oracle.kubernetes.operator.helpers.PodHelper.hasClusterNameOrNull;
37+
import static oracle.kubernetes.operator.helpers.PodHelper.isNotAdminServer;
3738

3839
/**
3940
* Operator's mapping between custom resource Domain and runtime details about that domain,
@@ -101,27 +102,60 @@ private static <K, V> boolean removeIfPresentAnd(
101102
*/
102103
public long getNumScheduledServers(String clusterName) {
103104
return getServersInNoOtherCluster(clusterName)
105+
.filter(PodHelper::isScheduled)
106+
.count();
107+
}
108+
109+
/**
110+
* Counts the number of unclustered managed servers and managed servers in the specified cluster that are scheduled.
111+
* @param clusterName cluster name of the pod server
112+
* @param adminServerName Name of the admin server
113+
* @return Number of scheduled managed servers
114+
*/
115+
public long getNumScheduledManagedServers(String clusterName, String adminServerName) {
116+
return getManagedServersInNoOtherCluster(clusterName, adminServerName)
104117
.filter(PodHelper::isScheduled)
105118
.count();
106119
}
107120

108121
/**
109-
* Counts the number of unclustered servers and servers in the specified cluster that are ready.
122+
* Counts the number of unclustered servers (including admin) and servers in the specified cluster that are ready.
110123
* @param clusterName cluster name of the pod server
111124
* @return Number of ready servers
112125
*/
113126
public long getNumReadyServers(String clusterName) {
114127
return getServersInNoOtherCluster(clusterName)
128+
.filter(PodHelper::hasReadyServer)
129+
.count();
130+
}
131+
132+
/**
133+
* Counts the number of unclustered managed servers and managed servers in the specified cluster that are ready.
134+
* @param clusterName cluster name of the pod server
135+
* @return Number of ready servers
136+
*/
137+
public long getNumReadyManagedServers(String clusterName, String adminServerName) {
138+
return getManagedServersInNoOtherCluster(clusterName, adminServerName)
115139
.filter(PodHelper::hasReadyServer)
116140
.count();
117141
}
118142

119143
@Nonnull
120144
private Stream<V1Pod> getServersInNoOtherCluster(String clusterName) {
145+
return getServers().values().stream()
146+
.map(ServerKubernetesObjects::getPod)
147+
.map(AtomicReference::get)
148+
.filter(this::isNotDeletingPod)
149+
.filter(p -> hasClusterNameOrNull(p, clusterName));
150+
}
151+
152+
@Nonnull
153+
private Stream<V1Pod> getManagedServersInNoOtherCluster(String clusterName, String adminServerName) {
121154
return getServers().values().stream()
122155
.map(ServerKubernetesObjects::getPod)
123156
.map(AtomicReference::get)
124157
.filter(this::isNotDeletingPod)
158+
.filter(p -> isNotAdminServer(p, adminServerName))
125159
.filter(p -> hasClusterNameOrNull(p, clusterName));
126160
}
127161

@@ -755,4 +789,4 @@ public int hashCode() {
755789
.toHashCode();
756790
}
757791
}
758-
}
792+
}

operator/src/main/java/oracle/kubernetes/operator/helpers/PodHelper.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import oracle.kubernetes.weblogic.domain.model.Shutdown;
4040

4141
import static oracle.kubernetes.operator.LabelConstants.CLUSTERNAME_LABEL;
42+
import static oracle.kubernetes.operator.LabelConstants.SERVERNAME_LABEL;
4243
import static oracle.kubernetes.operator.ProcessingConstants.SERVERS_TO_ROLL;
4344

4445
public class PodHelper {
@@ -114,6 +115,22 @@ private static String getClusterName(@Nonnull Map<String,String> labels) {
114115
return labels.get(CLUSTERNAME_LABEL);
115116
}
116117

118+
static boolean isNotAdminServer(@Nullable V1Pod pod, String adminServerName) {
119+
return Optional.ofNullable(getServerName(pod)).map(s -> !s.equals(adminServerName)).orElse(true);
120+
}
121+
122+
private static String getServerName(@Nullable V1Pod pod) {
123+
return Optional.ofNullable(pod)
124+
.map(V1Pod::getMetadata)
125+
.map(V1ObjectMeta::getLabels)
126+
.map(PodHelper::getServerName)
127+
.orElse(null);
128+
}
129+
130+
private static String getServerName(@Nonnull Map<String,String> labels) {
131+
return labels.get(SERVERNAME_LABEL);
132+
}
133+
117134
/**
118135
* get if pod is in ready state.
119136
* @param pod pod

operator/src/main/java/oracle/kubernetes/operator/steps/ManagedServerUpIteratorStep.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@
2424
import oracle.kubernetes.operator.helpers.ServiceHelper;
2525
import oracle.kubernetes.operator.logging.LoggingFacade;
2626
import oracle.kubernetes.operator.logging.LoggingFactory;
27+
import oracle.kubernetes.operator.wlsconfig.WlsDomainConfig;
2728
import oracle.kubernetes.operator.work.NextAction;
2829
import oracle.kubernetes.operator.work.Packet;
2930
import oracle.kubernetes.operator.work.Step;
3031
import oracle.kubernetes.weblogic.domain.model.Domain;
3132

33+
import static oracle.kubernetes.operator.ProcessingConstants.DOMAIN_TOPOLOGY;
34+
3235
/**
3336
* A step which will bring up the specified managed servers in parallel.
3437
* Adds to packet:
@@ -168,22 +171,35 @@ public NextAction apply(Packet packet) {
168171

169172
if (startDetailsQueue.isEmpty()) {
170173
return doNext(new ManagedServerUpAfterStep(getNext()), packet);
171-
} else if (hasServerAvailableToStart(packet.getSpi(DomainPresenceInfo.class))) {
174+
} else if (hasServerAvailableToStart(packet)) {
172175
numStarted.getAndIncrement();
173176
return doForkJoin(this, packet, Collections.singletonList(startDetailsQueue.poll()));
174177
} else {
175178
return doDelay(this, packet, SCHEDULING_DETECTION_DELAY, TimeUnit.MILLISECONDS);
176179
}
177180
}
178181

179-
private boolean hasServerAvailableToStart(DomainPresenceInfo info) {
180-
return ((numStarted.get() < info.getNumScheduledServers(clusterName))
181-
&& (canStartConcurrently(info.getNumReadyServers(clusterName))));
182+
private boolean hasServerAvailableToStart(Packet packet) {
183+
DomainPresenceInfo info = packet.getSpi(DomainPresenceInfo.class);
184+
String adminServerName = ((WlsDomainConfig) packet.get(DOMAIN_TOPOLOGY)).getAdminServerName();
185+
return ((getNumServersStarted() <= info.getNumScheduledManagedServers(clusterName, adminServerName)
186+
&& (canStartConcurrently(info.getNumReadyManagedServers(clusterName, adminServerName)))));
182187
}
183188

184189
private boolean canStartConcurrently(long numReady) {
185-
return ((this.maxConcurrency > 0) && (numStarted.get() < (this.maxConcurrency + numReady - 1)))
186-
|| (this.maxConcurrency == 0);
190+
return (ignoreConcurrencyLimits() || numNotReady(numReady) < this.maxConcurrency);
191+
}
192+
193+
private long numNotReady(long numReady) {
194+
return getNumServersStarted() - numReady;
195+
}
196+
197+
private int getNumServersStarted() {
198+
return numStarted.get();
199+
}
200+
201+
private boolean ignoreConcurrencyLimits() {
202+
return this.maxConcurrency == 0;
187203
}
188204
}
189205

operator/src/test/java/oracle/kubernetes/operator/steps/ManagedServerUpIteratorStepTest.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private static String getManagedServerName(int n) {
9494
private final Step nextStep = new TerminalStep();
9595
private final KubernetesTestSupport testSupport = new KubernetesTestSupport();
9696
private final List<Memento> mementos = new ArrayList<>();
97-
private final DomainPresenceInfo domainPresenceInfo = createDomainPresenceInfoWithServers();
97+
private DomainPresenceInfo domainPresenceInfo = createDomainPresenceInfoWithAdminServer();
9898
private final WlsDomainConfig domainConfig = createDomainConfig();
9999
private final Collection<ServerStartupInfo> startupInfos = new ArrayList<>();
100100

@@ -108,10 +108,9 @@ private static WlsDomainConfig createDomainConfig() {
108108
.withCluster(clusterConfig);
109109
}
110110

111-
private DomainPresenceInfo createDomainPresenceInfoWithServers(String... serverNames) {
111+
private DomainPresenceInfo createDomainPresenceInfoWithAdminServer() {
112112
DomainPresenceInfo dpi = new DomainPresenceInfo(domain);
113113
addServer(dpi, ADMIN);
114-
Arrays.asList(serverNames).forEach(serverName -> addServer(dpi, serverName));
115114
return dpi;
116115
}
117116

@@ -249,6 +248,23 @@ public void whenConcurrencyLimitIs1_secondClusteredServerDoesNotStartIfFirstIsNo
249248
assertThat(getStartedManagedServers(), hasSize(1));
250249
}
251250

251+
@Test
252+
public void whileAdminServerStopped_canStartManagedServer() {
253+
createDomainPresenceInfoWithNoAdminServer();
254+
addWlsCluster(CLUSTER1, MS1);
255+
256+
invokeStepWithServerStartupInfos();
257+
258+
assertThat(getStartedManagedServers(), hasSize(1));
259+
}
260+
261+
private void createDomainPresenceInfoWithNoAdminServer() {
262+
domainPresenceInfo = new DomainPresenceInfo(domain);
263+
testSupport
264+
.addToPacket(ProcessingConstants.DOMAIN_TOPOLOGY, domainConfig)
265+
.addDomainPresenceInfo(domainPresenceInfo);
266+
}
267+
252268
@Test
253269
public void whenConcurrencyLimitIs1_secondClusteredServerStartsAfterFirstIsReady() {
254270
configureCluster(CLUSTER1).withMaxConcurrentStartup(1);

0 commit comments

Comments
 (0)