diff options
author | Dan Timoney <dtimoney@att.com> | 2023-06-19 16:05:33 -0400 |
---|---|---|
committer | Dan Timoney <dtimoney@att.com> | 2023-08-10 14:48:32 -0400 |
commit | 6a7f13fa7e284cbec5b0743c10fdd33286aaf2ec (patch) | |
tree | 42fa7649ca8f912af8d47f35bad4b284369fae9d /cadi/core/src/main/java/org/onap/ccsdk/apps/cadi/PropAccess.java | |
parent | a76d3f0de616b542baea9360e80a921f5f028a78 (diff) |
Port to java 17
Update to java 17 / springboot 3 to align with OpenDaylight Argon.
Copied and ported CADI library from AAF
Issue-ID: CCSDK-3917
Signed-off-by: Dan Timoney <dtimoney@att.com>
Change-Id: Idecb0cf43c48ccbbc0c61bf4278b87a37f92a56e
Diffstat (limited to 'cadi/core/src/main/java/org/onap/ccsdk/apps/cadi/PropAccess.java')
-rw-r--r-- | cadi/core/src/main/java/org/onap/ccsdk/apps/cadi/PropAccess.java | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/cadi/core/src/main/java/org/onap/ccsdk/apps/cadi/PropAccess.java b/cadi/core/src/main/java/org/onap/ccsdk/apps/cadi/PropAccess.java new file mode 100644 index 00000000..ff9aac6f --- /dev/null +++ b/cadi/core/src/main/java/org/onap/ccsdk/apps/cadi/PropAccess.java @@ -0,0 +1,437 @@ +/** + * ============LICENSE_START==================================================== + * org.onap.ccsdk.apps + * =========================================================================== + * Copyright (c) 2023 AT&T Intellectual Property. All rights reserved. + * + * Modifications Copyright (C) 2018 IBM. + * =========================================================================== + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END==================================================== + * + */ + +package org.onap.ccsdk.apps.cadi; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map.Entry; +import java.util.Properties; + +import org.onap.ccsdk.apps.cadi.config.Config; +import org.onap.ccsdk.apps.cadi.config.SecurityInfo; +import org.onap.ccsdk.apps.cadi.util.Split; + +public class PropAccess implements Access { + // Sonar says cannot be static... it's ok. not too many PropAccesses created. + private final SimpleDateFormat iso8601 = newISO8601(); + private Symm symm; + public static final Level DEFAULT = Level.AUDIT; + private int level; + private Properties props; + private List<String> recursionProtection = null; + private LogIt logIt; + private String name; + + public PropAccess() { + logIt = new StreamLogIt(System.out); + init(null); + } + + /** + * This Constructor soly exists to instantiate Servlet Context Based Logging that will call "init" later. + * @param sc + */ + protected PropAccess(Object o) { + logIt = new StreamLogIt(System.out); + props = new Properties(); + } + + public PropAccess(String ... args) { + this(System.out,args); + } + + public PropAccess(PrintStream ps, String[] args) { + logIt = new StreamLogIt(ps==null?System.out:ps); + init(logIt,args); + } + + public PropAccess(LogIt logit, String[] args) { + init(logit, args); + } + + public PropAccess(Properties p) { + this(System.out,p); + } + + public PropAccess(PrintStream ps, Properties p) { + logIt = new StreamLogIt(ps==null?System.out:ps); + init(p); + } + + protected void init(final LogIt logIt, final String[] args) { + this.logIt = logIt; + Properties nprops=new Properties(); + int eq; + for (String arg : args) { + if ((eq=arg.indexOf('='))>0) { + nprops.setProperty(arg.substring(0, eq),arg.substring(eq+1)); + } + } + init(nprops); + } + + public static SimpleDateFormat newISO8601() { + return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + } + + protected synchronized void init(Properties p) { + // Make sure these two are set before any changes in Logging + name = "cadi"; + + props = new Properties(); + // First, load related System Properties + for (Entry<Object,Object> es : System.getProperties().entrySet()) { + String key = es.getKey().toString(); + for (String start : new String[] {"cadi_","aaf_","cm_"}) { + if (key.startsWith(start)) { + props.put(key, es.getValue()); + } + } + } + // Second, overlay or fill in with Passed in Props + if (p!=null) { + props.putAll(p); + } + + // Preset LogLevel + String sLevel = props.getProperty(Config.CADI_LOGLEVEL); + // Third, load any Chained Property Files + load(props.getProperty(Config.CADI_PROP_FILES)); + + if(sLevel==null) { // if LogLev wasn't set before, check again after Chained Load + sLevel = props.getProperty(Config.CADI_LOGLEVEL); + if (sLevel==null) { + level=DEFAULT.maskOf(); + } else { + level=Level.valueOf(sLevel).maskOf(); + } + } + // Setup local Symmetrical key encryption + if (symm==null) { + try { + symm = Symm.obtain(this); + } catch (CadiException e) { + System.err.append("FATAL ERROR: Cannot obtain Key Information."); + e.printStackTrace(System.err); + System.exit(1); + } + } + + name = props.getProperty(Config.CADI_LOGNAME, name); + + SecurityInfo.setHTTPProtocols(this); + + } + + + private void load(String cadi_prop_files) { + if (cadi_prop_files==null) { + return; + } + String prevKeyFile = props.getProperty(Config.CADI_KEYFILE); + + + for(String filename : Split.splitTrim(File.pathSeparatorChar, cadi_prop_files)) { + Properties fileProps = new Properties(); + File file = new File(filename); + if (file.exists()) { + printf(Level.INIT,"Loading CADI Properties from %s",file.getAbsolutePath()); + try { + FileInputStream fis = new FileInputStream(file); + try { + fileProps.load(fis); + // Only load props from recursion which are not already in props + // meaning top Property file takes precedence + for(Entry<Object, Object> es : fileProps.entrySet()) { + if(props.get(es.getKey())==null) { + String key = es.getKey().toString(); + String value = es.getValue().toString(); + props.put(key, value); + if(key.contains("pass")) { + value = "vi XX"; + } + printf(Level.DEBUG," %s=%s",key,value); + } + } + // Recursively Load + String chainProp = fileProps.getProperty(Config.CADI_PROP_FILES); + if (chainProp!=null) { + if (recursionProtection==null) { + recursionProtection = new ArrayList<>(); + recursionProtection.add(cadi_prop_files); + } + if (!recursionProtection.contains(chainProp)) { + recursionProtection.add(chainProp); + load(chainProp); // recurse + } + } + } finally { + fis.close(); + } + } catch (Exception e) { + log(e,filename,"cannot be opened"); + } + } else { + printf(Level.WARN,"Warning: recursive CADI Property %s does not exist",file.getAbsolutePath()); + } + } + + // Trim + for (Entry<Object, Object> es : props.entrySet()) { + Object value = es.getValue(); + if (value instanceof String) { + String trim = ((String)value).trim(); + // Remove Beginning/End Quotes, which might be there if mixed with Bash Props + int s = 0, e=trim.length()-1; + if (s<e && trim.charAt(s)=='"' && trim.charAt(e)=='"') { + trim=trim.substring(s+1,e); + } + if (trim!=value) { // Yes, I want OBJECT equals + props.setProperty((String)es.getKey(), trim); + } + } + } + // Reset Symm if Keyfile Changes: + String newKeyFile = props.getProperty(Config.CADI_KEYFILE); + if ((prevKeyFile!=null && newKeyFile!=null) || (newKeyFile!=null && !newKeyFile.equals(prevKeyFile))) { + try { + symm = Symm.obtain(this); + } catch (CadiException e) { + System.err.append("FATAL ERROR: Cannot obtain Key Information."); + e.printStackTrace(System.err); + System.exit(1); + } + + prevKeyFile=newKeyFile; + } + + String loglevel = props.getProperty(Config.CADI_LOGLEVEL); + if (loglevel!=null) { + try { + level=Level.valueOf(loglevel).maskOf(); + } catch (IllegalArgumentException e) { + printf(Level.ERROR,"%s=%s is an Invalid Log Level",Config.CADI_LOGLEVEL,loglevel); + } + } + } + + @Override + public void load(InputStream is) throws IOException { + props.load(is); + load(props.getProperty(Config.CADI_PROP_FILES)); + } + + @Override + public void log(Level level, Object ... elements) { + if (willLog(level)) { + logIt.push(level,elements); + } + } + + public StringBuilder buildMsg(Level level, Object[] elements) { + return buildMsg(name,iso8601,level,elements); + } + + /* + * Need to pass in DateFormat per thread, because not marked as thread safe + */ + public static StringBuilder buildMsg(final String name, final DateFormat sdf, Level level, Object[] elements) { + final StringBuilder sb; + int end = elements.length; + if(sdf==null) { + sb = new StringBuilder(); + write(true,sb,elements); + } else { + sb = new StringBuilder( + sdf.format(new Date()) + ); + sb.append(' '); + sb.append(level.name()); + sb.append(" ["); + sb.append(name); + if (end<=0) { + sb.append("] "); + } else { + int idx = 0; + if(elements[idx]!=null && + elements[idx] instanceof Integer) { + sb.append('-'); + sb.append(elements[idx]); + ++idx; + } + sb.append("] "); + write(true,sb,elements); + } + } + return sb; + } + + private static boolean write(boolean first, StringBuilder sb, Object[] elements) { + String s; + for (Object o : elements) { + if (o!=null) { + if(o.getClass().isArray()) { + first = write(first,sb,(Object[])o); + } else if(o instanceof Throwable) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + ((Throwable)o).printStackTrace(ps); + sb.append(baos.toString()); + } else { + s=o.toString(); + if (first) { + first = false; + } else { + int l = s.length(); + if (l>0) { + switch(s.charAt(l-1)) { + case ' ': + break; + default: + sb.append(' '); + } + } + } + sb.append(s); + } + } + } + return first; + } + + @Override + public void log(Exception e, Object... elements) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + pw.println(); + e.printStackTrace(pw); + log(Level.ERROR,elements,sw.toString()); + } + + @Override + public void printf(Level level, String fmt, Object... elements) { + if (willLog(level)) { + log(level,String.format(fmt, elements)); + } + } + + @Override + public void setLogLevel(Level level) { + this.level = level.maskOf(); + } + + @Override + public boolean willLog(Level level) { + return level.inMask(this.level); + } + + @Override + public ClassLoader classLoader() { + return ClassLoader.getSystemClassLoader(); + } + + @Override + public String getProperty(String tag, String def) { + return props.getProperty(tag,def); + } + + @Override + public String decrypt(String encrypted, boolean anytext) throws IOException { + return (encrypted!=null && (anytext==true || encrypted.startsWith(Symm.ENC))) + ? symm.depass(encrypted) + : encrypted; + } + + public String encrypt(String unencrypted) throws IOException { + return Symm.ENC+symm.enpass(unencrypted); + } + + ////////////////// + // Additional + ////////////////// + public String getProperty(String tag) { + return props.getProperty(tag); + } + + + public Properties getProperties() { + return props; + } + + public void setProperty(String tag, String value) { + if (value!=null) { + props.put(tag, value); + if (Config.CADI_KEYFILE.equals(tag)) { + // reset decryption too + try { + symm = Symm.obtain(this); + } catch (CadiException e) { + System.err.append("FATAL ERROR: Cannot obtain Key Information."); + e.printStackTrace(System.err); + System.exit(1); + } + } + } + } + + public interface LogIt { + public void push(Level level, Object ... elements) ; + } + + private class StreamLogIt implements LogIt { + private PrintStream ps; + + public StreamLogIt(PrintStream ps) { + this.ps = ps; + } + @Override + public void push(Level level, Object ... elements) { + ps.println(buildMsg(level,elements)); + ps.flush(); + } + } + + public void set(LogIt logit) { + logIt = logit; + } + + public void setStreamLogIt(PrintStream ps) { + logIt = new StreamLogIt(ps); + } + + public String toString() { + return props.toString(); + } +} |