2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Modifications Copyright (C) 2018 IBM.
9 * ================================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ============LICENSE_END=========================================================
24 package org.onap.ccsdk.sli.core.sli.provider.base;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.LinkedList;
31 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
32 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
33 import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
34 import org.onap.ccsdk.sli.core.sli.SvcLogicExpressionFactory;
35 import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public class SetNodeExecutor extends AbstractSvcLogicNodeExecutor {
41 private static final Logger LOG = LoggerFactory.getLogger(SetNodeExecutor.class);
42 protected final String arrayPattern = "\\[\\d*\\]";
45 public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
46 throws SvcLogicException {
51 public void execute(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
52 String ifunsetStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("only-if-unset"), node, ctx);
54 boolean ifunset = "true".equalsIgnoreCase(ifunsetStr);
56 Set<Map.Entry<String, SvcLogicExpression>> parameterSet = node.getParameterSet();
58 for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parameterSet.iterator(); iter.hasNext();) {
59 Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
60 String curName = curEnt.getKey();
61 String lhsVarName = curName;
63 // Resolve LHS of assignment (could contain index variables)
65 // Backticks symbolize the variable should be handled as an expression instead of as a variable
66 if (curName.trim().startsWith("`")) {
67 int lastParen = curName.lastIndexOf("`");
68 String evalExpr = curName.trim().substring(1, lastParen);
69 SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(evalExpr);
70 lhsVarName = SvcLogicExpressionResolver.evaluate(lhsExpr, node, ctx);
72 SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(curName);
73 lhsVarName = SvcLogicExpressionResolver.resolveVariableName(lhsExpr, node, ctx);
75 } catch (Exception e) {
76 LOG.warn("Caught exception trying to resolve variable name (" + curName + ")", e);
79 boolean setValue = true;
81 if (curName.endsWith(".")) {
82 // Copy subtree - value should be a variable name
83 SvcLogicExpression curValue = curEnt.getValue();
85 if (curValue != null) {
86 String rhsRoot = curValue.toString();
88 if ((rhsRoot != null) && (rhsRoot.length() > 0)) {
89 if (rhsRoot.endsWith(".")) {
90 rhsRoot = rhsRoot.substring(0, rhsRoot.length() - 1);
93 // SDNGC-2321 : rhsRoot is variable name, possibly with subscript(s) to be resolved
95 SvcLogicExpression rhsExpr = SvcLogicExpressionFactory.parse(rhsRoot);
96 rhsRoot = SvcLogicExpressionResolver.resolveVariableName(rhsExpr, node, ctx);
97 } catch (Exception e) {
98 LOG.warn("Caught exception trying to resolve variable name (" + rhsRoot + ")", e);
101 // See if the parameters are reversed (copying service-data to input) .. this
102 // was done as a workaround to earlier issue
103 if (curName.endsWith("-input.") && rhsRoot.startsWith("service-data")) {
104 LOG.warn("Arguments appear to be reversed .. will copy input to service-data instead");
105 lhsVarName = rhsRoot + ".";
106 rhsRoot = curName.substring(0, curName.length() - 1);
109 rhsRoot = rhsRoot + ".";
110 String lhsPrefix = lhsVarName;
112 if (lhsPrefix.endsWith(".")) {
113 lhsPrefix = lhsPrefix.substring(0, lhsPrefix.length() - 1);
116 HashMap<String, String> parmsToAdd = new HashMap<>();
118 for (String sourceVarName : ctx.getAttributeKeySet()) {
119 if (sourceVarName.startsWith(rhsRoot)) {
120 String targetVar = lhsPrefix + "." + sourceVarName.substring(rhsRoot.length());
121 LOG.debug("Copying {} value to {}", sourceVarName, targetVar);
122 parmsToAdd.put(targetVar, ctx.getAttribute(sourceVarName));
125 for (String newParmName : parmsToAdd.keySet()) {
126 ctx.setAttribute(newParmName, parmsToAdd.get(newParmName));
129 // If RHS is empty, unset attributes in LHS
130 LinkedList<String> parmsToRemove = new LinkedList<>();
131 String prefix = lhsVarName + ".";
132 String arrayPrefix = lhsVarName + "[";
133 //Clear length value in case an array exists with this prefix
134 String lengthParamName = lhsVarName + "_length";
135 LOG.debug("Unsetting {} because prefix {} is being cleared.", lengthParamName, prefix);
137 for (String curCtxVarname : ctx.getAttributeKeySet()) {
138 String curCtxVarnameMatchingValue = curCtxVarname;
139 //Special handling for reseting array values, strips out brackets and any numbers between the brackets
140 //when testing if a context memory value starts with a prefix
141 if(!prefix.contains("[") && curCtxVarnameMatchingValue.contains("[")) {
142 curCtxVarnameMatchingValue = curCtxVarname.replaceAll(arrayPattern, "") + ".";
144 if (curCtxVarnameMatchingValue.startsWith(prefix)) {
145 LOG.debug("Unsetting {} because matching value {} starts with the prefix {}", curCtxVarname, curCtxVarnameMatchingValue, prefix);
146 parmsToRemove.add(curCtxVarname);
147 }else if (curCtxVarnameMatchingValue.startsWith(lengthParamName)) {
148 LOG.debug("Unsetting {} because matching value {} starts with the lengthParamName {}", curCtxVarname, curCtxVarnameMatchingValue, lengthParamName);
149 parmsToRemove.add(curCtxVarname);
150 }else if (curCtxVarnameMatchingValue.startsWith(arrayPrefix)) {
151 LOG.debug("Unsetting {} because matching value {} starts with the arrayPrefix {}", curCtxVarname, curCtxVarnameMatchingValue, arrayPrefix);
152 parmsToRemove.add(curCtxVarname);
155 for (String parmName : parmsToRemove) {
156 ctx.setAttribute(parmName, null);
162 String ctxValue = ctx.getAttribute(lhsVarName);
163 if ((ctxValue != null) && (ctxValue.length() > 0)) {
165 LOG.debug("Attribute {} already set and only-if-unset is true, so not overriding", lhsVarName);
169 String curValue = SvcLogicExpressionResolver.evaluate(curEnt.getValue(), node, ctx);
171 if (LOG.isDebugEnabled()) {
172 LOG.trace("Parameter value {} resolves to {}", curEnt.getValue().asParsedExpr(), curValue);
173 LOG.debug("Setting context attribute {} to {}", lhsVarName, curValue);
175 ctx.setAttribute(lhsVarName, curValue);