fix setnode null feature
short prefixes could cause bad behavior in the setnode null feature
Change-Id: I3876eaece8b8d695b0a98d8b5d69f955f2149402
Issue-ID: CCSDK-190
Signed-off-by: Kevin Smokowski <ks6305@att.com>
diff --git a/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutor.java b/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutor.java
index dc7fad0..cd47897 100644
--- a/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutor.java
+++ b/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutor.java
@@ -3,14 +3,14 @@
* ONAP : CCSDK
* ================================================================================
* Copyright (C) 2017 AT&T Intellectual Property. All rights
- * reserved.
+ * reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -26,7 +26,6 @@
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
-
import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
import org.onap.ccsdk.sli.core.sli.SvcLogicException;
import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
@@ -37,161 +36,131 @@
public class SetNodeExecutor extends SvcLogicNodeExecutor {
- private static final Logger LOG = LoggerFactory
- .getLogger(SetNodeExecutor.class);
+ private static final Logger LOG = LoggerFactory.getLogger(SetNodeExecutor.class);
- @Override
- public SvcLogicNode execute(SvcLogicService svc, SvcLogicNode node,
- SvcLogicContext ctx) throws SvcLogicException {
+ @Override
+ public SvcLogicNode execute(SvcLogicService svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+ execute(node,ctx);
+ return null;
+ }
- String ifunsetStr = SvcLogicExpressionResolver.evaluate(
- node.getAttribute("only-if-unset"), node, ctx);
+ public void execute(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+ String ifunsetStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("only-if-unset"), node, ctx);
- boolean ifunset = "true".equalsIgnoreCase(ifunsetStr);
+ boolean ifunset = "true".equalsIgnoreCase(ifunsetStr);
- Set<Map.Entry<String, SvcLogicExpression>> parameterSet = node
- .getParameterSet();
+ Set<Map.Entry<String, SvcLogicExpression>> parameterSet = node.getParameterSet();
- for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parameterSet
- .iterator(); iter.hasNext();) {
- Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
- String curName = curEnt.getKey();
- String lhsVarName = curName;
-
- // Resolve LHS of assignment (could contain index variables)
- try {
- //Backticks symbolize the variable should be handled as an expression instead of as a variable
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parameterSet.iterator(); iter.hasNext();) {
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+ String lhsVarName = curName;
+
+ // Resolve LHS of assignment (could contain index variables)
+ try {
+ // Backticks symbolize the variable should be handled as an expression instead of as a variable
if (curName.trim().startsWith("`")) {
int lastParen = curName.lastIndexOf("`");
String evalExpr = curName.trim().substring(1, lastParen);
SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(evalExpr);
lhsVarName = SvcLogicExpressionResolver.evaluate(lhsExpr, node, ctx);
} else {
- SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(curName);
- lhsVarName = SvcLogicExpressionResolver.resolveVariableName(lhsExpr, node, ctx);
+ SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(curName);
+ lhsVarName = SvcLogicExpressionResolver.resolveVariableName(lhsExpr, node, ctx);
}
- } catch (Exception e) {
- LOG.warn("Caught exception trying to resolve variable name ("+curName+")", e);
- }
-
+ } catch (Exception e) {
+ LOG.warn("Caught exception trying to resolve variable name (" + curName + ")", e);
+ }
- boolean setValue = true;
+ boolean setValue = true;
- if (curName.endsWith(".")) {
+ if (curName.endsWith(".")) {
+ // Copy subtree - value should be a variable name
+ SvcLogicExpression curValue = curEnt.getValue();
- // Copy subtree - value should be a variable name
- SvcLogicExpression curValue = curEnt.getValue();
+ if (curValue != null) {
+ String rhsRoot = curValue.toString();
- if (curValue != null) {
- String rhsRoot = curValue.toString();
-
- if ((rhsRoot != null) && (rhsRoot.length() > 0)) {
- if (rhsRoot.endsWith(".")) {
- rhsRoot = rhsRoot
- .substring(0, rhsRoot.length() - 1);
- }
+ if ((rhsRoot != null) && (rhsRoot.length() > 0)) {
+ if (rhsRoot.endsWith(".")) {
+ rhsRoot = rhsRoot.substring(0, rhsRoot.length() - 1);
+ }
+ // SDNGC-2321 : rhsRoot is variable name, possibly with subscript(s) to be resolved
+ try {
+ SvcLogicExpression rhsExpr = SvcLogicExpressionFactory.parse(rhsRoot);
+ rhsRoot = SvcLogicExpressionResolver.resolveVariableName(rhsExpr, node, ctx);
+ } catch (Exception e) {
+ LOG.warn("Caught exception trying to resolve variable name (" + rhsRoot + ")", e);
+ }
- // SDNGC-2321 : rhsRoot is variable name, possibly with subscript(s) to be resolved
- try {
- SvcLogicExpression rhsExpr = SvcLogicExpressionFactory.parse(rhsRoot);
- rhsRoot = SvcLogicExpressionResolver.resolveVariableName(rhsExpr, node, ctx);
- } catch (Exception e) {
- LOG.warn("Caught exception trying to resolve variable name ("+rhsRoot+")", e);
- }
-
- // See if the parameters are reversed (copying service-data to input) .. this
- // was done as a workaround to earlier issue
- if (curName.endsWith("-input.") && rhsRoot.startsWith("service-data")) {
- LOG.warn("Arguments appear to be reversed .. will copy input to service-data instead");
- lhsVarName = rhsRoot + ".";
- rhsRoot = curName.substring(0, curName.length()-1);
- }
-
- rhsRoot = rhsRoot + ".";
- String lhsPrefix = lhsVarName;
-
- if (lhsPrefix.endsWith(".")) {
- lhsPrefix = lhsPrefix.substring(0,
- lhsPrefix.length()-1);
- }
- int lhsPfxLength = lhsPrefix.length();
- HashMap<String, String> parmsToAdd = new HashMap<String,String>();
+ // See if the parameters are reversed (copying service-data to input) .. this
+ // was done as a workaround to earlier issue
+ if (curName.endsWith("-input.") && rhsRoot.startsWith("service-data")) {
+ LOG.warn("Arguments appear to be reversed .. will copy input to service-data instead");
+ lhsVarName = rhsRoot + ".";
+ rhsRoot = curName.substring(0, curName.length() - 1);
+ }
- for (String sourceVarName : ctx.getAttributeKeySet()) {
+ rhsRoot = rhsRoot + ".";
+ String lhsPrefix = lhsVarName;
- if (sourceVarName.startsWith(rhsRoot)) {
+ if (lhsPrefix.endsWith(".")) {
+ lhsPrefix = lhsPrefix.substring(0, lhsPrefix.length() - 1);
+ }
+ int lhsPfxLength = lhsPrefix.length();
+ HashMap<String, String> parmsToAdd = new HashMap<String, String>();
- String targetVar = lhsPrefix
- + "."
- + sourceVarName
- .substring(rhsRoot.length());
+ for (String sourceVarName : ctx.getAttributeKeySet()) {
- LOG.debug("Copying " + sourceVarName
- + " value to " + targetVar);
+ if (sourceVarName.startsWith(rhsRoot)) {
- parmsToAdd.put(targetVar,
- ctx.getAttribute(sourceVarName));
- }
- }
-
- for (String newParmName : parmsToAdd.keySet()) {
- ctx.setAttribute(newParmName, parmsToAdd.get(newParmName));
- }
+ String targetVar = lhsPrefix + "." + sourceVarName.substring(rhsRoot.length());
- } else {
- // If RHS is empty, unset attributes in LHS
- String lhsPrefix = lhsVarName.substring(0,
- lhsVarName.length() - 1);
- int lhsPfxLength = lhsPrefix.length();
-
- LinkedList<String> parmsToRemove = new LinkedList<String> ();
+ LOG.debug("Copying " + sourceVarName + " value to " + targetVar);
- for (String curCtxVarname : ctx.getAttributeKeySet()) {
+ parmsToAdd.put(targetVar, ctx.getAttribute(sourceVarName));
+ }
+ }
+ for (String newParmName : parmsToAdd.keySet()) {
+ ctx.setAttribute(newParmName, parmsToAdd.get(newParmName));
+ }
+ } else {
+ // If RHS is empty, unset attributes in LHS
+ LinkedList<String> parmsToRemove = new LinkedList<String>();
+ String prefix = lhsVarName + ".";
+ for (String curCtxVarname : ctx.getAttributeKeySet()) {
+ if (curCtxVarname.startsWith(prefix)) {
+ LOG.debug("Unsetting " + curCtxVarname);
+ parmsToRemove.add(curCtxVarname);
+ }
+ }
+ for (String parmName : parmsToRemove) {
+ ctx.setAttribute(parmName, null);
+ }
+ }
+ }
+ } else {
+ if (ifunset) {
+ String ctxValue = ctx.getAttribute(lhsVarName);
+ if ((ctxValue != null) && (ctxValue.length() > 0)) {
+ setValue = false;
+ LOG.debug("Attribute " + lhsVarName
+ + " already set and only-if-unset is true, so not overriding");
+ }
+ }
+ if (setValue) {
+ String curValue = SvcLogicExpressionResolver.evaluate(curEnt.getValue(), node, ctx);
- if (curCtxVarname.startsWith(lhsPrefix)) {
- LOG.debug("Unsetting " + curCtxVarname);
- parmsToRemove.add(curCtxVarname);
- }
- }
-
- for (String parmName : parmsToRemove) {
- ctx.setAttribute(parmName, null);
- }
-
- }
- }
-
- } else {
-
- if (ifunset) {
- String ctxValue = ctx.getAttribute(lhsVarName);
-
- if ((ctxValue != null) && (ctxValue.length() > 0)) {
- setValue = false;
- LOG.debug("Attribute "
- + lhsVarName
- + " already set and only-if-unset is true, so not overriding");
- }
- }
-
- if (setValue) {
- String curValue = SvcLogicExpressionResolver.evaluate(
- curEnt.getValue(), node, ctx);
-
- if (LOG.isDebugEnabled()) {
- LOG.trace("Parameter value "
- + curEnt.getValue().asParsedExpr()
- + " resolves to " + curValue);
- LOG.debug("Setting context attribute " + lhsVarName
- + " to " + curValue);
- }
- ctx.setAttribute(lhsVarName, curValue);
- }
- }
- }
-
- return null;
- }
-
+ if (LOG.isDebugEnabled()) {
+ LOG.trace("Parameter value " + curEnt.getValue().asParsedExpr() + " resolves to " + curValue);
+ LOG.debug("Setting context attribute " + lhsVarName + " to " + curValue);
+ }
+ ctx.setAttribute(lhsVarName, curValue);
+ }
+ }
+ }
+ }
}
+
diff --git a/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutorTest.java b/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutorTest.java
new file mode 100644
index 0000000..1333d07
--- /dev/null
+++ b/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutorTest.java
@@ -0,0 +1,56 @@
+package org.onap.ccsdk.sli.core.sli.provider;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import java.util.LinkedList;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicParser;
+
+public class SetNodeExecutorTest {
+ @Test
+ public void clearProperties() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertNull(ctx.getAttribute("si.field1"));
+ assertNull(ctx.getAttribute("si.field2"));
+ assertNull(ctx.getAttribute("si.field3"));
+ assertEquals("6", ctx.getAttribute("search1"));
+ assertEquals("KeepMe!", ctx.getAttribute("simonSays"));
+ }
+
+ @Test
+ public void subtreeCopy() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/copyValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertEquals("1",ctx.getAttribute("si.field1"));
+ assertEquals("2",ctx.getAttribute("si.field2"));
+ assertEquals("3",ctx.getAttribute("si.field3"));
+ assertEquals("1",ctx.getAttribute("rootTwo.field1"));
+ assertEquals("2",ctx.getAttribute("rootTwo.field2"));
+ assertEquals("3",ctx.getAttribute("rootTwo.field3"));
+ }
+
+}
diff --git a/sli/provider/src/test/resources/clearValues.xml b/sli/provider/src/test/resources/clearValues.xml
new file mode 100644
index 0000000..615c856
--- /dev/null
+++ b/sli/provider/src/test/resources/clearValues.xml
@@ -0,0 +1,18 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si.field1' value='1' />
+ <parameter name='si.field2' value='2' />
+ <parameter name='si.field3' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si.' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file
diff --git a/sli/provider/src/test/resources/copyValues.xml b/sli/provider/src/test/resources/copyValues.xml
new file mode 100644
index 0000000..f56f714
--- /dev/null
+++ b/sli/provider/src/test/resources/copyValues.xml
@@ -0,0 +1,16 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si.field1' value='1' />
+ <parameter name='si.field2' value='2' />
+ <parameter name='si.field3' value='3' />
+ </set>
+ <set>
+ <parameter name='rootTwo.' value='si.' />
+ </set>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file