Skip to content

Commit 528578b

Browse files
committed
Merge remote-tracking branch 'origin/main' into release/4.0
2 parents d9d7f5f + dcf99a5 commit 528578b

20 files changed

+378
-85
lines changed

integration-tests/src/test/java/oracle/weblogic/kubernetes/ItKubernetesDomainEvents.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import oracle.weblogic.kubernetes.annotations.Namespaces;
3636
import oracle.weblogic.kubernetes.logging.LoggingFacade;
3737
import oracle.weblogic.kubernetes.utils.DomainUtils;
38+
import oracle.weblogic.kubernetes.utils.K8sEvents;
3839
import org.junit.jupiter.api.AfterAll;
3940
import org.junit.jupiter.api.BeforeAll;
4041
import org.junit.jupiter.api.DisplayName;
@@ -399,6 +400,12 @@ void testK8SEventsMultiClusterEvents() {
399400
checkEvent(opNamespace, domainNamespace3, domainUid,
400401
DOMAIN_AVAILABLE, "Normal", timestamp);
401402
logger.info("verify the Cluster_Available event is generated");
403+
checkEvent(opNamespace, domainNamespace3, domainUid,
404+
CLUSTER_CHANGED, "Normal", timestamp);
405+
assertEquals(1, getOpGeneratedEventCount(domainNamespace3, domainUid,
406+
CLUSTER_CHANGED, timestamp2));
407+
assertEquals(1, K8sEvents.getOpGeneratedEventCountForResource(domainNamespace3, domainUid, cluster2Name,
408+
CLUSTER_CHANGED, timestamp));
402409
checkEvent(opNamespace, domainNamespace3, domainUid,
403410
CLUSTER_AVAILABLE, "Normal", timestamp);
404411
logger.info("verify the Completed event is generated");

integration-tests/src/test/java/oracle/weblogic/kubernetes/utils/K8sEvents.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020, 2022, Oracle and/or its affiliates.
1+
// Copyright (c) 2020, 2023, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.weblogic.kubernetes.utils;
@@ -371,6 +371,38 @@ public static int getOpGeneratedEventCount(
371371
return count;
372372
}
373373

374+
/**
375+
* Get the event count between a specific timestamp for the given resource (domain or cluster).
376+
*
377+
* @param domainNamespace namespace in which the domain exists
378+
* @param domainUid UID of the domain
379+
* @param resourceName the Uid/name of the resource
380+
* @param reason event to check for Created, Changed, deleted, processing etc
381+
* @param timestamp the timestamp after which to see events
382+
* @return count number of events count
383+
*/
384+
public static int getOpGeneratedEventCountForResource(
385+
String domainNamespace, String domainUid, String resourceName, String reason, OffsetDateTime timestamp) {
386+
int count = 0;
387+
try {
388+
List<CoreV1Event> events = Kubernetes.listOpGeneratedNamespacedEvents(domainNamespace);
389+
for (CoreV1Event event : events) {
390+
Map<String, String> labels = event.getMetadata().getLabels();
391+
if (event.getReason().equals(reason)
392+
&& labels.get("weblogic.domainUID").equals(domainUid)
393+
&& event.getInvolvedObject().getName().equals(resourceName)
394+
&& (isEqualOrAfter(timestamp, event))) {
395+
logger.info(Yaml.dump(event));
396+
count++;
397+
}
398+
}
399+
} catch (ApiException ex) {
400+
Logger.getLogger(K8sEvents.class.getName()).log(Level.SEVERE, null, ex);
401+
return -1;
402+
}
403+
return count;
404+
}
405+
374406
/**
375407
* Check if a given event is logged only once for the given pod.
376408
*

operator/src/main/java/oracle/kubernetes/operator/ClusterResourceStatusUpdater.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2022, Oracle and/or its affiliates.
1+
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.kubernetes.operator;
@@ -36,6 +36,7 @@
3636

3737
import static oracle.kubernetes.operator.KubernetesConstants.CLUSTER;
3838
import static oracle.kubernetes.operator.KubernetesConstants.HTTP_NOT_FOUND;
39+
import static oracle.kubernetes.operator.helpers.EventHelper.createClusterResourceEventData;
3940

4041
/**
4142
* Updates for status of Cluster resources.
@@ -255,14 +256,14 @@ private List<EventData> getClusterStatusConditionTrueEvents(List<ClusterConditio
255256

256257
private EventData toTrueClusterResourceEvent(ClusterCondition condition) {
257258
return Optional.ofNullable(condition.getType().getAddedEvent())
258-
.map(eventItem -> new ClusterResourceEventData(eventItem, resource))
259+
.map(eventItem -> createClusterResourceEventData(eventItem, resource, domain.getDomainUid()))
259260
.map(this::initializeClusterResourceEventData)
260261
.orElse(null);
261262
}
262263

263264
private EventData toFalseClusterResourceEvent(ClusterCondition removedCondition) {
264265
return Optional.ofNullable(removedCondition.getType().getRemovedEvent())
265-
.map(eventItem -> new ClusterResourceEventData(eventItem, resource))
266+
.map(eventItem -> createClusterResourceEventData(eventItem, resource, domain.getDomainUid()))
266267
.map(this::initializeClusterResourceEventData)
267268
.orElse(null);
268269
}

operator/src/main/java/oracle/kubernetes/operator/DomainProcessor.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2018, 2022, Oracle and/or its affiliates.
1+
// Copyright (c) 2018, 2023, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.kubernetes.operator;
@@ -34,6 +34,18 @@ public interface DomainProcessor {
3434
*/
3535
MakeRightDomainOperation createMakeRightOperation(DomainPresenceInfo liveInfo);
3636

37+
/**
38+
* Ensures that a cluster event is generated for a cluster resource no matter whether it is referenced by a domain
39+
* or not.
40+
*
41+
* @param clusterEvent the event that needs to be generated
42+
* @param cluster the cluster resource that the event is associated with
43+
* @param domainUid the UID of the domain that the cluster is referenced by
44+
* @return Make-right operation
45+
*/
46+
MakeRightClusterOperation createMakeRightOperationForClusterEvent(
47+
EventItem clusterEvent, ClusterResource cluster, String domainUid);
48+
3749
/**
3850
* Ensures that a cluster event is generated for a cluster resource no matter whether it is referenced by a domain
3951
* or not.

operator/src/main/java/oracle/kubernetes/operator/DomainProcessorImpl.java

Lines changed: 72 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2018, 2022, Oracle and/or its affiliates.
1+
// Copyright (c) 2018, 2023, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.kubernetes.operator;
@@ -36,7 +36,6 @@
3636
import oracle.kubernetes.operator.helpers.ConfigMapHelper;
3737
import oracle.kubernetes.operator.helpers.DomainPresenceInfo;
3838
import oracle.kubernetes.operator.helpers.EventHelper;
39-
import oracle.kubernetes.operator.helpers.EventHelper.ClusterResourceEventData;
4039
import oracle.kubernetes.operator.helpers.EventHelper.EventData;
4140
import oracle.kubernetes.operator.helpers.EventHelper.EventItem;
4241
import oracle.kubernetes.operator.helpers.KubernetesEventObjects;
@@ -141,6 +140,14 @@ private static DomainPresenceInfo getExistingDomainPresenceInfo(DomainPresenceIn
141140
return getExistingDomainPresenceInfo(newPresence.getNamespace(), newPresence.getDomainUid());
142141
}
143142

143+
private static ClusterPresenceInfo getExistingClusterPresenceInfo(String ns, String clusterName) {
144+
return clusters.computeIfAbsent(ns, k -> new ConcurrentHashMap<>()).get(clusterName);
145+
}
146+
147+
private static ClusterPresenceInfo getExistingClusterPresenceInfo(ClusterPresenceInfo newPresence) {
148+
return getExistingClusterPresenceInfo(newPresence.getNamespace(), newPresence.getResourceName());
149+
}
150+
144151
@Override
145152
public Map<String, Map<String,DomainPresenceInfo>> getDomainPresenceInfoMap() {
146153
return domains;
@@ -374,7 +381,9 @@ public void runMakeRight(MakeRightClusterOperation operation) {
374381
final ClusterPresenceInfo liveInfo = operation.getPresenceInfo();
375382
if (delegate.isNamespaceRunning(liveInfo.getNamespace())) {
376383
try (ThreadLoggingContext ignored = setThreadContext().presenceInfo(liveInfo)) {
377-
new ClusterPlan(operation, delegate).execute();
384+
if (shouldContinue(operation, liveInfo)) {
385+
new ClusterPlan(operation, delegate).execute();
386+
}
378387
}
379388
}
380389
}
@@ -394,10 +403,38 @@ private boolean shouldContinue(MakeRightDomainOperation operation, DomainPresenc
394403
}
395404
}
396405

406+
private boolean shouldContinue(MakeRightClusterOperation operation, ClusterPresenceInfo liveInfo) {
407+
final ClusterPresenceInfo cachedInfo = getExistingClusterPresenceInfo(liveInfo);
408+
if (hasDeletedClusterEventData(operation)) {
409+
return findClusterPresenceInfo(liveInfo.getNamespace(), liveInfo.getResourceName());
410+
} else if (isNewCluster(cachedInfo)) {
411+
return true;
412+
} else if (liveInfo.isFromOutOfDateEvent(operation, cachedInfo)) {
413+
return false;
414+
} else if (liveInfo.isClusterGenerationChanged(cachedInfo)) {
415+
return true;
416+
} else {
417+
cachedInfo.setCluster(liveInfo.getCluster());
418+
return false;
419+
}
420+
}
421+
397422
private boolean isNewDomain(DomainPresenceInfo cachedInfo) {
398423
return Optional.ofNullable(cachedInfo).map(DomainPresenceInfo::getDomain).orElse(null) == null;
399424
}
400425

426+
private boolean isNewCluster(ClusterPresenceInfo cachedInfo) {
427+
return Optional.ofNullable(cachedInfo).map(ClusterPresenceInfo::getCluster).orElse(null) == null;
428+
}
429+
430+
private boolean findClusterPresenceInfo(String namespace, String clusterName) {
431+
return Optional.ofNullable(clusters.get(namespace)).orElse(Collections.emptyMap()).get(clusterName) != null;
432+
}
433+
434+
private boolean hasDeletedClusterEventData(MakeRightClusterOperation operation) {
435+
return operation.getEventData() != null && operation.getEventData().getItem().name().equals("CLUSTER_DELETED");
436+
}
437+
401438
private void logStartingDomain(DomainPresenceInfo presenceInfo) {
402439
LOGGER.fine(MessageKeys.PROCESSING_DOMAIN, presenceInfo.getDomainUid());
403440
}
@@ -430,12 +467,24 @@ public void registerDomainPresenceInfo(DomainPresenceInfo info) {
430467
.put(info.getDomainUid(), info);
431468
}
432469

470+
@Override
471+
public void registerClusterPresenceInfo(ClusterPresenceInfo info) {
472+
clusters
473+
.computeIfAbsent(info.getNamespace(), k -> new ConcurrentHashMap<>())
474+
.put(info.getResourceName(), info);
475+
}
476+
433477
@Override
434478
public void unregisterDomainPresenceInfo(DomainPresenceInfo info) {
435479
unregisterPresenceInfo(info.getNamespace(), info.getDomainUid());
436480
unregisterEventK8SObject(info.getNamespace(), info.getDomainUid());
437481
}
438482

483+
@Override
484+
public void unregisterClusterPresenceInfo(ClusterPresenceInfo info) {
485+
unregisterPresenceInfoForCluster(info.getNamespace(), info.getResourceName());
486+
}
487+
439488
private static void unregisterEventK8SObject(String ns, String domainUid) {
440489
Optional.ofNullable(domainEventK8SObjects.get(ns)).ifPresent(m -> m.remove(domainUid));
441490
}
@@ -444,6 +493,10 @@ private static void unregisterPresenceInfo(String ns, String domainUid) {
444493
Optional.ofNullable(domains.get(ns)).ifPresent(m -> m.remove(domainUid));
445494
}
446495

496+
private static void unregisterPresenceInfoForCluster(String ns, String clusterName) {
497+
Optional.ofNullable(clusters.get(ns)).ifPresent(m -> m.remove(clusterName));
498+
}
499+
447500
@Override
448501
public void endScheduledDomainStatusUpdates(DomainPresenceInfo info) {
449502
Map<String, ScheduledFuture<?>> map = statusUpdaters.get(info.getNamespace());
@@ -727,14 +780,15 @@ public void dispatchClusterWatch(Watch.Response<ClusterResource> item) {
727780
}
728781

729782
private void handleAddedCluster(ClusterResource cluster) {
730-
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_CREATED, cluster).execute();
731783
List<DomainPresenceInfo> hostingDomains =
732784
getExistingDomainPresenceInfoForCluster(cluster.getNamespace(), cluster.getMetadata().getName());
733785
if (hostingDomains.isEmpty()) {
734786
LOGGER.info(MessageKeys.WATCH_CLUSTER_WITHOUT_DOMAIN, cluster.getMetadata().getName());
787+
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_CREATED, cluster, null).execute();
735788
} else {
736789
hostingDomains.forEach(info -> {
737790
LOGGER.info(MessageKeys.WATCH_CLUSTER, cluster.getMetadata().getName(), info.getDomainUid());
791+
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_CREATED, cluster, info.getDomainUid()).execute();
738792
createMakeRightOperation(info)
739793
.interrupt()
740794
.withExplicitRecheck()
@@ -744,11 +798,11 @@ private void handleAddedCluster(ClusterResource cluster) {
744798
}
745799

746800
private void handleModifiedCluster(ClusterResource cluster) {
747-
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_CHANGED, cluster).execute();
748801
List<DomainPresenceInfo> hostingDomains =
749802
getExistingDomainPresenceInfoForCluster(cluster.getNamespace(), cluster.getMetadata().getName());
750803
if (hostingDomains.isEmpty()) {
751804
LOGGER.info(MessageKeys.WATCH_CLUSTER_WITHOUT_DOMAIN, cluster.getMetadata().getName());
805+
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_CHANGED, cluster, null).execute();
752806
} else {
753807
hostingDomains.forEach(info -> {
754808
ClusterResource cachedResource = info.getClusterResource(cluster.getClusterName());
@@ -757,6 +811,7 @@ private void handleModifiedCluster(ClusterResource cluster) {
757811
}
758812

759813
LOGGER.fine(MessageKeys.WATCH_CLUSTER, cluster.getMetadata().getName(), info.getDomainUid());
814+
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_CHANGED, cluster, info.getDomainUid()).execute();
760815
createMakeRightOperation(info)
761816
.interrupt()
762817
.withExplicitRecheck()
@@ -766,14 +821,15 @@ private void handleModifiedCluster(ClusterResource cluster) {
766821
}
767822

768823
private void handleDeletedCluster(ClusterResource cluster) {
769-
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_DELETED, cluster).execute();
770824
List<DomainPresenceInfo> hostingDomains =
771825
getExistingDomainPresenceInfoForCluster(cluster.getNamespace(), cluster.getMetadata().getName());
772826
if (hostingDomains.isEmpty()) {
773827
LOGGER.info(MessageKeys.WATCH_CLUSTER_WITHOUT_DOMAIN, cluster.getMetadata().getName());
828+
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_DELETED, cluster, null).execute();
774829
} else {
775830
hostingDomains.forEach(info -> {
776831
LOGGER.info(MessageKeys.WATCH_CLUSTER_DELETED, cluster.getMetadata().getName(), info.getDomainUid());
832+
createMakeRightOperationForClusterEvent(EventItem.CLUSTER_DELETED, cluster, info.getDomainUid()).execute();
777833
info.removeClusterResource(cluster.getClusterName());
778834
createMakeRightOperation(info)
779835
.interrupt()
@@ -785,14 +841,16 @@ private void handleDeletedCluster(ClusterResource cluster) {
785841

786842
@Override
787843
public MakeRightClusterOperation createMakeRightOperationForClusterEvent(
788-
EventItem clusterEvent, ClusterResource cluster) {
844+
EventItem clusterEvent, ClusterResource cluster, String domainUid) {
789845
return delegate.createMakeRightOperation(this, createInfoForClusterEventOnly(cluster))
790846
.interrupt()
791-
.withEventData(createClusterResourceEventData(clusterEvent, cluster));
847+
.withEventData(EventHelper.createClusterResourceEventData(clusterEvent, cluster, domainUid));
792848
}
793849

794-
private ClusterResourceEventData createClusterResourceEventData(EventItem clusterEvent, ClusterResource cluster) {
795-
return new ClusterResourceEventData(clusterEvent, cluster);
850+
@Override
851+
public MakeRightClusterOperation createMakeRightOperationForClusterEvent(
852+
EventItem clusterEvent, ClusterResource cluster) {
853+
return createMakeRightOperationForClusterEvent(clusterEvent, cluster, null);
796854
}
797855

798856
@NotNull
@@ -913,17 +971,12 @@ private void addServerToMaps(Map<String, ServerHealth> serverHealthMap,
913971

914972
}
915973

916-
private class DomainPlan extends Plan<MakeRightDomainOperation> {
974+
private static class DomainPlan extends Plan<MakeRightDomainOperation> {
917975

918976
public DomainPlan(MakeRightDomainOperation operation, DomainProcessorDelegate delegate) {
919977
super(operation, delegate);
920978
}
921979

922-
@Override
923-
protected void cacheResourcePresenceInfo(ResourcePresenceInfo presenceInfo) {
924-
//No-op.
925-
}
926-
927980
@Override
928981
public CompletionCallback createCompletionCallback() {
929982
return new DomainPlanCompletionCallback();
@@ -1001,32 +1054,20 @@ private long delayUntilNextRetry(@Nonnull DomainPresenceInfo domainPresenceInfo)
10011054
return interval.getSeconds();
10021055

10031056
}
1004-
10051057
}
10061058

1007-
private class ClusterPlan extends Plan<MakeRightClusterOperation> {
1059+
private static class ClusterPlan extends Plan<MakeRightClusterOperation> {
10081060

10091061
public ClusterPlan(MakeRightClusterOperation operation, DomainProcessorDelegate delegate) {
10101062
super(operation, delegate);
10111063
}
10121064

1013-
@Override
1014-
protected void cacheResourcePresenceInfo(ResourcePresenceInfo presenceInfo) {
1015-
if (operation.getEventData().getItem() == EventHelper.EventItem.CLUSTER_DELETED) {
1016-
Optional.ofNullable(clusters.get(presenceInfo.getNamespace()))
1017-
.ifPresent(m -> m.remove(presenceInfo.getResourceName()));
1018-
} else {
1019-
clusters.computeIfAbsent(presenceInfo.getNamespace(), c -> new ConcurrentHashMap<>())
1020-
.computeIfAbsent(presenceInfo.getResourceName(), k -> (ClusterPresenceInfo) presenceInfo);
1021-
}
1022-
}
1023-
10241065
@Override
10251066
public CompletionCallback createCompletionCallback() {
10261067
return new ClusterPlanCompletionCallback();
10271068
}
10281069

1029-
class ClusterPlanCompletionCallback implements CompletionCallback {
1070+
static class ClusterPlanCompletionCallback implements CompletionCallback {
10301071

10311072
@Override
10321073
public void onCompletion(Packet packet) {
@@ -1044,7 +1085,7 @@ private void reportFailure(Throwable throwable) {
10441085
}
10451086
}
10461087

1047-
private abstract class Plan<T extends MakeRightOperation> {
1088+
private abstract static class Plan<T extends MakeRightOperation> {
10481089

10491090
final T operation;
10501091
protected final ResourcePresenceInfo presenceInfo;
@@ -1059,11 +1100,8 @@ public Plan(T operation, DomainProcessorDelegate delegate) {
10591100
this.firstStep = operation.createSteps();
10601101
this.packet = operation.createPacket();
10611102
this.gate = getMakeRightFiberGate(delegate, this.presenceInfo.getNamespace());
1062-
cacheResourcePresenceInfo(presenceInfo);
10631103
}
10641104

1065-
protected abstract void cacheResourcePresenceInfo(ResourcePresenceInfo presenceInfo);
1066-
10671105
private FiberGate getMakeRightFiberGate(DomainProcessorDelegate delegate, String ns) {
10681106
return makeRightFiberGates.computeIfAbsent(ns, k -> delegate.createFiberGate());
10691107
}

0 commit comments

Comments
 (0)