Sonar fixes in "appc-ranking-framework-lib"
[appc.git] / appc-dispatcher / appc-dispatcher-common / ranking-framework-lib / src / main / java / org / onap / appc / rankingframework / impl / BacktraceStrategy.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.appc.rankingframework.impl;
26
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 import org.onap.appc.rankingframework.RankedAttributesContext;
32 import com.att.eelf.configuration.EELFLogger;
33 import com.att.eelf.configuration.EELFManager;
34
35 class BacktraceStrategy implements Strategy {
36
37     private final EELFLogger logger = EELFManager.getInstance().getLogger(BacktraceStrategy.class);
38
39     @Override
40     public <R> R resolve(CompositeNode<R> rootNode, List<String> rankedNames, RankedAttributesContext context) {
41
42         logEntryPath(rankedNames, context);
43
44         Set<String> visited = new HashSet<>();
45
46         CompositeNode<R> parentNode = rootNode;
47         int depth = 0;
48         boolean stop = false;
49         R result = null;
50
51         String attribute = null;
52         Object value = null;
53
54         do {
55             if (value == null) {
56                 attribute = rankedNames.get(depth);
57                 value = Utils.value(context.getAttributeValue(attribute));
58             }
59
60             Node<R> childNode = getChildNode(parentNode, visited, attribute, value);
61
62             if (childNode != null) {
63                 switch (childNode.type()) {
64                     case COMPOSITE:
65                         depth++;
66                         value = null;
67                         parentNode = (CompositeNode<R>) childNode;
68                         break;
69                     case LEAF:
70                         log("Result node has been resolved succesfully - '%s'", childNode);
71                         result = ((LeafNode<R>) childNode).result();
72                         stop = true;
73                         break;
74                     default:
75                         throw new IllegalStateException(childNode.type().name());
76                 }
77             } else {
78                 if (!(Constants.DEFAULT_MATCH).equals(value)) {
79                     logger.debug("Exact match didn't work, trying the default option, if any");
80                     value = Constants.DEFAULT_MATCH;
81                 } else if (depth > 0) {
82                     log("Exact match didn't work and no default option available beneath '%s' - moving out",
83                             parentNode);
84                     depth--;
85                     value = null;
86                     parentNode = parentNode.parent();
87                 } else {
88                     logger.debug("Didn't success to resolve the path - stopping without result");
89                     stop = true;
90                 }
91             }
92         } while (!stop);
93
94         return result;
95     }
96
97     private <R> Node<R> getChildNode(CompositeNode<R> parentNode, Set<String> visited, String attribute, Object value) {
98
99         Node<R> childNode = parentNode.children().get(value);
100         if (childNode != null) {
101             log("Found matching node '%s' - checking it out", childNode);
102
103             if (!visited.add(childNode.id())) {
104                 log("The matching node '%s' was checked before - ignoring it", childNode);
105                 childNode = null;
106             }
107         } else {
108             log("Node '%s/{%s = %s}' not found  - falling back",
109                     parentNode, attribute, value != null ? value : "NULL");
110         }
111         return childNode;
112     }
113
114     private void logEntryPath(List<String> rankedNames, RankedAttributesContext context){
115         if (logger.isDebugEnabled()) {
116             StringBuilder buff = new StringBuilder(128);
117             for (String name : rankedNames) {
118                 buff.append("/{")
119                         .append(name)
120                         .append(" = ")
121                         .append(Utils.value(context.getAttributeValue(name)))
122                         .append('}');
123             }
124             logger.debug(String.format("Trying to resolve path: %s", buff));
125         }
126     }
127
128     private void log(String log, Object... args) {
129         if (logger.isDebugEnabled()) {
130             logger.debug(String.format(log, args));
131         }
132     }
133 }