Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add upvote and downvote tracker #2566

Merged
merged 1 commit into from
Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/java/run/halo/app/core/extension/Counter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public class Counter extends AbstractExtension {

private Integer upvote;

private Integer downvote;

private Integer totalComment;

private Integer approvedComment;
Expand All @@ -41,6 +43,8 @@ public <T extends Meter> void populateFrom(Collection<T> meters) {
this.visit = (int) meterCounter.count();
} else if (MeterUtils.isUpvoteCounter(meterCounter)) {
this.upvote = (int) meterCounter.count();
} else if (MeterUtils.isDownvoteCounter(meterCounter)) {
this.downvote = (int) meterCounter.count();
} else if (MeterUtils.isTotalCommentCounter(meterCounter)) {
this.totalComment = (int) meterCounter.count();
} else if (MeterUtils.isApprovedCommentCounter(meterCounter)) {
Expand All @@ -53,6 +57,7 @@ public <T extends Meter> void populateFrom(Collection<T> meters) {
private void populateDefaultValue() {
this.visit = 0;
this.upvote = 0;
this.downvote = 0;
this.totalComment = 0;
this.approvedComment = 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public TrackerEndpoint(MeterRegistry meterRegistry, VisitLogWriter visitLogWrite
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/Tracker";
return SpringdocRouteBuilder.route()
.POST("trackers/counter", this::increase,
.POST("trackers/counter", this::increaseVisit,
builder -> builder.operationId("count")
.description("Count an extension resource visits.")
.tag(tag)
Expand All @@ -55,12 +55,40 @@ public RouterFunction<ServerResponse> endpoint() {
.implementation(CounterRequest.class))
))
.response(responseBuilder()
.implementation(Double.class))
.implementation(Integer.class))
)
.POST("trackers/upvote", this::upvote,
builder -> builder.operationId("upvote")
.description("Upvote an extension resource.")
.tag(tag)
.requestBody(requestBodyBuilder()
.required(true)
.content(contentBuilder()
.mediaType(MediaType.APPLICATION_JSON_VALUE)
.schema(Builder.schemaBuilder()
.implementation(VoteRequest.class))
))
.response(responseBuilder()
.implementation(Integer.class))
)
.POST("trackers/downvote", this::downvote,
builder -> builder.operationId("downvote")
.description("Downvote an extension resource.")
.tag(tag)
.requestBody(requestBodyBuilder()
.required(true)
.content(contentBuilder()
.mediaType(MediaType.APPLICATION_JSON_VALUE)
.schema(Builder.schemaBuilder()
.implementation(VoteRequest.class))
))
.response(responseBuilder()
.implementation(Integer.class))
)
.build();
}

private Mono<ServerResponse> increase(ServerRequest request) {
private Mono<ServerResponse> increaseVisit(ServerRequest request) {
return request.bodyToMono(CounterRequest.class)
.switchIfEmpty(
Mono.error(new IllegalArgumentException("Counter request body must not be empty")))
Expand All @@ -78,6 +106,41 @@ private Mono<ServerResponse> increase(ServerRequest request) {
.flatMap(count -> ServerResponse.ok().bodyValue(count));
}

private Mono<ServerResponse> upvote(ServerRequest request) {
return request.bodyToMono(VoteRequest.class)
.switchIfEmpty(
Mono.error(new IllegalArgumentException("Upvote request body must not be empty")))
.map(voteRequest -> {
String counterName =
MeterUtils.nameOf(voteRequest.group(), voteRequest.plural(),
voteRequest.name());

Counter counter = MeterUtils.upvoteCounter(meterRegistry, counterName);
counter.increment();
return (int) counter.count();
})
.flatMap(count -> ServerResponse.ok().bodyValue(count));
}

private Mono<ServerResponse> downvote(ServerRequest request) {
return request.bodyToMono(VoteRequest.class)
.switchIfEmpty(
Mono.error(new IllegalArgumentException("Downvote request body must not be empty")))
.map(voteRequest -> {
String counterName =
MeterUtils.nameOf(voteRequest.group(), voteRequest.plural(),
voteRequest.name());

Counter counter = MeterUtils.downvoteCounter(meterRegistry, counterName);
counter.increment();
return (int) counter.count();
})
.flatMap(count -> ServerResponse.ok().bodyValue(count));
}

public record VoteRequest(String group, String plural, String name) {
}

public record CounterRequest(String group, String plural, String name, String hostname,
String screen, String language, String referrer) {
/**
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/run/halo/app/metrics/CounterMeterHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public Mono<Void> onApplicationReady(ApplicationReadyEvent event) {
MeterUtils.upvoteCounter(meterRegistry, name);
upvoteCounter.increment(nullSafe(counter.getUpvote()));

// downvote counter
io.micrometer.core.instrument.Counter downvoteCounter =
MeterUtils.downvoteCounter(meterRegistry, name);
downvoteCounter.increment(nullSafe(counter.getDownvote()));

// total comment counter
io.micrometer.core.instrument.Counter totalCommentCounter =
MeterUtils.totalCommentCounter(meterRegistry, name);
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/run/halo/app/metrics/MeterUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class MeterUtils {
public static final String SCENE = "scene";
public static final String VISIT_SCENE = "visit";
public static final String UPVOTE_SCENE = "upvote";
public static final String DOWNVOTE_SCENE = "downvote";
public static final String TOTAL_COMMENT_SCENE = "total_comment";
public static final String APPROVED_COMMENT_SCENE = "approved_comment";

Expand Down Expand Up @@ -51,6 +52,10 @@ public static Counter upvoteCounter(MeterRegistry registry, String name) {
return counter(registry, name, Tag.of(SCENE, UPVOTE_SCENE));
}

public static Counter downvoteCounter(MeterRegistry registry, String name) {
return counter(registry, name, Tag.of(SCENE, DOWNVOTE_SCENE));
}

public static Counter totalCommentCounter(MeterRegistry registry, String name) {
return counter(registry, name, Tag.of(SCENE, TOTAL_COMMENT_SCENE));
}
Expand All @@ -75,6 +80,14 @@ public static boolean isUpvoteCounter(Counter counter) {
return UPVOTE_SCENE.equals(sceneValue);
}

public static boolean isDownvoteCounter(Counter counter) {
String sceneValue = counter.getId().getTag(SCENE);
if (StringUtils.isBlank(sceneValue)) {
return false;
}
return DOWNVOTE_SCENE.equals(sceneValue);
}

public static boolean isTotalCommentCounter(Counter counter) {
String sceneValue = counter.getId().getTag(SCENE);
if (StringUtils.isBlank(sceneValue)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ protected boolean nonResourceURLMatches(Role.PolicyRule rule, String requestedUR
if (Objects.equals(ruleURL, requestedURL)) {
return true;
}
if (StringUtils.startsWith(ruleURL, WildCard.NonResourceAll)
if (StringUtils.endsWith(ruleURL, WildCard.NonResourceAll)
&& StringUtils.startsWith(requestedURL,
StringUtils.stripEnd(ruleURL, WildCard.NonResourceAll))) {
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/extensions/role-template-anonymous.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ rules:
- apiGroups: [ "api.halo.run" ]
resources: [ "*" ]
verbs: [ "*" ]
- nonResourceURLs: [ "/apis/api.halo.run/v1alpha1/trackers/counter" ]
- nonResourceURLs: [ "/apis/api.halo.run/v1alpha1/trackers/*" ]
verbs: [ "create" ]
9 changes: 9 additions & 0 deletions src/test/java/run/halo/app/metrics/MeterUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ void isUpvoteCounter() {
assertThat(MeterUtils.isVisitCounter(upvoteCounter)).isFalse();
}

@Test
void isDownvoteCounter() {
MeterRegistry meterRegistry = new SimpleMeterRegistry();
Counter downvoteCounter =
MeterUtils.downvoteCounter(meterRegistry, "posts.content.halo.run/fake-post");
assertThat(MeterUtils.isDownvoteCounter(downvoteCounter)).isTrue();
assertThat(MeterUtils.isVisitCounter(downvoteCounter)).isFalse();
}

@Test
void isTotalCommentCounter() {
MeterRegistry meterRegistry = new SimpleMeterRegistry();
Expand Down