• 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

74.77
/rqueue-core/src/main/java/com/github/sonus21/rqueue/utils/ValueResolver.java
1
/*
2
 * Copyright (c) 2019-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.utils;
18

19
import static com.github.sonus21.rqueue.utils.StringUtils.clean;
20

21
import org.springframework.beans.factory.config.BeanExpressionContext;
22
import org.springframework.beans.factory.config.BeanExpressionResolver;
23
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
24
import org.springframework.context.ApplicationContext;
25
import org.springframework.context.ConfigurableApplicationContext;
26
import org.springframework.expression.Expression;
27
import org.springframework.expression.ExpressionParser;
28
import org.springframework.expression.spel.standard.SpelExpressionParser;
29
import org.springframework.lang.NonNull;
30

31
public final class ValueResolver {
32

33
  private ValueResolver() {}
34

35
  @SuppressWarnings("unchecked")
36
  public static <T> T parseStringUsingSpel(String val, Class<?> t) {
37
    ExpressionParser parser = new SpelExpressionParser();
1✔
38
    Expression exp = parser.parseExpression(val);
1✔
39
    return (T) exp.getValue(t);
1✔
40
  }
41

42
  public static Long parseStringToLong(String val) {
43
    if (val == null) {
1!
UNCOV
44
      return null;
×
45
    }
46
    String tmpVal = clean(val);
1✔
47
    if (tmpVal.equals("null")) {
1!
UNCOV
48
      return null;
×
49
    }
50
    return parseStringUsingSpel(val, Long.class);
1✔
51
  }
52

53
  public static Integer parseStringToInt(String val) {
54
    if (val == null) {
1!
UNCOV
55
      return null;
×
56
    }
57
    String tmpVal = clean(val);
1✔
58
    if (tmpVal.equals("null") || tmpVal.isEmpty()) {
1!
UNCOV
59
      return null;
×
60
    }
61
    return parseStringUsingSpel(val, Integer.class);
1✔
62
  }
63

64
  public static boolean convertToBoolean(String s) {
65
    String tmpString = clean(s);
1✔
66
    if (tmpString == null) {
1!
UNCOV
67
      return false;
×
68
    }
69
    if (tmpString.equalsIgnoreCase("true")
1✔
70
        || tmpString.equals("1")
1!
71
        || tmpString.equalsIgnoreCase("yes")) {
1!
72
      return true;
1✔
73
    }
74
    if (tmpString.equalsIgnoreCase("false")
1✔
75
        || tmpString.equals("0")
1✔
76
        || tmpString.equals("")
1!
77
        || tmpString.equalsIgnoreCase("no")) {
1!
78
      return false;
1✔
79
    }
80
    throw new IllegalArgumentException(s + " cannot be converted to boolean");
1✔
81
  }
82

83
  @NonNull
84
  private static Object resolveExpression(ApplicationContext applicationContext, String name) {
85
    if (applicationContext instanceof ConfigurableApplicationContext) {
1!
86
      ConfigurableBeanFactory configurableBeanFactory =
1✔
87
          ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
1✔
88
      String placeholdersResolved = configurableBeanFactory.resolveEmbeddedValue(name);
1✔
89
      BeanExpressionResolver exprResolver = configurableBeanFactory.getBeanExpressionResolver();
1✔
90
      if (exprResolver == null) {
1✔
91
        return name;
1✔
92
      }
93
      Object result = exprResolver.evaluate(
1✔
94
          placeholdersResolved, new BeanExpressionContext(configurableBeanFactory, null));
95
      if (result != null) {
1!
96
        return result;
1✔
97
      }
98
    }
UNCOV
99
    return name;
×
100
  }
101

102
  public static String[] resolveKeyToArrayOfStrings(
103
      ApplicationContext applicationContext, String name) {
104
    Object result = resolveExpression(applicationContext, name);
1✔
105
    String[] values;
106
    if (result instanceof String[]) {
1✔
107
      values = (String[]) result;
1✔
108
    } else {
109
      values = ((String) result).split(Constants.Comma);
1✔
110
    }
111
    String[] cleanedStrings = new String[values.length];
1✔
112
    for (int i = 0; i < values.length; i++) {
1✔
113
      cleanedStrings[i] = clean(values[i]);
1✔
114
    }
115
    return cleanedStrings;
1✔
116
  }
117

118
  public static String resolveKeyToString(ApplicationContext applicationContext, String name) {
119
    String[] values = resolveKeyToArrayOfStrings(applicationContext, name);
1✔
120
    if (values.length == 1) {
1!
121
      return values[0];
1✔
122
    }
UNCOV
123
    throw new IllegalArgumentException("More than one value provided");
×
124
  }
125

126
  public static Integer resolveKeyToInteger(ApplicationContext applicationContext, String name) {
127
    Object result = resolveExpression(applicationContext, name);
1✔
128
    if (result instanceof Integer) {
1!
UNCOV
129
      return (Integer) result;
×
130
    }
131
    return parseStringToInt((String) result);
1✔
132
  }
133

134
  public static Long resolveKeyToLong(ApplicationContext applicationContext, String name) {
135
    Object result = resolveExpression(applicationContext, name);
1✔
136
    if (result instanceof Long) {
1!
UNCOV
137
      return (Long) result;
×
138
    } else if (result instanceof Integer) {
1!
139
      return ((Integer) result).longValue();
×
140
    }
141
    return parseStringToLong((String) result);
1✔
142
  }
143

144
  public static boolean resolveToBoolean(ApplicationContext applicationContext, String name) {
145
    Object result = resolveExpression(applicationContext, name);
1✔
146
    if (result instanceof Boolean) {
1!
UNCOV
147
      return (Boolean) result;
×
148
    }
149
    return convertToBoolean((String) result);
1✔
150
  }
151
}
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