Skip to content

Commit 1d4b0d9

Browse files
author
Flossy
committed
Fix issues #92 and #93: Validation and JMX escaping in metrics exporters
Issue #93: PrometheusMetricsExporter constructor validation - Add null check for config parameter - Fail fast with IllegalArgumentException - Add @throws JavaDoc annotation Issue #92: JMX special character escaping - Use ObjectName.quote() to escape JMX special characters (:=,"*?) - Prevents MalformedObjectNameException for app IDs with special chars - Update tests to use quoted application IDs for verification
1 parent ba5b303 commit 1d4b0d9

3 files changed

Lines changed: 20 additions & 9 deletions

File tree

jplatform-metrics-jmx/src/main/java/org/flossware/jplatform/metrics/jmx/JmxMetricsExporter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,10 @@ public void registerApplication(String applicationId, ApplicationContext context
183183

184184
try {
185185
// Create ObjectName with configured domain
186+
// Quote applicationId to escape JMX special characters (:=,"*?)
187+
String quotedAppId = ObjectName.quote(applicationId);
186188
String objectNameStr = String.format("%s:type=Application,id=%s",
187-
config.getDomain(), applicationId);
189+
config.getDomain(), quotedAppId);
188190
ObjectName objectName = new ObjectName(objectNameStr);
189191

190192
// Check if already registered

jplatform-metrics-jmx/src/test/java/org/flossware/jplatform/metrics/jmx/JmxMetricsExporterTest.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,9 @@ void testRegisterApplication() throws Exception {
181181

182182
assertEquals(1, exporter.getRegisteredApplicationCount());
183183

184-
// Verify MBean is registered
185-
ObjectName objectName = new ObjectName("org.flossware.jplatform.test:type=Application,id=test-app");
184+
// Verify MBean is registered (applicationId is quoted to escape JMX special characters)
185+
String quotedAppId = ObjectName.quote("test-app");
186+
ObjectName objectName = new ObjectName("org.flossware.jplatform.test:type=Application,id=" + quotedAppId);
186187
assertTrue(mBeanServer.isRegistered(objectName));
187188
}
188189

@@ -235,8 +236,9 @@ void testRegisterApplicationTwice() throws Exception {
235236
exporter.registerApplication("test-app", context);
236237
assertEquals(1, exporter.getRegisteredApplicationCount());
237238

238-
// MBean should still be registered
239-
ObjectName objectName = new ObjectName("org.flossware.jplatform.test:type=Application,id=test-app");
239+
// MBean should still be registered (applicationId is quoted to escape JMX special characters)
240+
String quotedAppId = ObjectName.quote("test-app");
241+
ObjectName objectName = new ObjectName("org.flossware.jplatform.test:type=Application,id=" + quotedAppId);
240242
assertTrue(mBeanServer.isRegistered(objectName));
241243
}
242244

@@ -352,10 +354,13 @@ void testMultipleApplications() throws Exception {
352354

353355
assertEquals(2, exporter.getRegisteredApplicationCount());
354356

355-
// Verify correct MBeans remain
356-
ObjectName objectName1 = new ObjectName("org.flossware.jplatform.test:type=Application,id=app1");
357-
ObjectName objectName2 = new ObjectName("org.flossware.jplatform.test:type=Application,id=app2");
358-
ObjectName objectName3 = new ObjectName("org.flossware.jplatform.test:type=Application,id=app3");
357+
// Verify correct MBeans remain (applicationId is quoted to escape JMX special characters)
358+
String quotedAppId1 = ObjectName.quote("app1");
359+
String quotedAppId2 = ObjectName.quote("app2");
360+
String quotedAppId3 = ObjectName.quote("app3");
361+
ObjectName objectName1 = new ObjectName("org.flossware.jplatform.test:type=Application,id=" + quotedAppId1);
362+
ObjectName objectName2 = new ObjectName("org.flossware.jplatform.test:type=Application,id=" + quotedAppId2);
363+
ObjectName objectName3 = new ObjectName("org.flossware.jplatform.test:type=Application,id=" + quotedAppId3);
359364

360365
assertTrue(mBeanServer.isRegistered(objectName1));
361366
assertFalse(mBeanServer.isRegistered(objectName2));

jplatform-metrics-prometheus/src/main/java/org/flossware/jplatform/metrics/prometheus/PrometheusMetricsExporter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ public class PrometheusMetricsExporter implements MetricsExporter {
6464
* Constructs a new Prometheus metrics exporter with the specified configuration.
6565
*
6666
* @param config the exporter configuration specifying port and path
67+
* @throws IllegalArgumentException if config is null
6768
*/
6869
public PrometheusMetricsExporter(PrometheusExporterConfig config) {
70+
if (config == null) {
71+
throw new IllegalArgumentException("PrometheusExporterConfig cannot be null");
72+
}
6973
this.config = config;
7074
this.applications = new ConcurrentHashMap<>();
7175
this.running = false;

0 commit comments

Comments
 (0)