From 168181418de462c53f7c0c326ea3ce5200467f09 Mon Sep 17 00:00:00 2001 From: Kevin Smokowski Date: Fri, 23 Feb 2018 20:51:21 +0000 Subject: 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 --- .../sli/core/sli/provider/SetNodeExecutor.java | 267 +++++++++------------ .../sli/core/sli/provider/SetNodeExecutorTest.java | 56 +++++ sli/provider/src/test/resources/clearValues.xml | 18 ++ sli/provider/src/test/resources/copyValues.xml | 16 ++ 4 files changed, 208 insertions(+), 149 deletions(-) create mode 100644 sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/SetNodeExecutorTest.java create mode 100644 sli/provider/src/test/resources/clearValues.xml create mode 100644 sli/provider/src/test/resources/copyValues.xml 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 dc7fad0a..cd478977 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.Iterator; 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 @@ import org.slf4j.LoggerFactory; 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 { + execute(node,ctx); + return null; + } - @Override - public SvcLogicNode execute(SvcLogicService svc, SvcLogicNode node, - SvcLogicContext ctx) throws SvcLogicException { + public void execute(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + String ifunsetStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("only-if-unset"), node, ctx); - String ifunsetStr = SvcLogicExpressionResolver.evaluate( - node.getAttribute("only-if-unset"), node, ctx); + boolean ifunset = "true".equalsIgnoreCase(ifunsetStr); - boolean ifunset = "true".equalsIgnoreCase(ifunsetStr); + Set> parameterSet = node.getParameterSet(); - Set> parameterSet = node - .getParameterSet(); + for (Iterator> iter = parameterSet.iterator(); iter.hasNext();) { + Map.Entry curEnt = iter.next(); + String curName = curEnt.getKey(); + String lhsVarName = curName; - for (Iterator> iter = parameterSet - .iterator(); iter.hasNext();) { - Map.Entry 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 + // 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); - } - - - boolean setValue = true; - - if (curName.endsWith(".")) { - - // Copy subtree - value should be a variable name - SvcLogicExpression curValue = curEnt.getValue(); - - if (curValue != null) { - String rhsRoot = curValue.toString(); - - 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); - } - - // 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 parmsToAdd = new HashMap(); - - for (String sourceVarName : ctx.getAttributeKeySet()) { - - if (sourceVarName.startsWith(rhsRoot)) { - - String targetVar = lhsPrefix - + "." - + sourceVarName - .substring(rhsRoot.length()); - - LOG.debug("Copying " + sourceVarName - + " value to " + targetVar); - - 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 - String lhsPrefix = lhsVarName.substring(0, - lhsVarName.length() - 1); - int lhsPfxLength = lhsPrefix.length(); - - LinkedList parmsToRemove = new LinkedList (); - - for (String curCtxVarname : ctx.getAttributeKeySet()) { - - 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; - } - + } catch (Exception e) { + LOG.warn("Caught exception trying to resolve variable name (" + curName + ")", e); + } + + boolean setValue = true; + + if (curName.endsWith(".")) { + // Copy subtree - value should be a variable name + SvcLogicExpression curValue = curEnt.getValue(); + + if (curValue != null) { + String rhsRoot = curValue.toString(); + + 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); + } + + // 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 parmsToAdd = new HashMap(); + + for (String sourceVarName : ctx.getAttributeKeySet()) { + + if (sourceVarName.startsWith(rhsRoot)) { + + String targetVar = lhsPrefix + "." + sourceVarName.substring(rhsRoot.length()); + + LOG.debug("Copying " + sourceVarName + " value to " + targetVar); + + 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 parmsToRemove = new LinkedList(); + 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 (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 00000000..1333d070 --- /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 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 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 00000000..615c8566 --- /dev/null +++ b/sli/provider/src/test/resources/clearValues.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ 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 00000000..f56f7140 --- /dev/null +++ b/sli/provider/src/test/resources/copyValues.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file -- cgit 1.2.3-korg