diff --git a/application/src/main/java/run/halo/app/metrics/VisitedEventReconciler.java b/application/src/main/java/run/halo/app/metrics/VisitedEventReconciler.java index 3e11bf7b0..968777a2c 100644 --- a/application/src/main/java/run/halo/app/metrics/VisitedEventReconciler.java +++ b/application/src/main/java/run/halo/app/metrics/VisitedEventReconciler.java @@ -4,16 +4,22 @@ import java.time.Duration; import java.time.Instant; import java.util.Iterator; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.springframework.context.SmartLifecycle; import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import run.halo.app.core.extension.Counter; import run.halo.app.event.post.VisitedEvent; import run.halo.app.extension.ExtensionClient; +import run.halo.app.extension.GroupVersionKind; +import run.halo.app.extension.Scheme; +import run.halo.app.extension.SchemeManager; import run.halo.app.extension.controller.Controller; import run.halo.app.extension.controller.ControllerBuilder; import run.halo.app.extension.controller.DefaultController; @@ -88,11 +94,6 @@ public class VisitedEventReconciler Duration.ofMinutes(5)); } - @EventListener(VisitedEvent.class) - public void handlePostPublished(VisitedEvent visitedEvent) { - mergeVisits(visitedEvent); - } - @Override public void start() { this.visitedEventController.start(); @@ -121,18 +122,53 @@ public class VisitedEventReconciler return this.running; } - private void mergeVisits(VisitedEvent event) { - String counterName = - MeterUtils.nameOf(event.getGroup(), event.getPlural(), event.getName()); - pooledVisitsMap.compute(counterName, (name, visits) -> { - if (visits == null) { - return 1; - } else { - return visits + 1; - } - }); - } - public record VisitCountBucket(String name, int visits) { } + + @Component + @RequiredArgsConstructor + public class VisitedEventListener { + private final SchemeManager schemeManager; + + @Async + @EventListener(VisitedEvent.class) + public void onVisited(VisitedEvent visitedEvent) { + mergeVisits(visitedEvent); + } + + private void mergeVisits(VisitedEvent event) { + var gpn = new GroupPluralName(event.getGroup(), event.getPlural(), event.getName()); + if (!checkVisitSubject(gpn)) { + log.debug("Skip visit event for: {}", gpn); + return; + } + String counterName = + MeterUtils.nameOf(event.getGroup(), event.getPlural(), event.getName()); + pooledVisitsMap.compute(counterName, (name, visits) -> { + if (visits == null) { + return 1; + } else { + return visits + 1; + } + }); + } + + private boolean checkVisitSubject(GroupPluralName groupPluralName) { + Optional schemeOptional = schemeManager.schemes().stream() + .filter(scheme -> { + GroupVersionKind gvk = scheme.groupVersionKind(); + return scheme.plural().equals(groupPluralName.plural()) + && gvk.group().equals(groupPluralName.group()); + }) + .findFirst(); + return schemeOptional.map( + scheme -> client.fetch(scheme.groupVersionKind(), groupPluralName.name()) + .isPresent() + ) + .orElse(false); + } + + record GroupPluralName(String group, String plural, String name) { + } + } } diff --git a/application/src/main/java/run/halo/app/metrics/VotedEventReconciler.java b/application/src/main/java/run/halo/app/metrics/VotedEventReconciler.java index 244b3bc11..915d498f4 100644 --- a/application/src/main/java/run/halo/app/metrics/VotedEventReconciler.java +++ b/application/src/main/java/run/halo/app/metrics/VotedEventReconciler.java @@ -2,16 +2,22 @@ package run.halo.app.metrics; import java.time.Duration; import java.time.Instant; +import java.util.Optional; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.springframework.context.SmartLifecycle; import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import run.halo.app.core.extension.Counter; import run.halo.app.event.post.DownvotedEvent; import run.halo.app.event.post.UpvotedEvent; import run.halo.app.event.post.VotedEvent; import run.halo.app.extension.ExtensionClient; +import run.halo.app.extension.GroupVersionKind; +import run.halo.app.extension.Scheme; +import run.halo.app.extension.SchemeManager; import run.halo.app.extension.controller.Controller; import run.halo.app.extension.controller.ControllerBuilder; import run.halo.app.extension.controller.DefaultController; @@ -77,11 +83,6 @@ public class VotedEventReconciler implements Reconciler, SmartLifecy Duration.ofMinutes(5)); } - @EventListener(VotedEvent.class) - public void handlePostPublished(VotedEvent votedEvent) { - votedEventQueue.addImmediately(votedEvent); - } - @Override public void start() { this.votedEventController.start(); @@ -98,4 +99,43 @@ public class VotedEventReconciler implements Reconciler, SmartLifecy public boolean isRunning() { return this.running; } + + @Component + @RequiredArgsConstructor + public class VotedEventListener { + private final SchemeManager schemeManager; + + /** + * Add up/down vote event to queue. + */ + @Async + @EventListener(VotedEvent.class) + public void onVoted(VotedEvent event) { + var gpn = new GroupPluralName(event.getGroup(), event.getPlural(), event.getName()); + if (!checkSubject(gpn)) { + log.debug("Skip voted event for: {}", gpn); + return; + } + votedEventQueue.addImmediately(event); + } + + private boolean checkSubject( + GroupPluralName groupPluralName) { + Optional schemeOptional = schemeManager.schemes().stream() + .filter(scheme -> { + GroupVersionKind gvk = scheme.groupVersionKind(); + return scheme.plural().equals(groupPluralName.plural()) + && gvk.group().equals(groupPluralName.group()); + }) + .findFirst(); + return schemeOptional.map( + scheme -> client.fetch(scheme.groupVersionKind(), groupPluralName.name()) + .isPresent() + ) + .orElse(false); + } + + record GroupPluralName(String group, String plural, String name) { + } + } }