configurable param resolution
[ccsdk/sli/plugins.git] / properties-node / provider / src / main / java / org / onap / ccsdk / sli / plugins / prop / PropertiesNode.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  * reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.plugins.prop;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Properties;
31 import java.util.Set;
32 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
33 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
34 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 public class PropertiesNode implements SvcLogicJavaPlugin {
39
40     private static final Logger log = LoggerFactory.getLogger(PropertiesNode.class);
41
42     public void readProperties(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException {
43         Parameters param = getParameters(paramMap);
44         Properties prop = new Properties();
45         try {
46             File file = new File(param.fileName);
47             try (InputStream in = new FileInputStream(file)) {
48                 Map<String, String> mm = null;
49                 String pfx = param.contextPrefix != null ? param.contextPrefix + '.' : "";
50                 if (param.fileBasedParsing) {
51                     byte[] data = new byte[(int) file.length()];
52                     if ("json".equalsIgnoreCase(getFileExtension(param.fileName))) {
53                         in.read(data);
54                         String str = new String(data, "UTF-8");
55                         mm = JsonParser.convertToProperties(str);
56                     } else if ("xml".equalsIgnoreCase(getFileExtension(param.fileName))) {
57                         in.read(data);
58                         String str = new String(data, "UTF-8");
59                         mm = XmlParser.convertToProperties(str, param.listNameList);
60                     } else {
61                         prop.load(in);
62                         for (Object key : prop.keySet()) {
63                             String name = (String) key;
64                             String value = prop.getProperty(name);
65                             if (value != null && value.trim().length() > 0) {
66                                 ctx.setAttribute(pfx + name, getObfuscatedVal(value.trim()));
67                                 log.info("+++ " + pfx + name + ": [" + maskPassword(pfx + name, value) + "]");
68                             }
69                         }
70                     }
71                     if (mm != null) {
72                         for (Map.Entry<String, String> entry : mm.entrySet()) {
73                             ctx.setAttribute(pfx + entry.getKey(), getObfuscatedVal(entry.getValue()));
74                             log.info("+++ " + pfx + entry.getKey() + ": ["
75                                     + maskPassword(pfx + entry.getKey(), entry.getValue()) + "]");
76                         }
77                     }
78                 } else {
79                     prop.load(in);
80                     for (Object key : prop.keySet()) {
81                         String name = (String) key;
82                         String value = prop.getProperty(name);
83                         if (value != null && value.trim().length() > 0) {
84                             ctx.setAttribute(pfx + name, getObfuscatedVal(value.trim()));
85                             log.info("+++ " + pfx + name + ": [" + maskPassword(pfx + name, value) + "]");
86                         }
87                     }
88                 }
89             }
90         } catch (IOException e) {
91             throw new SvcLogicException("Cannot read property file: " + param.fileName + ": " + e.getMessage(), e);
92         }
93     }
94
95     /* Unobfuscate param value */ 
96     private static String getObfuscatedVal(String paramValue) {
97         String resValue = paramValue;
98         if (paramValue != null && paramValue.startsWith("${") && paramValue.endsWith("}"))
99         {
100                 String paramStr = paramValue.substring(2, paramValue.length()-1);
101                 if (paramStr  != null && paramStr.length() > 0)
102                 {
103                         String val = System.getenv(paramStr);
104                         if (val != null && val.length() > 0)
105                         {
106                              resValue=val;
107                              log.info("Obfuscated value RESET for param value:" + paramValue);
108                         }
109                  }
110         }
111         return resValue;
112     }
113
114     /*
115      * Getting extension has to do the following "" --> "" "name" --> "" "name.txt" --> "txt"
116      * ".htpasswd" --> "" "name.with.many.dots.myext" --> "myext"
117      */
118     private static String getFileExtension(String fileName) {
119         if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
120             return fileName.substring(fileName.lastIndexOf(".") + 1);
121         } else {
122             return "";
123         }
124     }
125
126     protected Parameters getParameters(Map<String, String> paramMap) throws SvcLogicException {
127         Parameters p = new Parameters();
128         p.fileName = parseParam(paramMap, "fileName", true, null);
129         p.contextPrefix = parseParam(paramMap, "contextPrefix", false, null);
130         p.listNameList = getListNameList(paramMap);
131         String fileBasedParsingStr = paramMap.get("fileBasedParsing");
132         p.fileBasedParsing = "true".equalsIgnoreCase(fileBasedParsingStr);
133         return p;
134     }
135
136     protected Set<String> getListNameList(Map<String, String> paramMap) {
137         Set<String> ll = new HashSet<>();
138         for (Map.Entry<String, String> entry : paramMap.entrySet()) {
139             if (entry.getKey().startsWith("listName")) {
140                 ll.add(entry.getValue());
141             }
142         }
143         return ll;
144     }
145
146     private String parseParam(Map<String, String> paramMap, String name, boolean required, String def)
147             throws SvcLogicException {
148         String s = paramMap.get(name);
149
150         if (s == null || s.trim().length() == 0) {
151             if (!required) {
152                 return def;
153             }
154             throw new SvcLogicException("Parameter " + name + " is required in PropertiesNode");
155         }
156
157         s = s.trim();
158         String value = "";
159         int i = 0;
160         int i1 = s.indexOf('%');
161         while (i1 >= 0) {
162             int i2 = s.indexOf('%', i1 + 1);
163             if (i2 < 0) {
164                 throw new SvcLogicException("Cannot parse parameter " + name + ": " + s + ": no matching %");
165             }
166
167             String varName = s.substring(i1 + 1, i2);
168             String varValue = System.getenv(varName);
169             if (varValue == null) {
170                 varValue = "";
171             }
172
173             value += s.substring(i, i1);
174             value += varValue;
175
176             i = i2 + 1;
177             i1 = s.indexOf('%', i);
178         }
179         value += s.substring(i);
180
181         log.info("Parameter " + name + ": " + maskPassword(name, value));
182         return value;
183     }
184
185     private static Object maskPassword(String name, Object value) {
186         String[] pwdNames = {"pwd", "passwd", "password", "Pwd", "Passwd", "Password"};
187         for (String pwdName : pwdNames) {
188             if (name.contains(pwdName)) {
189                 return "**********";
190             }
191         }
192         return value;
193     }
194 }