create a directive for the template node 56/75256/3
authorSmokowski, Kevin (ks6305) <kevin.smokowski@att.com>
Thu, 3 Jan 2019 22:00:51 +0000 (22:00 +0000)
committerKevin Smokowski <kevin.smokowski@att.com>
Thu, 3 Jan 2019 22:04:46 +0000 (22:04 +0000)
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) <kevin.smokowski@att.com>
template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/HideNullJson.java [new file with mode: 0755]
template-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/template/TemplateNode.java [changed mode: 0644->0755]
template-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/template/HideNullJsonTest.java [new file with mode: 0755]
template-node/provider/src/test/resources/HideNullJson.vtl [new file with mode: 0755]

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 (executable)
index 0000000..d39d7e4
--- /dev/null
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index 0b5850a..6c0686c
@@ -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<String, String> 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 (executable)
index 0000000..1fb1f67
--- /dev/null
@@ -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<String, String> params = new HashMap<String, String>();
+        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 (executable)
index 0000000..3066794
--- /dev/null
@@ -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