From 3f25da46a8f093d96bdd4755f877d804a0272279 Mon Sep 17 00:00:00 2001 From: Greg Schueler Date: Thu, 8 Feb 2024 12:17:34 -0800 Subject: [PATCH] fix: quoting defaults to previous behavior if configuration value is null add tests --- .../plugins/logging/JsonLogFilter.groovy | 21 ++++++-- .../plugins/logging/JsonLogFilterSpec.groovy | 51 +++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/main/groovy/com/rundeck/plugins/logging/JsonLogFilter.groovy b/src/main/groovy/com/rundeck/plugins/logging/JsonLogFilter.groovy index 1f64052..a1b5e79 100644 --- a/src/main/groovy/com/rundeck/plugins/logging/JsonLogFilter.groovy +++ b/src/main/groovy/com/rundeck/plugins/logging/JsonLogFilter.groovy @@ -47,12 +47,12 @@ See [here](https://github.com/eiiches/jackson-jq#implementation-status-and-curre ) Boolean logData + //Note: we don't set a defaultValue, so that we can detect a null value if the user has not set it @PluginProperty( - title = 'Extra quotes', - description = '''If true, the result will be parse to string, that will add extra quotes to the result (compatible with rundeck 4.x)''', - defaultValue = 'false' + title = 'Extra quotes (Rundeck 4.x Compatibility)', + description = '''If true, the result will be parsed to a string with extra quotes to match Rundeck 4.x behavior.''' ) - Boolean extraQuotes=false + Boolean extraQuotes private StringBuffer buffer; OutputContext outputContext @@ -82,6 +82,19 @@ See [here](https://github.com/eiiches/jackson-jq#implementation-status-and-curre void complete(final PluginLoggingContext context) { if(buffer.size()>0) { + if (extraQuotes == null) { + //fall back to previous behavior + extraQuotes = true + context.log( + 1, + 'JSON jq key/value mapper: defaulting to rundeck 4.x quoting behavior' + ) + }else if(extraQuotes){ + context.log( + 1, + 'JSON jq key/value mapper: Using rundeck 4.x quoting behavior' + ) + } //apply json transform this.processJson(context) diff --git a/src/test/groovy/com/rundeck/plugins/logging/JsonLogFilterSpec.groovy b/src/test/groovy/com/rundeck/plugins/logging/JsonLogFilterSpec.groovy index ca452b9..0f738ac 100644 --- a/src/test/groovy/com/rundeck/plugins/logging/JsonLogFilterSpec.groovy +++ b/src/test/groovy/com/rundeck/plugins/logging/JsonLogFilterSpec.groovy @@ -15,6 +15,7 @@ class JsonLogFilterSpec extends Specification { plugin.filter = filter plugin.prefix = "result" plugin.logData = dolog + plugin.extraQuotes = false def sharedoutput = new DataOutput(ContextView.global()) def context = Mock(PluginLoggingContext) { getOutputContext() >> sharedoutput @@ -62,6 +63,55 @@ class JsonLogFilterSpec extends Specification { false | ".id" | ['{"id":"abc12345"}'] | [result: 'abc12345'] } + def "simple test legacy quoting"() { + given: + def plugin = new JsonLogFilter() + plugin.filter = filter + plugin.prefix = "result" + plugin.logData = dolog + plugin.extraQuotes = quoteVal + def sharedoutput = new DataOutput(ContextView.global()) + def context = Mock(PluginLoggingContext) { + getOutputContext() >> sharedoutput + } + def events = [] + lines.each { line -> + events << Mock(LogEventControl) { + getMessage() >> line + getEventType() >> 'log' + getLoglevel() >> LogLevel.NORMAL + } + } + when: + plugin.init(context) + events.each { + plugin.handleEvent(context, it) + } + plugin.complete(context) + then: + + sharedoutput.getSharedContext().getData(ContextView.global())?.getData() == (expect ? ['data': expect] : null) + if (expect) { + if (dolog) { + 1 * context.log(2, _, _) + } else { + 0 * context.log(*_) + } + } + + + where: + + quoteVal | dolog | filter | lines | expect + false | true | "." | ['{"test":"value"}'] | [test: 'value'] + null | true | "." | ['{"test":"value"}'] | [test: '"value"'] + true | true | "." | ['{"test":"value"}'] | [test: '"value"'] + true | true | "." | ['["value"]'] | ['result.0': '"value"'] + null | true | "." | ['["value"]'] | ['result.0': '"value"'] + false | true | "." | ['["value"]'] | ['result.0': 'value'] + + } + def "array test"() { given: def filter = ".[]" @@ -70,6 +120,7 @@ class JsonLogFilterSpec extends Specification { plugin.filter = filter plugin.prefix = "result" plugin.logData = dolog + plugin.extraQuotes = false def sharedoutput = new DataOutput(ContextView.global()) def context = Mock(PluginLoggingContext) { getOutputContext() >> sharedoutput