[POLICY-66] self-contained features support

installation/enable/disable of self contained package features:

Feature 3rd party dependencies, configuration files, and
custom installation scripts do not need to be packaged within the policy
core base to be used.

Change-Id: I35a472e63bd0f9f7aa6cd0c112d41d2b4604a892
Signed-off-by: Jorge Hernandez <jh1730@att.com>
diff --git a/feature-eelf/src/assembly/assemble_zip.xml b/feature-eelf/src/assembly/assemble_zip.xml
index 001d3c6..005d038 100644
--- a/feature-eelf/src/assembly/assemble_zip.xml
+++ b/feature-eelf/src/assembly/assemble_zip.xml
@@ -35,33 +35,42 @@
 	<fileSets>
 		<fileSet>
 			<directory>target</directory>
-			<outputDirectory>lib/opt</outputDirectory>
+			<outputDirectory>lib/feature</outputDirectory>
 			<includes>
 				<include>feature-eelf-${project.version}.jar</include>
 			</includes>
 		</fileSet>
 		<fileSet>
-			<directory>target/assembly/</directory>
-			<outputDirectory>.</outputDirectory>
-			<excludes/>
-		</fileSet>
-		<fileSet>
-			<directory>.</directory>
-			<outputDirectory>lib</outputDirectory>
+			<directory>target/assembly/lib</directory>
+			<outputDirectory>lib/dependencies</outputDirectory>
 			<includes>
 				<include>*.jar</include>
 			</includes>
 		</fileSet>
 		<fileSet>
-			<directory>src/main/install/config</directory>
+			<directory>src/main/feature/config</directory>
 			<outputDirectory>config</outputDirectory>
+			<fileMode>0644</fileMode>
+			<excludes/>
 		</fileSet>
 		<fileSet>
-			<directory>src/main/install/bin</directory>
+			<directory>src/main/feature/bin</directory>
 			<outputDirectory>bin</outputDirectory>
 			<fileMode>0744</fileMode>
 			<excludes/>
 		</fileSet>
+		<fileSet>
+			<directory>src/main/feature/db</directory>
+			<outputDirectory>db</outputDirectory>
+			<fileMode>0744</fileMode>
+			<excludes/>
+		</fileSet>
+		<fileSet>
+			<directory>src/main/feature/install</directory>
+			<outputDirectory>install</outputDirectory>
+			<fileMode>0744</fileMode>
+			<excludes/>
+		</fileSet>
 	</fileSets>
 
 </assembly>
diff --git a/feature-eelf/src/main/install/config/logback.xml b/feature-eelf/src/main/feature/config/logback-eelf.xml
similarity index 96%
rename from feature-eelf/src/main/install/config/logback.xml
rename to feature-eelf/src/main/feature/config/logback-eelf.xml
index f429562..7c2725d 100644
--- a/feature-eelf/src/main/install/config/logback.xml
+++ b/feature-eelf/src/main/feature/config/logback-eelf.xml
@@ -18,7 +18,7 @@
   ============LICENSE_END=========================================================
   -->
 
-<configuration scan="true" scanPeriod="30 seconds" debug="false">
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
 
 	<property name="errorLogName" value="error" />
 	<property name="metricsLogName" value="metrics" />
@@ -33,9 +33,10 @@
 	<property name="defaultAuditPattern"
 		value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
 	<property name="defaultErrorPattern"
-		value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{RequestId}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ErrorCategory}|%X{ErrorCode}|%X{ErrorDesciption}|%msg%n" />
+		value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{RequestId}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ErrorCategory}|%X{ErrorCode}|%X{ErrorDesciption}|%msg%replace(%xException){'\n',' - '}%nopex%n" />	
+		
 	<property name="networkPattern" value="[%d|%t]%m%n" />
-	<property name="debugPattern" value="[%date|%level|%logger{0}|%thread] %msg%n" />
+	<property name="debugPattern" value="[%date|%level|%logger{0}|%thread] %replace(%msg){'\n', ' '}%n" />
 
 	<property name="logDirectory" value="logs/Policy" />
 	<property name="debugLogDirectory" value="logs/Policy" />
@@ -169,7 +170,7 @@
 		<appender-ref ref="asyncEELFError" />
 	</logger>
 
-	<logger name="com.att.eelf.debug" level="info" additivity="false">
+	<logger name="com.att.eelf.debug" level="info">
 		<appender-ref ref="asyncEELFDebug" />
 	</logger>
 
diff --git a/feature-eelf/src/main/feature/install/disable b/feature-eelf/src/main/feature/install/disable
new file mode 100644
index 0000000..1eeb090
--- /dev/null
+++ b/feature-eelf/src/main/feature/install/disable
@@ -0,0 +1,33 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# ONAP POLICY
+# ================================================================================
+# Copyright (C) 2017 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=========================================================
+##
+
+if [[ "${DEBUG}" == "y" ]]; then
+	set -x
+fi
+
+SYSTEM_PROPS="${POLICY_HOME}"/config/system.properties
+
+if [[ -f ${SYSTEM_PROPS} && -r ${SYSTEM_PROPS} ]]; then
+	if grep -q "^logback.configurationFile=.*$" "${SYSTEM_PROPS}"; then
+		sed -i -e "s|^logback.configurationFile=.*$|logback.configurationFile=config/logback.xml|" "${SYSTEM_PROPS}"
+	fi
+fi
\ No newline at end of file
diff --git a/feature-eelf/src/main/feature/install/enable b/feature-eelf/src/main/feature/install/enable
new file mode 100644
index 0000000..55a2b99
--- /dev/null
+++ b/feature-eelf/src/main/feature/install/enable
@@ -0,0 +1,35 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# ONAP POLICY
+# ================================================================================
+# Copyright (C) 2017 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=========================================================
+##
+
+if [[ "${DEBUG}" == "y" ]]; then
+	set -x
+fi
+
+SYSTEM_PROPS="${POLICY_HOME}"/config/system.properties
+
+if [[ -f ${SYSTEM_PROPS} && -r ${SYSTEM_PROPS} ]]; then
+	if grep -q "^logback.configurationFile=.*$" "${SYSTEM_PROPS}"; then
+		sed -i -e "s|^logback.configurationFile=.*$|logback.configurationFile=config/logback-eelf.xml|" "${SYSTEM_PROPS}"
+	else
+		echo "logback.configurationFile=config/logback-eelf.xml" >> "${SYSTEM_PROPS}"
+	fi
+fi
\ No newline at end of file
diff --git a/feature-eelf/src/main/install/config/policyLogger.properties b/feature-eelf/src/main/install/config/policyLogger.properties
deleted file mode 100644
index d898725..0000000
--- a/feature-eelf/src/main/install/config/policyLogger.properties
+++ /dev/null
@@ -1,49 +0,0 @@
-###
-# ============LICENSE_START=======================================================
-# feature-eelf
-# ================================================================================
-# Copyright (C) 2017 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=========================================================
-###
-
-################################### Set concurrentHashMap and timer info  #######################
-#Timer initial delay and the delay between in milliseconds before task is to be execute.
-timer.delay.time=1000
-#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions.
-check.interval= 30000
-#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds. 
-event.expired.time=86400
-#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed 
-#to remove all expired records from this concurrentHashMap.
-concurrentHashMap.limit=5000
-#Size of the concurrentHashMap - when its size drops to this point, stop the Timer
-stop.check.point=2500
-################################### Set logging format #############################################
-# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println
-logger.type=EELF
-#################################### Set level for EELF or SYSTEMOUT logging ##################################
-# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all 
-# Set override flag. Set TRUE for override the level setups in logback.xml. Set FALSE for using the level setups of logback.xml
-override.logback.level.setup=FALSE
-debugLogger.level=INFO
-# Set level for metrics file. Set OFF to disable; set ON to enable
-metricsLogger.level=ON
-# Set level for error file. Set OFF to disable; set ON to enable
-error.level=ON
-# Set level for audit file. Set OFF to disable; set ON to enable
-audit.level=ON
-#################################### Set Policy Component ##################################
-# Set DROOLS for drools PDP. Set XACML to xacml PDP
-policy.component=DROOLS
diff --git a/feature-eelf/src/main/java/org/openecomp/policy/drools/eelf/EelfFeature.java b/feature-eelf/src/main/java/org/openecomp/policy/drools/eelf/EelfFeature.java
index de39f3a..83e7a4b 100644
--- a/feature-eelf/src/main/java/org/openecomp/policy/drools/eelf/EelfFeature.java
+++ b/feature-eelf/src/main/java/org/openecomp/policy/drools/eelf/EelfFeature.java
@@ -23,63 +23,46 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
+import org.openecomp.policy.common.logging.eelf.Configuration;
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
 import org.openecomp.policy.common.logging.flexlogger.Logger;
 import org.openecomp.policy.drools.features.PolicyEngineFeatureAPI;
 import org.openecomp.policy.drools.system.Main;
 import org.openecomp.policy.drools.system.PolicyEngine;
 
+/**
+ * Feature EELF : Enables EELF Logging Libraries 
+ */
 public class EelfFeature implements PolicyEngineFeatureAPI {
-	
-	/**
-	 * EELF logback configuration path system property
-	 */
-	public static final String EELF_LOGBACK_PATH_SYSTEM_PROPERTY = "com.att.eelf.logging.file";
-	
-	/**
-	 * EELF logback configuration path value
-	 */
-	public static final String EELF_LOGBACK_PATH_DEFAULT = "config";
-	
-	/**
-	 * EELF logback configuration file system property
-	 */
-	public static final String EELF_LOGBACK_FILE_SYSTEM_PROPERTY = "com.att.eelf.logging.path";
-	
-	/**
-	 * EELF logback configuration file default value
-	 */
-	public static final String EELF_LOGBACK_FILE_DEFAULT = "logback.xml";
 
 	@Override
 	public boolean beforeBoot(PolicyEngine engine, String cliArgs[]) {
 		
 		String logback = System.getProperty(Main.LOGBACK_CONFIGURATION_FILE_SYSTEM_PROPERTY, 
-				                            Main.LOGBACK_CONFIGURATION_FILE_DEFAULT);
-		
+				                            Main.LOGBACK_CONFIGURATION_FILE_DEFAULT);		
 		Path logbackPath = Paths.get(logback);
 		
-		if (System.getProperty(EELF_LOGBACK_PATH_SYSTEM_PROPERTY) == null)
-			System.setProperty(EELF_LOGBACK_PATH_SYSTEM_PROPERTY, logbackPath.getFileName().toString());
-		
-		if (System.getProperty(EELF_LOGBACK_FILE_SYSTEM_PROPERTY) == null)
-			System.setProperty(EELF_LOGBACK_FILE_SYSTEM_PROPERTY, 
+		if (System.getProperty(Configuration.PROPERTY_LOGGING_FILE_PATH) == null)
+			System.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, 
 					           logbackPath.toAbsolutePath().getParent().toString());
 		
+		if (System.getProperty(Configuration.PROPERTY_LOGGING_FILE_NAME) == null)
+			System.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, 
+					           logbackPath.getFileName().toString());
+		
 		Logger logger = FlexLogger.getLogger(this.getClass(), true);
 		
-		logger.warn("EELF/Common Frameworks Logging Enabled");
 		if (logger.isInfoEnabled()) {
-			logger.info("EELFFeature: Property " + Main.LOGBACK_CONFIGURATION_FILE_SYSTEM_PROPERTY + "=" + 
+			logger.info("eelf-feature: Property " + Main.LOGBACK_CONFIGURATION_FILE_SYSTEM_PROPERTY + "=" + 
 			            System.getProperty(Main.LOGBACK_CONFIGURATION_FILE_SYSTEM_PROPERTY));
-			logger.info("EELFFeature: Property " + EELF_LOGBACK_PATH_SYSTEM_PROPERTY + "=" + 
-		                System.getProperty(EELF_LOGBACK_PATH_SYSTEM_PROPERTY));
-			logger.info("EELFFeature: Property " + EELF_LOGBACK_FILE_SYSTEM_PROPERTY + "=" + 
-	                    System.getProperty(EELF_LOGBACK_FILE_SYSTEM_PROPERTY));
+			logger.info("eelf-feature: Property " + Configuration.PROPERTY_LOGGING_FILE_PATH + "=" + 
+		                System.getProperty(Configuration.PROPERTY_LOGGING_FILE_PATH));
+			logger.info("eelf-feature: Property " + Configuration.PROPERTY_LOGGING_FILE_NAME + "=" + 
+	                    System.getProperty(Configuration.PROPERTY_LOGGING_FILE_NAME));
 		}
 		
 		return false;
-	};
+	}
 	
 	@Override
 	public int getSequenceNumber() {
diff --git a/feature-eelf/src/test/java/org/openecomp/policy/drools/eelf/test/EElfTest.java b/feature-eelf/src/test/java/org/openecomp/policy/drools/eelf/test/EElfTest.java
index 2ded0d0..6023622 100644
--- a/feature-eelf/src/test/java/org/openecomp/policy/drools/eelf/test/EElfTest.java
+++ b/feature-eelf/src/test/java/org/openecomp/policy/drools/eelf/test/EElfTest.java
@@ -48,7 +48,7 @@
 	/**
 	 * logback configuration location
 	 */
-	public final static String LOGBACK_CONFIGURATION_FILE_DEFAULT = "src/main/install/config/logback.xml";
+	public final static String LOGBACK_CONFIGURATION_FILE_DEFAULT = "src/main/feature/config/logback-eelf.xml";
 	
 	/**
 	 * SLF4J Logger
@@ -73,15 +73,15 @@
 	/**
 	 * Assert Log Levels are the same between an EELF Logger and an SLF4J Logger
 	 * 
-	 * @param eelfAuditLogger
-	 * @param slf4jAuditLogger
+	 * @param eelfLogger EELF Logger
+	 * @param slf4jLogger SLF4J Logger
 	 */
-	protected void assertLogLevels(EELFLogger eelfAuditLogger, Logger slf4jAuditLogger) {
-		assertTrue(slf4jAuditLogger.isDebugEnabled() == eelfAuditLogger.isDebugEnabled());
-		assertTrue(slf4jAuditLogger.isInfoEnabled() == eelfAuditLogger.isInfoEnabled());
-		assertTrue(slf4jAuditLogger.isErrorEnabled() == eelfAuditLogger.isErrorEnabled());
-		assertTrue(slf4jAuditLogger.isWarnEnabled() == eelfAuditLogger.isWarnEnabled());
-		assertTrue(slf4jAuditLogger.isTraceEnabled() == eelfAuditLogger.isTraceEnabled());
+	protected void assertLogLevels(EELFLogger eelfLogger, Logger slf4jLogger) {
+		assertTrue(slf4jLogger.isDebugEnabled() == eelfLogger.isDebugEnabled());
+		assertTrue(slf4jLogger.isInfoEnabled() == eelfLogger.isInfoEnabled());
+		assertTrue(slf4jLogger.isErrorEnabled() == eelfLogger.isErrorEnabled());
+		assertTrue(slf4jLogger.isWarnEnabled() == eelfLogger.isWarnEnabled());
+		assertTrue(slf4jLogger.isTraceEnabled() == eelfLogger.isTraceEnabled());
 	}
 	
 	@Test
@@ -117,14 +117,22 @@
 		EELFLogger eelfAuditLogger = EELFManager.getInstance().getAuditLogger();
 		Logger slf4jAuditLogger = org.slf4j.LoggerFactory.getLogger(Configuration.AUDIT_LOGGER_NAME);
 		org.openecomp.policy.common.logging.flexlogger.Logger flexLogger = 
-												FlexLogger.getLogger(EElfTest.class);
+												FlexLogger.getLogger(EElfTest.class, true);
 		
-		/* generate an audit entry through both logs */
+		/* generate an error entry */
+		
+		Exception testException = new IllegalStateException("exception test");
+		flexLogger.error("flex-logger exception", testException);
+		EELFManager.getInstance().getErrorLogger().error("eelf-logger exception", testException);
+		org.slf4j.LoggerFactory.getLogger(Configuration.ERROR_LOGGER_NAME).error("slf4j-logger", testException);
+
+		
+		/* generate an audit entry through all logs */
 		
 		flexLogger.audit("flexlogger audit");
 		eelfAuditLogger.info("eelf audit");
 		slf4jAuditLogger.info("slf4j audit");
-
+		
 		/* check log levels in eelf and standard slf4j  change in both directions */
 		
 		/* eelf initiated */
diff --git a/feature-healthcheck/pom.xml b/feature-healthcheck/pom.xml
index 58ea768..12c6b4d 100644
--- a/feature-healthcheck/pom.xml
+++ b/feature-healthcheck/pom.xml
@@ -82,8 +82,9 @@
               <useRepositoryLayout>false</useRepositoryLayout>
               <addParentPoms>false</addParentPoms>
               <copyPom>false</copyPom>
-              <excludeGroupIds>org.opendaylight,com.brocade.odl</excludeGroupIds>
-              <excludeScope>provided</excludeScope>
+			  <includeScope>runtime</includeScope>
+			  <excludeScope>provided</excludeScope>
+			  <excludeTransitive>true</excludeTransitive>
             </configuration>
           </execution>
         </executions>
diff --git a/feature-healthcheck/src/assembly/assemble_zip.xml b/feature-healthcheck/src/assembly/assemble_zip.xml
index 51a752a..fcbb652 100644
--- a/feature-healthcheck/src/assembly/assemble_zip.xml
+++ b/feature-healthcheck/src/assembly/assemble_zip.xml
@@ -24,61 +24,51 @@
 	xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
-	<id>runtime</id>
+	<id>feature-healthcheck-package</id>
 	<formats>
 		<format>zip</format>
 	</formats>
 
-	<!-- we want "system" and related files right at the root level as this 
-		file is suppose to be unzip on top of a karaf distro. -->
 	<includeBaseDirectory>false</includeBaseDirectory>
 
 	<fileSets>
 		<fileSet>
 			<directory>target</directory>
-			<outputDirectory>lib/opt</outputDirectory>
+			<outputDirectory>lib/feature</outputDirectory>
 			<includes>
 				<include>feature-healthcheck-${project.version}.jar</include>
 			</includes>
 		</fileSet>
 		<fileSet>
-			<directory>target/assembly/</directory>
-			<outputDirectory>.</outputDirectory>
-			<excludes>
-			</excludes>
-		</fileSet>
-		<fileSet>
-			<directory>.</directory>
-			<outputDirectory>lib</outputDirectory>
+			<directory>target/assembly/lib</directory>
+			<outputDirectory>lib/dependencies</outputDirectory>
 			<includes>
 				<include>*.jar</include>
 			</includes>
 		</fileSet>
 		<fileSet>
-			<directory>src/main/server-gen/bin</directory>
-			<outputDirectory>bin</outputDirectory>
-			<fileMode>0744</fileMode>
-			<excludes>
-			</excludes>
-		</fileSet>
-		<fileSet>
-			<directory>src/main/server/bin</directory>
-			<outputDirectory>bin</outputDirectory>
-			<fileMode>0744</fileMode>
-			<excludes>
-			</excludes>
-		</fileSet>
-		<fileSet>
-			<directory>src/main/server-gen/scripts</directory>
-			<outputDirectory>scripts</outputDirectory>
-		</fileSet>
-		<fileSet>
-			<directory>src/main/server/scripts</directory>
-			<outputDirectory>scripts</outputDirectory>
-		</fileSet>
-		<fileSet>
-			<directory>src/main/server/config</directory>
+			<directory>src/main/feature/config</directory>
 			<outputDirectory>config</outputDirectory>
+			<fileMode>0644</fileMode>
+			<excludes/>
+		</fileSet>
+		<fileSet>
+			<directory>src/main/feature/bin</directory>
+			<outputDirectory>bin</outputDirectory>
+			<fileMode>0744</fileMode>
+			<excludes/>
+		</fileSet>
+		<fileSet>
+			<directory>src/main/feature/db</directory>
+			<outputDirectory>db</outputDirectory>
+			<fileMode>0744</fileMode>
+			<excludes/>
+		</fileSet>
+		<fileSet>
+			<directory>src/main/feature/install</directory>
+			<outputDirectory>install</outputDirectory>
+			<fileMode>0744</fileMode>
+			<excludes/>
 		</fileSet>
 	</fileSets>
 
diff --git a/policy-management/src/main/server/config/feature-healthcheck.properties b/feature-healthcheck/src/main/feature/config/feature-healthcheck.properties
similarity index 100%
rename from policy-management/src/main/server/config/feature-healthcheck.properties
rename to feature-healthcheck/src/main/feature/config/feature-healthcheck.properties
diff --git a/packages/base/src/files/bin/features b/packages/base/src/files/bin/features
new file mode 100644
index 0000000..7b14644
--- /dev/null
+++ b/packages/base/src/files/bin/features
@@ -0,0 +1,640 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# ONAP POLICY
+# ================================================================================
+# Copyright (C) 2017 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=========================================================
+##
+
+# #############################################################
+# Features Directory Layout:
+#
+# POLICY_HOME/
+#   └── features/
+#        └── <feature-name>*/
+#            └── [config]/
+#            │   └── <config-file>*
+#            └── lib/
+#            │   └── [dependencies]/
+#            │   │   └── <dependent-jar>*
+#            │   └── feature/
+#            │       └── <feature-jar>
+#            └── [install]
+#                └── [enable]
+#                └── [disable]
+#                └── [other-future-operations]
+#                └── [other-files]
+#
+#   <feature-name> directory should not have the "feature-" prefix.
+#   <config-file> preferable with "feature-" prefix.
+#
+# Example:
+#
+# POLICY_HOME/
+#   └── features/
+#        ├── eelf/
+#        │   ├── config/
+#        │   │   ├── logback-eelf.xml
+#        │   └── lib/
+#        │   │   └── dependencies/
+#        │   │   │   └── ECOMP-Logging-1.1.0-SNAPSHOT.jar
+#        │   │   │   └── eelf-core-1.0.0.jar
+#        │   │   └── feature/
+#        │   │       └── feature-eelf-1.1.0-SNAPSHOT.jar
+#        │   └── install/
+#        │       └── enable
+#        │       └── disable
+#        └── healthcheck/
+#            ├── config/
+#            │   └── feature-healthcheck.properties
+#            └── lib/
+#                └── feature/
+#                    └── feature-healthcheck-1.1.0-SNAPSHOT.jar
+# #############################################################
+
+if [[ ${DEBUG} == y ]]; then
+	echo "-- MAIN --"
+	set -x
+fi
+	
+# The directories at play
+
+LIB=${POLICY_HOME}/lib
+CONFIG=${POLICY_HOME}/config
+FEATURES=${POLICY_HOME}/features
+
+if [[ ! ( -d "${LIB}" && -x "${LIB}" ) ]]; then
+	echo "ERROR: no ${LIB} directory"
+	exit 1
+fi
+
+if [[ ! ( -d "${CONFIG}" && -x "${CONFIG}" ) ]]; then
+	echo "ERROR: no ${CONFIG} directory"
+	exit 2
+fi
+
+if [[ ! ( -d "${FEATURES}" && -x "${FEATURES}" ) ]]; then
+	echo "ERROR: no ${FEATURES} directory"
+	exit 3
+fi
+
+# relative per Feature Directory Paths
+
+FEATURE_DEPS="lib/dependencies"
+FEATURE_LIB="lib/feature"
+FEATURE_CONFIG="config"
+FEATURE_INSTALL="install"
+
+featureJars=$(find "${FEATURES}" -name "feature-*.jar" -type f -exec basename {} \; 2> /dev/null)
+if [[ -z ${featureJars} ]]; then
+	echo "no features"
+	usage
+	exit 0
+fi
+
+# default field lengths
+nameLength=20
+versionLength=15
+
+# update field lengths, if needed
+for jar in ${featureJars} ; do
+	# get file name without 'jar' suffix
+	tmp="${jar%\.jar}"
+
+	# remove feature prefix
+	tmp="${tmp#feature-}"
+		
+	# get feature name by removing the version portion
+	name="${tmp%%-[0-9]*}"
+
+	# extract version portion of name
+	version="${tmp#${name}-}"
+
+	# grow the size of the name/version field, if needed
+	if (( "${#name}" > nameLength )) ; then
+		nameLength="${#name}"
+	fi
+	if (( "${#version}" > versionLength )) ; then
+		versionLength="${#version}"
+	fi
+done
+
+# ##########################################################
+# usage: usage information
+# ##########################################################
+function usage
+{
+		# print out usage information
+		cat >&2 <<-'EOF'
+		Usage:  features status
+		            Get enabled/disabled status on all features
+		        features enable <feature> ...
+		            Enable the specified feature
+		        features disable <feature> ...
+		            Disable the specified feature
+		EOF
+}
+
+# ##########################################################
+# status: dump out status information
+# ##########################################################
+function status
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local tmp name version status
+	local format="%-${nameLength}s %-${versionLength}s %s\n"
+	
+	printf "${format}" "name" "version" "status"
+	printf "${format}" "----" "-------" "------"
+	
+	for jar in ${featureJars} ; do
+		# get file name without 'jar' suffix
+		tmp="${jar%\.jar}"
+		
+		# remove feature prefix
+		tmp="${tmp#feature-}"
+
+		# get feature name by removing the version portion
+		name="${tmp%%-[0-9]*}"
+
+		# extract version portion of name
+		version="${tmp#${name}-}"
+
+		# determine status
+		status=disabled
+		if [[ -e "${LIB}/${jar}" ]] ; then
+			status=enabled
+		fi
+		printf "${format}" "${name}" "${version}" "${status}"
+	done
+}
+
+# ##########################################################
+# depEnableAnalysis(featureName):  
+#                   reports on potential dependency conflicts
+#   featureName: name of the feature
+# ##########################################################
+function depEnableAnalysis()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	local featureDepJars featureDepJarPath depJarName multiVersionJars
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	featureDepJars=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
+	for featureDepJarPath in ${featureDepJars}; do
+		depJarName=$(basename "${featureDepJarPath}")
+		
+		# it could be a base jar
+
+		if [[ -f "${LIB}"/"${depJarName}" ]]; then
+			echo "WARN: dependency ${depJarName} already in use"
+			continue
+		fi
+		
+		# it could be a link from another feature
+
+		if [[ -L "${LIB}"/"${depJarName}" ]]; then
+			continue
+		fi
+		
+		# unadvisable if multiple versions exist
+
+		multiVersionJars=$(ls "${LIB}"/"${depJarName%%-[0-9]*.jar}"-*.jar 2> /dev/null)
+		if [[ -n "${multiVersionJars}" ]]; then
+			echo "WARN: other version of library ${depJarName} present: ${multiVersionJars}"
+			return 2
+		fi
+	done
+}
+
+# ##########################################################
+# configEnableAnalysis(featureName):  
+#                   reports on potential dependency conflicts
+#   featureName: name of the feature
+# ##########################################################
+function configEnableAnalysis()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	local featureConfigs configPath configFileName
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	featureConfigs=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ 2> /dev/null)
+	for configPath in ${featureConfigs}; do
+		configFileName=$(basename "${configPath}")
+		if [[ -e "${LIB}"/"${configFileName}" ]]; then
+			echo "ERROR: a config file of the same name is already in the base: ${configFileName}"
+			return 2
+		fi
+	done
+}
+
+# ##########################################################
+# enableFeatureDeps(featureName):  
+#                               enables feature dependencies
+#   featureName: name of the feature
+# ##########################################################
+function enableFeatureDeps()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	local featureDeps featureDepPath depJarName
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	featureDeps=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
+	for featureDepPath in ${featureDeps}; do
+		depJarName=$(basename "${featureDepPath}")
+		if [[ ! -f "${LIB}"/"${depJarName}" ]]; then
+			ln -s -f "${featureDepPath}" "${LIB}/"
+		fi
+	done
+}
+
+# ##########################################################
+# enableFeatureConfig(featureName):  
+#                               enables feature configuration
+#   featureName: name of the feature
+# ##########################################################
+function enableFeatureConfig()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	local featureConfigs featureConfigPath
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	featureConfigs=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ -type f -maxdepth 1 2> /dev/null)
+	for featureConfigPath in ${featureConfigs}; do
+		ln -s -f "${featureConfigPath}" "${CONFIG}/"
+	done 
+}
+
+# ##########################################################
+# enableFeatureOp(featureName): 'enable' feature operation
+#   featureName: name of the feature
+# ##########################################################
+function enableFeatureOp()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	enableScript="${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"/enable
+	if [[ -f ${enableScript} ]]; then
+		(
+			cd "${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"
+			chmod u+x enable
+			./enable
+		)
+	fi
+}
+
+# ##########################################################
+# enableFeature(featureName, featureJar):  enables a feature
+#   featureName: name of the feature
+#   featureJar:  path to feature jar implementation
+# ##########################################################
+function enableFeature()
+{
+	if [[ $DEBUG == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	local featureJar="$2"
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	if [[ -z ${featureJar} ]]; then
+		echo "WARN: no feature jar"
+		return 2
+	fi
+	
+	if ! depEnableAnalysis "${featureName}"; then
+		return 3
+	fi
+	
+	if ! configEnableAnalysis "${featureName}"; then
+		return 4
+	fi
+	
+	# enable feature itself
+
+	ln -s -f "${featureJar}" "${LIB}/"
+		
+	# enable dependent libraries if any
+	
+	enableFeatureDeps "${featureName}"
+	
+	# enable configuration
+
+	enableFeatureConfig "${featureName}" 
+	
+	# TODO: run feature install DB scripts if any
+
+	# run custom enable if any
+
+	enableFeatureOp "${featureName}"
+}
+
+# ##########################################################
+# disableFeatureDeps(featureName):  
+#			disables feature dependencies
+# ##########################################################
+function disableFeatureDeps()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	local xDepsEnabledMap featureBaseDirs aFeatureDir aFeatureName
+	local featureDeps aFeatureDep 
+	local depJarPath depJarName depJarRealPath
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	declare -A xDepsEnabledMap
+	
+	featureBaseDirs=$(ls -d "${FEATURES}"/*/ 2> /dev/null)
+	for aFeatureDir in ${featureBaseDirs}; do 
+		aFeatureName=$(basename "${aFeatureDir}")
+		if [[ "${aFeatureName}" == "${featureName}" ]]; then
+			continue
+		fi
+		
+		depJarPaths=$(ls "${aFeatureDir}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
+		for depJarPath in ${depJarPaths}; do
+			if [[ "$?" == 0 ]] ; then
+				depJarName=$(basename "${depJarPath}")
+				xDepsEnabledMap[${depJarName}]="${depJarPath}"
+			fi
+		done
+	done
+	
+	if [[ ${DEBUG} == y ]]; then
+		echo "${!xDepsEnabledMap[@]}"
+		echo "${xDepsEnabledMap[@]}"
+	fi
+	
+	featureDeps=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
+	for aFeatureDep in ${featureDeps}; do
+		depJarName=$(basename "${aFeatureDep}")
+		if [[ -L "${LIB}"/"${depJarName}" ]]; then
+			depJarRealPath=$(readlink -f "${LIB}"/"${depJarName}")
+			if [[ "${depJarRealPath}" == "${aFeatureDep}" ]]; then
+				rm -f "${LIB}"/"${depJarName}"
+				
+				# case there were multiple features using this library
+				# re-enable link fron an enabled feature
+		
+				if [[ -n ${xDepsEnabledMap[${depJarName}]} ]]; then
+					ln -s -f "${xDepsEnabledMap[${depJarName}]}" "${LIB}/"
+				fi
+			fi
+		fi		
+	done
+}
+
+# ##########################################################
+# disableFeatureConfig(featureName):  
+#                               disables feature configuration
+#   featureName: name of the feature
+# ##########################################################
+function disableFeatureConfig()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	local featureConfigs featureConfigPath
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	featureConfigs=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ -type f -maxdepth 1 2> /dev/null)
+	for featureConfigPath in ${featureConfigs}; do
+		configFileName=$(basename "${featureConfigPath}")
+		rm -f "${CONFIG}"/"${configFileName}" 2> /dev/null
+	done 
+}
+
+# ##########################################################
+# disableFeatureOp(featureName): 'enable' feature operation
+#   featureName: name of the feature
+# ##########################################################
+function disableFeatureOp()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return 1
+	fi
+	
+	disableScript="${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"/disable
+	if [[ -f ${disableScript} ]]; then
+		(
+			cd "${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"
+			chmod u+x disable
+			./disable
+		)
+	fi
+}
+
+# ##########################################################
+# disableFeature(featureName, featureJar):  enables a feature
+#   featureName: name of the feature
+# ##########################################################
+function disableFeature()
+{
+	if [[ ${DEBUG} == y ]]; then
+		echo "-- ${FUNCNAME[0]} $@ --"
+		set -x
+	fi
+	
+	local featureName="$1"
+	
+	if [[ -z ${featureName} ]]; then
+		echo "WARN: no feature name"
+		return
+	fi
+	
+	# disable feature itself
+
+	(
+	cd "${LIB}"
+	rm -f feature-"${featureName}"-[0-9]*.jar 2> /dev/null
+	)
+		
+	# disable dependencies if any
+
+	disableFeatureDeps "${featureName}"
+	
+	# disable configuration if any
+
+	disableFeatureConfig "${featureName}"
+	
+	# run feature uninstall DB scripts if any
+	# TODO: future
+
+	# run custom disable if any
+	disableFeatureOp "${featureName}"
+}
+
+case "$1" in
+	status)
+	{
+		# dump out status information
+		status
+	};;
+
+	enable)
+	{
+		if [[ -f "${POLICY_HOME}"/PID ]]; then
+			echo "ERROR: enable: not allowed when policy is running .."
+			echo
+			status
+			exit 10
+		fi
+		
+		# enable the specified options
+		shift
+		match=
+		for name in "$@" ; do
+			# look for matches - 'file' has the full path name
+			file=$(ls "${FEATURES}"/"${name}"/"${FEATURE_LIB}"/feature-"${name}"-[0-9]*.jar 2> /dev/null)
+			if [[ "$?" != 0 ]] ; then
+				# no matching file
+				echo "${name}:  no such option"
+			else
+				# make sure there is only one feature jar
+				countFeatureJars=$(echo "${file}" | wc -w)
+				if [[ ${countFeatureJars} != 1 ]]; then
+					echo "WARNING: skipping ${name},  ${countFeatureJars} feature libraries found"
+					continue
+				fi			
+				
+				# found a match (handle multiple matches, just in case)
+				match=true
+				
+				enableFeature "${name}" "${file}"
+			fi
+		done
+		if [[ "${match}" ]] ; then
+			echo
+			status
+		fi
+	};;
+
+	disable)
+	{
+		if [[ -f "${POLICY_HOME}"/PID ]]; then
+			echo "ERROR: disable: not allowed when policy is running .."
+			echo
+			status
+			exit 11
+		fi
+		
+		# disable the specified options
+		shift
+		match=
+		for name in "$@" ; do
+			# look for matches -- 'file' has the last segment of the path name
+			file=$(ls "${FEATURES}"/"${name}"/"${FEATURE_LIB}"/feature-"${name}"-[0-9]*.jar 2> /dev/null)
+			if [[ "$?" != 0 ]] ; then
+				echo "${name}:  no such option"
+			else
+				# found a match (handle multiple matches, just in case)
+				match=true
+				
+				disableFeature "${name}"
+			fi
+		done
+		if [[ "${match}" ]] ; then
+			echo
+			status
+		fi
+	};;
+
+	*)
+	{
+		usage
+	};;
+esac
+exit
diff --git a/policy-management/src/main/server-gen/bin/options b/policy-management/src/main/server-gen/bin/options
deleted file mode 100644
index ae3d48d..0000000
--- a/policy-management/src/main/server-gen/bin/options
+++ /dev/null
@@ -1,145 +0,0 @@
-#! /bin/bash
-
-###
-# ============LICENSE_START=======================================================
-# ONAP POLICY
-# ================================================================================
-# Copyright (C) 2017 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=========================================================
-##
-
-lib=${POLICY_HOME}/lib
-opt=${lib}/opt
-
-# change to the options directory
-cd ${opt}
-
-# default field lengths
-nameLength=20
-versionLength=15
-
-# update field lengths, if needed
-for jar in $(ls) ; do
-	# get file name without 'jar' suffix
-	tmp="${jar%\.jar}"
-
-	# get feature name by removing the version portion
-	name="${tmp%%-[0-9]*}"
-
-	# extract version portion of name
-	version="${tmp#${name}-}"
-
-	# grow the size of the name/version field, if needed
-	if (( "${#name}" > nameLength )) ; then
-		nameLength="${#name}"
-	fi
-	if (( "${#version}" > versionLength )) ; then
-		versionLength="${#version}"
-	fi
-done
-
-# dump out status information
-function status
-{
-	local tmp name version status
-	local format="%-${nameLength}s %-${versionLength}s %s\n"
-
-	printf "${format}" "name" "version" "status"
-	printf "${format}" "----" "-------" "------"
-	for jar in $(ls) ; do
-		# get file name without 'jar' suffix
-		tmp="${jar%\.jar}"
-
-		# get feature name by removing the version portion
-		name="${tmp%%-[0-9]*}"
-
-		# extract version portion of name
-		version="${tmp#${name}-}"
-
-		# determine status
-		status=disabled
-		if [[ -e "${lib}/${jar}" ]] ; then
-			status=enabled
-		fi
-		printf "${format}" "${name}" "${version}" "${status}"
-	done
-}
-
-case "$1" in
-	status)
-	{
-		# dump out status information
-		status
-	};;
-
-	enable)
-	{
-		# enable the specified options
-		shift
-		match=
-		for name in "$@" ; do
-			# look for matches - 'file' has the full path name
-			file=$(ls ${opt}/"${name}"-[0-9]* 2>/dev/null)
-			if [[ "$?" != 0 ]] ; then
-				# no matching file
-				echo "${name}:  no such option"
-			else
-				# found a match (handle multiple matches, just in case)
-				match=true
-				ln -s -f ${file} "${lib}/"
-			fi
-		done
-		if [[ "${match}" ]] ; then
-			echo
-			status
-		fi
-	};;
-
-	disable)
-	{
-		# disable the specified options
-		shift
-		match=
-		for name in "$@" ; do
-			# look for matches -- 'file' has the last segment of the path name
-			file=$(ls "${name}"-[0-9]* 2>/dev/null)
-			if [[ "$?" != 0 ]] ; then
-				echo "${name}:  no such option"
-			else
-				# found a match (handle multiple matches, just in case)
-				match=true
-				(cd ${lib} ; rm -f ${file})
-			fi
-		done
-		if [[ "${match}" ]] ; then
-			echo
-			status
-		fi
-	};;
-
-	*)
-	{
-		# print out usage information
-		cat >&2 <<-'EOF'
-		Usage:  options status
-		            Get enabled/disabled status on all options
-		        options enable <option> ...
-		            Enable the specified options
-		        options disable <option> ...
-		            Disable the specified options
-		EOF
-	};;
-esac
-exit
diff --git a/policy-management/src/main/server/config/system.properties b/policy-management/src/main/server/config/system.properties
index 67294c8..6456ef5 100644
--- a/policy-management/src/main/server/config/system.properties
+++ b/policy-management/src/main/server/config/system.properties
@@ -35,9 +35,4 @@
 
 # standard logging
 
-logback.configurationFile=config/logback.xml
-
-# eelf logging
-
-com.att.eelf.logging.path=config
-com.att.eelf.logging.file=logback.xml
\ No newline at end of file
+logback.configurationFile=config/logback.xml
\ No newline at end of file