Allow encrypted property values 29/97229/6
authorjhh <jorge.hernandez-herrero@att.com>
Thu, 17 Oct 2019 02:30:26 +0000 (21:30 -0500)
committerJorge Hernandez <jorge.hernandez-herrero@att.com>
Thu, 24 Oct 2019 14:12:41 +0000 (14:12 +0000)
Issue-ID: POLICY-1945
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
Change-Id: I0317a6de838d99b579638252859e42fc49cedfa8
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
policy-management/src/main/java/org/onap/policy/drools/system/Main.java
policy-management/src/main/server/config/engine-system.properties
policy-management/src/main/server/config/engine.properties
policy-utils/src/main/java/org/onap/policy/drools/utils/CryptoCoderValueLookup.java [new file with mode: 0644]
policy-utils/src/main/java/org/onap/policy/drools/utils/EnvironmentVariableWithDefaultLookup.java [new file with mode: 0644]
policy-utils/src/main/java/org/onap/policy/drools/utils/PropertyUtil.java
policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java
policy-utils/src/test/resources/interpolation.properties

index 0e7b44f..3451587 100644 (file)
@@ -21,7 +21,9 @@
 package org.onap.policy.drools.system;
 
 import java.util.Properties;
+import org.apache.commons.lang3.StringUtils;
 import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
+import org.onap.policy.common.utils.security.CryptoUtils;
 import org.onap.policy.drools.persistence.SystemPersistenceConstants;
 import org.onap.policy.drools.properties.DroolsPropertyConstants;
 import org.onap.policy.drools.utils.PropertyUtil;
