• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sonus21 / rqueue / 25600722838

09 May 2026 12:06PM UTC coverage: 83.396% (-5.3%) from 88.677%
25600722838

push

github

web-flow
Nats v2 web (#295)

* ci: compile main sources in coverage_report job

The coverage_report job was producing an effectively empty
jacocoTestReport.xml (3.4KB vs ~1.1MB locally) because no .class files
existed when coverageReportOnly ran — the job checked out source code
and downloaded .exec artifacts, but never compiled. JaCoCo's report
generator skips packages/classes it cannot resolve, so the merged XML
ended up with only <sessioninfo> entries and no <package> elements.

That made coverallsJacoco silently no-op via the
"source file set empty, skipping" branch in CoverallsReporter, so
"Push coverage to Coveralls" reported success without uploading.

Verified by downloading the coverage-report artifact from a recent run
and comparing its XML structure against a local build's report.

Assisted-By: Claude Code

* nats-web: implement pause / soft-delete admin ops and capability-aware Q-detail

Replace the all-stub `NatsRqueueUtilityService` with real impls for the operations
JetStream can model: `pauseUnpauseQueue` persists the `paused` flag on `QueueConfig`
in the queue-config KV bucket and notifies the local listener container so the poller
stops dispatching; `deleteMessage` is a soft delete via `MessageMetadataService`
(stream message persists, dashboard hides via the metadata flag); `getDataType`
reports `STREAM`. `moveMessage`, `enqueueMessage`, and `makeEmpty` deliberately
remain "not supported" — there is no JetStream primitive for those.

Update `RqueueQDetailServiceImpl.getRunningTasks` / `getScheduledTasks` to return
header-only tables when the broker capabilities suppress those sections, instead of
emitting zero rows or 501s on NATS.

20 new unit tests cover the pause/delete paths and lock in the still-unsupported
operations. Updates `nats-task.md` / `nats-task-v2.md` to reflect what landed.

Assisted-By: Claude Code

* nats-web: capability-aware nav / charts and stream-based peek

End-to-end browser-tested the NATS dashboard and shipped the t... (continued)

2566 of 3407 branches covered (75.32%)

Branch coverage included in aggregate %.

795 of 1072 new or added lines in 22 files covered. (74.16%)

312 existing lines in 38 files now uncovered.

7715 of 8921 relevant lines covered (86.48%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.74
/rqueue-web/src/main/java/com/github/sonus21/rqueue/web/controller/ReactiveRqueueViewController.java
1
/*
2
 * Copyright (c) 2021-2026 Sonu Kumar
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * You may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and limitations under the License.
14
 *
15
 */
16

17
package com.github.sonus21.rqueue.web.controller;
18

19
import com.github.sonus21.rqueue.config.RqueueWebConfig;
20
import com.github.sonus21.rqueue.utils.condition.ReactiveEnabled;
21
import com.github.sonus21.rqueue.web.RqueueViewControllerService;
22
import com.github.sonus21.rqueue.web.view.RqueueHtmlRenderer;
23
import java.nio.charset.StandardCharsets;
24
import org.springframework.beans.factory.annotation.Autowired;
25
import org.springframework.context.annotation.Conditional;
26
import org.springframework.core.io.buffer.DataBuffer;
27
import org.springframework.http.MediaType;
28
import org.springframework.http.server.reactive.ServerHttpRequest;
29
import org.springframework.http.server.reactive.ServerHttpResponse;
30
import org.springframework.stereotype.Controller;
31
import org.springframework.ui.Model;
32
import org.springframework.web.bind.annotation.GetMapping;
33
import org.springframework.web.bind.annotation.PathVariable;
34
import org.springframework.web.bind.annotation.RequestMapping;
35
import org.springframework.web.bind.annotation.RequestParam;
36
import reactor.core.publisher.Mono;
37

38
@Conditional(ReactiveEnabled.class)
39
@Controller
40
@RequestMapping(path = "${rqueue.web.url.prefix:}rqueue")
41
public class ReactiveRqueueViewController extends BaseReactiveController {
42

43
  private final RqueueHtmlRenderer renderer;
44
  private final RqueueViewControllerService rqueueViewControllerService;
45

46
  @Autowired
47
  public ReactiveRqueueViewController(
48
      RqueueWebConfig rqueueWebConfig,
49
      RqueueViewControllerService rqueueViewControllerService,
50
      RqueueHtmlRenderer renderer) {
51
    super(rqueueWebConfig);
1✔
52
    this.renderer = renderer;
1✔
53
    this.rqueueViewControllerService = rqueueViewControllerService;
1✔
54
  }
1✔
55

56
  private String xForwardedPrefix(ServerHttpRequest request) {
57
    return request.getHeaders().getFirst("x-forwarded-prefix");
1✔
58
  }
59

60
  private Mono<Void> writeHtml(ServerHttpResponse response, String html) {
61
    response.getHeaders().setContentType(MediaType.TEXT_HTML);
1✔
62
    byte[] bytes = html.getBytes(StandardCharsets.UTF_8);
1✔
63
    DataBuffer buffer = response.bufferFactory().wrap(bytes);
1✔
64
    return response.writeWith(Mono.just(buffer));
1✔
65
  }
66

67
  @GetMapping
68
  public Mono<Void> index(Model model, ServerHttpRequest request, ServerHttpResponse response) {
69
    if (!isEnabled(response)) return Mono.empty();
1✔
70
    rqueueViewControllerService.index(model, xForwardedPrefix(request));
1✔
71
    return writeHtml(response, renderer.renderIndex(model.asMap()));
1✔
72
  }
73

74
  @GetMapping("queues")
75
  public Mono<Void> queues(
76
      Model model,
77
      @RequestParam(name = "page", defaultValue = "1") int pageNumber,
78
      ServerHttpRequest request,
79
      ServerHttpResponse response) {
80
    if (!isEnabled(response)) return Mono.empty();
1✔
81
    rqueueViewControllerService.queues(model, xForwardedPrefix(request), pageNumber);
1✔
82
    return writeHtml(response, renderer.renderQueues(model.asMap()));
1✔
83
  }
84

85
  @GetMapping("queues/{queueName}")
86
  public Mono<Void> queueDetail(
87
      @PathVariable("queueName") String queueName,
88
      Model model,
89
      ServerHttpRequest request,
90
      ServerHttpResponse response) {
91
    if (!isEnabled(response)) return Mono.empty();
1✔
92
    rqueueViewControllerService.queueDetail(model, xForwardedPrefix(request), queueName);
1✔
93
    return writeHtml(response, renderer.renderQueueDetail(model.asMap()));
1✔
94
  }
95

96
  @GetMapping("workers")
97
  public Mono<Void> workers(
98
      Model model,
99
      @RequestParam(name = "page", defaultValue = "1") int pageNumber,
100
      ServerHttpRequest request,
101
      ServerHttpResponse response) {
NEW
102
    if (!isEnabled(response)) return Mono.empty();
×
NEW
103
    rqueueViewControllerService.workers(model, xForwardedPrefix(request), pageNumber);
×
NEW
104
    return writeHtml(response, renderer.renderWorkers(model.asMap()));
×
105
  }
106

107
  @GetMapping("running")
108
  public Mono<Void> running(Model model, ServerHttpRequest request, ServerHttpResponse response) {
109
    if (!isEnabled(response)) return Mono.empty();
1✔
110
    rqueueViewControllerService.running(model, xForwardedPrefix(request));
1✔
111
    return writeHtml(response, renderer.renderRunning(model.asMap()));
1✔
112
  }
113

114
  @GetMapping("scheduled")
115
  public Mono<Void> scheduled(Model model, ServerHttpRequest request, ServerHttpResponse response) {
116
    if (!isEnabled(response)) return Mono.empty();
1✔
117
    rqueueViewControllerService.scheduled(model, xForwardedPrefix(request));
1✔
118
    return writeHtml(response, renderer.renderRunning(model.asMap()));
1✔
119
  }
120

121
  @GetMapping("dead")
122
  public Mono<Void> dead(Model model, ServerHttpRequest request, ServerHttpResponse response) {
123
    if (!isEnabled(response)) return Mono.empty();
1✔
124
    rqueueViewControllerService.dead(model, xForwardedPrefix(request));
1✔
125
    return writeHtml(response, renderer.renderRunning(model.asMap()));
1✔
126
  }
127

128
  @GetMapping("pending")
129
  public Mono<Void> pending(Model model, ServerHttpRequest request, ServerHttpResponse response) {
130
    if (!isEnabled(response)) return Mono.empty();
1✔
131
    rqueueViewControllerService.pending(model, xForwardedPrefix(request));
1✔
132
    return writeHtml(response, renderer.renderRunning(model.asMap()));
1✔
133
  }
134

135
  @GetMapping("utility")
136
  public Mono<Void> utility(Model model, ServerHttpRequest request, ServerHttpResponse response) {
137
    if (!isEnabled(response)) return Mono.empty();
1✔
138
    rqueueViewControllerService.utility(model, xForwardedPrefix(request));
1✔
139
    return writeHtml(response, renderer.renderUtility(model.asMap()));
1✔
140
  }
141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc