2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.cadi;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.PrintStream;
29 import java.text.SimpleDateFormat;
30 import java.util.ArrayList;
31 import java.util.Date;
32 import java.util.List;
33 import java.util.Map.Entry;
35 import org.onap.aaf.cadi.config.Config;
36 import org.onap.aaf.cadi.config.SecurityInfo;
38 import java.util.Properties;
40 public class PropAccess implements Access {
41 // Sonar says cannot be static... it's ok. not too many PropAccesses created.
42 private final SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
44 public static Level DEFAULT = Level.AUDIT;
48 private Properties props;
49 private List<String> recursionProtection = null;
54 logIt = new StreamLogIt(System.out);
59 * This Constructor soly exists to instantiate Servlet Context Based Logging that will call "init" later.
62 protected PropAccess(Object o) {
63 logIt = new StreamLogIt(System.out);
64 props = new Properties();
67 public PropAccess(String ... args) {
68 this(System.out,args);
71 public PropAccess(PrintStream ps, String[] args) {
72 logIt = new StreamLogIt(ps==null?System.out:ps);
73 Properties nprops=new Properties();
75 for(String arg : args) {
76 if((eq=arg.indexOf('='))>0) {
77 nprops.setProperty(arg.substring(0, eq),arg.substring(eq+1));
83 public PropAccess(LogIt logit, String[] args) {
87 public PropAccess(Properties p) {
91 public PropAccess(PrintStream ps, Properties p) {
92 logIt = new StreamLogIt(ps==null?System.out:ps);
96 protected void init(Properties p) {
97 // Make sure these two are set before any changes in Logging
99 level=DEFAULT.maskOf();
101 props = new Properties();
102 // First, load related System Properties
103 for(Entry<Object,Object> es : System.getProperties().entrySet()) {
104 String key = es.getKey().toString();
105 for(String start : new String[] {"cadi_","aaf_","cm_"}) {
106 if(key.startsWith(start)) {
107 props.put(key, es.getValue());
111 // Second, overlay or fill in with Passed in Props
116 // Third, load any Chained Property Files
117 load(props.getProperty(Config.CADI_PROP_FILES));
119 String sLevel = props.getProperty(Config.CADI_LOGLEVEL);
121 level=Level.valueOf(sLevel).maskOf();
123 // Setup local Symmetrical key encryption
126 symm = Symm.obtain(this);
127 } catch (CadiException e) {
128 System.err.append("FATAL ERROR: Cannot obtain Key Information.");
129 e.printStackTrace(System.err);
134 name = props.getProperty(Config.CADI_LOGNAME, name);
136 specialConversions();
139 private void specialConversions() {
140 // Critical - if no Security Protocols set, then set it. We'll just get messed up if not
141 if(props.get(Config.CADI_PROTOCOLS)==null) {
142 props.setProperty(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT);
146 temp=props.get(Config.CADI_PROTOCOLS);
147 if(props.get(Config.HTTPS_PROTOCOLS)==null && temp!=null) {
148 props.put(Config.HTTPS_PROTOCOLS, temp);
152 if("1.7".equals(System.getProperty("java.specification.version"))
153 && (temp==null || (temp instanceof String && ((String)temp).contains("TLSv1.2")))) {
154 System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
159 private void load(String cadi_prop_files) {
160 if(cadi_prop_files==null) {
163 String prevKeyFile = props.getProperty(Config.CADI_KEYFILE);
164 int prev = 0, end = cadi_prop_files.length();
168 idx = cadi_prop_files.indexOf(File.pathSeparatorChar,prev);
172 File file = new File(filename=cadi_prop_files.substring(prev,idx));
174 printf(Level.INIT,"Loading CADI Properties from %s",file.getAbsolutePath());
176 FileInputStream fis = new FileInputStream(file);
180 String chainProp = props.getProperty(Config.CADI_PROP_FILES);
181 if(chainProp!=null) {
182 if(recursionProtection==null) {
183 recursionProtection = new ArrayList<String>();
184 recursionProtection.add(cadi_prop_files);
186 if(!recursionProtection.contains(chainProp)) {
187 recursionProtection.add(chainProp);
188 load(chainProp); // recurse
194 } catch (Exception e) {
195 log(e,filename,"cannot be opened");
198 printf(Level.WARN,"Warning: recursive CADI Property %s does not exist",file.getAbsolutePath());
204 for(Entry<Object, Object> es : props.entrySet()) {
205 Object value = es.getValue();
206 if(value instanceof String) {
207 String trim = ((String)value).trim();
208 if(trim!=value) { // Yes, I want OBJECT equals
209 props.setProperty((String)es.getKey(), trim);
213 // Reset Symm if Keyfile Changes:
214 String newKeyFile = props.getProperty(Config.CADI_KEYFILE);
215 if((prevKeyFile!=null && newKeyFile!=null) || (newKeyFile!=null && !newKeyFile.equals(prevKeyFile))) {
217 symm = Symm.obtain(this);
218 } catch (CadiException e) {
219 System.err.append("FATAL ERROR: Cannot obtain Key Information.");
220 e.printStackTrace(System.err);
224 prevKeyFile=newKeyFile;
227 String loglevel = props.getProperty(Config.CADI_LOGLEVEL);
230 level=Level.valueOf(loglevel).maskOf();
231 } catch (IllegalArgumentException e) {
232 printf(Level.ERROR,"%s=%s is an Invalid Log Level",Config.CADI_LOGLEVEL,loglevel);
236 specialConversions();
240 public void load(InputStream is) throws IOException {
242 load(props.getProperty(Config.CADI_PROP_FILES));
246 public void log(Level level, Object ... elements) {
248 logIt.push(level,elements);
252 protected StringBuilder buildMsg(Level level, Object[] elements) {
253 StringBuilder sb = new StringBuilder(iso8601.format(new Date()));
255 sb.append(level.name());
259 int end = elements.length;
264 if(elements[idx] instanceof Integer) {
266 sb.append(elements[idx]);
271 boolean first = true;
272 for(Object o : elements) {
280 switch(s.charAt(l-1)) {
296 public void log(Exception e, Object... elements) {
297 log(Level.ERROR,e.getMessage(),elements);
298 e.printStackTrace(System.err);
302 public void printf(Level level, String fmt, Object... elements) {
304 log(level,String.format(fmt, elements));
309 public void setLogLevel(Level level) {
310 this.level = level.maskOf();
314 public boolean willLog(Level level) {
315 return level.inMask(this.level);
319 public ClassLoader classLoader() {
320 return ClassLoader.getSystemClassLoader();
324 public String getProperty(String tag, String def) {
325 return props.getProperty(tag,def);
329 public String decrypt(String encrypted, boolean anytext) throws IOException {
330 return (encrypted!=null && (anytext==true || encrypted.startsWith(Symm.ENC)))
331 ? symm.depass(encrypted)
335 public String encrypt(String unencrypted) throws IOException {
336 return Symm.ENC+symm.enpass(unencrypted);
342 public String getProperty(String tag) {
343 return props.getProperty(tag);
347 public Properties getProperties() {
351 public void setProperty(String tag, String value) {
353 props.put(tag, value);
354 if(Config.CADI_KEYFILE.equals(tag)) {
355 // reset decryption too
357 symm = Symm.obtain(this);
358 } catch (CadiException e) {
359 System.err.append("FATAL ERROR: Cannot obtain Key Information.");
360 e.printStackTrace(System.err);
367 public interface LogIt {
368 public void push(Level level, Object ... elements) ;
371 private class StreamLogIt implements LogIt {
372 private PrintStream ps;
374 public StreamLogIt(PrintStream ps) {
378 public void push(Level level, Object ... elements) {
379 ps.println(buildMsg(level,elements));
385 public void set(LogIt logit) {