@@ -34,6 +36,10 @@ import org.slf4j.LoggerFactory;
  * Programmatic entry point to the management layer.
  */
 public class Main {
+    /**
+     * Symmetric Key to decode sensitive configuration data.
+     */
+    protected static final String SYSTEM_SYMM_KEY = "engine.symm.key";
 
     /** constructor (hides public default one). */
     private Main() {}
@@ -52,6 +58,9 @@ public class Main {
         /* system properties */
 
         for (Properties systemProperties : SystemPersistenceConstants.getManager().getSystemProperties()) {
+            if (!StringUtils.isBlank(systemProperties.getProperty(SYSTEM_SYMM_KEY))) {
+                PropertyUtil.setDefaultCryptoCoder(new CryptoUtils(systemProperties.getProperty(SYSTEM_SYMM_KEY)));
+            }
             PropertyUtil.setSystemProperties(systemProperties);
         }
 
index c1f21b8..a61df28 100644 (file)
@@ -30,8 +30,12 @@ com.sun.management.jmxremote.ssl=false
 
 # certs
 
-javax.net.ssl.trustStore=${env:POLICY_HOME}/etc/ssl/policy-truststore
-javax.net.ssl.trustStorePassword=${env:TRUSTSTORE_PASSWD}
+javax.net.ssl.trustStore=${envd:POLICY_HOME:/opt/app/policy}/etc/ssl/policy-truststore
+javax.net.ssl.trustStorePassword=${envd:TRUSTSTORE_PASSWD}
 
-javax.net.ssl.keyStore=${env:POLICY_HOME}/etc/ssl/policy-keystore
-javax.net.ssl.keyStorePassword=${env:KEYSTORE_PASSWD}
+javax.net.ssl.keyStore=${envd:POLICY_HOME:/opt/app/policy}/etc/ssl/policy-keystore
+javax.net.ssl.keyStorePassword=${envd:KEYSTORE_PASSWD}
+
+# symmetric key for sensitive configuration data
+
+engine.symm.key=${envd:SYMM_KEY}
\ No newline at end of file
index aa9b6d8..4f114d8 100644 (file)
 
 dmaap.source.topics=PDPD-CONFIGURATION
 
-dmaap.source.topics.PDPD-CONFIGURATION.servers=${env:DMAAP_SERVERS}
-dmaap.source.topics.PDPD-CONFIGURATION.effectiveTopic=${env:PDPD_CONFIGURATION_TOPIC}
-dmaap.source.topics.PDPD-CONFIGURATION.apiKey=${env:PDPD_CONFIGURATION_API_KEY}
-dmaap.source.topics.PDPD-CONFIGURATION.apiSecret=${env:PDPD_CONFIGURATION_API_SECRET}
-dmaap.source.topics.PDPD-CONFIGURATION.consumerGroup=${env:PDPD_CONFIGURATION_CONSUMER_GROUP}
-dmaap.source.topics.PDPD-CONFIGURATION.consumerInstance=${env:PDPD_CONFIGURATION_CONSUMER_INSTANCE}
+dmaap.source.topics.PDPD-CONFIGURATION.servers=${envd:DMAAP_SERVERS}
+dmaap.source.topics.PDPD-CONFIGURATION.effectiveTopic=${envd:PDPD_CONFIGURATION_TOPIC}
+dmaap.source.topics.PDPD-CONFIGURATION.apiKey=${envd:PDPD_CONFIGURATION_API_KEY}
+dmaap.source.topics.PDPD-CONFIGURATION.apiSecret=${envd:PDPD_CONFIGURATION_API_SECRET}
+dmaap.source.topics.PDPD-CONFIGURATION.consumerGroup=${envd:PDPD_CONFIGURATION_CONSUMER_GROUP}
+dmaap.source.topics.PDPD-CONFIGURATION.consumerInstance=${envd:PDPD_CONFIGURATION_CONSUMER_INSTANCE}
 dmaap.source.topics.PDPD-CONFIGURATION.managed=false
 dmaap.source.topics.PDPD-CONFIGURATION.https=true
 
 http.server.services=SECURED-CONFIG
 
-http.server.services.SECURED-CONFIG.host=${env:TELEMETRY_HOST}
+http.server.services.SECURED-CONFIG.host=${envd:TELEMETRY_HOST}
 http.server.services.SECURED-CONFIG.port=9696
-http.server.services.SECURED-CONFIG.userName=${env:TELEMETRY_USER}
-http.server.services.SECURED-CONFIG.password=${env:TELEMETRY_PASSWORD}
+http.server.services.SECURED-CONFIG.userName=${envd:TELEMETRY_USER}
+http.server.services.SECURED-CONFIG.password=${envd:TELEMETRY_PASSWORD}
 http.server.services.SECURED-CONFIG.restPackages=org.onap.policy.drools.server.restful
 http.server.services.SECURED-CONFIG.managed=false
 http.server.services.SECURED-CONFIG.swagger=true
 http.server.services.SECURED-CONFIG.https=true
-http.server.services.SECURED-CONFIG.aaf=${env:AAF}
+http.server.services.SECURED-CONFIG.aaf=${envd:AAF:false}
 http.server.services.SECURED-CONFIG.serialization.provider=org.onap.policy.common.gson.JacksonHandler,org.onap.policy.common.endpoints.http.server.YamlJacksonHandler
 
-aaf.namespace=${env:AAF_NAMESPACE}
-aaf.root.permission=${env:AAF_NAMESPACE}.pdpd
+aaf.namespace=${envd:AAF_NAMESPACE:false}
+aaf.root.permission=${envd:AAF_NAMESPACE:org.onap.policy}.pdpd
+
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/CryptoCoderValueLookup.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/CryptoCoderValueLookup.java
new file mode 100644 (file)
index 0000000..9d4a882
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.drools.utils;
+
+import org.apache.commons.configuration2.interpol.Lookup;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.policy.common.utils.security.CryptoCoder;
+
+/**
+ * Crypto Coder value look up.  Syntax:  ${enc:encoded-value}.
+ */
+public class CryptoCoderValueLookup implements Lookup {
+
+    protected final CryptoCoder cryptoCoder;
+
+    /**
+     * Crypto Coder Lookup.
+     *
+     * @param crypto crypto coder
+     */
+    public CryptoCoderValueLookup(CryptoCoder crypto) {
+        this.cryptoCoder = crypto;
+    }
+
+    @Override
+    public String lookup(String key) {
+        if (StringUtils.isBlank(key)) {
+            return null;
+        }
+
+        return cryptoCoder.decrypt(PropertyUtil.CRYPTO_CODER_PROPERTY_PREFIX + ":" + key);
+    }
+}
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/EnvironmentVariableWithDefaultLookup.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/EnvironmentVariableWithDefaultLookup.java
new file mode 100644 (file)
index 0000000..e0d3e38
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.drools.utils;
+
+import com.google.common.base.Splitter;
+import java.util.List;
+import org.apache.commons.configuration2.interpol.Lookup;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Environment Variable with a default value.   The syntax is
+ * ${envd:variable-name:default-value}.
+ */
+public class EnvironmentVariableWithDefaultLookup implements Lookup {
+
+    @Override
+    public String lookup(String key) {
+        if (StringUtils.isBlank(key)) {
+            return null;
+        }
+
+        List<String> envWithDefault =
+            Splitter.on(":").trimResults().omitEmptyStrings().splitToList(key);
+        if (envWithDefault.isEmpty()) {
+            return StringUtils.EMPTY;
+        }
+
+        String envVar = System.getenv(envWithDefault.get(0));
+        if (StringUtils.isNotEmpty(envVar)) {
+            return envVar;
+        }
+
+        if (envWithDefault.size() > 1) {
+            return String.join(":", envWithDefault.subList(1, envWithDefault.size()));
+        }
+
+        return StringUtils.EMPTY;
+    }
+}
index 8594995..0b49993 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * policy-utils
+ * ONAP
  * ================================================================================
  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
@@ -30,9 +30,10 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
-
+import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.ConfigurationConverter;
 import org.apache.commons.configuration2.SystemConfiguration;
+import org.onap.policy.common.utils.security.CryptoCoder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,6 +42,8 @@ import org.slf4j.LoggerFactory;
  * file, and optionally get notifications of future changes.
  */
 public class PropertyUtil {
+    public static final String ENV_WITH_DEFAULT_PROPERTY_PREFIX = "envd";
+    public static final String CRYPTO_CODER_PROPERTY_PREFIX = "enc";
 
     // timer thread used for polling for property file changes
     private static Timer timer = null;
@@ -51,10 +54,17 @@ public class PropertyUtil {
 
     private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class.getName());
 
+    private static volatile CryptoCoder cryptoCoder;
+
     /**
-     * Read in a properties file.  Variable interpolation is performed by using
-     * apache commons configuration2 library.   This allows for embedding system properties,
-     * constants, and environment variables in property files.
+     * Sets a default Crypto Coder.
+     */
+    public static void setDefaultCryptoCoder(CryptoCoder cryptoCoder) {
+        PropertyUtil.cryptoCoder = cryptoCoder;
+    }
+
+    /**
+     * Read in a properties file and performs variable interpolation.
      *
      * @param file the properties file
      * @return a Properties object, containing the associated properties
@@ -63,22 +73,22 @@ public class PropertyUtil {
      *     a problem loading the properties file.
      */
     public static Properties getProperties(File file) throws IOException {
-        // create an InputStream (may throw a FileNotFoundException)
-        Properties rval = new Properties();
-        try (FileInputStream fis = new FileInputStream(file)) {
-            // create the properties instance
-
-            // load properties (may throw an IOException)
-            rval.load(fis);
-        }
+        return getInterpolatedProperties(getPropertiesFile(file));
+    }
 
-        /*
-         * Return properties file with environment variables interpolated.
-         * It is necessary to construct the object in this fashion and avoid
-         * builders since they use the commons-beanutils (optional) library that has been
-         * flagged as insecured.
-         */
-        return getInterpolatedProperties(rval);
+    /**
+     * Reads a property files and performs variable interpolation.  It uses a
+     * crypto coder to interpolate encrypted sensitive data.
+     *
+     * @param file the properties file
+     * @param cryptoCoder a custom CryptoCoder implementation
+     * @return a Properties object, containing the associated properties
+     * @throws IOException - subclass 'FileNotFoundException' if the file
+     *     does not exist or can't be opened, and 'IOException' if there is
+     *     a problem loading the properties file.
+     */
+    public static Properties getProperties(File file, CryptoCoder cryptoCoder) throws IOException {
+        return getInterpolatedProperties(getPropertiesFile(file), cryptoCoder);
     }
 
     /**
@@ -88,12 +98,27 @@ public class PropertyUtil {
      * @return a Properties object, containing the associated properties
      * @throws IOException - subclass 'FileNotFoundException' if the file
      *     does not exist or can't be opened, and 'IOException' if there is
-     *     a problem loading the properties file.
+     *     a problem loading the properties file
      */
     public static Properties getProperties(String fileName) throws IOException {
         return getProperties(new File(fileName));
     }
 
+    /**
+     * Reads a property files and performs variable interpolation.  It uses a
+     * crypto coder to interpolate encrypted sensitive data.
+     *
+     * @param fileName the properties file name
+     * @param cryptoCoder a custom CryptoCoder implementation
+     * @return a Properties object, containing the associated properties
+     * @throws IOException - subclass 'FileNotFoundException' if the file
+     *     does not exist or can't be opened, and 'IOException' if there is
+     *     a problem loading the properties file
+     */
+    public static Properties getProperties(String fileName, CryptoCoder cryptoCoder) throws IOException {
+        return getProperties(new File(fileName), cryptoCoder);
+    }
+
     /**
      * Read in a properties file, and register for update notifications.
      * NOTE: it is possible that the first callback will occur while this
@@ -110,8 +135,7 @@ public class PropertyUtil {
      *     does not exist or can't be opened, and 'IOException' if there is
      *     a problem loading the properties file.
      */
-    public static Properties getProperties(File file, Listener listener)
-        throws IOException {
+    public static Properties getProperties(File file, Listener listener) throws IOException {
         File propFile = file;
         if (listener == null) {
             // no listener specified -- just fetch the properties
@@ -151,19 +175,63 @@ public class PropertyUtil {
      *     does not exist or can't be opened, and 'IOException' if there is
      *     a problem loading the properties file.
      */
-    public static Properties getProperties(String fileName, Listener listener)
-        throws IOException {
+    public static Properties getProperties(String fileName, Listener listener) throws IOException {
         return getProperties(new File(fileName), listener);
     }
 
     /**
-     * gets interpolated properties from a properties object.
+     * Get an interpolated properties object from a properties one.
      *
-     * @param properties object
-     * @return properties
+     * @param properties non-interpolated properties object
+     * @return Properties - interpolated properties object
      */
     public static Properties getInterpolatedProperties(Properties properties) {
-        return ConfigurationConverter.getProperties(ConfigurationConverter.getConfiguration(properties));
+        return getInterpolatedProperties(properties, cryptoCoder);
+    }
+
+    /**
+     * Get an interpolated properties object from a properties one.
+     *
+     * @param properties non-interpolated properties object
+     * @param cryptoCoder crypto coder
+     * @return Properties - interpolated properties object
+     */
+    public static Properties getInterpolatedProperties(Properties properties, CryptoCoder cryptoCoder) {
+        Configuration config = ConfigurationConverter.getConfiguration(properties);
+        config.getInterpolator()
+            .registerLookup(ENV_WITH_DEFAULT_PROPERTY_PREFIX, new EnvironmentVariableWithDefaultLookup());
+
+        if (cryptoCoder == null) {
+            return ConfigurationConverter.getProperties(config);
+        }
+
+        config.getInterpolator().registerLookup(CRYPTO_CODER_PROPERTY_PREFIX, new CryptoCoderValueLookup(cryptoCoder));
+        Properties props = ConfigurationConverter.getProperties(config);
+        props.stringPropertyNames().forEach(key -> {
+            props.setProperty(key, cryptoCoder.decrypt(props.getProperty(key)));
+        });
+        return props;
+    }
+
+    /**
+     * Read in a properties file from disk.
+     *
+     * @param file the properties file
+     * @return a Properties object, containing the associated properties
+     * @throws IOException - subclass 'FileNotFoundException' if the file
+     *     does not exist or can't be opened, and 'IOException' if there is
+     *     a problem loading the properties file.
+     */
+    protected static Properties getPropertiesFile(File file) throws IOException {
+        // create an InputStream (may throw a FileNotFoundException)
+        Properties rval = new Properties();
+        try (FileInputStream fis = new FileInputStream(file)) {
+            // create the properties instance
+
+            // load properties (may throw an IOException)
+            rval.load(fis);
+        }
+        return rval;
     }
 
     /**
@@ -172,8 +240,20 @@ public class PropertyUtil {
      * @param properties properties file
      */
     public static void setSystemProperties(Properties properties) {
-        Properties interpolatedProps = getInterpolatedProperties(properties);
-        SystemConfiguration.setSystemProperties(ConfigurationConverter.getConfiguration(interpolatedProps));
+        SystemConfiguration
+            .setSystemProperties(ConfigurationConverter
+                .getConfiguration(getInterpolatedProperties(properties)));
+    }
+
+    /**
+     * sets system properties from a properties file.
+     *
+     * @param properties properties file
+     */
+    public static void setSystemProperties(Properties properties, CryptoCoder cryptoCoder) {
+        SystemConfiguration
+            .setSystemProperties(ConfigurationConverter
+                .getConfiguration(getInterpolatedProperties(properties, cryptoCoder)));
     }
 
     /* ============================================================ */
index f05974c..006d709 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * policy-utils
+ * ONAP
  * ================================================================================
  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
@@ -30,22 +30,38 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
-
+import org.apache.commons.lang3.StringUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.onap.policy.common.utils.security.CryptoUtils;
 import org.onap.policy.drools.utils.logging.LoggerUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class PropertyUtilTest {
 
-    private static final Logger logger = LoggerFactory.getLogger(PropertyUtilTest.class);
     private static final String INTERPOLATION_PROPERTIES = "src/test/resources/interpolation.properties";
+    private static final String INTERPOLATION_CRYPTO_KEY = "MTIzNDU2Nzg5MDEyMzQ1Ng==";
+    private static final String INTERPOLATION_PLAINTEXT = "HelloWorld";
+    private static final String INTERPOLATION_ENVD_DEFAULT_VALUE = "default";
+    private static final String INTERPOLATION_ENC_HELLOWORLD = "enc:hcI2XVX+cxPz/6rlbebkWpCFF6WPbBtT7iJRr2VHUkA=";
+    private static final String INTERPOLATION_ENC_HELLOWORLD_VAR = "${" + INTERPOLATION_ENC_HELLOWORLD + "}";
+
     private static final String INTERPOLATION_NO = "interpolation.no";
     private static final String INTERPOLATION_ENV = "interpolation.env";
+    private static final String INTERPOLATION_ENVD = "interpolation.envd";
     private static final String INTERPOLATION_CONST = "interpolation.const";
     private static final String INTERPOLATION_SYS = "interpolation.sys";
+    private static final String INTERPOLATION_ENVD_NONE = "interpolation.envd.none";
+    private static final String INTERPOLATION_ENVD_DEFAULT = "interpolation.envd.default";
+    private static final String INTERPOLATION_ENVD_NO_DEFAULT = "interpolation.envd.nodefault";
+    private static final String INTERPOLATION_ENC = "interpolation.enc";
+    private static final String INTERPOLATION_ENC2 = "interpolation.enc2";
+    private static final String INTERPOLATION_ENVENC = "interpolation.envenc";
+
+
+    private static final Logger logger = LoggerFactory.getLogger(PropertyUtilTest.class);
 
     private static File directory = null;
 
@@ -136,25 +152,85 @@ public class PropertyUtilTest {
         // they should match
         assertEquals(prop1, prop2);
 
-        Properties prop3 = PropertyUtil.getProperties(INTERPOLATION_PROPERTIES);
+        // tests performed in sequence
+        testGetCryptoCoderArg();
+        testGetNoCryptoProps();
+        testGetDefaultCryptoProps();
+        testGetNoCryptoSystemProps();
+        testGetCryptoArgSystemProps();
+        testGetDefaultCryptoSystemProps();
 
-        assertEquals("no", prop3.getProperty(INTERPOLATION_NO));
-        assertEquals(System.getenv("HOME"), prop3.getProperty(INTERPOLATION_ENV));
-        assertEquals(LoggerUtil.ROOT_LOGGER, prop3.getProperty(INTERPOLATION_CONST));
-        assertEquals(System.getProperty("user.home"), prop3.getProperty(INTERPOLATION_SYS));
+    }
 
-        Properties prop4 = new Properties();
-        prop4.put(INTERPOLATION_NO, "no");
-        prop4.put(INTERPOLATION_ENV, "${env:HOME}");
-        prop4.put(INTERPOLATION_CONST, "${const:org.onap.policy.drools.utils.logging.LoggerUtil.ROOT_LOGGER}");
-        prop4.put(INTERPOLATION_SYS, "${sys:user.home}");
+    private void testGetDefaultCryptoSystemProps() throws IOException {
+        // system properties + default crypto coder
+        PropertyUtil.setDefaultCryptoCoder(new CryptoUtils(INTERPOLATION_CRYPTO_KEY));
+        PropertyUtil.setSystemProperties(PropertyUtil.getPropertiesFile(new File(INTERPOLATION_PROPERTIES)));
+        assertPropInterpolation(System.getProperties());
+        assertPropEncInterpolation(System.getProperties());
+    }
 
-        PropertyUtil.setSystemProperties(prop4);
+    private void testGetCryptoArgSystemProps() throws IOException {
+        // system properties + crypto coder passed in
+        PropertyUtil
+            .setSystemProperties(PropertyUtil
+                .getPropertiesFile(new File(INTERPOLATION_PROPERTIES)), new CryptoUtils(INTERPOLATION_CRYPTO_KEY));
+        assertPropInterpolation(System.getProperties());
+        assertPropEncInterpolation(System.getProperties());
+    }
+
+    private void testGetNoCryptoSystemProps() throws IOException {
+        /* system properties + no crypto coder */
+        PropertyUtil.setDefaultCryptoCoder(null);
+        PropertyUtil.setSystemProperties(PropertyUtil.getPropertiesFile(new File(INTERPOLATION_PROPERTIES)));
+        assertPropInterpolation(System.getProperties());
+        assertPropNoEncInterpolation(System.getProperties());
+    }
+
+    private void testGetDefaultCryptoProps() throws IOException {
+        /* properties + default crypto coder */
+        PropertyUtil.setDefaultCryptoCoder(new CryptoUtils(INTERPOLATION_CRYPTO_KEY));
+        Properties props = PropertyUtil.getProperties(INTERPOLATION_PROPERTIES);
+        assertPropInterpolation(props);
+        assertPropEncInterpolation(props);
+    }
+
+    private void testGetNoCryptoProps() throws IOException {
+        /* properties + no crypto coder */
+        Properties props = PropertyUtil.getProperties(INTERPOLATION_PROPERTIES);
+        assertPropInterpolation(props);
+        assertPropNoEncInterpolation(props);
+    }
+
+    private void testGetCryptoCoderArg() throws IOException {
+        /* properties + crypto coder passed in */
+        Properties props =
+            PropertyUtil.getProperties(INTERPOLATION_PROPERTIES, new CryptoUtils(INTERPOLATION_CRYPTO_KEY));
+        assertPropInterpolation(props);
+        assertPropEncInterpolation(props);
+    }
+
+    private void assertPropNoEncInterpolation(Properties props) {
+        assertEquals(INTERPOLATION_ENC_HELLOWORLD_VAR, props.getProperty(INTERPOLATION_ENC));
+        assertEquals(INTERPOLATION_ENC_HELLOWORLD, props.getProperty(INTERPOLATION_ENC2));
+        assertEquals(INTERPOLATION_ENC_HELLOWORLD, props.getProperty(INTERPOLATION_ENVENC));
+    }
+
+    private void assertPropEncInterpolation(Properties props) {
+        assertEquals(INTERPOLATION_PLAINTEXT, props.getProperty(INTERPOLATION_ENC));
+        assertEquals(INTERPOLATION_PLAINTEXT, props.getProperty(INTERPOLATION_ENC2));
+        assertEquals(INTERPOLATION_PLAINTEXT, props.getProperty(INTERPOLATION_ENVENC));
+    }
 
-        assertEquals("no", System.getProperty(INTERPOLATION_NO));
-        assertEquals(System.getenv("HOME"), System.getProperty(INTERPOLATION_ENV));
-        assertEquals(LoggerUtil.ROOT_LOGGER, System.getProperty(INTERPOLATION_CONST));
-        assertEquals(System.getProperty("user.home"), System.getProperty(INTERPOLATION_SYS));
+    private void assertPropInterpolation(Properties props) {
+        assertEquals("no", props.getProperty(INTERPOLATION_NO));
+        assertEquals(System.getenv("HOME"), props.getProperty(INTERPOLATION_ENV));
+        assertEquals(System.getenv("HOME"), props.getProperty(INTERPOLATION_ENVD));
+        assertEquals(StringUtils.EMPTY, props.getProperty(INTERPOLATION_ENVD_NONE));
+        assertEquals(StringUtils.EMPTY, props.getProperty(INTERPOLATION_ENVD_NO_DEFAULT));
+        assertEquals(LoggerUtil.ROOT_LOGGER, props.getProperty(INTERPOLATION_CONST));
+        assertEquals(System.getProperty("user.home"), props.getProperty(INTERPOLATION_SYS));
+        assertEquals(INTERPOLATION_ENVD_DEFAULT_VALUE, props.getProperty(INTERPOLATION_ENVD_DEFAULT));
     }
 
     /**
index 6655433..2145fb6 100644 (file)
@@ -2,3 +2,10 @@ interpolation.no=no
 interpolation.env=${env:HOME}
 interpolation.const=${const:org.onap.policy.drools.utils.logging.LoggerUtil.ROOT_LOGGER}
 interpolation.sys=${sys:user.home}
+interpolation.envd=${envd:HOME}
+interpolation.envd.default=${envd:BLAH:default}
+interpolation.envd.none=${envd:BLAH}
+interpolation.envd.nodefault=${envd:BLAH:}
+interpolation.enc=${enc:hcI2XVX+cxPz/6rlbebkWpCFF6WPbBtT7iJRr2VHUkA=}
+interpolation.enc2=enc:hcI2XVX+cxPz/6rlbebkWpCFF6WPbBtT7iJRr2VHUkA=
+interpolation.envenc=${envd:HELLOWORLD:enc:hcI2XVX+cxPz/6rlbebkWpCFF6WPbBtT7iJRr2VHUkA=}
\ No newline at end of file