Skip to content
Merged
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
26 changes: 17 additions & 9 deletions native/src/main/java/io/ballerina/lib/cdc/Listener.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,16 @@
* This class contains utility functions for the cdc:Listener object.
*/
public class Listener {
private static final String CHANGE_CONSUMER_KEY = "ChangeConsumer";
private static final String COMP_CALLBACK_KEY = "CompletionCallback";
private static final String LIVENESS_INTERVAL_KEY = "LivenessInterval";
private static final String LISTENER_START_TIME_KEY = "ListenerStartTime";
private static final BString LIVENESS_INTERVAL_CONFIG_KEY = StringUtils.fromString("livenessInterval");
private static final long DEFAULT_LIVENESS_INTERVAL_MILLIS = 60000;

public static final String TABLE_TO_SERVICE_MAP_KEY = "TABLE_TO_SERVICE_MAP";
public static final String DEBEZIUM_ENGINE_KEY = "DEB_ENGINE";
public static final String EXECUTOR_SERVICE_KEY = "ExecutorService";
public static final String CHANGE_CONSUMER_KEY = "ChangeConsumer";
public static final String COMP_CALLBACK_KEY = "CompletionCallback";
public static final String LIVENESS_INTERVAL_KEY = "LivenessInterval";
public static final String LISTENER_START_TIME_KEY = "ListenerStartTime";
public static final BString LIVENESS_INTERVAL_CONFIG_KEY = StringUtils.fromString("livenessInterval");
public static final String IS_STARTED_KEY = "isStarted";
public static final String HAS_ATTACHED_SERVICE_KEY = "hasAttachedService";
public static final String LISTENER_ID = "Id";
Expand Down Expand Up @@ -162,10 +163,17 @@ public static Object start(Environment environment, BObject listener, BMap<BStri
}

Properties engineProperties = populateEngineProperties(config);
Long livenessInterval = ((BDecimal) config.get(LIVENESS_INTERVAL_CONFIG_KEY))
.decimalValue()
.multiply(BigDecimal.valueOf(1000))
.longValue();

Long livenessInterval;
if (config.containsKey(LIVENESS_INTERVAL_CONFIG_KEY)) {
livenessInterval = ((BDecimal) config.get(LIVENESS_INTERVAL_CONFIG_KEY))
.decimalValue()
.multiply(BigDecimal.valueOf(1000))
.longValue();
} else {
livenessInterval = DEFAULT_LIVENESS_INTERVAL_MILLIS;
}
Comment on lines +167 to +175
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Validate livenessInterval value before casting.

If the key exists but is null or not a BDecimal, this will throw at runtime. Also consider rejecting non‑positive values to avoid immediate liveness failures.

✅ Suggested guard with explicit error
-            Long livenessInterval;
-            if (config.containsKey(LIVENESS_INTERVAL_CONFIG_KEY)) {
-                livenessInterval = ((BDecimal) config.get(LIVENESS_INTERVAL_CONFIG_KEY))
-                        .decimalValue()
-                        .multiply(BigDecimal.valueOf(1000))
-                        .longValue();
-            } else {
-                livenessInterval = DEFAULT_LIVENESS_INTERVAL_MILLIS;
-            }
+            Long livenessInterval = DEFAULT_LIVENESS_INTERVAL_MILLIS;
+            if (config.containsKey(LIVENESS_INTERVAL_CONFIG_KEY)) {
+                Object rawInterval = config.get(LIVENESS_INTERVAL_CONFIG_KEY);
+                if (!(rawInterval instanceof BDecimal)) {
+                    return createCdcError("'livenessInterval' must be a decimal number");
+                }
+                long computedMillis = ((BDecimal) rawInterval).decimalValue()
+                        .multiply(BigDecimal.valueOf(1000))
+                        .longValue();
+                if (computedMillis <= 0) {
+                    return createCdcError("'livenessInterval' must be > 0");
+                }
+                livenessInterval = computedMillis;
+            }
🤖 Prompt for AI Agents
In `@native/src/main/java/io/ballerina/lib/cdc/Listener.java` around lines 167 -
175, The livenessInterval assignment in Listener (the block reading
LIVENESS_INTERVAL_CONFIG_KEY from config) must validate that
config.get(LIVENESS_INTERVAL_CONFIG_KEY) is non-null and an instance of BDecimal
before casting, and reject non-positive values; change the logic that sets
livenessInterval to first fetch Object val =
config.get(LIVENESS_INTERVAL_CONFIG_KEY), if val == null use
DEFAULT_LIVENESS_INTERVAL_MILLIS, else if val instanceof BDecimal convert via
((BDecimal) val).decimalValue().multiply(BigDecimal.valueOf(1000)).longValue()
and if the resulting long <= 0 throw an IllegalArgumentException (or
Ballerina-specific error) with a clear message referencing
LIVENESS_INTERVAL_CONFIG_KEY, otherwise assign it, and if val is not a BDecimal
throw a similar informative error instead of allowing a ClassCastException.


@SuppressWarnings("unchecked")
ConcurrentHashMap<String, Service> serviceMap = (ConcurrentHashMap<String, Service>) listener
.getNativeData(TABLE_TO_SERVICE_MAP_KEY);
Expand Down