From 57fd31e090909d55a36f957e45a84d9295254d44 Mon Sep 17 00:00:00 2001 From: "Smokowski, Kevin (ks6305)" Date: Thu, 3 Jan 2019 22:00:51 +0000 Subject: [PATCH] create a directive for the template node The directive is called hideNullJson, it hides json when it is null to deal with optional json attributes Change-Id: I0b7a2c2f19e6f83e0d8c8c6f3552889c83dc997f Issue-ID: CCSDK-903 Signed-off-by: Smokowski, Kevin (ks6305) --- .../ccsdk/sli/plugins/template/HideNullJson.java | 98 ++++++++++++++++++++++ .../ccsdk/sli/plugins/template/TemplateNode.java | 6 ++ .../sli/plugins/template/HideNullJsonTest.java | 46 ++++++++++ .../provider/src/test/resources/HideNullJson.vtl | 22 +++++ 4 files changed, 172 insertions(+) create mode 100755 template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/HideNullJson.java mode change 100644 => 100755 template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/TemplateNode.java create mode 100755 template-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/template/HideNullJsonTest.java create mode 100755 template-node/provider/src/test/resources/HideNullJson.vtl diff --git a/template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/HideNullJson.java b/template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/HideNullJson.java new file mode 100755 index 00000000..d39d7e40 --- /dev/null +++ b/template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/HideNullJson.java @@ -0,0 +1,98 @@ + +package org.onap.ccsdk.sli.plugins.template; + +import java.io.IOException; +import java.io.Writer; + +import org.apache.velocity.context.InternalContextAdapter; +import org.apache.velocity.exception.MethodInvocationException; +import org.apache.velocity.exception.ParseErrorException; +import org.apache.velocity.exception.ResourceNotFoundException; +import org.apache.velocity.runtime.directive.Directive; +import org.apache.velocity.runtime.parser.node.Node; + +// This directive can be used when handling optional json attributes in a template +// If an attribute value is null the entire name-value pair will not be rendered +// If an attribute value is not null the name-value pair will be rendered +// Additional optional parameters decide which values are quoted and if a comma and or newline should be appended +public class HideNullJson extends Directive { + + public String getName() { + return "hideNullJson"; + } + + public int getType() { + return BLOCK; + } + + // The first parameter is the json key + // The second parameter is the json value + // This directive handles placing the colon between the json key and json value + // The third parameter is a boolean, when true the json key is surrounded in double quotes by this directive + // The third parameter is true by default and is optional + // The fourth parameter is a boolean when true the json value is surrounded in double quotes by this directive + // The fourth parameter is true by default and is optional + // The fifth parameter is a boolean when true a comma is appended to the end + // The fifth parameter is true by default and is optional + // The sixth parameter is a boolean when true a newline is appended to the end + // The sixth parameter is true by default and is optional + public boolean render(InternalContextAdapter context, Writer writer, Node node) + throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { + String tagValue = null; + Object tagValueObject = node.jjtGetChild(1).value(context); + if (tagValueObject == null) { + return true; + } + tagValue = String.valueOf(tagValueObject); + + String tagName = String.valueOf(node.jjtGetChild(0).value(context)); + + Boolean quoteTagName = getBooleanParameter(true,node,2,context); + Boolean quoteTagValue = getBooleanParameter(true,node,3,context); + Boolean appendComma = getBooleanParameter(true,node,4,context); + Boolean appendNewLine = getBooleanParameter(true,node,5,context); + + StringBuilder sb = new StringBuilder(); + + if (quoteTagName) { + appendQuotedString(tagName,sb); + }else { + sb.append(tagName); + } + + sb.append(":"); + + if (quoteTagValue) { + appendQuotedString(tagValue,sb); + }else { + sb.append(tagValue); + } + + if(appendComma) { + sb.append(","); + } + + if(appendNewLine) { + sb.append("\n"); + } + writer.write(sb.toString()); + return true; + } + + private Boolean getBooleanParameter(Boolean defaultBool, Node node, int parameterPostion, InternalContextAdapter context) { + if (node.jjtGetNumChildren() > parameterPostion && node.jjtGetChild(parameterPostion) != null) { + Object val = node.jjtGetChild(parameterPostion).value(context); + if (val != null) { + return (Boolean) val; + } + } + return defaultBool; + } + + private void appendQuotedString(String str, StringBuilder sb) { + sb.append("\""); + sb.append(str); + sb.append("\""); + } + +} \ No newline at end of file diff --git a/template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/TemplateNode.java b/template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/TemplateNode.java old mode 100644 new mode 100755 index 0b5850a0..6c0686c0 --- a/template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/TemplateNode.java +++ b/template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/TemplateNode.java @@ -25,6 +25,7 @@ package org.onap.ccsdk.sli.plugins.template; import java.io.FileInputStream; import java.io.StringWriter; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; @@ -52,6 +53,7 @@ public class TemplateNode implements SvcLogicJavaPlugin { ve = new VelocityEngine(); setProperties(); ve.init(); + ve.loadDirective("org.onap.ccsdk.sli.plugins.template.HideNullJson"); } protected void setProperties() { @@ -97,6 +99,10 @@ public class TemplateNode implements SvcLogicJavaPlugin { VelocityContext context = new VelocityContext(); context.put("ctx", ctx); context.put("params", params); + //Adding these values directly to context makes working with the values cleaner + for (Entry entry : params.entrySet()) { + context.put(entry.getKey(), entry.getValue()); + } StringWriter sw = new StringWriter(); template.merge(context, sw); ctx.setAttribute(outputPath, sw.toString()); diff --git a/template-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/template/HideNullJsonTest.java b/template-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/template/HideNullJsonTest.java new file mode 100755 index 00000000..1fb1f676 --- /dev/null +++ b/template-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/template/HideNullJsonTest.java @@ -0,0 +1,46 @@ +package org.onap.ccsdk.sli.plugins.template; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; + +public class HideNullJsonTest { + + @Test + public void testSampleTemplate() throws Exception { + TemplateNode t = new MockTemplateNode(); + + Map params = new HashMap(); + params.put(TemplateNode.PREFIX_KEY, "output"); + params.put(TemplateNode.OUTPUT_PATH_KEY, "mycontainer"); + params.put(TemplateNode.TEMPLATE_PATH, "src/test/resources/HideNullJson.vtl"); + + //Setup sample data to feed into the directive + params.put("service-type", "\"VPN\""); //the value is quoted to test an override + params.put("svc-request-id", "REQ001"); + params.put("svc-action", "CREATE"); + params.put("service-instance-id", "SVC001"); + params.put("customerNameTag", "customer-name"); + params.put("customer-name", "TestCust"); + params.put("siidTag", "\"service-instance-id\""); //the value is quoted to test an override + + SvcLogicContext ctx = new SvcLogicContext(); + t.evaluateTemplate(params, ctx); + String result = ctx.getAttribute("output.mycontainer"); + assertTrue(result.contains("\"svc-request-id\":\"REQ001\",")); + assertTrue(result.contains("\"svc-action\":\"CREATE\"")); + assertFalse(result.contains("\"svc-action\":\"CREATE\",")); // there should be no trailing comma + assertTrue(result.contains("\"service-type\":\"VPN\",")); + assertTrue(result.contains("\"customer-name\":\"TestCust\",")); + assertTrue(result.contains("\"service-instance-id\":\"SVC001\"")); + assertFalse(result.contains("\"service-instance-id\":\"SVC001\",")); // there should be no trailing comma + //This should be hidden by the directive because the parameter was never populated + assertFalse(result.contains("customer-phone-number")); + } + +} \ No newline at end of file diff --git a/template-node/provider/src/test/resources/HideNullJson.vtl b/template-node/provider/src/test/resources/HideNullJson.vtl new file mode 100755 index 00000000..30667945 --- /dev/null +++ b/template-node/provider/src/test/resources/HideNullJson.vtl @@ -0,0 +1,22 @@ +## This is an example comment +## This velocity template is used to test the hideNullJson directive +{ + "input": { + "request-header": { +## by default the values parameters provided are surrounded in double quotes and separated by a colon + #hideNullJson("svc-request-id",$svc-request-id)#end +## override default settings so the comma isn't written + #hideNullJson("svc-action",$svc-action, true, true, false)#end + }, + "service-information": { +## if we look at the values in parameters we see service-type is already surrounded by quotes +## we override the default so the string isn't surrounded by excess quotes + #hideNullJson("service-type",$service-type,true,false,true)#end +## the first parameter doesn't need to be a literal + #hideNullJson($customerNameTag,$customer-name)#end +## if the first parameter already has already been quoted we can override the default + #hideNullJson($siidTag,$service-instance-id,false,true,false)#end + #hideNullJson("customer-phone-number",$customer-phone-number)#end + } + } +} \ No newline at end of file -- 2.16.6