Initial OpenECOMP policy/drools-pdp commit 59/359/1
authorPamela Dragosh <pdragosh@research.att.com>
Wed, 15 Feb 2017 00:45:48 +0000 (19:45 -0500)
committerPamela Dragosh <pdragosh@research.att.com>
Wed, 15 Feb 2017 00:46:03 +0000 (19:46 -0500)
Change-Id: I0072ccab6f40ed32da39667f9f8523b6d6dad2e2
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
203 files changed:
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
LICENSE.txt [new file with mode: 0644]
README.md [new file with mode: 0644]
packages/base/.gitignore [new file with mode: 0644]
packages/base/pom.xml [new file with mode: 0644]
packages/base/src/assembly/zip.xml [new file with mode: 0644]
packages/base/src/files/bin/db_upgrade_droolspdp.sh [new file with mode: 0644]
packages/base/src/files/bin/db_upgrade_droolspdp_remote.sh [new file with mode: 0644]
packages/base/src/files/bin/monitor.sh [new file with mode: 0644]
packages/base/src/files/bin/policy.sh [new file with mode: 0644]
packages/base/src/files/data/mysql/160400_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/160400_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/160401_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/160401_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/160700_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/160700_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161000_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161000_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161001_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161001_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161002_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161002_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161003_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161003_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161004_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/161004_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/170200_droolspdp_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/data/mysql/170200_droolspdp_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/etc/cron.d/monitor.cron [new file with mode: 0755]
packages/base/src/files/etc/monitor/monitor.cfg [new file with mode: 0644]
packages/base/src/files/etc/profile.d/env.sh [new file with mode: 0644]
packages/base/src/files/etc/profile.d/su.cfg [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151000_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151000_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151001_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151001_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151002_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151002_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151200_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/151200_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/160200_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/160200_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/160201_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/160201_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/160400_downgrade_script.sql [new file with mode: 0644]
packages/base/src/files/install/mysql/data/160400_upgrade_script.sql [new file with mode: 0644]
packages/base/src/files/m2/settings.xml [new file with mode: 0755]
packages/base/src/files/m2/standalone-settings.xml [new file with mode: 0755]
packages/install/.gitignore [new file with mode: 0644]
packages/install/pom.xml [new file with mode: 0644]
packages/install/src/assembly/zip.xml [new file with mode: 0644]
packages/install/src/files/base.conf [new file with mode: 0644]
packages/install/src/files/policy-management.conf [new file with mode: 0644]
packages/pom.xml [new file with mode: 0644]
policy-core/pom.xml [new file with mode: 0644]
policy-core/src/assembly/assemble_zip.xml [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/core/FeatureAPI.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/core/PolicyContainer.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/core/PolicySession.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmx.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxListener.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxMBean.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/properties/Lockable.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java [new file with mode: 0644]
policy-core/src/main/java/org/openecomp/policy/drools/properties/Startable.java [new file with mode: 0644]
policy-core/src/main/resources/META-INF/jndi.properties [new file with mode: 0644]
policy-core/src/main/resources/META-INF/persistence.xml [new file with mode: 0644]
policy-endpoints/pom.xml [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/Topic.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicEndpoint.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicListener.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicRegisterable.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSink.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSource.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopic.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSink.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSource.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSink.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSinkFactory.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSource.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSourceFactory.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSink.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSinkFactory.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSource.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSourceFactory.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusConsumer.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusPublisher.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusTopicBase.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineBusTopicSink.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineDmaapTopicSink.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineUebTopicSink.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedBusTopicSource.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedDmaapTopicSource.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedUebTopicSource.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClient.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClientFactory.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/internal/JerseyClient.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java [new file with mode: 0644]
policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyServletServer.java [new file with mode: 0644]
policy-endpoints/src/main/resources/schema/pdpd-configuration.jsonschema [new file with mode: 0644]
policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java [new file with mode: 0644]
policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java [new file with mode: 0644]
policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java [new file with mode: 0644]
policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEndpoints.java [new file with mode: 0644]
policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestMockHealthCheck.java [new file with mode: 0644]
policy-healthcheck/pom.xml [new file with mode: 0644]
policy-healthcheck/src/assembly/assemble_zip.xml [new file with mode: 0644]
policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheck.java [new file with mode: 0644]
policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheckFeature.java [new file with mode: 0644]
policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java [new file with mode: 0644]
policy-healthcheck/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI [new file with mode: 0644]
policy-management/config/policy-engine.properties [new file with mode: 0644]
policy-management/config/policyLogger.properties [new file with mode: 0644]
policy-management/pom.xml [new file with mode: 0644]
policy-management/src/assembly/assemble_zip.xml [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsControllerFactory.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/persistence/SystemPersistence.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/JsonProtocolFilter.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/ProtocolCoderToolset.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/ControllerConfiguration.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/DroolsConfiguration.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/PdpdConfiguration.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/system/Main.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyController.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyControllerFactory.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java [new file with mode: 0644]
policy-management/src/main/java/org/openecomp/policy/drools/system/internal/AggregatedPolicyController.java [new file with mode: 0644]
policy-management/src/main/server-gen/bin/add-secured-participant.sh [new file with mode: 0644]
policy-management/src/main/server-gen/bin/create-api-key.sh [new file with mode: 0644]
policy-management/src/main/server-gen/bin/create-secured-topic.sh [new file with mode: 0644]
policy-management/src/main/server-gen/bin/options [new file with mode: 0644]
policy-management/src/main/server-gen/bin/pdpd-configuration.sh [new file with mode: 0644]
policy-management/src/main/server-gen/bin/policy-management-controller [new file with mode: 0644]
policy-management/src/main/server-gen/bin/rest-add-controller.sh [new file with mode: 0644]
policy-management/src/main/server-gen/bin/rest-delete-controller.sh [new file with mode: 0644]
policy-management/src/main/server/config/IntegrityMonitor.properties [new file with mode: 0644]
policy-management/src/main/server/config/controller.properties.README [new file with mode: 0644]
policy-management/src/main/server/config/droolsPersistence.properties [new file with mode: 0644]
policy-management/src/main/server/config/log4j.properties [new file with mode: 0644]
policy-management/src/main/server/config/logback.xml [new file with mode: 0644]
policy-management/src/main/server/config/makefile [new file with mode: 0644]
policy-management/src/main/server/config/policy-engine.properties [new file with mode: 0644]
policy-management/src/main/server/config/policy-healthcheck.properties [new file with mode: 0644]
policy-management/src/main/server/config/policyLogger.properties [new file with mode: 0644]
policy-management/src/main/server/config/system.properties [new file with mode: 0644]
policy-management/src/main/server/config/xacmlPersistence.properties [new file with mode: 0644]
policy-persistence/config/policy-engine.properties [new file with mode: 0644]
policy-persistence/config/policyLogger.properties [new file with mode: 0644]
policy-persistence/pom.xml [new file with mode: 0644]
policy-persistence/src/assembly/assemble_zip.xml [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/core/DbAudit.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorProperties.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/im/PMStandbyStateChangeNotifier.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdp.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpEntity.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpImpl.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpObject.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsConnector.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPersistenceProperties.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSession.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSessionEntity.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/ThreadRunningChecker.java [new file with mode: 0644]
policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/XacmlPersistenceProperties.java [new file with mode: 0644]
policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI [new file with mode: 0644]
policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/IntegrityAuditIntegrationTest.java [new file with mode: 0644]
policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/ResiliencyTestCases.java [new file with mode: 0644]
policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/StandbyStateManagementTest.java [new file with mode: 0644]
policy-persistence/src/test/resources/IntegrityMonitor.properties [new file with mode: 0644]
policy-persistence/src/test/resources/META-INF/persistence.xml [new file with mode: 0644]
policy-persistence/src/test/resources/droolsPersistence.properties [new file with mode: 0644]
policy-persistence/src/test/resources/log4j.properties [new file with mode: 0644]
policy-persistence/src/test/resources/logback.xml [new file with mode: 0644]
policy-persistence/src/test/resources/xacmlPersistence.properties [new file with mode: 0644]
policy-persistence/src/test/server/config/IntegrityMonitor.properties [new file with mode: 0644]
policy-persistence/src/test/server/config/droolsPersistence.properties [new file with mode: 0644]
policy-persistence/src/test/server/config/policyLogger.properties [new file with mode: 0644]
policy-persistence/src/test/server/config/xacmlPersistence.properties [new file with mode: 0644]
policy-utils/pom.xml [new file with mode: 0644]
policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedService.java [new file with mode: 0644]
policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedServiceImpl.java [new file with mode: 0644]
policy-utils/src/main/java/org/openecomp/policy/drools/utils/Pair.java [new file with mode: 0644]
policy-utils/src/main/java/org/openecomp/policy/drools/utils/PropertyUtil.java [new file with mode: 0644]
policy-utils/src/main/java/org/openecomp/policy/drools/utils/ReflectionUtil.java [new file with mode: 0644]
policy-utils/src/main/java/org/openecomp/policy/drools/utils/Triple.java [new file with mode: 0644]
policy-utils/src/test/java/org/openecomp/policy/drools/utils/PropertyUtilTest.java [new file with mode: 0644]
policy-utils/src/test/resources/log4j.properties [new file with mode: 0644]
pom.xml [new file with mode: 0644]
project-configs/maven/conf/settings.xml [new file with mode: 0644]
version.properties [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..37cd4d1
--- /dev/null
@@ -0,0 +1,7 @@
+.project
+.settings
+.classpath
+.jupiter
+.pydevproject
+target
+.metadata/
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..6a107fd
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.openecomp.org
+port=29418
+project=policy/drools-pdp.git
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..dde205e
--- /dev/null
@@ -0,0 +1,16 @@
+Copyright Â© 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.
+
+ECOMP and OpenECOMP are trademarks and service marks of AT&T Intellectual Property.
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..6614ee6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+This source repository contains the OpenECOMP Policy DroolsPDP code. The settings file only needs to support the standard Maven repositories (e.g. central = http://repo1.maven.org/maven2/), and any proxy settings needed in your environment.
+
+To build it using Maven 3, first build 'policy-common-modules' (which contains dependencies), and then run: mvn clean install
diff --git a/packages/base/.gitignore b/packages/base/.gitignore
new file mode 100644 (file)
index 0000000..b83d222
--- /dev/null
@@ -0,0 +1 @@
+/target/
diff --git a/packages/base/pom.xml b/packages/base/pom.xml
new file mode 100644 (file)
index 0000000..80ba20b
--- /dev/null
@@ -0,0 +1,95 @@
+<!--
+  ============LICENSE_START=======================================================
+  Policy Packages
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.openecomp.policy.drools-pdp</groupId>
+               <artifactId>packages</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>base</artifactId>
+       <packaging>pom</packaging>
+
+       <name>Base Package</name>
+       <description>D2 ECOMP Policy Drools PDP Packaging</description>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <artifactId>maven-assembly-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>single</goal>
+                                               </goals>
+                                               <phase>package</phase>
+                                               <configuration>
+                                                       <descriptors>
+                                                               <descriptor>src/assembly/zip.xml</descriptor>
+                                                       </descriptors>
+                                                       <appendAssemblyId>false</appendAssemblyId>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+
+       <profiles>
+               <profile>
+                       <id>unix_pe_version</id>
+                       <activation>
+                               <os>
+                                       <family>!windows</family>
+                               </os>
+                       </activation>
+                       <build>
+                               <plugins>
+                                       <plugin>
+                                               <groupId>org.codehaus.mojo</groupId>
+                                               <artifactId>exec-maven-plugin</artifactId>
+                                               <executions>
+                                                       <execution>
+                                                               <id>create-version-file</id>
+                                                               <goals>
+                                                                       <goal>exec</goal>
+                                                               </goals>
+                                                               <phase>prepare-package</phase>
+                                                               <configuration>
+                                                                       <executable>/bin/bash</executable>
+                                                                       <arguments>
+                                                                               <argument>-c</argument>
+                                                                               <argument>mkdir -p target ; echo -e 'version="${project.version}"\ndescription="Open ECOMP Drools PDP"\nbuildTag="'"${BUILD_TAG}"'"\ncommit="'"${GIT_COMMIT}"'"\ntimestamp="${maven.build.timestamp}"' >target/build.info</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+       </profiles>
+
+</project>
diff --git a/packages/base/src/assembly/zip.xml b/packages/base/src/assembly/zip.xml
new file mode 100644 (file)
index 0000000..1f3b206
--- /dev/null
@@ -0,0 +1,42 @@
+<!--
+  ============LICENSE_START=======================================================
+  Base Package
+  ================================================================================
+  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=========================================================
+  -->
+
+<assembly>
+       <id>base</id>
+       <formats>
+               <format>tar.gz</format>
+       </formats>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <fileSets>
+               <fileSet>
+                       <directory>${project.build.directory}</directory>
+                       <outputDirectory>etc</outputDirectory>
+                       <includes><include>build.info</include></includes>
+                       <fileMode>700</fileMode>
+                       <directoryMode>700</directoryMode>
+               </fileSet>
+               <fileSet>
+                       <directory>src/files</directory>
+                       <outputDirectory>.</outputDirectory>
+                       <fileMode>700</fileMode>
+                       <directoryMode>700</directoryMode>
+               </fileSet>
+       </fileSets>
+</assembly>
diff --git a/packages/base/src/files/bin/db_upgrade_droolspdp.sh b/packages/base/src/files/bin/db_upgrade_droolspdp.sh
new file mode 100644 (file)
index 0000000..738317d
--- /dev/null
@@ -0,0 +1,154 @@
+#!/bin/bash 
+
+###
+# ============LICENSE_START=======================================================
+# Base Package
+# ================================================================================
+# 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=========================================================
+###
+
+#
+# db_upgrade_droolspdp.sh: Run this script to upgrade drools database to a given release level, 
+# it is recommended that you switch to the policy user to run this script
+# 
+# Usage  : db_upgrade_droolspdp.sh target_db_release_level db_user_id  db_user_password
+# Example: db_upgrade_droolspdp.sh 151000                  policy_user password
+#
+# Assumption: 1. DB upgrade sql script in $POLICY_HOME/data/mysql folder with read permission
+#             2. DB user has privilege to create/drop/alter database table
+#
+# Note: The default location for db release script is $POLICY_HOME/data/mysql
+#       The release level is represented as Two-digit-Year+Two-digit-Month+two-digit-Sub-release (151000, 151001)
+#       Drools database version is represented by record with the_key of 'DROOLS_VERSION'
+#
+
+TARGET_RELEASE=""
+CURRENT_RELEASE=""
+DB_UPGRADE_USER=""
+DB_UPGRADE_PASSWORD=""
+DB_UPGRADE_DIR=$POLICY_HOME/data/mysql
+DATE=`date +"%Y%m%d%H%M%S"`
+LOG=""
+ERR=""
+
+function get_current_release_level
+{
+  echo "Get current release level started ...@`date`" | tee -a $LOG
+  # display output vertical
+  query="select version from support.db_version where the_key = 'DROOLS_VERSION' \G"
+  CURRENT_RELEASE=`${MYSQL} --skip-column-names --execute "${query}" 2>$ERR | grep -v "*"`
+  echo "CURRENT_RELEASE: [$CURRENT_RELEASE]" | tee -a $LOG
+  echo "Get current release level completed ...@`date`" | tee -a $LOG
+}
+
+function evaluate_upgrade_downgrade
+{
+  echo "CURRENT_RELEASE --> [$CURRENT_RELEASE]" | tee -a $LOG
+  echo "TARGET_RELEASE  --> [$TARGET_RELEASE] " | tee -a $LOG
+  if [[ "${CURRENT_RELEASE}" < "${TARGET_RELEASE}" ]]; then 
+    # perform db upgrade
+    UPGRADE_LIST=/tmp/db_upgrade_droolspdp_list.$$
+    find ${DB_UPGRADE_DIR} -name "*_upgrade_script.sql" 2>/dev/null | grep "droolspdp" | sort > $UPGRADE_LIST
+    while read -r file
+    do
+      RELEASE=`basename $file | cut -d'_' -f1`
+      #echo "[$RELEASE] [$TARGET_RELEASE]" | tee -a $LOG
+      if [ "${RELEASE}" -gt "${CURRENT_RELEASE}" ] && [ "${RELEASE}" -le "${TARGET_RELEASE}" ]; then
+        run_script "UPGRADE" "${file}" 2>&1 | tee -a $LOG
+      fi
+    done < $UPGRADE_LIST
+    rm -f $UPGRADE_LIST
+    set_current_release_level $TARGET_RELEASE
+  elif [[ "${CURRENT_RELEASE}" > "${TARGET_RELEASE}" ]]; then 
+    # perform db downgrade
+    DOWNGRADE_LIST=/tmp/db_downgrade_list.$$
+    find ${DB_UPGRADE_DIR} -name "*_downgrade_script.sql" 2>/dev/null | grep "droolspdp" | sort -r > $DOWNGRADE_LIST
+    while read -r file
+    do
+      RELEASE=`basename $file | cut -d'_' -f1`
+      #echo "[$RELEASE] [$TARGET_RELEASE]" | tee -a $LOG
+      if [ "${RELEASE}" -le "${CURRENT_RELEASE}" ] && [ "${RELEASE}" -gt "${TARGET_RELEASE}" ]; then 
+        run_script "DOWNGRADE" "${file}"
+      fi
+    done < $DOWNGRADE_LIST
+    rm -f $DOWNGRADE_LIST
+    set_current_release_level $TARGET_RELEASE
+  else
+    echo "CURRENT DB RELEASE LEVEL THE SAME AS TARGET RELEASE LEVEL, NO ACTION TAKEN ..." | tee -a $LOG
+  fi
+}
+
+function run_script
+{
+  action="${1}"
+  script="${2}"
+  echo "Perform DB $action use $script ..." | tee -a $LOG
+  echo "--" | tee -a $LOG
+  ${MYSQL} --verbose < "${script}" 2>$ERR | tee -a $LOG
+  echo "--" | tee -a $LOG
+}
+
+function set_current_release_level
+{
+  RELEASE="${1}"
+  echo "Set current release level to [$RELEASE] started ...@`date`" | tee -a $LOG
+  update_statement="insert into support.db_version (the_key, version) values ('DROOLS_VERSION', '${RELEASE}') on duplicate key update version='${RELEASE}';"
+  ${MYSQL} --execute "${update_statement}" 
+
+  echo "" | tee -a $LOG
+  echo "CURRENT_RELEASE set to: [$RELEASE]" | tee -a $LOG
+  echo "" | tee -a $LOG
+  echo "Set current release level completed ...@`date`" | tee -a $LOG
+}
+
+function check_directory
+{
+  if [ ! -d $DB_UPGRADE_DIR ]; then
+    echo "ERROR, DIRECTORY NOT EXIST: $DB_UPGRADE_DIR, PROCESS EXIT ..."
+    exit;
+  else
+    if [ ! -d $DB_UPGRADE_DIR/logs ]; then
+      mkdir $DB_UPGRADE_DIR/logs
+    fi
+  fi
+}
+
+# MAIN
+#check_directory
+LOG=$POLICY_HOME/logs/db_upgrade_droolspdp_$DATE.log
+ERR=$POLICY_HOME/logs/db_upgrade_droolspdp_$DATE.err
+echo "db_upgrade_droolspdp.sh started ..." | tee -a $LOG
+if [ $# -eq 3 ]; then 
+  TARGET_RELEASE="${1}"
+  DB_UPGRADE_USER="${2}"
+  DB_UPGRADE_PASSWORD="${3}"
+  echo "TARGET_RELEASE : $TARGET_RELEASE" | tee -a $LOG
+  echo "DB_UPGRADE_USER: $DB_UPGRADE_USER" | tee -a $LOG
+  echo "DB_UPGRADE_DIR : $DB_UPGRADE_DIR" | tee -a $LOG
+  #
+  if [ ${#TARGET_RELEASE} -ne 6 ]; then 
+    echo "ERROR, TARGET_RELEASE MUST BE 6 DIGITS: $TARGET_RELEASE" | tee -a $LOG | tee -a $ERR
+  else
+    typeset -r MYSQL="mysql -u${DB_UPGRADE_USER} -p${DB_UPGRADE_PASSWORD} ";
+    get_current_release_level
+    evaluate_upgrade_downgrade
+  fi
+else
+  echo "Usage  : db_upgrade_droolspdp.sh target_release_level db_user_id   db_user_password" | tee -a $LOG
+  echo "Example: db_upgrade_droolspdp.sh 151000               policy_user  password" | tee -a $LOG
+fi
+
+echo "db_upgrade_droolspdp.sh completed ..." | tee -a $LOG
diff --git a/packages/base/src/files/bin/db_upgrade_droolspdp_remote.sh b/packages/base/src/files/bin/db_upgrade_droolspdp_remote.sh
new file mode 100644 (file)
index 0000000..96cfda1
--- /dev/null
@@ -0,0 +1,151 @@
+#!/bin/bash 
+#
+# db_upgrade_droolspdp_remote.sh: This script is to perform database schema upgrade on remote db, 
+#                       no shecma downgrade will be performed in case db_version is higher then target_version
+# 
+# Logic: 1. Get target schema version from db scripts in $POLICY_HOME/data/mysql
+#        2. Get current db schema version from support.db_version table (of target system)
+#        3. Apply db upgrade script in order if target_version is HIGHER than db_version
+#        4. Print out warning message        if target_version is LOWER than db_version
+#        4. Print out message                if target_version is EQUAL to db_version
+#
+#
+# Usage  : db_upgrade_droolspdp_remote.sh db_user_id  db_user_password hostname
+# Example: db_upgrade_droolspdp_remote.sh policy_user password         policydb
+#
+# Assumption: 1. DB schema upgrade script in $POLICY_HOME/data/mysql folder with read permission
+#             2. DB user has privilege to create/drop/alter database table
+#
+# Note: The default location for db schema upgrade script is $POLICY_HOME/data/mysql
+#       The release level is represented as Two-digit-Year+Two-digit-Month+two-digit-Sub-release (151000, 151001)
+#
+#
+
+TARGET_SCHEMA_VERSION=""
+CURRENT_SCHEMA_VERSION=""
+DB_UPGRADE_USER=""
+DB_UPGRADE_PASSWORD=""
+DB_HOSTNAME=""
+DB_UPGRADE_DIR=$POLICY_HOME/data/mysql
+DATE=`date +"%Y%m%d%H%M%S"`
+LOG=""
+ERR=""
+
+function get_current_schema_version
+{
+  echo "Get current schema version from [${DB_HOSTNAME}] started ...@`date`" | tee -a $LOG
+  # display output vertical
+  query="select version from support.db_version where the_key = 'DROOLS_VERSION' \G"
+  CURRENT_SCHEMA_VERSION=`${MYSQL} --skip-column-names --execute "${query}" 2>$ERR | grep -v "*"`
+  error_msg=`cat $ERR | grep "doesn't exist"`
+  if [ "${error_msg}" != "" ]; then
+    echo "Create support.db_version table ..." | tee -a $LOG
+    sql="create table support.db_version(the_key varchar(20) not null, version varchar(20), primary key(the_key));"
+    ${MYSQL} --execute "${sql}"
+    CURRENT_SCHEMA_VERSION="00"
+  fi
+  echo "CURRENT_SCHEMA_VERSION: [$CURRENT_SCHEMA_VERSION]" | tee -a $LOG
+  echo "Get current schema version from [${DB_HOSTNAME}] completed ...@`date`" | tee -a $LOG
+}
+
+function get_target_schema_version
+{
+  UPGRADE_LIST=/tmp/db_upgrade_list.$$
+  find ${DB_UPGRADE_DIR} -name "*_upgrade_script.sql" 2>/dev/null | grep "droolspdp" | sort -r | head -1 > $UPGRADE_LIST
+  while read -r file
+  do
+    TARGET_SCHEMA_VERSION=`basename $file | cut -d'_' -f1`
+    echo "TARGET_SCHEMA_VERSION: [$TARGET_SCHEMA_VERSION]" | tee -a $LOG
+    break
+  done < $UPGRADE_LIST
+  rm -f $UPGRADE_LIST
+}
+
+function evaluate_upgrade_downgrade
+{
+  echo "CURRENT_SCHEMA_VERSION --> [$CURRENT_SCHEMA_VERSION]" | tee -a $LOG
+  echo "TARGET_SCHEMA_VERSION  --> [$TARGET_SCHEMA_VERSION] " | tee -a $LOG
+  if [[ "${CURRENT_SCHEMA_VERSION}" < "${TARGET_SCHEMA_VERSION}" ]]; then 
+    # perform db upgrade
+    UPGRADE_LIST=/tmp/db_upgrade_list.$$
+    find ${DB_UPGRADE_DIR} -name "*_upgrade_script.sql" 2>/dev/null | grep "droolspdp" | sort > $UPGRADE_LIST
+    while read -r file
+    do
+      DB_VERSION=`basename $file | cut -d'_' -f1`
+      #echo "[$DB_VERSION] [$TARGET_SCHEMA_VERSION]" | tee -a $LOG
+      if [ "${DB_VERSION}" -gt "${CURRENT_SCHEMA_VERSION}" ] && [ "${DB_VERSION}" -le "${TARGET_SCHEMA_VERSION}" ]; then
+        run_script "UPGRADE" "${file}" 2>&1 | tee -a $LOG
+      fi
+    done < $UPGRADE_LIST
+    rm -f $UPGRADE_LIST
+    set_current_release_level $TARGET_SCHEMA_VERSION
+  elif [[ "${CURRENT_SCHEMA_VERSION}" > "${TARGET_SCHEMA_VERSION}" ]]; then 
+    # db downgrade
+    echo "WARNING: Target db schema version is LOWER than current db scema version, please run downgrade script manually." | tee -a $LOG | tee -a $ERR
+  else
+    echo "CURRENT SCHEMA VERSION THE SAME AS TARGET SCHEMA VERSION, NO ACTION TAKEN ..." | tee -a $LOG
+  fi
+}
+
+function run_script
+{
+  action="${1}"
+  script="${2}"
+  echo "Perform DB $action on [${DB_HOSTNAME}] use $script ..." | tee -a $LOG
+  echo "--" | tee -a $LOG
+  ${MYSQL} --verbose < "${script}" 2>$ERR | tee -a $LOG
+  echo "--" | tee -a $LOG
+}
+
+function set_current_release_level
+{
+  DB_VERSION="${1}"
+  echo "Set current release level on [${DB_HOSTNAME}] to [$DB_VERSION] started ...@`date`" | tee -a $LOG
+  update_statement="insert into support.db_version (the_key, version) values ('DROOLS_VERSION', '${DB_VERSION}') on duplicate key update version='${DB_VERSION}';"
+  ${MYSQL} --execute "${update_statement}" 
+
+  echo "" | tee -a $LOG
+  echo "CURRENT_SCHEMA_VERSION set to: [$DB_VERSION]" | tee -a $LOG
+  echo "" | tee -a $LOG
+  echo "Set current release level on [${DB_HOSTNAME}] to [$DB_VERSION] completed ...@`date`" | tee -a $LOG
+}
+
+function check_directory
+{
+  if [ ! -d $DB_UPGRADE_DIR ]; then
+    echo "ERROR, DIRECTORY NOT EXIST: $DB_UPGRADE_DIR, PROCESS EXIT ..."
+    exit;
+  else
+    if [ ! -d $DB_UPGRADE_DIR/logs ]; then
+      mkdir $DB_UPGRADE_DIR/logs
+    fi
+  fi
+}
+
+# MAIN
+#check_directory
+LOG=$POLICY_HOME/logs/db_upgrade_droolspdp_remote_$DATE.log
+ERR=$POLICY_HOME/logs/db_upgrade_droolspdp_remote_$DATE.err
+echo "db_upgrade_droolspdp_remote.sh started ..." | tee -a $LOG
+if [ $# -eq 3 ]; then 
+  DB_UPGRADE_USER="${1}"
+  DB_UPGRADE_PASSWORD="${2}"
+  DB_HOSTNAME="${3}"
+  echo "DB_UPGRADE_USER: $DB_UPGRADE_USER" | tee -a $LOG
+  echo "DB_UPGRADE_DIR : $DB_UPGRADE_DIR"  | tee -a $LOG
+  echo "DB_HOSTNAME    : $DB_HOSTNAME"     | tee -a $LOG
+  #
+  typeset -r MYSQL="mysql -u${DB_UPGRADE_USER} -p${DB_UPGRADE_PASSWORD} -h ${DB_HOSTNAME}";
+  get_target_schema_version
+  if [ ${#TARGET_SCHEMA_VERSION} -ne 6 ]; then 
+    echo "ERROR, TARGET_SCHEMA_VERSION MUST BE 6 DIGITS: $TARGET_SCHEMA_VERSION" | tee -a $LOG | tee -a $ERR
+  else
+    get_current_schema_version
+    evaluate_upgrade_downgrade
+  fi
+else
+  echo "Usage  : db_upgrade_droolspdp_remote.sh db_user_id   db_user_password db_hostname" | tee -a $LOG
+  echo "Example: db_upgrade_droolspdp_remote.sh policy_user  password         policydb" | tee -a $LOG
+fi
+
+echo "db_upgrade_droolspdp_remote.sh completed ..." | tee -a $LOG
diff --git a/packages/base/src/files/bin/monitor.sh b/packages/base/src/files/bin/monitor.sh
new file mode 100644 (file)
index 0000000..f4fad48
--- /dev/null
@@ -0,0 +1,148 @@
+#!/bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# Base Package
+# ================================================================================
+# 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=========================================================
+###
+
+function usage() {
+       echo -n "syntax: $(basename $0) "
+       echo "[--debug]"
+}
+
+function log() {
+       echo "$(date +"%Y-%m-%d_%H-%M-%S") $1" >> ${POLICY_HOME}/logs/monitor.log
+}
+
+function monitor() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+               
+       CONTROLLER=$1
+       STATUS=$2
+
+       if [[ -z ${CONTROLLER} ]]; then
+               log "WARNING: invalid invocation: no component provided"
+               return
+       fi
+       
+       if [[ -z ${STATUS} ]]; then
+               log "WARNING: invalid invocation: no on/off/uninstalled switch provided for ${CONTROLLER}"
+               return
+       fi
+
+       if [[ "${STATUS}" == "off" ]]; then
+               off ${CONTROLLER}
+       else
+               if [[ "${STATUS}" == "on" ]]; then
+                       on ${CONTROLLER}
+               fi
+       fi
+}
+
+function on() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+               
+       CONTROLLER=$1
+       NAGIOS_COMPONENT_SERVICE="Check_${CONTROLLER}-AliveStatus_AP_24094"
+
+       ${POLICY_HOME}/bin/${CONTROLLER} status
+       if [[ $? != 0 ]]; then
+               log "starting ${CONTROLLER}"
+
+               # need to make sure we don't pass the lock file descriptor
+               ${POLICY_HOME}/bin/${CONTROLLER} umstart {cfg}>&-
+       else            
+               log "OK: ${CONTROLLER} (UP)"
+       fi
+}
+
+function off() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+               
+       CONTROLLER=$1
+       NAGIOS_COMPONENT_SERVICE="Check_${CONTROLLER}-AliveStatus_AP_24094"
+
+       ${POLICY_HOME}/bin/${CONTROLLER} status
+       if [[ $? != 0 ]]; then
+               log "OK: ${CONTROLLER} (DOWN)"
+
+       else
+               log "stopping ${CONTROLLER}"
+               ${POLICY_HOME}/bin/${CONTROLLER} umstop
+       fi
+}
+
+function process_config() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+       
+       CONF_FILE=${POLICY_HOME}/etc/monitor/monitor.cfg
+       while read line || [ -n "${line}" ]; do
+        if [[ -n ${line} ]] && [[ ${line} != *#* ]]; then
+               controller=$(echo "${line}" | awk -F = '{print $1;}')
+               status=$(echo "${line}" | awk -F = '{print $2;}')
+                       if [[ -n ${controller} ]] && [[ -n ${status} ]]; then
+                       monitor ${controller} ${status}
+               fi
+        fi
+       done < "${CONF_FILE}"
+       return 0
+}
+
+log "Enter monitor"
+
+DEBUG=n
+until [[ -z "$1" ]]; do
+       case $1 in
+               -d|--debug|debug)       DEBUG=y
+                                                       set -x
+                                                       ;;                                                              
+               *)                                      usage
+                                                       exit 1
+                                                       ;;
+       esac
+       shift
+done
+
+if pidof -o %PPID -x $(basename $0) > /dev/null 2>&1; then
+       log "WARNING: $(basename $0) from the previous iteration still running.  Exiting."
+       exit 1
+fi
+
+. ${POLICY_HOME}/etc/profile.d/env.sh
+
+if [[ ${NAGIOS_NRDP_DISABLED} == true ]]; then
+       log "Nagios NRDS is disabled."
+fi
+
+if flock ${cfg} ; then
+       process_config
+fi {cfg}>>${POLICY_HOME}/etc/monitor/monitor.cfg.lock
+
+
diff --git a/packages/base/src/files/bin/policy.sh b/packages/base/src/files/bin/policy.sh
new file mode 100644 (file)
index 0000000..67f56ca
--- /dev/null
@@ -0,0 +1,154 @@
+#!/bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# Base Package
+# ================================================================================
+# 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=========================================================
+###
+
+function usage() {
+       echo -n "syntax: $(basename $0) "
+       echo -n "[--debug] "
+       echo    "status|start|stop"
+}
+
+function check_x_file() {
+        if [[ $DEBUG == y ]]; then
+                echo "-- ${FUNCNAME[0]} --"
+                set -x
+        fi
+
+        FILE=$1
+        if [[ ! -f ${FILE} || ! -x ${FILE} ]]; then
+        return 1
+        fi
+
+        return 0
+}
+
+function policy_op() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+
+       operation=$1
+       
+       cd $POLICY_HOME
+       echo "[drools-pdp-controllers]"
+       for binScript in bin/*-controller; do
+               if check_x_file "${binScript}"; then
+                       trap "rm -f /tmp/out$$" EXIT
+                       ${binScript} ${operation} >/tmp/out$$
+                       echo " L [${controller}]: $(sed ':a;N;$!ba;s/\n/ /g' /tmp/out$$)"
+               else
+                       echo "  L [${controller}]: -"
+               fi
+       done
+}
+
+function policy_status() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+       
+       policy_op "status"
+
+       NUM_CRONS=$(crontab -l 2> /dev/null | wc -l)
+       echo "  ${NUM_CRONS} cron jobs installed."
+       
+}
+
+function policy_start() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+       
+       policy_op "start"
+}
+
+
+function policy_stop() {
+       if [[ $DEBUG == y ]]; then
+               echo "-- ${FUNCNAME[0]} --"
+               set -x
+       fi
+       
+       policy_op "stop"
+}
+
+#########################################################################
+##
+## script execution body
+##
+#########################################################################
+
+DEBUG=n
+OPERATION=none
+
+until [[ -z "$1" ]]; do
+       case $1 in
+               -d|--debug|debug)       DEBUG=y
+                                               set -x
+                                               ;;
+               -i|--status|status)             OPERATION=status
+                                               ;;
+               -s|--start|start)               OPERATION=start
+                                               ;;
+               -h|--stop|stop|--halt|halt)     OPERATION=halt
+                                               ;;
+               *)                              usage
+                                               exit 1
+                                               ;;
+       esac
+       shift
+done
+
+# operation validation
+case $OPERATION in
+       status) ;;
+       start)  ;;
+       halt)   ;;
+       *)      echo "invalid operation \(${OPERATION}\): must be in {status|start|stop}";
+               usage
+               exit 1
+               ;;
+esac
+
+if [[ -z ${POLICY_HOME} ]]; then
+       echo "error: POLICY_HOME is unset."
+       exit 1
+fi
+
+# operation validation
+case $OPERATION in
+       status) 
+               policy_status
+               ;;
+       start)  
+               policy_start
+               ;;
+       halt)   
+               policy_stop
+               ;;
+       *)              echo "invalid operation \(${OPERATION}\): must be in {status|start|stop}";
+                       usage
+                       exit 1
+                       ;;
+esac
diff --git a/packages/base/src/files/data/mysql/160400_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/160400_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..44f4919
--- /dev/null
@@ -0,0 +1,23 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.sessioninfo; 
+drop table if exists drools.WORKITEMINFO; 
+drop table if exists drools.droolspdpentity; 
diff --git a/packages/base/src/files/data/mysql/160400_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/160400_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..03e9652
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+-- use BLOB instead of LONGVARBINARY
+drop table if exists drools.sessioninfo; 
+CREATE TABLE drools.SESSIONINFO 
+(
+ID BIGINT NOT NULL, 
+LASTMODIFICATIONDATE TIMESTAMP, 
+RULESBYTEARRAY BLOB,  
+STARTDATE TIMESTAMP default current_timestamp,  
+OPTLOCK INTEGER, 
+PRIMARY KEY (ID)
+); 
+
+drop table if exists drools.WORKITEMINFO; 
+CREATE TABLE drools.WORKITEMINFO 
+(
+WORKITEMID BIGINT NOT NULL, 
+CREATIONDATE TIMESTAMP default current_timestamp, 
+`NAME` VARCHAR(500), 
+PROCESSINSTANCEID BIGINT, 
+STATE BIGINT, 
+OPTLOCK INTEGER, 
+WORKITEMBYTEARRAY BLOB, 
+PRIMARY KEY (WORKITEMID)
+); 
+
+drop table if exists drools.droolspdpentity; 
+CREATE TABLE drools.DROOLSPDPENTITY
+(
+  PDPID VARCHAR(100) NOT NULL,
+  DESIGNATED BOOLEAN NOT NULL DEFAULT FALSE,
+  PRIORITY INT NOT NULL DEFAULT 0,
+  UPDATEDDATE DATE NOT NULL,
+  GROUPID VARCHAR(100) NOT NULL,
+  SESSIONID BIGINT NOT NULL
+);
+
diff --git a/packages/base/src/files/data/mysql/160401_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/160401_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..c8bbe03
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.droolspdpentity; 
+CREATE TABLE drools.DROOLSPDPENTITY
+(
+  PDPID VARCHAR(100) NOT NULL,
+  DESIGNATED BOOLEAN NOT NULL DEFAULT FALSE,
+  PRIORITY INT NOT NULL DEFAULT 0,
+  UPDATEDDATE DATE NOT NULL,
+  GROUPID VARCHAR(100) NOT NULL,
+  SESSIONID BIGINT NOT NULL
+);
diff --git a/packages/base/src/files/data/mysql/160401_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/160401_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..e7d9221
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.droolspdpentity; 
+CREATE TABLE drools.DROOLSPDPENTITY
+(
+  PDPID VARCHAR(100) NOT NULL,
+  DESIGNATED BOOLEAN NOT NULL DEFAULT FALSE,
+  PRIORITY INT NOT NULL DEFAULT 0,
+  UPDATEDDATE TIMESTAMP NOT NULL,
+  GROUPID VARCHAR(100) NOT NULL,
+  SESSIONID BIGINT NOT NULL
+);
diff --git a/packages/base/src/files/data/mysql/160700_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/160700_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..c8613bb
--- /dev/null
@@ -0,0 +1,25 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.droolssessionentity; 
+drop table if exists drools.droolspdpentity; 
+drop table if exists drools.sessioninfo; 
+drop table if exists drools.WORKITEMINFO; 
+
diff --git a/packages/base/src/files/data/mysql/160700_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/160700_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..3350859
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.droolssessionentity; 
+drop table if exists drools.droolspdpentity; 
+CREATE TABLE drools.DROOLSPDPENTITY 
+( 
+  PDPID VARCHAR(100) NOT NULL, 
+  DESIGNATED BOOLEAN NOT NULL DEFAULT FALSE, 
+  PRIORITY INT NOT NULL DEFAULT 0, 
+  UPDATEDDATE TIMESTAMP NOT NULL, 
+  GROUPID VARCHAR(100) NOT NULL, 
+  SESSIONID BIGINT NOT NULL, 
+  PRIMARY KEY(PDPID) 
+); 
+CREATE TABLE drools.DROOLSSESSIONENTITY 
+( 
+  PDPID VARCHAR(100) NOT NULL, 
+  SESSIONNAME VARCHAR(100) NOT NULL, 
+  SESSIONID BIGINT NOT NULL, 
+  PDPENTITY_pdpId BIGINT NOT NULL, 
+  PRIMARY KEY(PDPID,SESSIONNAME) 
+); 
+ALTER TABLE drools.DROOLSSESSIONENTITY ADD CONSTRAINT FK_DROOLSSESSIONENTITY_DROOLSPDPENTITY_PDPID 
+FOREIGN KEY (PDPID) REFERENCES drools.DROOLSPDPENTITY (PDPID);
+
+drop table if exists drools.sessioninfo; 
+CREATE TABLE drools.SESSIONINFO 
+( 
+ID BIGINT NOT NULL, 
+LASTMODIFICATIONDATE TIMESTAMP, 
+RULESBYTEARRAY BLOB, 
+STARTDATE TIMESTAMP default current_timestamp, 
+OPTLOCK INTEGER, 
+PRIMARY KEY (ID) 
+); 
+drop table if exists drools.WORKITEMINFO; 
+CREATE TABLE drools.WORKITEMINFO 
+( 
+WORKITEMID BIGINT NOT NULL, 
+CREATIONDATE TIMESTAMP default current_timestamp, 
+`NAME` VARCHAR(500), 
+PROCESSINSTANCEID BIGINT, 
+STATE BIGINT, 
+OPTLOCK INTEGER, 
+WORKITEMBYTEARRAY BLOB, 
+PRIMARY KEY (WORKITEMID) 
+);
diff --git a/packages/base/src/files/data/mysql/161000_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/161000_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..b1ab793
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.droolssessionentity; 
+drop table if exists drools.droolspdpentity; 
+CREATE TABLE drools.DROOLSPDPENTITY 
+( 
+  PDPID VARCHAR(100) NOT NULL, 
+  DESIGNATED BOOLEAN NOT NULL DEFAULT FALSE, 
+  PRIORITY INT NOT NULL DEFAULT 0, 
+  UPDATEDDATE TIMESTAMP NOT NULL, 
+  GROUPID VARCHAR(100) NOT NULL, 
+  SESSIONID BIGINT NOT NULL, 
+  PRIMARY KEY(PDPID) 
+); 
+CREATE TABLE drools.DROOLSSESSIONENTITY 
+( 
+  PDPID VARCHAR(100) NOT NULL, 
+  SESSIONNAME VARCHAR(100) NOT NULL, 
+  SESSIONID BIGINT NOT NULL, 
+  PDPENTITY_pdpId BIGINT NOT NULL, 
+  PRIMARY KEY(PDPID,SESSIONNAME) 
+); 
+ALTER TABLE drools.DROOLSSESSIONENTITY ADD CONSTRAINT FK_DROOLSSESSIONENTITY_DROOLSPDPENTITY_PDPID 
+FOREIGN KEY (PDPID) REFERENCES drools.DROOLSPDPENTITY (PDPID);
+
+drop table if exists drools.LastSiteEntity; 
+
diff --git a/packages/base/src/files/data/mysql/161000_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/161000_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..9ef2442
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+DROP TABLE if exists drools.DROOLSSESSIONENTITY; 
+DROP TABLE if exists drools.DROOLSPDPENTITY; 
+CREATE TABLE if not exists drools.DROOLSPDPENTITY 
+(
+pdpId VARCHAR(255) NOT NULL, 
+designated TINYINT(1) default 0 NOT NULL, 
+priority INTEGER NOT NULL, 
+site VARCHAR(50), 
+updatedDate DATETIME NOT NULL, 
+PRIMARY KEY (pdpId)
+); 
+
+CREATE TABLE if not exists drools.DROOLSSESSIONENTITY 
+(
+sessionName VARCHAR(255) NOT NULL, 
+pdpId VARCHAR(255) NOT NULL, 
+sessionId BIGINT NOT NULL, 
+PDPENTITY_pdpId VARCHAR(255), 
+PRIMARY KEY (sessionName, pdpId)
+); 
+ALTER TABLE drools.DROOLSSESSIONENTITY ADD CONSTRAINT FK_DROOLSSESSIONENTITY_PDPENTITY_pdpId 
+FOREIGN KEY (PDPENTITY_pdpId) 
+REFERENCES drools.DROOLSPDPENTITY (pdpId);  
+
+drop table if exists drools.LastSiteEntity; 
+
+CREATE TABLE `drools`.`LastSiteEntity` 
+( `id` INT NOT NULL , 
+`siteName` VARCHAR(50) NOT NULL 
+); 
+
+
diff --git a/packages/base/src/files/data/mysql/161001_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/161001_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..983a9f3
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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 foreign_key_checks=0; 
+
+drop table if exists drools.LastSiteEntity; 
+
+CREATE TABLE `drools`.`LastSiteEntity` 
+( `id` INT NOT NULL , 
+`siteName` VARCHAR(50) NOT NULL 
+); 
+
+drop table if exists drools.DROOLSPDPENTITY; 
+
+CREATE TABLE if not exists drools.DROOLSPDPENTITY 
+(
+pdpId VARCHAR(255) NOT NULL, 
+designated TINYINT(1) default 0 NOT NULL, 
+priority INTEGER NOT NULL, 
+site VARCHAR(50), 
+updatedDate DATETIME NOT NULL, 
+PRIMARY KEY (pdpId)
+); 
+
+drop table if exists drools.DROOLSSESSIONENTITY; 
+CREATE TABLE if not exists drools.DROOLSSESSIONENTITY 
+(
+sessionName VARCHAR(255) NOT NULL, 
+pdpId VARCHAR(255) NOT NULL, 
+sessionId BIGINT NOT NULL, 
+PDPENTITY_pdpId VARCHAR(255), 
+PRIMARY KEY (sessionName, pdpId)
+); 
+ALTER TABLE drools.DROOLSSESSIONENTITY ADD CONSTRAINT FK_DROOLSSESSIONENTITY_PDPENTITY_pdpId 
+FOREIGN KEY (PDPENTITY_pdpId) 
+REFERENCES drools.DROOLSPDPENTITY (pdpId);  
+
+set foreign_key_checks=1; 
diff --git a/packages/base/src/files/data/mysql/161001_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/161001_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..2731e1b
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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 foreign_key_checks=0; 
+
+drop table if exists drools.LastSiteEntity; 
+
+drop table if exists drools.DROOLSPDPENTITY; 
+
+CREATE TABLE if not exists drools.DROOLSPDPENTITY 
+( 
+pdpId VARCHAR(255) NOT NULL, 
+designated TINYINT(1) default 0 NOT NULL, 
+priority INTEGER NOT NULL, 
+site VARCHAR(50), 
+updatedDate DATETIME NOT NULL, 
+designatedDate DATETIME NOT NULL, 
+PRIMARY KEY (pdpId) 
+);
+
+drop table if exists drools.DROOLSSESSIONENTITY; 
+CREATE TABLE if not exists drools.DROOLSSESSIONENTITY 
+(
+sessionName VARCHAR(255) NOT NULL, 
+pdpId VARCHAR(255) NOT NULL, 
+sessionId BIGINT NOT NULL, 
+PDPENTITY_pdpId VARCHAR(255), 
+PRIMARY KEY (sessionName, pdpId)
+); 
+ALTER TABLE drools.DROOLSSESSIONENTITY ADD CONSTRAINT FK_DROOLSSESSIONENTITY_PDPENTITY_pdpId 
+FOREIGN KEY (PDPENTITY_pdpId) 
+REFERENCES drools.DROOLSPDPENTITY (pdpId);  
+
+set foreign_key_checks=1; 
diff --git a/packages/base/src/files/data/mysql/161002_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/161002_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..90ed645
--- /dev/null
@@ -0,0 +1,21 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.IntegrityAuditEntity;
diff --git a/packages/base/src/files/data/mysql/161002_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/161002_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..ff99d36
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.IntegrityAuditEntity;
+create table if not exists drools.IntegrityAuditEntity
+(
+    id int not null auto_increment, 
+    persistenceUnit varchar(100) not null, 
+    site varchar(100), 
+    nodeType varchar(100), 
+    resourceName varchar(100) not null, 
+    designated boolean default false, 
+    jdbcDriver varchar(100) not null, 
+    jdbcUrl varchar(100) not null, 
+    jdbcUser varchar(30) not null, 
+    jdbcPassword varchar(30) not null, 
+    createdDate TIMESTAMP NOT NULL default current_timestamp,
+    lastUpdated TIMESTAMP NOT NULL,
+    primary key(id)
+); 
+
+alter table drools.IntegrityAuditEntity add constraint resourceName_uniq unique(resourceName);
+
diff --git a/packages/base/src/files/data/mysql/161003_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/161003_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..ba9ac57
--- /dev/null
@@ -0,0 +1,22 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.SEQUENCE; 
diff --git a/packages/base/src/files/data/mysql/161003_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/161003_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..7f8c17c
--- /dev/null
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists drools.SEQUENCE; 
+CREATE TABLE drools.SEQUENCE
+(
+SEQ_NAME VARCHAR(50) NOT NULL,
+SEQ_COUNT NUMERIC(38),
+PRIMARY KEY (SEQ_NAME)
+); 
+
+INSERT INTO drools.SEQUENCE (SEQ_NAME,SEQ_COUNT) VALUES ('SEQ_GEN',3050); 
diff --git a/packages/base/src/files/data/mysql/161004_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/161004_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..0f75658
--- /dev/null
@@ -0,0 +1,2 @@
+alter table drools.droolsPdpEntity modify updatedDate datetime not null; 
+alter table drools.droolsPdpEntity modify designatedDate datetime not null; 
diff --git a/packages/base/src/files/data/mysql/161004_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/161004_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..f3a6cdd
--- /dev/null
@@ -0,0 +1,5 @@
+alter table drools.droolsPdpEntity modify updatedDate timestamp not null; 
+alter table drools.droolsPdpEntity modify designatedDate timestamp not null; 
+
+
\ No newline at end of file
diff --git a/packages/base/src/files/data/mysql/170200_droolspdp_downgrade_script.sql b/packages/base/src/files/data/mysql/170200_droolspdp_downgrade_script.sql
new file mode 100644 (file)
index 0000000..928a584
--- /dev/null
@@ -0,0 +1,21 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+alter table drools.IntegrityAuditEntity modify jdbcUrl varchar(100) not null; 
diff --git a/packages/base/src/files/data/mysql/170200_droolspdp_upgrade_script.sql b/packages/base/src/files/data/mysql/170200_droolspdp_upgrade_script.sql
new file mode 100644 (file)
index 0000000..93bb69e
--- /dev/null
@@ -0,0 +1,21 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+alter table drools.IntegrityAuditEntity modify jdbcUrl varchar(200) not null; 
diff --git a/packages/base/src/files/etc/cron.d/monitor.cron b/packages/base/src/files/etc/cron.d/monitor.cron
new file mode 100755 (executable)
index 0000000..b732172
--- /dev/null
@@ -0,0 +1 @@
+* * * * * export POLICY_HOME=${{POLICY_HOME}}; ${{POLICY_HOME}}/bin/monitor.sh >/dev/null 2>&1
diff --git a/packages/base/src/files/etc/monitor/monitor.cfg b/packages/base/src/files/etc/monitor/monitor.cfg
new file mode 100644 (file)
index 0000000..afc6c71
--- /dev/null
@@ -0,0 +1,6 @@
+# Line Format: component=status where
+#   component=<component name>, e.g. policy-management-controller
+#   status=on|off where
+#      on: component is to be monitored and should started
+#      off: component is to be monitored and should stopped
+# There should be no component duplicate lines
diff --git a/packages/base/src/files/etc/profile.d/env.sh b/packages/base/src/files/etc/profile.d/env.sh
new file mode 100644 (file)
index 0000000..be8e747
--- /dev/null
@@ -0,0 +1,35 @@
+###
+# ============LICENSE_START=======================================================
+# Base Package
+# ================================================================================
+# 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=========================================================
+###
+
+export POLICY_HOME=${{POLICY_HOME}}
+export JAVA_HOME=${{JAVA_HOME}}
+export ENGINE_MANAGEMENT_USER=${{ENGINE_MANAGEMENT_USER}}
+export ENGINE_MANAGEMENT_PASSWORD=${{ENGINE_MANAGEMENT_PASSWORD}}
+export ENGINE_MANAGEMENT_PORT=${{ENGINE_MANAGEMENT_PORT}}
+export ENGINE_MANAGEMENT_HOST=${{ENGINE_MANAGEMENT_HOST}}
+
+for x in $POLICY_HOME/bin $JAVA_HOME/bin $HOME/bin ; do
+  if [ -d $x ] ; then
+    case ":$PATH:" in
+      *":$x:"*) :;; # already there
+      *) PATH="$x:$PATH";;
+    esac
+  fi
+done
diff --git a/packages/base/src/files/etc/profile.d/su.cfg b/packages/base/src/files/etc/profile.d/su.cfg
new file mode 100644 (file)
index 0000000..9cacea3
--- /dev/null
@@ -0,0 +1 @@
+# name=value pairs for su purposes
diff --git a/packages/base/src/files/install/mysql/data/151000_downgrade_script.sql b/packages/base/src/files/install/mysql/data/151000_downgrade_script.sql
new file mode 100644 (file)
index 0000000..d336c5c
--- /dev/null
@@ -0,0 +1,75 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+use xacml;\r
+\r
+DROP TABLE IF EXISTS XACML.SYSTEMLOGDB;\r
+DROP TABLE IF EXISTS XACML.SEQUENCE;\r
+DROP TABLE IF EXISTS XACML.RULEALGORITHMS;\r
+DROP TABLE IF EXISTS XACML.ROLES;\r
+DROP TABLE IF EXISTS XACML.POLICYALGORITHMS;\r
+DROP TABLE IF EXISTS XACML.POLICY_MANANGEMENT;\r
+DROP TABLE IF EXISTS XACML.PIPRESOLVERPARAMS;\r
+DROP TABLE IF EXISTS XACML.PIPRESOLVER;\r
+DROP TABLE IF EXISTS XACML.PIPCONFIGPARAMS;\r
+DROP TABLE IF EXISTS XACML.PIPCONFIGURATION;\r
+DROP TABLE IF EXISTS XACML.PIPTYPE;\r
+DROP TABLE IF EXISTS XACML.OBADVICEEXPRESSIONS;\r
+DROP TABLE IF EXISTS XACML.GLOBALROLESETTINGS;\r
+DROP TABLE IF EXISTS XACML.FUNCTIONARGUMENTS;\r
+DROP TABLE IF EXISTS XACML.FUNCTIONDEFINITION;\r
+DROP TABLE IF EXISTS XACML.ECOMPNAME;\r
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;\r
+DROP TABLE IF EXISTS XACML.ATTRIBUTEASSIGNMENT;\r
+DROP TABLE IF EXISTS XACML.CONSTRAINTVALUES;\r
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;\r
+DROP TABLE IF EXISTS XACML.OBADVICE;\r
+DROP TABLE IF EXISTS XACML.CONSTRAINTTYPE;\r
+DROP TABLE IF EXISTS XACML.CATEGORY;\r
+DROP TABLE IF EXISTS XACML.DATATYPE;\r
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;\r
+DROP TABLE IF EXISTS XACML.SERVICEGROUP; \r
+DROP TABLE IF EXISTS XACML.SECURITYZONE;\r
+DROP TABLE IF EXISTS XACML.POLICYENTITY;\r
+DROP TABLE IF EXISTS XACML.CONFIGURATIONDATAENTITY;\r
+DROP TABLE IF EXISTS XACML.POLICYDBDAOENTITY;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYSCORE;\r
+DROP TABLE IF EXISTS XACML.ACTIONLIST;\r
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;\r
+DROP TABLE IF EXISTS XACML.TERM;\r
+DROP TABLE IF EXISTS XACML.PREFIXLIST;\r
+DROP TABLE IF EXISTS XACML.SCOPE; \r
+DROP TABLE IF EXISTS XACML.ENFORCINGTYPE;\r
+DROP TABLE IF EXISTS XACML.PORTLIST;\r
+DROP TABLE IF EXISTS XACML.GROUPSERVICELIST;\r
+DROP TABLE IF EXISTS XACML.VSCLACTION;\r
+DROP TABLE IF EXISTS XACML.VNFTYPE;\r
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;\r
+\r
+-- DROP SEQUENCE IF EXISTS XACML.SEQCONFIG;\r
+-- DROP SEQUENCE IF EXISTS XACML.SEQPOLICY;\r
+\r
+DROP TABLE IF EXISTS LOG.SEQUENCE; \r
+DROP TABLE IF EXISTS LOG.SYSTEMLOGDB; \r
+\r
+DROP VIEW IF EXISTS xacml.match_functions;\r
+DROP VIEW IF EXISTS xacml.xacml.function_flattener;\r
+DROP VIEW IF EXISTS xacml.xacml.higherorder_bag_functions;\r
diff --git a/packages/base/src/files/install/mysql/data/151000_upgrade_script.sql b/packages/base/src/files/install/mysql/data/151000_upgrade_script.sql
new file mode 100644 (file)
index 0000000..065d705
--- /dev/null
@@ -0,0 +1,1563 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * Base Package\r
+ * ================================================================================\r
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+use xacml;\r
+\r
+DROP TABLE IF EXISTS XACML.SYSTEMLOGDB;\r
+DROP TABLE IF EXISTS XACML.SEQUENCE;\r
+DROP TABLE IF EXISTS XACML.RULEALGORITHMS;\r
+DROP TABLE IF EXISTS XACML.ROLES;\r
+DROP TABLE IF EXISTS XACML.POLICYALGORITHMS;\r
+DROP TABLE IF EXISTS XACML.POLICY_MANANGEMENT;\r
+DROP TABLE IF EXISTS XACML.PIPRESOLVERPARAMS;\r
+DROP TABLE IF EXISTS XACML.PIPRESOLVER;\r
+DROP TABLE IF EXISTS XACML.PIPCONFIGPARAMS;\r
+DROP TABLE IF EXISTS XACML.PIPCONFIGURATION;\r
+DROP TABLE IF EXISTS XACML.PIPTYPE;\r
+DROP TABLE IF EXISTS XACML.OBADVICEEXPRESSIONS;\r
+DROP TABLE IF EXISTS XACML.GLOBALROLESETTINGS;\r
+DROP TABLE IF EXISTS XACML.FUNCTIONARGUMENTS;\r
+DROP TABLE IF EXISTS XACML.FUNCTIONDEFINITION;\r
+DROP TABLE IF EXISTS XACML.ECOMPNAME;\r
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;\r
+DROP TABLE IF EXISTS XACML.ATTRIBUTEASSIGNMENT;\r
+DROP TABLE IF EXISTS XACML.CONSTRAINTVALUES;\r
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;\r
+DROP TABLE IF EXISTS XACML.OBADVICE;\r
+DROP TABLE IF EXISTS XACML.CONSTRAINTTYPE;\r
+DROP TABLE IF EXISTS XACML.CATEGORY;\r
+DROP TABLE IF EXISTS XACML.DATATYPE;\r
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;\r
+DROP TABLE IF EXISTS XACML.SERVICEGROUP; \r
+DROP TABLE IF EXISTS XACML.SECURITYZONE; \r
+DROP TABLE IF EXISTS XACML.VSCLACTION; \r
+DROP TABLE IF EXISTS XACML.VNFTYPE; \r
+DROP TABLE IF EXISTS XACML.POLICYENTITY;\r
+DROP TABLE IF EXISTS XACML.CONFIGURATIONDATAENTITY;\r
+DROP TABLE IF EXISTS XACML.PolicyDBDaoEntity;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYSCORE;\r
+DROP TABLE IF EXISTS XACML.ACTIONLIST;\r
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;\r
+DROP TABLE IF EXISTS XACML.TERM;\r
+DROP TABLE IF EXISTS XACML.PREFIXLIST;\r
+DROP TABLE IF EXISTS XACML.SCOPE; \r
+DROP TABLE IF EXISTS XACML.GROUPSERVICELIST;\r
+DROP TABLE IF EXISTS XACML.ENFORCINGTYPE;\r
+DROP TABLE IF EXISTS XACML.PORTLIST;\r
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;\r
+\r
+-- DROP SEQUENCE IF EXISTS XACML.SEQCONFIG;\r
+-- DROP SEQUENCE IF EXISTS XACML.SEQPOLICY;\r
+DROP TABLE IF EXISTS LOG.SEQUENCE; \r
+DROP TABLE IF EXISTS LOG.SYSTEMLOGDB; \r
+\r
+DROP VIEW IF EXISTS xacml.match_functions;\r
+DROP VIEW IF EXISTS xacml.function_flattener;\r
+DROP VIEW IF EXISTS xacml.higherorder_bag_functions;\r
+\r
+DROP TABLE IF EXISTS XACML.GroupServiceList;\r
+\r
+CREATE TABLE XACML.GroupServiceList\r
+(\r
+id INTEGER NOT NULL,\r
+name varchar(32),\r
+serviceList varchar(255),\r
+PRIMARY KEY (id)\r
+)\r
+;\r
+CREATE INDEX IDX_GROUPSERVICELIST ON XACML.GROUPSERVICELIst(ID);\r
+\r
+DROP TABLE IF EXISTS XACML.PolicyAlgorithms;\r
+\r
+CREATE TABLE XACML.PolicyAlgorithms\r
+(\r
+id INTEGER NOT NULL,\r
+ is_standard CHAR NOT NULL,\r
+ short_name VARCHAR(64) NOT NULL,\r
+ xacml_id VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (id)\r
+) \r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.AttributeAssignment;\r
+\r
+CREATE TABLE XACML.AttributeAssignment\r
+(\r
+id INTEGER NOT NULL,\r
+ attribute_id INTEGER,\r
+ expression VARCHAR(5000) NOT NULL,\r
+ OBADVICE_id INTEGER,\r
+ PRIMARY KEY (id)\r
+) \r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.roles;\r
+CREATE TABLE XACML.roles\r
+(\r
+id INTEGER NOT NULL,\r
+ attuid VARCHAR(45) NOT NULL,\r
+ role VARCHAR(45) NOT NULL,\r
+ scope VARCHAR(45),\r
+ PRIMARY KEY (id)\r
+) \r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYSCORE;\r
+CREATE TABLE XACML.POLICYSCORE\r
+(\r
+POLICY_NAME VARCHAR(200) NOT NULL,\r
+ POLICY_SCORE VARCHAR(100),\r
+ PRIMARY KEY (POLICY_NAME)\r
+) \r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.GlobalRoleSettings;\r
+CREATE TABLE XACML.GlobalRoleSettings\r
+(\r
+role VARCHAR(45) NOT NULL,\r
+ lockdown BOOLEAN,\r
+ PRIMARY KEY (role)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PIPResolverParams;\r
+CREATE TABLE XACML.PIPResolverParams\r
+(\r
+id INTEGER NOT NULL,\r
+ PARAM_DEFAULT VARCHAR(2048),\r
+ PARAM_NAME VARCHAR(1024) NOT NULL,\r
+ PARAM_VALUE VARCHAR(2048) NOT NULL,\r
+ REQUIRED CHAR NOT NULL,\r
+ ID_RESOLVER INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.Attribute;\r
+CREATE TABLE XACML.Attribute\r
+(\r
+id INTEGER NOT NULL,\r
+ ATTRIBUTE_VALUE VARCHAR(255),\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048),\r
+ is_designator CHAR NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ PRIORITY VARCHAR(45),\r
+ selector_path VARCHAR(2048),\r
+ xacml_id VARCHAR(100) NOT NULL UNIQUE,\r
+ category INTEGER,\r
+ constraint_type INTEGER,\r
+ datatype INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.FunctionArguments;\r
+CREATE TABLE XACML.FunctionArguments\r
+(\r
+id INTEGER NOT NULL,\r
+ arg_index INTEGER NOT NULL,\r
+ is_bag INTEGER NOT NULL,\r
+ datatype_id INTEGER,\r
+ function_id INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.actionlist;\r
+CREATE TABLE XACML.actionlist\r
+(\r
+id INTEGER NOT NULL,\r
+ actionname VARCHAR(45) NOT NULL,\r
+ description VARCHAR(64),\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.Obadvice;\r
+CREATE TABLE XACML.Obadvice\r
+(\r
+id INTEGER NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP NOT NULL,\r
+ description VARCHAR(2048),\r
+ fulfill_on VARCHAR(32),\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ type VARCHAR(100) NOT NULL,\r
+ xacml_id VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ObadviceExpressions;\r
+CREATE TABLE XACML.ObadviceExpressions\r
+(\r
+id INTEGER NOT NULL,\r
+ type VARCHAR(100) NOT NULL,\r
+ obadvice_id INTEGER,\r
+ attribute_id INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.RuleAlgorithms;\r
+CREATE TABLE XACML.RuleAlgorithms\r
+(\r
+id INTEGER NOT NULL,\r
+ is_standard CHAR NOT NULL,\r
+ short_name VARCHAR(64) NOT NULL,\r
+ xacml_id VARCHAR(255) NOT NULL UNIQUE,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ConstraintValues;\r
+CREATE TABLE XACML.ConstraintValues\r
+(\r
+id INTEGER NOT NULL,\r
+ property VARCHAR(1000),\r
+ value VARCHAR(1000),\r
+ attribute_id INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.DecisionSettings;\r
+CREATE TABLE XACML.DecisionSettings\r
+(\r
+id INTEGER NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048),\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ PRIORITY VARCHAR(45),\r
+ xacml_id VARCHAR(45) NOT NULL UNIQUE,\r
+ datatype INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.policy_manangement;\r
+CREATE TABLE XACML.policy_manangement\r
+(\r
+id INTEGER NOT NULL,\r
+ CONFIG_NAME VARCHAR(45) NOT NULL,\r
+ CREATE_DATE_TIME TIMESTAMP NOT NULL,\r
+ CREATED_BY VARCHAR(45) NOT NULL,\r
+ ECOMP_NAME VARCHAR(45) NOT NULL,\r
+ POLICY_NAME VARCHAR(45) NOT NULL,\r
+ scope VARCHAR(45) NOT NULL,\r
+ UPDATE_DATE_TIME TIMESTAMP NOT NULL,\r
+ UPDATED_BY VARCHAR(45) NOT NULL,\r
+ XML text NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PIPConfiguration;\r
+CREATE TABLE XACML.PIPConfiguration\r
+(\r
+id INTEGER NOT NULL,\r
+ CLASSNAME VARCHAR(2048) NOT NULL,\r
+ CREATED_BY VARCHAR(255) NOT NULL,\r
+ CREATED_DATE TIMESTAMP NOT NULL,\r
+ DESCRIPTION VARCHAR(2048),\r
+ ISSUER VARCHAR(1024),\r
+ MODIFIED_BY VARCHAR(255) NOT NULL,\r
+ MODIFIED_DATE TIMESTAMP NOT NULL,\r
+ NAME VARCHAR(255) NOT NULL,\r
+ READ_ONLY CHAR NOT NULL,\r
+ REQUIRES_RESOLVER CHAR NOT NULL,\r
+ TYPE INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.protocollist;\r
+CREATE TABLE XACML.protocollist\r
+(\r
+id INTEGER NOT NULL,\r
+ description VARCHAR(64),\r
+ protocolname VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+\r
+DROP TABLE IF EXISTS XACML.FunctionDefinition;\r
+CREATE TABLE XACML.FunctionDefinition \r
+( \r
+id INTEGER NOT NULL,\r
+ arg_lb INTEGER NOT NULL,\r
+ arg_ub INTEGER NOT NULL,\r
+ ho_arg_lb INTEGER,\r
+ ho_arg_ub INTEGER,\r
+ ho_primitive CHAR,\r
+ is_bag_return INTEGER NOT NULL,\r
+ is_higher_order INTEGER NOT NULL,\r
+ short_name VARCHAR(64) NOT NULL,\r
+ xacml_id VARCHAR(255) NOT NULL,\r
+ return_datatype INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PIPResolver;\r
+CREATE TABLE XACML.PIPResolver\r
+(\r
+id INTEGER NOT NULL,\r
+ CLASSNAME VARCHAR(2048) NOT NULL,\r
+ CREATED_BY VARCHAR(255) NOT NULL,\r
+ CREATED_DATE TIMESTAMP NOT NULL,\r
+ DESCRIPTION VARCHAR(2048),\r
+ ISSUER VARCHAR(1024),\r
+ MODIFIED_BY VARCHAR(255) NOT NULL,\r
+ MODIFIED_DATE TIMESTAMP NOT NULL,\r
+ NAME VARCHAR(255) NOT NULL,\r
+ READ_ONLY CHAR NOT NULL,\r
+ PIP_ID INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.TERM;\r
+CREATE TABLE XACML.TERM\r
+(\r
+id INTEGER NOT NULL,\r
+ description VARCHAR(100),\r
+ action VARCHAR(100),\r
+ destIPList VARCHAR(100),\r
+ destPortList VARCHAR(100),\r
+ portList VARCHAR(100),\r
+ protocolList VARCHAR(100),\r
+ srcIPList VARCHAR(100),\r
+ srcPortList VARCHAR(100),\r
+ termName VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PREFIXLIST;\r
+CREATE TABLE XACML.PREFIXLIST\r
+(\r
+id INTEGER NOT NULL,\r
+ pl_name VARCHAR(45) NOT NULL,\r
+ pl_value VARCHAR(64) NOT NULL,\r
+ description VARCHAR(255),\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.Datatype;\r
+CREATE TABLE XACML.Datatype\r
+(\r
+id INTEGER NOT NULL,\r
+ is_standard CHAR NOT NULL,\r
+ short_name VARCHAR(64) NOT NULL,\r
+ xacml_id VARCHAR(255) NOT NULL UNIQUE,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PIPType;\r
+CREATE TABLE XACML.PIPType\r
+(\r
+id INTEGER NOT NULL,\r
+ type VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ActionPolicyDict;\r
+CREATE TABLE XACML.ActionPolicyDict\r
+(\r
+id INTEGER NOT NULL,\r
+ ATTRIBUTE_NAME VARCHAR(45) NOT NULL,\r
+ Body VARCHAR(4096),\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048),\r
+ Headers VARCHAR(1024),\r
+ Method VARCHAR(45) NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ Type VARCHAR(45) NOT NULL,\r
+ URL VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.Category;\r
+CREATE TABLE XACML.Category\r
+(\r
+id INTEGER NOT NULL,\r
+ grouping VARCHAR(64) NOT NULL,\r
+ is_standard CHAR NOT NULL,\r
+ short_name VARCHAR(64) NOT NULL,\r
+ xacml_id VARCHAR(255) NOT NULL UNIQUE,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.Scope;\r
+CREATE TABLE XACML.Scope\r
+(\r
+scopeId BIGINT NOT NULL,\r
+ parentScope BIGINT,\r
+ scopeName VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (scopeId)\r
+)\r
+;\r
+CREATE INDEX parentScope ON Scope (parentScope);\r
+\r
+DROP TABLE IF EXISTS XACML.EcompName;\r
+CREATE TABLE XACML.EcompName\r
+(\r
+id INTEGER NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048),\r
+ ecomp_Name VARCHAR(100) NOT NULL UNIQUE,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ConstraintType;\r
+CREATE TABLE XACML.ConstraintType\r
+(\r
+id INTEGER NOT NULL,\r
+ constraint_type VARCHAR(64) NOT NULL,\r
+ description VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.EnforcingType;\r
+CREATE TABLE XACML.EnforcingType\r
+(\r
+id INTEGER NOT NULL,\r
+ connectionQuery VARCHAR(255) NOT NULL,\r
+ enforcingType VARCHAR(255) NOT NULL UNIQUE,\r
+ script VARCHAR(255) NOT NULL,\r
+ valueQuery VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PIPConfigParams;\r
+CREATE TABLE XACML.PIPConfigParams\r
+(\r
+id INTEGER NOT NULL,\r
+ PARAM_DEFAULT VARCHAR(2048),\r
+ PARAM_NAME VARCHAR(1024) NOT NULL,\r
+ PARAM_VALUE VARCHAR(2048) NOT NULL,\r
+ REQUIRED CHAR NOT NULL,\r
+ PIP_ID INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.portlist;\r
+CREATE TABLE XACML.portlist\r
+(\r
+id INTEGER NOT NULL,\r
+ description VARCHAR(64),\r
+ portname VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.SEQUENCE;\r
+CREATE TABLE XACML.SEQUENCE\r
+(\r
+SEQ_NAME VARCHAR(50) NOT NULL,\r
+ SEQ_COUNT NUMERIC(38),\r
+ PRIMARY KEY (SEQ_NAME)\r
+)\r
+;\r
+-- INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0);\r
+-- CREATE SEQUENCE seq START WITH 1;\r
+\r
+DROP TABLE IF EXISTS XACML.SYSTEMLOGDB;\r
+CREATE TABLE XACML.SYSTEMLOGDB\r
+(\r
+ id INTEGER NOT NULL AUTO_INCREMENT,\r
+ system VARCHAR(255) NOT NULL,\r
+ description VARCHAR(2048),\r
+ remote VARCHAR(255) NOT NULL,\r
+ type VARCHAR(10) NOT NULL,\r
+ date TIMESTAMP NOT NULL,\r
+ logtype VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (id)\r
+) \r
+\r
+;\r
+\r
+DROP TABLE IF EXISTS LOG.SEQUENCE;\r
+CREATE TABLE LOG.SEQUENCE\r
+(\r
+SEQ_NAME VARCHAR(50) NOT NULL,\r
+ SEQ_COUNT NUMERIC(38),\r
+ PRIMARY KEY (SEQ_NAME)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS LOG.SYSTEMLOGDB;\r
+CREATE TABLE LOG.SYSTEMLOGDB\r
+(\r
+ id INTEGER NOT NULL AUTO_INCREMENT,\r
+ system VARCHAR(255) NOT NULL,\r
+ description VARCHAR(2048),\r
+ remote VARCHAR(255) NOT NULL,\r
+ type VARCHAR(10) NOT NULL,\r
+ date TIMESTAMP NOT NULL,\r
+ logtype VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (id)\r
+) \r
+;\r
+\r
+drop table if exists SUPPORT.DB_VERSION; \r
+create table SUPPORT.DB_VERSION\r
+(\r
+  the_key varchar(20) primary key not null, \r
+  version varchar(20)\r
+) \r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.SERVICEGROUP; \r
+CREATE TABLE XACML.SERVICEGROUP\r
+(\r
+id integer NOT NULL,\r
+name varchar(32),\r
+type varchar(16),\r
+transportprotocol varchar(255),\r
+appprotocol varchar(255),\r
+ports varchar(255), \r
+`desc` varchar(255),\r
+primary key(id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.SECURITYZONE; \r
+CREATE TABLE XACML.SECURITYZONE\r
+(\r
+id integer NOT NULL,\r
+name varchar(32),\r
+value varchar(64), \r
+primary key(id)\r
+)\r
+;\r
+\r
+CREATE TABLE XACML.VSCLACTION\r
+(\r
+ID INTEGER NOT NULL,\r
+VSCL_ACTION VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45) NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+CREATE TABLE XACML.VNFTYPE\r
+(\r
+ID INTEGER NOT NULL,\r
+VNF_TYPE VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45) NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYENTITY;\r
+CREATE TABLE XACML.PolicyEntity\r
+(\r
+policyId BIGINT NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ deleted BOOLEAN NOT NULL,\r
+ description VARCHAR(2048) NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ policyData TEXT,\r
+ policyName VARCHAR(255) NOT NULL,\r
+ scope VARCHAR(255) NOT NULL,\r
+ version INTEGER,\r
+ configurationDataId BIGINT,\r
+ PRIMARY KEY (policyId))\r
+;\r
+CREATE INDEX scope ON XACML.PolicyEntity (scope);\r
+CREATE INDEX policyName ON XACML.PolicyEntity (policyName);\r
+\r
+DROP TABLE IF EXISTS XACML.ConfigurationDataEntity;\r
+CREATE TABLE XACML.ConfigurationDataEntity\r
+(\r
+configurationDataId BIGINT NOT NULL,\r
+ configBody TEXT,\r
+ configType VARCHAR(255) NOT NULL,\r
+ configurationName VARCHAR(255) NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ deleted BOOLEAN NOT NULL,\r
+ description VARCHAR(2048) NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ version INTEGER,\r
+ PRIMARY KEY (configurationDataId))\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PolicyDBDaoEntity;\r
+CREATE TABLE XACML.PolicyDBDaoEntity\r
+(\r
+ policyDBDaoUrl VARCHAR(500) NOT NULL UNIQUE,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ PRIMARY KEY (policyDBDaoUrl))\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;\r
+CREATE TABLE ADDRESSGROUP\r
+(\r
+ id INTEGER NOT NULL,\r
+ name varchar(32),\r
+ description VARCHAR(64),\r
+ prefixlist varchar(255)\r
+);\r
+\r
+create index idx_addressgroup on ADDRESSGROUP(ID);\r
+\r
+\r
+\r
+create or replace view xacml.match_functions \r
+as select d.id as id, d.short_name as shortname, d.xacml_id as xacmlid,        \r
+d.return_datatype as return_datatype, d.is_bag_return as is_bag_return,        \r
+d.arg_lb as arg_lb,    d.arg_ub as arg_ub,     a1.is_bag as arg1_isbag, \r
+a1.datatype_id as arg1_datatype, a2.is_bag as arg2_isbag,      \r
+a2.datatype_id as arg2_datatype \r
+from (xacml.functiondefinition d \r
+left join xacml.functionarguments a1 on (a1.function_id = d.id and a1.arg_index = 1) \r
+left join xacml.functionarguments a2 on (a2.function_id = d.id and a2.arg_index = 2)) \r
+where (d.arg_lb = 2 and d.arg_ub = 2 and d.return_datatype = 18 and a1.is_bag = 0) \r
+order by d.short_name;\r
+\r
+create or replace view xacml.function_flattener \r
+as select d.id as id, d.short_name as shortname,\r
+d.return_datatype as return_datatype, d.is_bag_return as is_bag_return, \r
+d.is_higher_order as is_higher_order, d.arg_lb as arg_lb, d.arg_ub as arg_ub, \r
+a1.is_bag as arg1_isbag, a1.datatype_id as arg1_datatype, a2.is_bag as arg2_isbag, \r
+a2.datatype_id as arg2_datatype, a3.is_bag as arg3_isbag, \r
+a3.datatype_id as arg3_datatype \r
+from (xacml.functiondefinition d left join xacml.functionarguments a1 \r
+on (a1.function_id = d.id and a1.arg_index = 1) \r
+left join xacml.functionarguments a2 on (a2.function_id = d.id and a2.arg_index = 2) \r
+left join xacml.functionarguments a3 on (a3.function_id = d.id and a3.arg_index = 3)) \r
+order by d.id;\r
+\r
+create or replace view xacml.higherorder_bag_functions \r
+as select * from xacml.function_flattener \r
+where is_higher_order = 1 and is_bag_return = 1 and return_datatype=18 \r
+and arg_lb=2 and arg_ub=2 and arg1_isbag = 1 and (arg2_isbag = 1 or arg2_isbag is null);\r
+\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.SYSTEMLOGDB TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.SEQUENCE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.RULEALGORITHMS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ROLES TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICYALGORITHMS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICY_MANANGEMENT TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPRESOLVERPARAMS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPRESOLVER TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPCONFIGPARAMS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPCONFIGURATION TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPTYPE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.OBADVICEEXPRESSIONS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.GLOBALROLESETTINGS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.FUNCTIONARGUMENTS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.FUNCTIONDEFINITION TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ECOMPNAME TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.DECISIONSETTINGS TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ATTRIBUTEASSIGNMENT TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CONSTRAINTVALUES TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ATTRIBUTE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.OBADVICE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CONSTRAINTTYPE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CATEGORY TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.DATATYPE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ACTIONPOLICYDICT TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICYENTITY TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CONFIGURATIONDATAENTITY TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PolicyDBDaoEntity TO policy_user;\r
+\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICYSCORE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ACTIONLIST TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PROTOCOLLIST TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.TERM TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PREFIXLIST TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.SCOPE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ENFORCINGTYPE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PORTLIST TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.GROUPSERVICELIST TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.VSCLACTION TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.VNFTYPE TO policy_user;\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ADDRESSGROUP TO policy_user;\r
+\r
+GRANT SELECT, INSERT, UPDATE, DELETE ON LOG.SEQUENCE TO policy_user; \r
+GRANT SELECT, INSERT, UPDATE, DELETE ON LOG.SYSTEMLOGDB TO policy_user; \r
+\r
+grant insert, update, delete, select on support.db_version to policy_user; \r
+grant select on xacml.match_functions to policy_user; \r
+grant select on xacml.function_flattener to policy_user; \r
+grant select on xacml.higherorder_bag_functions to policy_user; \r
+\r
+\r
+\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1401,'super-admin',str_to_date('2015-05-11 19:56:54.930000','%Y-%m-%d %H:%i:%s.%f'),null,'1','super-admin',str_to_date('2015-05-11 19:56:54.930000','%Y-%m-%d %H:%i:%s.%f'),null,'true',5,null,18,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1455,'super-admin',str_to_date('2015-05-13 14:10:44.134000','%Y-%m-%d %H:%i:%s.%f'),null,'1','super-admin',str_to_date('2015-05-13 14:10:44.134000','%Y-%m-%d %H:%i:%s.%f'),null,'Test-Kat',5,null,26,'High',null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1551,'super-admin',str_to_date('2015-05-22 11:40:23.118000','%Y-%m-%d %H:%i:%s.%f'),null,'1','super-admin',str_to_date('2015-05-22 11:40:23.118000','%Y-%m-%d %H:%i:%s.%f'),null,'test',5,null,26,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1926,'super-admin',str_to_date('2015-06-09 11:42:16.580000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window starts (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:29:46.407000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Thursday_Start:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1927,'super-admin',str_to_date('2015-06-09 11:42:33.966000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window starts (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:29:24.841000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Friday_Start:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1928,'super-admin',str_to_date('2015-06-09 11:42:49.867000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window starts (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:29:32.730000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Saturday_Start:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1929,'super-admin',str_to_date('2015-06-09 11:43:11.486000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window starts (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:34:08.866000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Sunday_Start:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1954,'super-admin',str_to_date('2015-06-11 23:30:12.656000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window ends (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:30:39.869000','%Y-%m-%d %H:%i:%s.%f'),null,'Window _Monday_End:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1955,'super-admin',str_to_date('2015-06-11 23:30:46.701000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window ends (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:32:01.698000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Friday_End:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1956,'super-admin',str_to_date('2015-06-11 23:31:10.449000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window ends (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:31:42.361000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Saturday_End:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1957,'super-admin',str_to_date('2015-06-11 23:32:25.542000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window ends (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:32:45.215000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Sunday_End:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1958,'super-admin',str_to_date('2015-06-11 23:32:55.89000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window ends (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:33:11.766000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Thursday_End:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1959,'super-admin',str_to_date('2015-06-11 23:33:28.664000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window ends (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:33:47.905000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Tuesday_End:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (1960,'super-admin',str_to_date('2015-06-11 23:34:18.912000','%Y-%m-%d %H:%i:%s.%f'),'Hour when maintenance window ends (0 to 24)','1','super-admin',str_to_date('2015-06-11 23:35:12.283000','%Y-%m-%d %H:%i:%s.%f'),null,'Window_Wednesday_End:',5,null,12,null,null);\r
+INSERT INTO XACML.ATTRIBUTE (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,IS_DESIGNATOR,MODIFIED_BY,MODIFIED_DATE,SELECTOR_PATH,XACML_ID,CATEGORY,CONSTRAINT_TYPE,DATATYPE,PRIORITY,ATTRIBUTE_VALUE) VALUES (2904,'super-admin',str_to_date('2015-08-24 18:06:29.370000','%Y-%m-%d %H:%i:%s.%f'),'Test','1','super-admin',str_to_date('2015-08-24 18:06:29.370000','%Y-%m-%d %H:%i:%s.%f'),null,'KK1:(0)',5,null,26,null,null);\r
+\r
+\r
+\r
+\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (4,'subject','S','intermediary-subject','urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject');\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (5,'resource','S','resource','urn:oasis:names:tc:xacml:3.0:attribute-category:resource');\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (6,'subject','S','codebase','urn:oasis:names:tc:xacml:1.0:subject-category:codebase');\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (7,'action','S','action','urn:oasis:names:tc:xacml:3.0:attribute-category:action');\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (8,'subject','S','access-subject','urn:oasis:names:tc:xacml:1.0:subject-category:access-subject');\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (9,'environment','S','environment','urn:oasis:names:tc:xacml:3.0:attribute-category:environment');\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (10,'subject','S','requesting-machine','urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine');\r
+INSERT INTO XACML.CATEGORY (ID,GROUPING,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (11,'subject','S','recipient-subject','urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject');\r
+\r
+\r
+INSERT INTO XACML.CONSTRAINTTYPE (ID,CONSTRAINT_TYPE,DESCRIPTION) VALUES (1,'Range','Set a range of min and/or max integer/double values the attribute can be set to during policy creation.');\r
+INSERT INTO XACML.CONSTRAINTTYPE (ID,CONSTRAINT_TYPE,DESCRIPTION) VALUES (2,'Regular Expression','Define a regular expression the attribute must match against during policy creation.');\r
+INSERT INTO XACML.CONSTRAINTTYPE (ID,CONSTRAINT_TYPE,DESCRIPTION) VALUES (3,'Enumeration','Enumerate a set of values that the attribute may be set to during policy creation.');\r
+\r
+\r
+\r
+\r
+\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (12,'S','integer','http://www.w3.org/2001/XMLSchema#integer');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (13,'S','base64Binary','http://www.w3.org/2001/XMLSchema#base64Binary');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (14,'S','x500Name','urn:oasis:names:tc:xacml:1.0:data-type:x500Name');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (15,'S','dayTimeDuration','http://www.w3.org/2001/XMLSchema#dayTimeDuration');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (16,'S','time','http://www.w3.org/2001/XMLSchema#time');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (17,'S','dnsName','urn:oasis:names:tc:xacml:2.0:data-type:dnsName');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (18,'S','boolean','http://www.w3.org/2001/XMLSchema#boolean');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (19,'S','dateTime','http://www.w3.org/2001/XMLSchema#dateTime');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (20,'S','rfc822Name','urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (21,'S','date','http://www.w3.org/2001/XMLSchema#date');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (22,'S','ipAddress','urn:oasis:names:tc:xacml:2.0:data-type:ipAddress');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (23,'S','yearMonthDuration','http://www.w3.org/2001/XMLSchema#yearMonthDuration');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (24,'S','hexBinary','http://www.w3.org/2001/XMLSchema#hexBinary');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (25,'S','double','http://www.w3.org/2001/XMLSchema#double');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (26,'S','string','http://www.w3.org/2001/XMLSchema#string');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (27,'S','anyURI','http://www.w3.org/2001/XMLSchema#anyURI');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (28,'S','xpathExpression','urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression');\r
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (29,'S','user','');\r
+\r
+\r
+\r
+\r
+INSERT INTO XACML.ECOMPNAME (ID,CREATED_BY,CREATED_DATE,DESCRIPTION,ECOMP_NAME,MODIFIED_BY,MODIFIED_DATE) VALUES (1456,'super-admin',str_to_date('2015-05-13 14:21:34.778000','%Y-%m-%d %H:%i:%s.%f'),'orchestrator','MSO','super-admin',str_to_date('2015-05-13 14:21:34.778000','%Y-%m-%d %H:%i:%s.%f'));\r
+\r
+\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (1,1,0,12,1);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (2,2,0,12,1);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (3,1,0,12,2);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (4,2,0,12,2);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (5,1,0,25,3);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (6,1,1,12,4);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (7,1,1,25,5);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (8,1,0,26,6);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (9,2,0,26,6);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (10,1,0,26,7);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (11,2,0,26,7);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (12,1,0,26,8);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (13,2,0,26,8);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (14,1,0,26,9);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (15,2,0,26,9);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (16,1,0,26,10);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (17,1,0,26,11);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (18,1,0,18,12);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (19,1,0,26,13);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (20,1,0,12,14);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (21,1,0,26,15);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (22,1,0,25,16);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (23,1,0,26,17);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (24,1,0,16,18);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (25,1,0,26,19);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (26,1,0,21,20);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (27,1,0,26,21);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (28,1,0,19,22);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (29,1,0,26,23);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (30,1,0,27,24);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (31,1,0,26,25);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (32,1,0,15,26);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (33,1,0,26,27);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (34,1,0,23,28);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (35,1,0,26,29);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (36,1,0,14,30);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (37,1,0,26,31);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (38,1,0,20,32);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (39,1,0,26,33);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (40,1,0,22,34);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (41,1,0,26,35);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (42,1,0,17,36);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (43,2,0,27,37);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (44,1,0,26,37);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (45,1,0,26,38);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (46,2,0,27,38);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (47,1,0,26,39);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (48,2,0,26,39);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (49,1,0,26,40);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (50,2,0,27,40);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (51,1,0,26,41);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (52,2,0,12,41);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (53,3,0,12,41);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (54,1,0,27,42);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (55,2,0,12,42);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (56,3,0,12,42);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (57,1,0,18,43);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (58,2,0,18,43);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (59,1,0,12,44);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (60,2,0,12,44);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (61,1,0,25,45);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (62,2,0,25,45);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (63,1,0,21,46);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (64,2,0,21,46);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (65,1,0,16,47);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (66,2,0,16,47);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (67,1,0,19,48);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (68,2,0,19,48);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (69,1,0,15,49);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (70,2,0,15,49);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (71,1,0,23,50);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (72,2,0,23,50);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (73,1,0,27,51);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (74,2,0,27,51);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (75,1,0,14,52);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (76,2,0,14,52);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (77,1,0,20,53);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (78,2,0,20,53);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (79,1,0,24,54);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (80,2,0,24,54);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (81,1,0,13,55);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (82,2,0,13,55);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (83,1,0,12,56);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (84,2,0,12,56);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (85,1,0,25,57);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (86,2,0,25,57);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (89,1,0,25,58);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (90,2,0,25,58);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (91,1,0,12,59);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (92,2,0,12,59);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (93,1,0,25,60);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (94,2,0,25,60);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (95,1,0,12,61);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (96,2,0,12,61);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (97,1,0,25,62);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (98,2,0,25,62);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (99,1,0,12,63);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (100,2,0,12,63);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (101,1,0,12,64);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (102,1,0,25,65);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (103,1,0,25,66);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (104,1,0,25,67);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (125,1,0,26,68);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (126,1,0,26,69);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (128,1,0,12,70);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (129,1,0,12,71);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (130,2,0,12,71);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (131,1,0,12,72);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (132,2,0,12,72);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (133,1,0,12,73);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (134,2,0,12,73);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (135,1,0,25,74);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (136,2,0,25,74);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (137,1,0,25,75);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (138,2,0,25,75);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (139,1,0,25,76);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (140,2,0,25,76);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (141,1,0,25,77);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (142,2,0,25,77);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (143,1,0,19,78);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (144,2,0,15,78);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (145,1,0,19,79);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (146,2,0,23,79);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (147,1,0,19,80);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (148,2,0,15,80);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (149,1,0,19,81);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (150,2,0,23,81);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (151,1,0,21,82);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (152,2,0,23,82);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (153,1,0,21,83);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (154,2,0,23,83);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (155,1,0,26,84);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (156,2,0,26,84);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (157,1,0,26,85);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (158,2,0,26,85);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (159,1,0,26,86);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (160,2,0,26,86);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (161,1,0,26,87);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (162,2,0,26,87);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (163,1,0,16,88);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (164,2,0,16,88);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (165,1,0,16,89);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (166,2,0,16,89);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (167,1,0,16,90);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (168,2,0,16,90);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (169,1,0,16,91);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (170,2,0,16,91);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (171,1,0,16,92);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (172,2,0,16,92);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (173,1,0,19,93);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (174,2,0,19,93);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (175,1,0,19,94);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (176,2,0,19,94);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (177,1,0,19,95);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (178,2,0,19,95);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (179,1,0,19,96);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (180,2,0,19,96);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (181,1,0,21,97);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (182,2,0,21,97);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (183,1,0,21,98);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (184,2,0,21,98);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (185,2,0,21,99);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (186,1,0,21,99);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (187,2,0,21,100);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (188,1,0,21,100);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (189,1,1,26,101);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (190,1,1,26,102);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (191,1,0,26,103);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (192,2,1,26,103);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (193,1,0,26,104);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (194,1,1,12,105);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (195,1,0,12,106);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (196,2,1,12,106);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (197,1,0,12,107);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (198,1,1,25,108);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (199,1,0,25,109);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (200,2,1,25,109);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (201,1,0,25,110);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (202,1,1,18,111);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (203,1,1,18,112);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (204,1,0,18,113);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (205,2,1,18,113);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (206,1,0,18,114);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (207,1,1,16,115);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (208,1,1,16,116);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (209,1,0,16,117);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (210,2,1,16,117);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (211,1,0,16,118);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (212,1,1,21,119);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (213,1,1,21,120);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (214,1,0,21,121);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (215,2,1,21,121);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (216,1,0,21,122);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (217,1,1,19,123);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (218,1,1,19,124);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (219,1,0,19,125);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (220,2,1,19,125);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (221,1,0,19,126);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (222,1,1,27,127);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (223,1,1,27,128);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (224,1,0,27,129);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (225,2,1,27,129);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (226,1,0,27,130);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (227,1,1,24,131);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (228,1,1,24,132);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (229,1,0,24,133);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (230,2,1,24,133);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (231,1,0,24,134);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (232,1,1,13,135);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (233,1,1,13,136);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (234,1,0,13,137);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (235,2,1,13,137);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (236,1,0,13,138);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (237,1,1,15,139);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (238,1,1,15,140);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (239,1,0,15,141);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (240,2,1,15,141);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (241,1,0,15,142);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (242,1,1,23,143);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (243,1,1,23,144);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (244,2,1,23,145);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (245,1,0,23,145);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (246,1,0,23,146);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (247,1,1,14,147);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (248,1,1,14,148);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (249,1,0,14,149);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (250,2,1,14,149);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (251,1,0,14,150);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (252,1,1,20,151);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (253,1,1,20,152);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (254,1,0,20,153);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (255,2,1,20,153);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (256,1,0,20,154);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (257,1,1,22,155);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (258,1,1,22,156);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (259,1,0,22,157);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (260,2,1,22,157);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (261,1,0,22,158);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (262,1,1,17,159);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (263,1,1,17,160);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (264,1,0,17,161);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (265,2,1,17,161);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (266,1,0,17,162);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (267,1,0,26,163);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (268,2,0,26,163);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (269,1,0,26,164);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (270,2,0,27,164);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (271,1,0,26,165);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (272,2,0,22,165);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (273,1,0,26,166);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (274,2,0,17,166);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (275,1,0,26,167);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (276,2,0,20,167);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (277,1,0,26,168);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (278,2,0,14,168);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (279,1,1,26,169);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (280,2,1,26,169);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (281,1,1,26,170);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (282,2,1,26,170);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (283,1,1,26,171);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (284,1,1,26,172);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (285,2,1,26,172);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (286,1,1,26,173);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (287,2,1,26,173);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (288,2,1,12,174);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (289,1,1,12,174);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (290,1,1,12,175);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (292,2,1,12,176);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (293,1,1,12,176);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (294,2,1,12,177);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (295,1,1,12,177);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (296,1,1,25,178);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (297,2,1,25,178);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (298,1,1,25,179);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (299,1,1,25,180);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (300,2,1,25,180);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (301,1,1,25,181);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (302,2,1,25,181);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (303,1,1,18,182);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (304,2,1,18,182);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (305,1,1,18,183);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (306,2,1,18,183);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (307,1,1,18,184);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (308,1,1,18,185);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (309,2,1,18,185);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (310,1,1,18,186);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (311,2,1,18,186);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (312,2,1,16,187);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (313,1,1,16,187);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (314,1,1,16,188);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (315,2,1,16,188);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (316,1,1,16,189);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (317,1,1,16,190);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (318,2,1,16,190);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (319,1,1,16,191);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (320,2,1,16,191);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (321,1,1,21,192);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (322,2,1,21,192);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (323,1,1,21,193);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (324,2,1,21,193);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (325,1,1,21,194);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (326,1,1,21,195);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (327,2,1,21,195);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (328,1,1,21,196);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (329,2,1,21,196);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (330,1,1,19,197);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (331,2,1,19,197);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (332,1,1,19,198);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (333,2,1,19,198);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (334,1,1,19,199);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (335,1,1,19,200);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (336,2,1,19,200);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (337,1,1,19,201);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (338,2,1,19,201);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (339,1,1,27,202);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (340,2,1,27,202);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (341,1,1,27,203);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (342,2,1,27,203);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (343,1,1,27,204);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (344,1,1,27,205);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (345,2,1,27,205);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (346,1,1,27,206);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (347,2,1,27,206);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (348,1,1,24,207);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (349,2,1,24,207);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (350,1,1,24,208);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (351,2,1,24,208);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (352,1,1,24,209);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (353,1,1,24,210);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (354,2,1,24,210);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (355,1,1,24,211);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (356,2,1,24,211);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (357,1,1,13,212);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (358,2,1,13,212);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (359,1,1,13,213);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (360,2,1,13,213);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (361,1,1,13,214);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (362,1,1,13,215);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (363,2,1,13,215);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (364,1,1,13,216);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (365,2,1,13,216);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (366,1,1,15,217);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (367,2,1,15,217);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (368,1,1,15,218);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (369,2,1,15,218);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (370,1,1,15,219);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (371,1,1,15,220);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (372,2,1,15,220);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (373,1,1,15,221);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (374,2,1,15,221);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (375,1,1,23,222);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (376,2,1,23,222);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (377,1,1,23,223);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (378,2,1,23,223);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (380,1,1,23,224);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (381,1,1,23,225);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (382,2,1,23,225);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (383,2,1,23,226);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (384,1,1,23,226);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (385,1,1,14,227);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (386,2,1,14,227);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (387,1,1,14,228);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (388,2,1,14,228);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (389,1,1,14,229);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (390,1,1,14,230);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (391,2,1,14,230);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (392,1,1,14,231);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (393,2,1,14,231);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (394,1,1,20,232);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (395,2,1,20,232);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (396,1,1,20,233);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (397,2,1,20,233);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (398,1,1,20,234);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (399,1,1,20,235);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (400,2,1,20,235);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (401,1,1,20,236);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (402,2,1,20,236);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (403,1,0,14,237);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (404,2,0,14,237);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (405,1,0,26,238);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (406,2,0,20,238);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (407,1,1,12,239);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (408,2,1,12,239);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (409,1,1,25,240);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (410,2,1,25,240);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (411,1,0,18,241);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (412,1,0,18,242);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (413,1,0,12,243);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (414,2,0,18,243);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (415,1,0,18,244);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (416,1,0,18,245);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (417,2,0,null,245);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (418,3,1,null,245);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (419,1,0,18,246);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (420,2,0,null,246);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (421,3,1,null,246);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (422,1,0,18,247);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (423,2,1,null,247);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (424,3,1,null,247);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (433,1,0,18,248);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (434,2,1,null,248);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (435,3,1,null,248);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (436,1,0,18,249);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (437,2,1,null,249);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (438,3,1,null,249);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (439,1,0,18,250);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (440,2,1,null,250);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (441,3,1,null,250);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (442,1,0,null,251);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (447,2,1,null,251);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (448,1,0,28,252);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (449,1,0,28,253);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (450,2,0,28,253);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (451,1,0,28,254);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (452,2,0,28,254);\r
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (453,3,0,16,92);\r
+\r
+\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (1,2,2,null,null,null,0,0,'integer-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (2,2,2,null,null,null,0,0,'integer-subtract','urn:oasis:names:tc:xacml:1.0:function:integer-subtract',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (3,1,1,null,null,null,0,0,'double-to-integer','urn:oasis:names:tc:xacml:1.0:function:double-to-integer',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (4,1,1,null,null,null,0,0,'integer-one-and-only','urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (5,1,1,null,null,null,0,0,'double-one-and-only','urn:oasis:names:tc:xacml:1.0:function:double-one-and-only',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (6,2,2,null,null,null,0,0,'string-equal','urn:oasis:names:tc:xacml:1.0:function:string-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (7,2,2,null,null,null,0,0,'string-equal-ignore-case','urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (8,2,2,null,null,null,0,0,'string-starts-with','urn:oasis:names:tc:xacml:3.0:function:string-starts-with',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (9,2,2,null,null,null,0,0,'string-ends-with','urn:oasis:names:tc:xacml:3.0:function: string-ends-with',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (10,2,-1,null,null,null,0,0,'string-concatenate','urn:oasis:names:tc:xacml:2.0:function:string-concatenate',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (11,1,1,null,null,null,0,0,'boolean-from-string','urn:oasis:names:tc:xacml:3.0:function:boolean-from-string',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (12,1,1,null,null,null,0,0,'string-from-boolean','urn:oasis:names:tc:xacml:3.0:function:string-from-boolean',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (13,1,1,null,null,null,0,0,'integer-from-string','urn:oasis:names:tc:xacml:3.0:function:integer-from-string',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (14,1,1,null,null,null,0,0,'string-from-integer','urn:oasis:names:tc:xacml:3.0:function:string-from-integer',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (15,1,1,null,null,null,0,0,'double-from-string','urn:oasis:names:tc:xacml:3.0:function:double-from-string',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (16,1,1,null,null,null,0,0,'string-from-double','urn:oasis:names:tc:xacml:3.0:function:string-from-double',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (17,1,1,null,null,null,0,0,'time-from-string','urn:oasis:names:tc:xacml:3.0:function:time-from-string',16);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (18,1,1,null,null,null,0,0,'string-from-time','urn:oasis:names:tc:xacml:3.0:function:string-from-time',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (19,1,1,null,null,null,0,0,'date-from-string','urn:oasis:names:tc:xacml:3.0:function:date-from-string',21);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (20,1,1,null,null,null,0,0,'string-from-date','urn:oasis:names:tc:xacml:3.0:function:string-from-date',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (21,1,1,null,null,null,0,0,'dateTime-from-string','urn:oasis:names:tc:xacml:3.0:function:dateTime-from-string',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (22,1,1,null,null,null,0,0,'string-from-dateTime','urn:oasis:names:tc:xacml:3.0:function:string-from-dateTime',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (23,1,1,null,null,null,0,0,'anyURI-from-string','urn:oasis:names:tc:xacml:3.0:function:anyURI-from-string',27);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (24,1,1,null,null,null,0,0,'string-from-anyURI','urn:oasis:names:tc:xacml:3.0:function:string-from-anyURI',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (25,1,1,null,null,null,0,0,'dayTimeDuration-from-string','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-from-string',15);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (26,1,1,null,null,null,0,0,'string-from-dayTimeDuration','urn:oasis:names:tc:xacml:3.0:function:string-from-dayTimeDuration',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (27,1,1,null,null,null,0,0,'yearMonthDuration-from-string','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-from-string',23);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (28,1,1,null,null,null,0,0,'string-from-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:string-from-yearMonthDuration',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (29,1,1,null,null,null,0,0,'x500Name-from-string','urn:oasis:names:tc:xacml:3.0:function:x500Name-from-string',14);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (30,1,1,null,null,null,0,0,'string-from-x500Name','urn:oasis:names:tc:xacml:3.0:function:string-from-x500Name',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (31,1,1,null,null,null,0,0,'rfc822Name-from-string','urn:oasis:names:tc:xacml:3.0:function:rfc822Name-from-string',20);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (32,1,1,null,null,null,0,0,'string-from-rfc822Name','urn:oasis:names:tc:xacml:3.0:function:string-from-rfc822Name',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (33,1,1,null,null,null,0,0,'ipAddress-from-string','urn:oasis:names:tc:xacml:3.0:function:ipAddress-from-string',22);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (34,1,1,null,null,null,0,0,'string-from-ipAddress','urn:oasis:names:tc:xacml:3.0:function:string-from-ipAddress',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (35,1,1,null,null,null,0,0,'dnsName-from-string','urn:oasis:names:tc:xacml:3.0:function:dnsName-from-string',17);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (36,1,1,null,null,null,0,0,'string-from-dnsName','urn:oasis:names:tc:xacml:3.0:function:string-from-dnsName',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (37,2,2,null,null,null,0,0,'anyURI-starts-with','urn:oasis:names:tc:xacml:3.0:function:anyURI-starts-with',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (38,2,2,null,null,null,0,0,'anyURI-ends-with','urn:oasis:names:tc:xacml:3.0:function:anyURI-ends-with',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (39,2,2,null,null,null,0,0,'string-contains','urn:oasis:names:tc:xacml:3.0:function:string-contains',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (40,2,2,null,null,null,0,0,'anyURI-contains','urn:oasis:names:tc:xacml:3.0:function:anyURI-contains',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (41,3,3,null,null,null,0,0,'string-substring','urn:oasis:names:tc:xacml:3.0:function:string-substring',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (42,3,3,null,null,null,0,0,'anyURI-substring','urn:oasis:names:tc:xacml:3.0:function:anyURI-substring',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (43,2,2,null,null,null,0,0,'boolean-equal','urn:oasis:names:tc:xacml:1.0:function:boolean-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (44,2,2,null,null,null,0,0,'integer-equal','urn:oasis:names:tc:xacml:1.0:function:integer-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (45,2,2,null,null,null,0,0,'double-equal','urn:oasis:names:tc:xacml:1.0:function:double-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (46,2,2,null,null,null,0,0,'date-equal','urn:oasis:names:tc:xacml:1.0:function:date-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (47,2,2,null,null,null,0,0,'time-equal','urn:oasis:names:tc:xacml:1.0:function:time-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (48,2,2,null,null,null,0,0,'dateTime-equal','urn:oasis:names:tc:xacml:1.0:function:dateTime-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (49,2,2,null,null,null,0,0,'dayTimeDuration-equal','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (50,2,2,null,null,null,0,0,'yearMonthDuration-equal','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (51,2,2,null,null,null,0,0,'anyURI-equal','urn:oasis:names:tc:xacml:1.0:function:anyURI-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (52,2,2,null,null,null,0,0,'x500Name-equal','urn:oasis:names:tc:xacml:1.0:function:x500Name-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (53,2,2,null,null,null,0,0,'rfc822Name-equal','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (54,2,2,null,null,null,0,0,'hexBinary-equal','urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (55,2,2,null,null,null,0,0,'base64Binary-equal','urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (56,2,2,null,null,null,0,0,'integer-add','urn:oasis:names:tc:xacml:1.0:function:integer-add',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (57,2,2,null,null,null,0,0,'double-add','urn:oasis:names:tc:xacml:1.0:function:double-add',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (58,2,2,null,null,null,0,0,'double-subtract','urn:oasis:names:tc:xacml:1.0:function:double-subtract',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (59,2,2,null,null,null,0,0,'integer-multiply','urn:oasis:names:tc:xacml:1.0:function:integer-multiply',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (60,2,2,null,null,null,0,0,'double-multiply','urn:oasis:names:tc:xacml:1.0:function:double-multiply',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (61,2,2,null,null,null,0,0,'integer-divide','urn:oasis:names:tc:xacml:1.0:function:integer-divide',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (62,2,2,null,null,null,0,0,'double-divide','urn:oasis:names:tc:xacml:1.0:function:double-divide',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (63,2,2,null,null,null,0,0,'integer-mod','urn:oasis:names:tc:xacml:1.0:function:integer-mod',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (64,1,1,null,null,null,0,0,'integer-abs','urn:oasis:names:tc:xacml:1.0:function:integer-abs',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (65,1,1,null,null,null,0,0,'double-abs','urn:oasis:names:tc:xacml:1.0:function:double-abs',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (66,1,1,null,null,null,0,0,'round','urn:oasis:names:tc:xacml:1.0:function:round',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (67,1,1,null,null,null,0,0,'floor','urn:oasis:names:tc:xacml:1.0:function:floor',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (68,1,1,null,null,null,0,0,'string-normalize-space','urn:oasis:names:tc:xacml:1.0:function:string-normalize-space',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (69,1,1,null,null,null,0,0,'string-normalize-to-lower-case','urn:oasis:names:tc:xacml:1.0:function:string-normalize-to-lower-case',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (70,1,1,null,null,null,0,0,'integer-to-double','urn:oasis:names:tc:xacml:1.0:function:integer-to-double',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (71,2,2,null,null,null,0,0,'integer-greater-than','urn:oasis:names:tc:xacml:1.0:function:integer-greater-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (72,2,2,null,null,null,0,0,'integer-less-than','urn:oasis:names:tc:xacml:1.0:function:integer-less-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (73,2,2,null,null,null,0,0,'integer-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (74,2,2,null,null,null,0,0,'double-greater-than','urn:oasis:names:tc:xacml:1.0:function:double-greater-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (75,2,2,null,null,null,0,0,'double-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (76,2,2,null,null,null,0,0,'double-less-than','urn:oasis:names:tc:xacml:1.0:function:double-less-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (77,2,2,null,null,null,0,0,'double-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:double-less-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (78,2,2,null,null,null,0,0,'dateTime-add-dayTimeDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-add-dayTimeDuration',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (79,2,2,null,null,null,0,0,'dateTime-add-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-add-yearMonthDuration',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (80,2,2,null,null,null,0,0,'dateTime-subtract-dayTimeDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-subtract-dayTimeDuration',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (81,2,2,null,null,null,0,0,'dateTime-subtract-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-subtract-yearMonthDuration',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (82,2,2,null,null,null,0,0,'date-add-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:date-add-yearMonthDuration',21);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (83,2,2,null,null,null,0,0,'date-subtract-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration',21);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (84,2,2,null,null,null,0,0,'string-greater-than','urn:oasis:names:tc:xacml:1.0:function:string-greater-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (85,2,2,null,null,null,0,0,'string-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:string-greater-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (86,2,2,null,null,null,0,0,'string-less-than','urn:oasis:names:tc:xacml:1.0:function:string-less-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (87,2,2,null,null,null,0,0,'string-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:string-less-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (88,2,2,null,null,null,0,0,'time-greater-than','urn:oasis:names:tc:xacml:1.0:function:time-greater-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (89,2,2,null,null,null,0,0,'time-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (90,2,2,null,null,null,0,0,'time-less-than','urn:oasis:names:tc:xacml:1.0:function:time-less-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (91,2,2,null,null,null,0,0,'time-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:time-less-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (92,3,3,null,null,null,0,0,'time-in-range','urn:oasis:names:tc:xacml:2.0:function:time-in-range',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (93,2,2,null,null,null,0,0,'dateTime-greater-than','urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (94,2,2,null,null,null,0,0,'dateTime-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (95,2,2,null,null,null,0,0,'dateTime-less-than','urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (96,2,2,null,null,null,0,0,'dateTime-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (97,2,2,null,null,null,0,0,'date-greater-than','urn:oasis:names:tc:xacml:1.0:function:date-greater-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (98,2,2,null,null,null,0,0,'date-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:date-greater-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (99,2,2,null,null,null,0,0,'date-less-than','urn:oasis:names:tc:xacml:1.0:function:date-less-than',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (100,2,2,null,null,null,0,0,'date-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (101,1,1,null,null,null,0,0,'string-one-and-only','urn:oasis:names:tc:xacml:1.0:function:string-one-and-only',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (102,1,1,null,null,null,0,0,'string-bag-size','urn:oasis:names:tc:xacml:1.0:function:string-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (103,2,2,null,null,null,0,0,'string-is-in','urn:oasis:names:tc:xacml:1.0:function:string-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (104,1,-1,null,null,null,1,0,'string-bag','urn:oasis:names:tc:xacml:1.0:function:string-bag',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (105,1,1,null,null,null,0,0,'integer-bag-size','urn:oasis:names:tc:xacml:1.0:function:integer-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (106,2,2,null,null,null,0,0,'integer-is-in','urn:oasis:names:tc:xacml:1.0:function:integer-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (107,1,-1,null,null,null,1,0,'integer-bag','urn:oasis:names:tc:xacml:1.0:function:integer-bag',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (108,1,1,null,null,null,0,0,'double-bag-size','urn:oasis:names:tc:xacml:1.0:function:double-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (109,2,2,null,null,null,0,0,'double-is-in','urn:oasis:names:tc:xacml:1.0:function:double-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (110,1,-1,null,null,null,1,0,'double-bag','urn:oasis:names:tc:xacml:1.0:function:double-bag',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (111,1,1,null,null,null,0,0,'boolean-one-and-only','urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (112,1,1,null,null,null,0,0,'boolean-bag-size','urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (113,2,2,null,null,null,0,0,'boolean-is-in','urn:oasis:names:tc:xacml:1.0:function:boolean-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (114,1,-1,null,null,null,1,0,'boolean-bag','urn:oasis:names:tc:xacml:1.0:function:boolean-bag',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (115,1,1,null,null,null,0,0,'time-one-and-only','urn:oasis:names:tc:xacml:1.0:function:time-one-and-only',16);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (116,1,1,null,null,null,0,0,'time-bag-size','urn:oasis:names:tc:xacml:1.0:function:time-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (117,2,2,null,null,null,0,0,'time-is-in','urn:oasis:names:tc:xacml:1.0:function:time-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (118,1,-1,null,null,null,1,0,'time-bag','urn:oasis:names:tc:xacml:1.0:function:time-bag',16);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (119,1,1,null,null,null,0,0,'date-one-and-only','urn:oasis:names:tc:xacml:1.0:function:date-one-and-only',21);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (120,1,1,null,null,null,0,0,'date-bag-size','urn:oasis:names:tc:xacml:1.0:function:date-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (121,2,2,null,null,null,0,0,'date-is-in','urn:oasis:names:tc:xacml:1.0:function:date-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (122,1,-1,null,null,null,1,0,'date-bag','urn:oasis:names:tc:xacml:1.0:function:date-bag',21);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (123,1,1,null,null,null,0,0,'dateTime-one-and-only','urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (124,1,1,null,null,null,0,0,'dateTime-bag-size','urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (125,2,2,null,null,null,0,0,'dateTime-is-in','urn:oasis:names:tc:xacml:1.0:function:dateTime-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (126,1,-1,null,null,null,1,0,'dateTime-bag','urn:oasis:names:tc:xacml:1.0:function:dateTime-bag',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (127,1,1,null,null,null,0,0,'anyURI-one-and-only','urn:oasis:names:tc:xacml:1.0:function:anyURI-one-and-only',27);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (128,1,1,null,null,null,0,0,'anyURI-bag-size','urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (129,2,2,null,null,null,0,0,'anyURI-is-in','urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (130,1,-1,null,null,null,1,0,'anyURI-bag','urn:oasis:names:tc:xacml:1.0:function:anyURI-bag',27);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (131,1,1,null,null,null,0,0,'hexBinary-one-and-only','urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only',24);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (132,1,1,null,null,null,0,0,'hexBinary-bag-size','urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (133,2,2,null,null,null,0,0,'hexBinary-is-in','urn:oasis:names:tc:xacml:1.0:function:hexBinary-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (134,1,-1,null,null,null,1,0,'hexBinary-bag','urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag',24);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (135,1,1,null,null,null,0,0,'base64Binary-one-and-only','urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only',13);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (136,1,1,null,null,null,0,0,'base64Binary-bag-size','urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (137,2,2,null,null,null,0,0,'base64Binary-is-in','urn:oasis:names:tc:xacml:1.0:function:base64Binary-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (138,1,-1,null,null,null,1,0,'base64Binary-bag','urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag',13);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (139,1,1,null,null,null,0,0,'dayTimeDuration-one-and-only','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-one-and-only',15);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (140,1,1,null,null,null,0,0,'dayTimeDuration-bag-size','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (141,2,2,null,null,null,0,0,'dayTimeDuration-is-in','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (142,1,-1,null,null,null,1,0,'dayTimeDuration-bag','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-bag',15);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (143,1,1,null,null,null,0,0,'yearMonthDuration-one-and-only','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-one-and-only',23);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (144,1,1,null,null,null,0,0,'yearMonthDuration-bag-size','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (145,2,2,null,null,null,0,0,'yearMonthDuration-is-in','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (146,1,-1,null,null,null,1,0,'yearMonthDuration-bag','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-bag',23);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (147,1,1,null,null,null,0,0,'x500Name-one-and-only','urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only',14);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (148,1,1,null,null,null,0,0,'x500Name-bag-size','urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (149,2,2,null,null,null,0,0,'x500Name-is-in','urn:oasis:names:tc:xacml:1.0:function:x500Name-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (150,1,-1,null,null,null,1,0,'x500Name-bag','urn:oasis:names:tc:xacml:1.0:function:x500Name-bag',14);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (151,1,1,null,null,null,0,0,'rfc822Name-one-and-only','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only',20);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (152,1,1,null,null,null,0,0,'rfc822Name-bag-size','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (153,2,2,null,null,null,0,0,'rfc822Name-is-in','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (154,1,-1,null,null,null,1,0,'rfc822Name-bag','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag',20);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (155,1,1,null,null,null,0,0,'ipAddress-one-and-only','urn:oasis:names:tc:xacml:2.0:function:ipAddress-one-and-only',22);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (156,1,1,null,null,null,0,0,'ipAddress-bag-size','urn:oasis:names:tc:xacml:2.0:function:ipAddress-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (157,2,2,null,null,null,0,0,'ipAddress-is-in','urn:oasis:names:tc:xacml:2.0:function:ipAddress-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (158,1,-1,null,null,null,1,0,'ipAddress-bag','urn:oasis:names:tc:xacml:2.0:function:ipAddress-bag',22);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (159,1,1,null,null,null,0,0,'dnsName-one-and-only','urn:oasis:names:tc:xacml:2.0:function:dnsName-one-and-only',17);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (160,1,1,null,null,null,0,0,'dnsName-bag-size','urn:oasis:names:tc:xacml:2.0:function:dnsName-bag-size',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (161,2,2,null,null,null,0,0,'dnsName-is-in','urn:oasis:names:tc:xacml:2.0:function:dnsName-is-in',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (162,1,-1,null,null,null,1,0,'dnsName-bag','urn:oasis:names:tc:xacml:2.0:function:dnsName-bag',17);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (163,2,2,null,null,null,0,0,'string-regexp-match','urn:oasis:names:tc:xacml:1.0:function:string-regexp-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (164,2,2,null,null,null,0,0,'anyURI-regexp-match','urn:oasis:names:tc:xacml:2.0:function:anyURI-regexp-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (165,2,2,null,null,null,0,0,'ipAddress-regexp-match','urn:oasis:names:tc:xacml:2.0:function:ipAddress-regexp-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (166,2,2,null,null,null,0,0,'dnsName-regexp-match','urn:oasis:names:tc:xacml:2.0:function:dnsName-regexp-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (167,2,2,null,null,null,0,0,'rfc822Name-regexp-match','urn:oasis:names:tc:xacml:2.0:function:rfc822Name-regexp-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (168,2,2,null,null,null,0,0,'x500Name-regexp-match','urn:oasis:names:tc:xacml:2.0:function:x500Name-regexp-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (169,2,2,null,null,null,1,0,'string-intersection','urn:oasis:names:tc:xacml:1.0:function:string-intersection',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (170,2,2,null,null,null,0,0,'string-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (171,2,-1,null,null,null,1,0,'string-union','urn:oasis:names:tc:xacml:1.0:function:string-union',26);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (172,2,2,null,null,null,0,0,'string-subset','urn:oasis:names:tc:xacml:1.0:function:string-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (173,2,2,null,null,null,0,0,'string-set-equals','urn:oasis:names:tc:xacml:1.0:function:string-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (174,2,2,null,null,null,0,0,'integer-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:integer-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (175,2,-1,null,null,null,1,0,'integer-union','urn:oasis:names:tc:xacml:1.0:function:integer-union',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (176,2,2,null,null,null,0,0,'integer-subset','urn:oasis:names:tc:xacml:1.0:function:integer-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (177,2,2,null,null,null,0,0,'integer-set-equals','urn:oasis:names:tc:xacml:1.0:function:integer-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (178,2,2,null,null,null,0,0,'double-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:double-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (179,2,-1,null,null,null,1,0,'double-union','urn:oasis:names:tc:xacml:1.0:function:double-union',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (180,2,2,null,null,null,0,0,'double-subset','urn:oasis:names:tc:xacml:1.0:function:double-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (181,2,2,null,null,null,0,0,'double-set-equals','urn:oasis:names:tc:xacml:1.0:function:double-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (182,2,2,null,null,null,1,0,'boolean-intersection','urn:oasis:names:tc:xacml:1.0:function:boolean-intersection',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (183,2,2,null,null,null,0,0,'boolean-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:boolean-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (184,2,-1,null,null,null,1,0,'boolean-union','urn:oasis:names:tc:xacml:1.0:function:boolean-union',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (185,2,2,null,null,null,0,0,'boolean-subset','urn:oasis:names:tc:xacml:1.0:function:boolean-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (186,2,2,null,null,null,0,0,'boolean-set-equals','urn:oasis:names:tc:xacml:1.0:function:boolean-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (187,2,2,null,null,null,1,0,'time-intersection','urn:oasis:names:tc:xacml:1.0:function:time-intersection',16);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (188,2,2,null,null,null,0,0,'time-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:time-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (189,2,-1,null,null,null,1,0,'time-union','urn:oasis:names:tc:xacml:1.0:function:time-union',16);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (190,2,2,null,null,null,0,0,'time-subset','urn:oasis:names:tc:xacml:1.0:function:time-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (191,2,2,null,null,null,0,0,'time-set-equals','urn:oasis:names:tc:xacml:1.0:function:time-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (192,2,2,null,null,null,1,0,'date-intersection','urn:oasis:names:tc:xacml:1.0:function:date-intersection',21);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (193,2,2,null,null,null,0,0,'date-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:date-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (194,2,-1,null,null,null,1,0,'date-union','urn:oasis:names:tc:xacml:1.0:function:date-union',21);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (195,2,2,null,null,null,0,0,'date-subset','urn:oasis:names:tc:xacml:1.0:function:date-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (196,2,2,null,null,null,0,0,'date-set-equals','urn:oasis:names:tc:xacml:1.0:function:date-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (197,2,2,null,null,null,1,0,'dateTime-intersection','urn:oasis:names:tc:xacml:1.0:function:dateTime-intersection',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (198,2,2,null,null,null,0,0,'dateTime-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:dateTime-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (199,2,-1,null,null,null,1,0,'dateTime-union','urn:oasis:names:tc:xacml:1.0:function:dateTime-union',19);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (200,2,2,null,null,null,0,0,'dateTime-subset','urn:oasis:names:tc:xacml:1.0:function:dateTime-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (201,2,2,null,null,null,0,0,'dateTime-set-equals','urn:oasis:names:tc:xacml:1.0:function:dateTime-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (202,2,2,null,null,null,1,0,'anyURI-intersection','urn:oasis:names:tc:xacml:1.0:function:anyURI-intersection',27);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (203,2,2,null,null,null,0,0,'anyURI-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:anyURI-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (204,2,-1,null,null,null,1,0,'anyURI-union','urn:oasis:names:tc:xacml:1.0:function:anyURI-union',27);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (205,2,2,null,null,null,0,0,'anyURI-subset','urn:oasis:names:tc:xacml:1.0:function:anyURI-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (206,2,2,null,null,null,0,0,'anyURI-set-equals','urn:oasis:names:tc:xacml:1.0:function:anyURI-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (207,2,2,null,null,null,1,0,'hexBinary-intersection','urn:oasis:names:tc:xacml:1.0:function:hexBinary-intersection',24);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (208,2,2,null,null,null,0,0,'hexBinary-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:hexBinary-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (209,2,-1,null,null,null,1,0,'hexBinary-union','urn:oasis:names:tc:xacml:1.0:function:hexBinary-union',24);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (210,2,2,null,null,null,0,0,'hexBinary-subset','urn:oasis:names:tc:xacml:1.0:function:hexBinary-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (211,2,2,null,null,null,0,0,'hexBinary-set-equals','urn:oasis:names:tc:xacml:1.0:function:hexBinary-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (212,2,2,null,null,null,1,0,'base64Binary-intersection','urn:oasis:names:tc:xacml:1.0:function:base64Binary-intersection',13);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (213,2,2,null,null,null,0,0,'base64Binary-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:base64Binary-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (214,2,-1,null,null,null,1,0,'base64Binary-union','urn:oasis:names:tc:xacml:1.0:function:base64Binary-union',13);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (215,2,2,null,null,null,0,0,'base64Binary-subset','urn:oasis:names:tc:xacml:1.0:function:base64Binary-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (216,2,2,null,null,null,0,0,'base64Binary-set-equals','urn:oasis:names:tc:xacml:1.0:function:base64Binary-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (217,2,2,null,null,null,1,0,'dayTimeDuration-intersection','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-intersection',15);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (218,2,2,null,null,null,0,0,'dayTimeDuration-at-least-one-member-of','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (219,2,-1,null,null,null,1,0,'dayTimeDuration-union','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-union',15);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (220,2,2,null,null,null,0,0,'dayTimeDuration-subset','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (221,2,2,null,null,null,0,0,'dayTimeDuration-set-equals','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (222,2,2,null,null,null,1,0,'yearMonthDuration-intersection','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-intersection',23);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (223,2,2,null,null,null,0,0,'yearMonthDuration-at-least-one-member-of','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (224,2,-1,null,null,null,1,0,'yearMonthDuration-union','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-union',23);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (225,2,2,null,null,null,0,0,'yearMonthDuration-subset','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (226,2,2,null,null,null,0,0,'yearMonthDuration-set-equals','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (227,2,2,null,null,null,1,0,'x500Name-intersection','urn:oasis:names:tc:xacml:1.0:function:x500Name-intersection',14);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (228,2,2,null,null,null,0,0,'x500Name-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:x500Name-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (229,2,-1,null,null,null,1,0,'x500Name-union','urn:oasis:names:tc:xacml:1.0:function:x500Name-union',14);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (230,2,2,null,null,null,0,0,'x500Name-subset','urn:oasis:names:tc:xacml:1.0:function:x500Name-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (231,2,2,null,null,null,0,0,'x500Name-set-equals','urn:oasis:names:tc:xacml:1.0:function:x500Name-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (232,2,2,null,null,null,1,0,'rfc822Name-intersection','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-intersection',20);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (233,2,2,null,null,null,0,0,'rfc822Name-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-at-least-one-member-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (234,2,-1,null,null,null,1,0,'rfc822Name-union','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-union',20);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (235,2,2,null,null,null,0,0,'rfc822Name-subset','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-subset',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (236,2,2,null,null,null,0,0,'rfc822Name-set-equals','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-set-equals',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (237,2,2,null,null,null,0,0,'x500Name-match','urn:oasis:names:tc:xacml:1.0:function:x500Name-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (238,2,2,null,null,null,0,0,'rfc822Name-match','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (239,2,2,null,null,null,1,0,'integer-intersection','urn:oasis:names:tc:xacml:1.0:function:integer-intersection',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (240,2,2,null,null,null,1,0,'double-intersection','urn:oasis:names:tc:xacml:1.0:function:double-intersection',25);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (241,0,-1,null,null,null,0,0,'or','urn:oasis:names:tc:xacml:1.0:function:or',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (242,0,-1,null,null,null,0,0,'and','urn:oasis:names:tc:xacml:1.0:function:and',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (243,2,-1,null,null,null,0,0,'n-of','urn:oasis:names:tc:xacml:1.0:function:n-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (244,1,1,null,null,null,0,0,'not','urn:oasis:names:tc:xacml:1.0:function:not',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (245,2,-1,1,-1,'1',0,1,'any-of','urn:oasis:names:tc:xacml:3.0:function:any-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (246,2,-1,1,-1,'1',0,1,'all-of','urn:oasis:names:tc:xacml:3.0:function:all-of',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (247,2,-1,1,-1,'0',0,1,'any-of-any','urn:oasis:names:tc:xacml:3.0:function:any-of-any',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (248,3,3,2,2,'1',0,1,'all-of-any','urn:oasis:names:tc:xacml:1.0:function:all-of-any',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (249,3,3,2,2,'1',0,1,'any-of-all','urn:oasis:names:tc:xacml:1.0:function:any-of-all',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (250,3,3,2,2,'1',0,1,'all-of-all','urn:oasis:names:tc:xacml:1.0:function:all-of-all',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (251,2,-1,1,-1,'1',1,1,'map','urn:oasis:names:tc:xacml:3.0:function:map',null);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (252,1,1,null,null,null,0,0,'xpath-node-count','urn:oasis:names:tc:xacml:3.0:function:xpath-node-count',12);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (253,2,2,null,null,null,0,0,'xpath-node-equal','urn:oasis:names:tc:xacml:3.0:function:xpath-node-equal',18);\r
+INSERT INTO XACML.FUNCTIONDEFINITION (ID,ARG_LB,ARG_UB,HO_ARG_LB,HO_ARG_UB,HO_PRIMITIVE,IS_BAG_RETURN,IS_HIGHER_ORDER,SHORT_NAME,XACML_ID,RETURN_DATATYPE) VALUES (254,2,2,null,null,null,0,0,'xpath-node-match','urn:oasis:names:tc:xacml:3.0:function:xpath-node-match',18);\r
+\r
+\r
+INSERT INTO XACML.GLOBALROLESETTINGS (ROLE,LOCKDOWN) VALUES ('super-admin',0);\r
+\r
+\r
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1711,null,'type','jdbc','0',1709);\r
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1712,null,'jdbc.url','jdbc:h2:file:/','0',1709);\r
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1713,null,'jdbc.driver','org.h2.Driver','0',1709);\r
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1714,null,'jdbc.conn.password','smil3yfc','0',1709);\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (500,'SQL');\r
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (501,'LDAP');\r
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (502,'CSV');\r
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (503,'Hyper-CSV');\r
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (504,'Custom');\r
+\r
+\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (29,'S','ordered-deny-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:ordered-deny-overrides');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (30,'S','on-permit-apply-second','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:on-permit-apply-second');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (31,'S','deny-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (32,'S','permit-unless-deny','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-unless-deny');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (33,'S','deny-unless-permit','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-unless-permit');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (34,'S','permit-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-overrides');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (35,'S','only-one-applicable','urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:only-one-applicable');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (36,'S','first-applicable','urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable');\r
+INSERT INTO XACML.POLICYALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (37,'S','ordered-permit-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:ordered-permit-overrides');\r
+\r
+\r
+\r
+\r
+\r
+\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (38,'S','permit-unless-deny','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-unless-deny');\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (39,'S','permit-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides');\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (40,'S','deny-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides');\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (41,'S','ordered-permit-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:ordered-permit-overrides');\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (42,'S','deny-unless-permit','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit');\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (43,'S','ordered-deny-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:ordered-deny-overrides');\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (44,'S','only-one-applicable','urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:only-one-applicable');\r
+INSERT INTO XACML.RULEALGORITHMS (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (45,'S','first-applicable','urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable');\r
+\r
+\r
+INSERT INTO XACML.SEQUENCE (SEQ_NAME,SEQ_COUNT) VALUES ('SEQ_GEN',3050);\r
+\r
+\r
+\r
+ALTER TABLE XACML.AttributeAssignment ADD CONSTRAINT FK_AttributeAssignment_OBADVICE_id \r
+FOREIGN KEY (OBADVICE_id) REFERENCES XACML.Obadvice (id);\r
+ALTER TABLE XACML.PIPResolverParams ADD CONSTRAINT FK_PIPResolverParams_ID_RESOLVER \r
+FOREIGN KEY (ID_RESOLVER) REFERENCES XACML.PIPResolver (id);\r
+ALTER TABLE XACML.Attribute ADD CONSTRAINT FK_Attribute_category \r
+FOREIGN KEY (category) REFERENCES XACML.Category (id);\r
+ALTER TABLE XACML.Attribute ADD CONSTRAINT FK_Attribute_constraint_type \r
+FOREIGN KEY (constraint_type) REFERENCES XACML.ConstraintType (id);\r
+ALTER TABLE XACML.Attribute ADD CONSTRAINT FK_Attribute_datatype \r
+FOREIGN KEY (datatype) REFERENCES XACML.Datatype (id);\r
+ALTER TABLE XACML.FunctionArguments ADD CONSTRAINT FK_FunctionArguments_function_id \r
+FOREIGN KEY (function_id) REFERENCES XACML.FunctionDefinition (id);\r
+ALTER TABLE XACML.FunctionArguments ADD CONSTRAINT FK_FunctionArguments_datatype_id \r
+FOREIGN KEY (datatype_id) REFERENCES XACML.Datatype (id);\r
+ALTER TABLE XACML.ObadviceExpressions ADD CONSTRAINT FK_ObadviceExpressions_obadvice_id \r
+FOREIGN KEY (obadvice_id) REFERENCES XACML.Obadvice (id);\r
+ALTER TABLE XACML.ObadviceExpressions ADD CONSTRAINT FK_ObadviceExpressions_attribute_id \r
+FOREIGN KEY (attribute_id) REFERENCES XACML.Attribute (id);\r
+ALTER TABLE XACML.ConstraintValues ADD CONSTRAINT FK_ConstraintValues_attribute_id \r
+FOREIGN KEY (attribute_id) REFERENCES XACML.Attribute (id);\r
+ALTER TABLE XACML.DecisionSettings ADD CONSTRAINT FK_DecisionSettings_datatype \r
+FOREIGN KEY (datatype) REFERENCES XACML.Datatype (id);\r
+ALTER TABLE XACML.PIPConfiguration ADD CONSTRAINT FK_PIPConfiguration_TYPE \r
+FOREIGN KEY (TYPE) REFERENCES XACML.PIPType (id);\r
+\r
+ALTER TABLE FunctionDefinition ADD CONSTRAINT FK_FunctionDefinition_return_datatype \r
+FOREIGN KEY (return_datatype) REFERENCES XACML.Datatype (id);\r
+ALTER TABLE PIPResolver ADD CONSTRAINT FK_PIPResolver_PIP_ID \r
+FOREIGN KEY (PIP_ID) REFERENCES XACML.PIPConfiguration (id);\r
+ALTER TABLE PIPConfigParams ADD CONSTRAINT FK_PIPConfigParams_PIP_ID \r
+FOREIGN KEY (PIP_ID) REFERENCES XACML.PIPConfiguration (id);\r
+\r
+ALTER TABLE XACML.PolicyEntity ADD CONSTRAINT UNQ_PolicyEntity_0 UNIQUE (policyName, scope, deleted);\r
+ALTER TABLE XACML.PolicyEntity ADD CONSTRAINT FK_PolicyEntity_configurationDataId FOREIGN KEY (configurationDataId) \r
+ REFERENCES XACML.ConfigurationDataEntity (configurationDataId);\r
diff --git a/packages/base/src/files/install/mysql/data/151001_downgrade_script.sql b/packages/base/src/files/install/mysql/data/151001_downgrade_script.sql
new file mode 100644 (file)
index 0000000..06cf389
--- /dev/null
@@ -0,0 +1,248 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+SET FOREIGN_KEY_CHECKS=0; \r
+DROP TABLE IF EXISTS XACML.ENFORCINGTYPE;\r
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;\r
+DROP TABLE IF EXISTS XACML.TERM;\r
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;\r
+DROP TABLE IF EXISTS XACML.PORTLIST;\r
+DROP TABLE IF EXISTS XACML.PREFIXLIST;\r
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;\r
+DROP TABLE IF EXISTS XACML.POLICYSCORE;\r
+DROP TABLE IF EXISTS XACML.VSCLACTION;\r
+DROP TABLE IF EXISTS XACML.VNFTYPE;\r
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;\r
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;\r
+DROP TABLE IF EXISTS XACML.POLICY_MANAGEMENT;\r
+DROP TABLE IF EXISTS XACML.SCOPES;\r
+\r
+DROP TABLE IF EXISTS XACML.SERVICEGROUP;\r
+CREATE TABLE XACML.SERVICEGROUP\r
+(\r
+id integer NOT NULL,\r
+name varchar(32),\r
+type varchar(16),\r
+transportprotocol varchar(255),\r
+appprotocol varchar(255),\r
+ports varchar(255),\r
+`desc` varchar(255),\r
+primary key(id)\r
+)\r
+;\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SERVICEGROUP TO POLICY_USER;\r
+\r
+\r
+DROP TABLE IF EXISTS XACML.EnforcingType;\r
+CREATE TABLE XACML.EnforcingType\r
+(\r
+id INTEGER NOT NULL,\r
+ connectionQuery VARCHAR(255) NOT NULL,\r
+ enforcingType VARCHAR(255) NOT NULL UNIQUE,\r
+ script VARCHAR(255) NOT NULL,\r
+ valueQuery VARCHAR(255) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ActionPolicyDict;\r
+CREATE TABLE XACML.ActionPolicyDict\r
+(\r
+id INTEGER NOT NULL,\r
+ ATTRIBUTE_NAME VARCHAR(45) NOT NULL,\r
+ Body VARCHAR(4096),\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048),\r
+ Headers VARCHAR(1024),\r
+ Method VARCHAR(45) NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ Type VARCHAR(45) NOT NULL,\r
+ URL VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.TERM;\r
+CREATE TABLE XACML.TERM\r
+(\r
+id INTEGER NOT NULL,\r
+ description VARCHAR(100),\r
+ action VARCHAR(100),\r
+ destIPList VARCHAR(100),\r
+ destPortList VARCHAR(100),\r
+ portList VARCHAR(100),\r
+ protocolList VARCHAR(100),\r
+ srcIPList VARCHAR(100),\r
+ srcPortList VARCHAR(100),\r
+ termName VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;\r
+CREATE TABLE XACML.PROTOCOLLIST\r
+(\r
+id INTEGER NOT NULL,\r
+ description VARCHAR(64),\r
+ protocolname VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PORTLIST;\r
+CREATE TABLE XACML.PORTLIST\r
+(\r
+id INTEGER NOT NULL,\r
+ description VARCHAR(64),\r
+ portname VARCHAR(45) NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.PREFIXLIST;\r
+CREATE TABLE XACML.PREFIXLIST\r
+(\r
+id INTEGER NOT NULL,\r
+ pl_name VARCHAR(45) NOT NULL,\r
+ pl_value VARCHAR(64) NOT NULL,\r
+ description VARCHAR(255),\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;\r
+CREATE TABLE ADDRESSGROUP\r
+(\r
+ id INTEGER NOT NULL,\r
+ name varchar(32),\r
+ description VARCHAR(64),\r
+ prefixlist varchar(255)\r
+);\r
+\r
+CREATE INDEX idx_addressgroup on XACML.ADDRESSGROUP(ID);\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYSCORE;\r
+CREATE TABLE XACML.POLICYSCORE\r
+(\r
+POLICY_NAME VARCHAR(200) NOT NULL,\r
+ POLICY_SCORE VARCHAR(100),\r
+ PRIMARY KEY (POLICY_NAME)\r
+)\r
+;\r
+\r
+CREATE TABLE XACML.VSCLACTION\r
+(\r
+ID INTEGER NOT NULL,\r
+VSCL_ACTION VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45) NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+CREATE TABLE XACML.VNFTYPE\r
+(\r
+ID INTEGER NOT NULL,\r
+VNF_TYPE VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45) NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;\r
+CREATE TABLE XACML.ATTRIBUTE\r
+(\r
+id INTEGER NOT NULL,\r
+ ATTRIBUTE_VALUE VARCHAR(255),\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048),\r
+ is_designator CHAR NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ PRIORITY VARCHAR(45),\r
+ selector_path VARCHAR(2048),\r
+ xacml_id VARCHAR(100) NOT NULL UNIQUE,\r
+ category INTEGER,\r
+ constraint_type INTEGER,\r
+ datatype INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;\r
+CREATE TABLE XACML.DECISIONSETTINGS\r
+(\r
+id INTEGER NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048),\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ PRIORITY VARCHAR(45),\r
+ xacml_id VARCHAR(45) NOT NULL UNIQUE,\r
+ datatype INTEGER,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICY_MANANGEMENT;\r
+CREATE TABLE XACML.POLICY_MANANGEMENT\r
+(\r
+id INTEGER NOT NULL,\r
+ CONFIG_NAME VARCHAR(45) NOT NULL,\r
+ CREATE_DATE_TIME TIMESTAMP NOT NULL,\r
+ CREATED_BY VARCHAR(45) NOT NULL,\r
+ ECOMP_NAME VARCHAR(45) NOT NULL,\r
+ POLICY_NAME VARCHAR(45) NOT NULL,\r
+ scope VARCHAR(45) NOT NULL,\r
+ UPDATE_DATE_TIME TIMESTAMP NOT NULL,\r
+ UPDATED_BY VARCHAR(45) NOT NULL,\r
+ XML text NOT NULL,\r
+ PRIMARY KEY (id)\r
+)\r
+;\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ENFORCINGTYPE;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ACTIONPOLICYDICT;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.TERM;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.PROTOCOLLIST;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.PORTLIST;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.PREFIXLIST;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ADDRESSGROUP;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.POLICYSCORE;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.VSCLACTION;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.VNFTYPE;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ATTRIBUTE;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.DECISIONSETTINGS;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.POLICY_MANAGEMENT;\r
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.SCOPES;\r
+\r
+\r
+set foreign_key_checks=1; \r
diff --git a/packages/base/src/files/install/mysql/data/151001_upgrade_script.sql b/packages/base/src/files/install/mysql/data/151001_upgrade_script.sql
new file mode 100644 (file)
index 0000000..9708fd4
--- /dev/null
@@ -0,0 +1,246 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+set foreign_key_checks=0; \r
+DROP TABLE IF EXISTS XACML.SERVICEGROUP;\r
+CREATE TABLE XACML.SERVICEGROUP\r
+(\r
+id integer NOT NULL,\r
+name varchar(32),\r
+type varchar(16),\r
+transportprotocol varchar(255),\r
+appprotocol varchar(255),\r
+ports varchar(255),\r
+description varchar(255),\r
+primary key(id)\r
+)\r
+;\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SERVICEGROUP TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.ENFORCINGTYPE;\r
+CREATE TABLE XACML.ENFORCINGTYPE\r
+(\r
+ID INTEGER NOT NULL,\r
+ENFORCINGTYPE VARCHAR(255) NOT NULL,\r
+SCRIPT VARCHAR(5000) NOT NULL,\r
+CONNECTIONQUERY VARCHAR(1000) NOT NULL,\r
+VALUEQUERY VARCHAR(1000) NOT NULL,\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ENFORCINGTYPE TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;\r
+CREATE TABLE XACML.ACTIONPOLICYDICT \r
+(\r
+ID INTEGER NOT NULL,\r
+TYPE VARCHAR(45) NOT NULL,\r
+URL VARCHAR(45) NOT NULL,\r
+METHOD VARCHAR(45) NOT NULL,\r
+HEADERS VARCHAR(1024) NOT NULL,\r
+BODY VARCHAR(4096) NOT NULL,\r
+CREATED_DATE   TIMESTAMP NOT NULL,\r
+CREATED_BY    VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE  TIMESTAMP NOT NULL,\r
+MODIFIED_BY    VARCHAR(45) NOT NULL,\r
+ATTRIBUTE_NAME VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(1024),\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ACTIONPOLICYDICT TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.TERM;\r
+CREATE TABLE XACML.TERM\r
+(\r
+ID INTEGER NOT NULL,\r
+TERMNAME VARCHAR(45) NOT NULL,\r
+SRCIPLIST VARCHAR(100),\r
+DESTIPLIST VARCHAR(100),\r
+PROTOCOLLIST VARCHAR(100),\r
+PORTLIST VARCHAR(100),\r
+SRCPORTLIST VARCHAR(100),\r
+DESTPORTLIST VARCHAR(100),\r
+ACTION VARCHAR(100),\r
+DESCRIPTION VARCHAR(100),\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.TERM TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;\r
+CREATE TABLE XACML.PROTOCOLLIST\r
+(\r
+ID INTEGER NOT NULL,\r
+PROTOCOLNAME VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(64),\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.PROTOCOLLIST TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.PORTLIST;\r
+CREATE TABLE XACML.PORTLIST\r
+(\r
+ID INTEGER NOT NULL,\r
+PORTNAME VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(64),\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.PORTLIST TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.PREFIXLIST;\r
+CREATE TABLE XACML.PREFIXLIST\r
+(\r
+ID INTEGER NOT NULL,\r
+PL_NAME VARCHAR(45) NOT NULL,\r
+PL_VALUE VARCHAR(64),\r
+DESCRIPTION VARCHAR(255) NULL, \r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.PREFIXLIST TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;\r
+CREATE TABLE XACML.ADDRESSGROUP\r
+(\r
+ ID INTEGER NOT NULL,\r
+ NAME VARCHAR(32),\r
+ DESCRIPTION VARCHAR(64),\r
+ PREFIXLIST VARCHAR(255), \r
+ PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ADDRESSGROUP TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYSCORE;\r
+CREATE TABLE XACML.POLICYSCORE\r
+(\r
+POLICY_NAME VARCHAR(100) NOT NULL,\r
+POLICY_SCORE VARCHAR(100),\r
+PRIMARY KEY(POLICY_NAME)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.POLICYSCORE TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.VSCLACTION;\r
+CREATE TABLE XACML.VSCLACTION\r
+(\r
+ID INTEGER NOT NULL,\r
+VSCL_ACTION VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45) NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.VSCLACTION TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.VNFTYPE;\r
+CREATE TABLE XACML.VNFTYPE\r
+(\r
+ID INTEGER NOT NULL,\r
+VNF_TYPE VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45) NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.VNFTYPE TO POLICY_USER;\r
+\r
+SET FOREIGN_KEY_CHECKS=0; \r
+\r
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;\r
+CREATE TABLE XACML.ATTRIBUTE\r
+(\r
+ID INTEGER NOT NULL, \r
+CREATED_BY VARCHAR(255) NOT NULL, \r
+CREATED_DATE TIMESTAMP, \r
+DESCRIPTION VARCHAR(2048),\r
+IS_DESIGNATOR CHAR(1) NOT NULL, \r
+MODIFIED_BY VARCHAR(255) NOT NULL, \r
+MODIFIED_DATE TIMESTAMP NOT NULL, \r
+SELECTOR_PATH VARCHAR(2048),\r
+XACML_ID VARCHAR(500) NOT NULL,  \r
+CATEGORY INTEGER, \r
+CONSTRAINT_TYPE INTEGER, \r
+DATATYPE INTEGER, \r
+PRIORITY VARCHAR(45), \r
+ATTRIBUTE_VALUE VARCHAR(45),\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ATTRIBUTE TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;\r
+CREATE TABLE XACML.DECISIONSETTINGS\r
+(\r
+  ID INTEGER NOT NULL, \r
+  XACML_ID VARCHAR(45) NOT NULL, \r
+  DESCRIPTION VARCHAR(45), \r
+  DATATYPE VARCHAR(45) NOT NULL, \r
+  CREATED_BY VARCHAR(45) NOT NULL, \r
+  MODIFIED_DATE TIMESTAMP NOT NULL, \r
+  MODIFIED_BY VARCHAR(45) NOT NULL, \r
+  PRIORITY VARCHAR(45), \r
+  CREATED_DATE TIMESTAMP NOT NULL,\r
+  PRIMARY KEY(ID)\r
+); \r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.DECISIONSETTINGS TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICY_MANAGEMENT;\r
+CREATE TABLE XACML.POLICY_MANAGEMENT\r
+(\r
+  ID INTEGER NOT NULL, \r
+  CONFIG_NAME VARCHAR(45) NOT NULL, \r
+  CREATE_DATE_TIME TIMESTAMP, \r
+  CREATED_BY VARCHAR(45) NOT NULL, \r
+  ECOMP_NAME VARCHAR(45) NOT NULL, \r
+  POLICY_NAME VARCHAR(45) NOT NULL, \r
+  SCOPE VARCHAR(45) NOT NULL, \r
+  UPDATE_DATE_TIME TIMESTAMP NOT NULL, \r
+  UPDATED_BY VARCHAR(45) NOT NULL, \r
+  XML TEXT NOT NULL,\r
+  PRIMARY KEY(ID)\r
+); \r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.POLICY_MANAGEMENT TO POLICY_USER;\r
+\r
+DROP TABLE IF EXISTS XACML.SCOPES;\r
+CREATE TABLE XACML.SCOPES\r
+(\r
+  ID INTEGER NOT NULL, \r
+  SCOPE VARCHAR(45) NOT NULL, \r
+  PARENT_SCOPE INTEGER, \r
+  PRIMARY KEY(ID)\r
+); \r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SCOPES TO POLICY_USER;\r
+\r
+\r
+set foreign_key_checks=1; \r
diff --git a/packages/base/src/files/install/mysql/data/151002_downgrade_script.sql b/packages/base/src/files/install/mysql/data/151002_downgrade_script.sql
new file mode 100644 (file)
index 0000000..66cdf30
--- /dev/null
@@ -0,0 +1,21 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+REVOKE INSERT, UPDATE, DELETE, SELECT ON XACML.SECURITYZONE from policy_user;\r
diff --git a/packages/base/src/files/install/mysql/data/151002_upgrade_script.sql b/packages/base/src/files/install/mysql/data/151002_upgrade_script.sql
new file mode 100644 (file)
index 0000000..3b4d27e
--- /dev/null
@@ -0,0 +1,21 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SECURITYZONE TO policy_user; \r
diff --git a/packages/base/src/files/install/mysql/data/151200_downgrade_script.sql b/packages/base/src/files/install/mysql/data/151200_downgrade_script.sql
new file mode 100644 (file)
index 0000000..a314722
--- /dev/null
@@ -0,0 +1,43 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+set foreign_key_checks=0;\r
+\r
+DROP TABLE IF EXISTS xacml.PolicyEntity;\r
+DROP TABLE IF EXISTS xacml.ConfigurationDataEntity;\r
+DROP TABLE IF EXISTS xacml.PolicyDBDaoEntity;\r
+DROP TABLE IF EXISTS xacml.GroupEntity;\r
+DROP TABLE IF EXISTS xacml.PdpEntity;\r
+DROP TABLE IF EXISTS xacml.ActionBodyEntity;\r
+DROP TABLE IF EXISTS xacml.DatabaseLockEntity;\r
+DROP TABLE IF EXISTS xacml.PolicyGroupEntity;\r
+\r
+ALTER TABLE XACML.TERM DROP COLUMN FROMZONE;\r
+ALTER TABLE XACML.TERM DROP COLUMN TOZONE;\r
+  \r
+ALTER TABLE XACML.ACTIONPOLICYDICT DROP INDEX ACTIONPOLICYDICT_UNIQUE;\r
+\r
+DROP TABLE IF EXISTS XACML.ZONE;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYVERSION;\r
+\r
+ALTER TABLE XACML.VSCLACTION DROP INDEX VSCLACTION_VSCL_ACTION_UNIQUE;\r
+\r
+set foreign_key_checks=1;\r
diff --git a/packages/base/src/files/install/mysql/data/151200_upgrade_script.sql b/packages/base/src/files/install/mysql/data/151200_upgrade_script.sql
new file mode 100644 (file)
index 0000000..ecb23da
--- /dev/null
@@ -0,0 +1,226 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+set foreign_key_checks=0;\r
+\r
+DROP TABLE IF EXISTS xacml.PolicyEntity;\r
+CREATE TABLE xacml.PolicyEntity\r
+(\r
+policyId BIGINT NOT NULL AUTO_INCREMENT,\r
+created_by VARCHAR(255) NOT NULL,\r
+created_date TIMESTAMP,\r
+deleted BOOLEAN NOT NULL,\r
+description VARCHAR(2048) NOT NULL,\r
+modified_by VARCHAR(255) NOT NULL,\r
+modified_date TIMESTAMP NOT NULL,\r
+policyData TEXT,\r
+policyName VARCHAR(255) NOT NULL,\r
+policyVersion INTEGER,\r
+scope VARCHAR(255) NOT NULL,\r
+version INTEGER,\r
+actionBodyId BIGINT,\r
+configurationDataId BIGINT,\r
+PRIMARY KEY (policyId)\r
+);\r
\r
+CREATE INDEX scope ON xacml.PolicyEntity (scope);\r
+CREATE INDEX policyName ON xacml.PolicyEntity (policyName);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PolicyEntity to policy_user; \r
+\r
+DROP TABLE IF EXISTS xacml.ConfigurationDataEntity;\r
+CREATE TABLE xacml.ConfigurationDataEntity\r
+(\r
+ configurationDataId BIGINT NOT NULL AUTO_INCREMENT,\r
+ configBody TEXT,\r
+ configType VARCHAR(255) NOT NULL,\r
+ configurationName VARCHAR(255) NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ deleted BOOLEAN NOT NULL,\r
+ description VARCHAR(2048) NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ version INTEGER,\r
+ PRIMARY KEY (configurationDataId)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.ConfigurationDataEntity to policy_user;\r
+\r
+DROP TABLE IF EXISTS xacml.PolicyDBDaoEntity;\r
+CREATE TABLE xacml.PolicyDBDaoEntity\r
+(\r
+ policyDBDaoUrl VARCHAR(500) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ description VARCHAR(2048) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ password VARCHAR(100),\r
+ username VARCHAR(100),\r
+ PRIMARY KEY (policyDBDaoUrl)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PolicyDBDaoEntity to policy_user;\r
+\r
+DROP TABLE IF EXISTS xacml.GroupEntity;\r
+CREATE TABLE xacml.GroupEntity\r
+(\r
+groupKey BIGINT NOT NULL AUTO_INCREMENT,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ defaultGroup BOOLEAN NOT NULL,\r
+ deleted BOOLEAN NOT NULL,\r
+ description VARCHAR(2048) NOT NULL,\r
+ groupId VARCHAR(100) NOT NULL,\r
+ groupName VARCHAR(255) NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ version INTEGER,\r
+ PRIMARY KEY (groupKey)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.GroupEntity to policy_user;\r
+\r
+DROP TABLE IF EXISTS xacml.PdpEntity;\r
+CREATE TABLE xacml.PdpEntity\r
+(\r
+pdpKey BIGINT NOT NULL AUTO_INCREMENT,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ deleted BOOLEAN NOT NULL,\r
+ description VARCHAR(2048) NOT NULL,\r
+ jmxPort INTEGER NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ pdpId VARCHAR(255) NOT NULL,\r
+ pdpName VARCHAR(255) NOT NULL,\r
+ groupKey BIGINT,\r
+ PRIMARY KEY (pdpKey)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PdpEntity to policy_user;\r
+\r
+DROP TABLE IF EXISTS xacml.ActionBodyEntity;\r
+CREATE TABLE xacml.ActionBodyEntity\r
+(\r
+actionBodyId BIGINT NOT NULL AUTO_INCREMENT,\r
+ actionBody TEXT,\r
+ actionBodyName VARCHAR(255) NOT NULL,\r
+ created_by VARCHAR(255) NOT NULL,\r
+ created_date TIMESTAMP,\r
+ deleted BOOLEAN NOT NULL,\r
+ modified_by VARCHAR(255) NOT NULL,\r
+ modified_date TIMESTAMP NOT NULL,\r
+ version INTEGER,\r
+ PRIMARY KEY (actionBodyId)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.ActionBodyEntity to policy_user;\r
+\r
+DROP TABLE IF EXISTS xacml.DatabaseLockEntity;\r
+CREATE TABLE xacml.DatabaseLockEntity\r
+(\r
+ lock_key INTEGER NOT NULL,\r
+ PRIMARY KEY (lock_key)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.DatabaseLockEntity to policy_user;\r
+\r
+DROP TABLE IF EXISTS xacml.PolicyGroupEntity;\r
+CREATE TABLE xacml.PolicyGroupEntity\r
+(\r
+groupKey BIGINT NOT NULL AUTO_INCREMENT,\r
+ policyId BIGINT NOT NULL,\r
+ PRIMARY KEY (groupKey,policyId)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PolicyGroupEntity to policy_user;\r
+\r
+ALTER TABLE xacml.PolicyEntity ADD CONSTRAINT UNQ_PolicyEntity_0 UNIQUE (policyName, scope);\r
+ALTER TABLE xacml.PolicyEntity ADD CONSTRAINT FK_PolicyEntity_configurationDataId FOREIGN KEY (configurationDataId) \r
+REFERENCES xacml.ConfigurationDataEntity (configurationDataId);\r
+ALTER TABLE xacml.PolicyEntity ADD CONSTRAINT FK_PolicyEntity_actionBodyId FOREIGN KEY (actionBodyId) \r
+REFERENCES xacml.ActionBodyEntity (actionBodyId);\r
+ALTER TABLE xacml.PdpEntity ADD CONSTRAINT FK_PdpEntity_groupKey FOREIGN KEY (groupKey) \r
+REFERENCES xacml.GroupEntity (groupKey);\r
+\r
+ALTER TABLE xacml.PolicyGroupEntity ADD CONSTRAINT FK_PolicyGroupEntity_policyId FOREIGN KEY (policyId) \r
+REFERENCES xacml.PolicyEntity (policyId);\r
+\r
+ALTER TABLE xacml.PolicyGroupEntity ADD CONSTRAINT FK_PolicyGroupEntity_groupKey FOREIGN KEY (groupKey) \r
+REFERENCES xacml.GroupEntity (groupKey);\r
+\r
+-- CREATE SEQUENCE xacml.seqActBody START WITH 1;\r
+-- CREATE SEQUENCE xacml.seqGroup INCREMENT BY 50 START WITH 50;\r
+-- CREATE SEQUENCE xacml.seqConfig START WITH 1;\r
+-- CREATE SEQUENCE xacml.seqPolicy START WITH 1;\r
+-- CREATE SEQUENCE xacml.seqPdp INCREMENT BY 50 START WITH 50;\r
+\r
+DROP TABLE IF EXISTS XACML.TERM;\r
+CREATE TABLE XACML.TERM\r
+(\r
+  ID int NOT NULL,\r
+  termName VARCHAR(45) NOT NULL,\r
+  fromzone VARCHAR(100),\r
+  tozone VARCHAR(100), \r
+  srcIPList VARCHAR(100),\r
+  destIPList VARCHAR(100) ,\r
+  protocolList VARCHAR(100) ,\r
+  portList VARCHAR(100) ,\r
+  srcPortList VARCHAR(100) ,\r
+  destPortList VARCHAR(100) ,\r
+  action VARCHAR(100),\r
+  DESCRIPTION VARCHAR(100),\r
+  PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.TERM TO policy_user; \r
+\r
+ALTER TABLE XACML.ACTIONPOLICYDICT add constraint ACTIONPOLICYDICT_UNIQUE UNIQUE(ATTRIBUTE_NAME);\r
+\r
+DROP TABLE IF EXISTS XACML.ZONE;\r
+CREATE TABLE XACML.ZONE\r
+(\r
+ ID INTEGER NOT NULL,\r
+ zonename VARCHAR(45) NOT NULL,\r
+ zonevalue VARCHAR(64)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ZONE TO policy_user;\r
+\r
+DROP TABLE IF EXISTS XACML.POLICYVERSION;\r
+\r
+CREATE TABLE XACML.POLICYVERSION \r
+(\r
+ID INTEGER NOT NULL,\r
+POLICY_NAME VARCHAR(255) NOT NULL,\r
+ACTIVE_VERSION INTEGER NULL,\r
+HIGHEST_VERSION INTEGER NULL, \r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.POLICYVERSION to policy_user;\r
+\r
+ALTER TABLE XACML.VSCLACTION ADD CONSTRAINT VSCLACTION_VSCL_ACTION_UNIQUE UNIQUE(VSCL_ACTION);\r
+\r
+set foreign_key_checks=1;\r
diff --git a/packages/base/src/files/install/mysql/data/160200_downgrade_script.sql b/packages/base/src/files/install/mysql/data/160200_downgrade_script.sql
new file mode 100644 (file)
index 0000000..41baaa9
--- /dev/null
@@ -0,0 +1,39 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+drop table if exists xacml.DCAEuuid; \r
+drop table if exists xacml.MicroServiceLocation; \r
+drop table if exists xacml.DCAEUsers; \r
+drop table if exists xacml.microserviceconfigname; \r
+drop table if exists xacml.vmType; \r
+\r
+alter table xacml.term drop column created_by; \r
+alter table xacml.term drop column created_date; \r
+alter table xacml.term drop column modified_by; \r
+alter table xacml.term drop column modified_date;\r
\r
+drop table if exists xacml.pepoptions; \r
+drop table if exists xacml.VarbindDictionary; \r
+drop table if exists xacml.GocEventAlarm; \r
+drop table if exists xacml.GocTraversal;\r
+drop table if exists xacml.BRMSParamTemplate;  \r
+\r
+alter table xacml.roles drop column name; \r
+\r
diff --git a/packages/base/src/files/install/mysql/data/160200_upgrade_script.sql b/packages/base/src/files/install/mysql/data/160200_upgrade_script.sql
new file mode 100644 (file)
index 0000000..46629a9
--- /dev/null
@@ -0,0 +1,127 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+drop table if exists xacml.DCAEuuid; \r
+CREATE TABLE xacml.DCAEuuid (\r
+ ID int NOT NULL,\r
+ name VARCHAR(45) NOT NULL,\r
+ description VARCHAR(64)\r
+ ); \r
+\r
+drop table if exists xacml.MicroServiceLocation; \r
+CREATE TABLE xacml.MicroServiceLocation (\r
+ ID int NOT NULL,\r
+ name VARCHAR(45) NOT NULL,\r
+ description VARCHAR(64)\r
+ ); \r
+\r
+drop table if exists xacml.DCAEUsers; \r
+CREATE TABLE xacml.DCAEUsers (\r
+ ID int NOT NULL,\r
+ name VARCHAR(45) NOT NULL,\r
+ description VARCHAR(64)\r
+ ); \r
+\r
+drop table if exists xacml.microserviceconfigname; \r
+CREATE TABLE xacml.microserviceconfigname (\r
+ ID int NOT NULL,\r
+ name VARCHAR(45) NOT NULL,\r
+ description VARCHAR(64)\r
+ ); \r
+\r
+drop table if exists xacml.vmType; \r
+CREATE TABLE xacml.vmType (\r
+ ID int NOT NULL,\r
+ name VARCHAR(45) NOT NULL,\r
+ description VARCHAR(64)\r
+ ); \r
\r
+alter table xacml.term add created_by varchar(100); \r
+alter table xacml.term add created_date date; \r
+alter table xacml.term add modified_by varchar(100); \r
+alter table xacml.term add modified_date date; \r
\r
+drop table if exists xacml.pepoptions; \r
+CREATE TABLE xacml.PEPOPTIONS (\r
+ID INT NOT NULL,\r
+PEP_NAME VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(1024),\r
+Actions VARCHAR(1024) NOT NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+);\r
+\r
+drop table if exists xacml.VarbindDictionary; \r
+CREATE TABLE xacml.VarbindDictionary (\r
+Id INT NOT NULL, \r
+created_by VARCHAR(255) NOT NULL, \r
+created_date TIMESTAMP, \r
+modified_by VARCHAR(255) NOT NULL, \r
+modified_date TIMESTAMP NOT NULL, \r
+varbind_Description VARCHAR(2048), \r
+varbind_Name VARCHAR(45) NOT NULL UNIQUE, \r
+varbind_oid VARCHAR(45) NOT NULL, \r
+PRIMARY KEY (Id)\r
+); \r
+\r
+drop table if exists xacml.GocEventAlarm; \r
+CREATE TABLE xacml.GocEventAlarm(\r
+Id INT NOT NULL,\r
+Event VARCHAR(45) NOT NULL,\r
+description VARCHAR(1024),\r
+Alarm VARCHAR(1024) NOT NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+); \r
+\r
+drop table if exists xacml.GocTraversal; \r
+CREATE TABLE xacml.GocTraversal(\r
+ID INT NOT NULL,\r
+TRAVERSAL VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45) NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY VARCHAR(45) NOT NULL,\r
+MODIFIED_DATE TIMESTAMP NOT NULL,\r
+MODIFIED_BY VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+); \r
+\r
+drop table if exists xacml.BRMSParamTemplate; \r
+CREATE TABLE xacml.BRMSParamTemplate(\r
+ID INT NOT NULL,\r
+param_template_name VARCHAR(45) NOT NULL,\r
+DESCRIPTION VARCHAR(45),\r
+rule LONGTEXT NOT NULL,\r
+CREATED_DATE TIMESTAMP NOT NULL,\r
+CREATED_BY  VARCHAR(45) NOT NULL,\r
+PRIMARY KEY(ID)\r
+); \r
+\r
+alter table xacml.roles add name varchar(45);\r
+\r
+\r
+\r
\r
diff --git a/packages/base/src/files/install/mysql/data/160201_downgrade_script.sql b/packages/base/src/files/install/mysql/data/160201_downgrade_script.sql
new file mode 100644 (file)
index 0000000..5f6381a
--- /dev/null
@@ -0,0 +1,43 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+alter table xacml.attribute modify created_date timestamp;\r
+alter table xacml.obadvice modify created_date timestamp;\r
+alter table xacml.decisionsettings modify created_date timestamp;\r
+alter table xacml.actionpolicydict modify created_date timestamp;\r
+alter table xacml.ecompname modify created_date timestamp;\r
+alter table xacml.policyentity modify created_date timestamp;\r
+alter table xacml.configurationdataentity  modify created_date timestamp;\r
+alter table xacml.policydbdaoentity  modify created_date timestamp;\r
+\r
+alter table xacml.actionpolicydict modify created_date timestamp;\r
+alter table xacml.vsclaction modify created_date timestamp;\r
+alter table xacml.vnftype modify created_date timestamp;\r
+\r
+alter table xacml.groupentity modify created_date timestamp;\r
+alter table xacml.pdpentity modify created_date timestamp;\r
+alter table xacml.actionbodyentity modify created_date timestamp;\r
+\r
+alter table xacml.term modify created_date timestamp;\r
+alter table xacml.varbinddictionary modify created_date timestamp;\r
+alter table xacml.pepoptions modify created_date timestamp;\r
+alter table xacml.goceventalarm modify created_date timestamp;\r
+alter table xacml.goctraversal modify created_date timestamp;\r
+alter table xacml.brmsparamtemplate modify created_date timestamp;\r
diff --git a/packages/base/src/files/install/mysql/data/160201_upgrade_script.sql b/packages/base/src/files/install/mysql/data/160201_upgrade_script.sql
new file mode 100644 (file)
index 0000000..70ddf79
--- /dev/null
@@ -0,0 +1,44 @@
+/*-\r
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+alter table xacml.attribute modify created_date timestamp default current_timestamp;\r
+alter table xacml.obadvice modify created_date timestamp default current_timestamp;\r
+alter table xacml.decisionsettings modify created_date timestamp default current_timestamp;\r
+alter table xacml.actionpolicydict modify created_date timestamp default current_timestamp;\r
+alter table xacml.ecompname modify created_date timestamp default current_timestamp;\r
+alter table xacml.policyentity modify created_date timestamp default current_timestamp;\r
+alter table xacml.configurationdataentity  modify created_date timestamp default current_timestamp;\r
+alter table xacml.policydbdaoentity  modify created_date timestamp default current_timestamp;\r
+\r
+alter table xacml.actionpolicydict modify created_date timestamp default current_timestamp;\r
+alter table xacml.vsclaction modify created_date timestamp default current_timestamp;\r
+alter table xacml.vnftype modify created_date timestamp default current_timestamp;\r
+\r
+alter table xacml.groupentity modify created_date timestamp default current_timestamp;\r
+alter table xacml.pdpentity modify created_date timestamp default current_timestamp;\r
+alter table xacml.actionbodyentity modify created_date timestamp default current_timestamp;\r
+\r
+alter table xacml.term modify created_date timestamp default current_timestamp;\r
+alter table xacml.term modify modified_date timestamp not null; \r
+alter table xacml.varbinddictionary modify created_date timestamp default current_timestamp;\r
+alter table xacml.pepoptions modify created_date timestamp default current_timestamp;\r
+alter table xacml.goceventalarm modify created_date timestamp default current_timestamp;\r
+alter table xacml.goctraversal modify created_date timestamp default current_timestamp;\r
+alter table xacml.brmsparamtemplate modify created_date timestamp default current_timestamp;\r
diff --git a/packages/base/src/files/install/mysql/data/160400_downgrade_script.sql b/packages/base/src/files/install/mysql/data/160400_downgrade_script.sql
new file mode 100644 (file)
index 0000000..d5a990f
--- /dev/null
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists xacml.MicroServiceModels; 
+drop table if exists xacml.GocRCAlarm; 
+drop table if exists xacml.xacmlGocVnfType; 
+drop table if exists xacml.CLOSEDLOOPD2SERVICES; 
+drop table if exists xacml.CLOSEDLOOPSITE; 
+drop table if exists xacml.USERINFO; 
+
+drop table if exists drools.sessioninfo; 
+drop table if exists drools.WORKITEMINFO; 
+drop table if exists drools.droolspdpentity; 
+
+
diff --git a/packages/base/src/files/install/mysql/data/160400_upgrade_script.sql b/packages/base/src/files/install/mysql/data/160400_upgrade_script.sql
new file mode 100644 (file)
index 0000000..745b471
--- /dev/null
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Base Package
+ * ================================================================================
+ * 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=========================================================
+ */
+
+drop table if exists xacml.MicroServiceModels; 
+CREATE TABLE xacml.MicroServiceModels (
+ID INTEGER NOT NULL,
+modelName VARCHAR(75) NOT NULL,
+DESCRIPTION VARCHAR(45),
+Dependency VARCHAR(255),
+imported_by VARCHAR(45) NOT NULL,
+attributes LONGTEXT,
+ref_attributes LONGTEXT,
+PRIMARY KEY(ID)
+); 
+
+drop table if exists xacml.GocRCAlarm; 
+CREATE TABLE xacml.GocRCAlarm(
+ID int NOT NULL,
+alarmName VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL default current_timestamp,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+drop table if exists xacml.xacmlGocVnfType; 
+CREATE TABLE xacml.xacmlGocVnfType(
+ID int NOT NULL,
+vnfName VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL default current_timestamp,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+drop table if exists xacml.CLOSEDLOOPD2SERVICES; 
+CREATE TABLE xacml.CLOSEDLOOPD2SERVICES(
+ID INTEGER NOT NULL,
+SERVICE_NAME VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL default current_timestamp,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+); 
+
+drop table if exists xacml.CLOSEDLOOPSITE; 
+CREATE TABLE xacml.CLOSEDLOOPSITE(
+ID INTEGER NOT NULL,
+SITE_NAME VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL default current_timestamp,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+drop table if exists xacml.USERINFO; 
+CREATE TABLE xacml.USERINFO(
+ATTUID VARCHAR(45) NOT NULL,
+NAME VARCHAR(45) NOT NULL,
+PRIMARY KEY(ATTUID)
+); 
+
+-- use BLOB instead of LONGVARBINARY
+drop table if exists drools.sessioninfo; 
+CREATE TABLE drools.SESSIONINFO 
+(
+ID BIGINT NOT NULL, 
+LASTMODIFICATIONDATE TIMESTAMP, 
+RULESBYTEARRAY BLOB,  
+STARTDATE TIMESTAMP default current_timestamp,  
+OPTLOCK INTEGER, 
+PRIMARY KEY (ID)
+); 
+
+drop table if exists drools.WORKITEMINFO; 
+CREATE TABLE drools.WORKITEMINFO 
+(
+WORKITEMID BIGINT NOT NULL, 
+CREATIONDATE TIMESTAMP default current_timestamp, 
+`NAME` VARCHAR(500), 
+PROCESSINSTANCEID BIGINT, 
+STATE BIGINT, 
+OPTLOCK INTEGER, 
+WORKITEMBYTEARRAY BLOB, 
+PRIMARY KEY (WORKITEMID)
+); 
+
+drop table if exists drools.droolspdpentity; 
+CREATE TABLE drools.DROOLSPDPENTITY
+(
+  PDPID VARCHAR(100) NOT NULL,
+  DESIGNATED BOOLEAN NOT NULL DEFAULT FALSE,
+  PRIORITY INT NOT NULL DEFAULT 0,
+  UPDATEDDATE DATE NOT NULL,
+  GROUPID VARCHAR(100) NOT NULL,
+  SESSIONID BIGINT NOT NULL
+);
+
diff --git a/packages/base/src/files/m2/settings.xml b/packages/base/src/files/m2/settings.xml
new file mode 100755 (executable)
index 0000000..f7b3c9e
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  Base Package
+  ================================================================================
+  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=========================================================
+  -->
+
+
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
+  <profiles>
+    <profile>
+      <id>policy-profile</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+
+      <repositories>
+        <repository>
+          <id>${{snapshotRepositoryID}}</id>
+          <url>${{snapshotRepositoryUrl}}</url>
+          <releases>
+            <enabled>false</enabled>
+            <updatePolicy>always</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+            <updatePolicy>always</updatePolicy>
+         </snapshots>
+        </repository>
+
+        <repository>
+          <id>${{releaseRepositoryID}}</id>
+          <url>${{releaseRepositoryUrl}}</url>
+          <releases>
+            <enabled>true</enabled>
+            <updatePolicy>always</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>false</enabled>
+            <updatePolicy>always</updatePolicy>
+         </snapshots>
+        </repository>
+      </repositories>
+
+    </profile>
+  </profiles>
+
+  <activeProfiles>
+    <activeProfile>policy-profile</activeProfile>
+  </activeProfiles>
+
+  <servers>
+    <server>
+      <id>${{snapshotRepositoryID}}</id>
+     <username>${{repositoryUsername}}</username>
+     <password>${{repositoryPassword}}</password>
+    </server>
+    <server>
+      <id>${{releaseRepositoryID}}</id>
+     <username>${{repositoryUsername}}</username>
+     <password>${{repositoryPassword}}</password>
+    </server>
+  </servers>
+
+</settings>
+
diff --git a/packages/base/src/files/m2/standalone-settings.xml b/packages/base/src/files/m2/standalone-settings.xml
new file mode 100755 (executable)
index 0000000..277113c
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  Base Package
+  ================================================================================
+  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=========================================================
+  -->
+
+
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
+  <profiles>
+    <profile>
+      <id>policy-profile</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+
+      <repositories>
+        <repository>
+          <id>${{fileRepoID}}</id>
+          <url>${{fileRepoUrl}}</url>
+          <releases>
+            <enabled>true</enabled>
+            <updatePolicy>always</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+            <updatePolicy>always</updatePolicy>
+         </snapshots>
+        </repository>
+      </repositories>
+
+    </profile>
+  </profiles>
+
+  <activeProfiles>
+    <activeProfile>policy-profile</activeProfile>
+  </activeProfiles>
+
+</settings>
+
diff --git a/packages/install/.gitignore b/packages/install/.gitignore
new file mode 100644 (file)
index 0000000..b83d222
--- /dev/null
@@ -0,0 +1 @@
+/target/
diff --git a/packages/install/pom.xml b/packages/install/pom.xml
new file mode 100644 (file)
index 0000000..2ed2954
--- /dev/null
@@ -0,0 +1,94 @@
+<!--
+  ============LICENSE_START=======================================================
+  Policy Packages
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.openecomp.policy.drools-pdp</groupId>
+               <artifactId>packages</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>install-drools</artifactId>
+       <packaging>pom</packaging>
+
+       <name>Installation Package</name>
+       <description>D2 ECOMP Policy Drools PDP Installation Package</description>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <artifactId>maven-assembly-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>single</goal>
+                                               </goals>
+                                               <phase>package</phase>
+                                               <configuration>
+                                                       <descriptors>
+                                                               <descriptor>src/assembly/zip.xml</descriptor>
+                                                       </descriptors>
+                                                       <appendAssemblyId>false</appendAssemblyId>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+
+       <!--  List any dependencies here that should be included in the installer zip -->
+       <dependencies>
+               <dependency>
+                       <groupId>org.openecomp.policy.drools-pdp</groupId>
+                       <artifactId>base</artifactId>
+                       <version>${project.version}</version>
+                       <type>tar.gz</type>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.policy.drools-pdp</groupId>
+                       <artifactId>policy-core</artifactId>
+                       <version>${project.version}</version>
+                       <type>zip</type>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.policy.drools-pdp</groupId>
+                       <artifactId>policy-management</artifactId>
+                       <version>${project.version}</version>
+                       <type>zip</type>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.policy.drools-pdp</groupId>
+                       <artifactId>policy-persistence</artifactId>
+                       <version>${project.version}</version>
+                       <type>zip</type>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.policy.drools-pdp</groupId>
+                       <artifactId>policy-healthcheck</artifactId>
+                       <version>${project.version}</version>
+                       <type>zip</type>
+               </dependency>
+       </dependencies>
+
+</project>
diff --git a/packages/install/src/assembly/zip.xml b/packages/install/src/assembly/zip.xml
new file mode 100644 (file)
index 0000000..48b82d4
--- /dev/null
@@ -0,0 +1,39 @@
+<!--
+  ============LICENSE_START=======================================================
+  Installation Package
+  ================================================================================
+  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=========================================================
+  -->
+
+<assembly>
+       <id>zipfile</id>
+       <formats>
+               <format>zip</format>
+       </formats>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <fileSets>
+               <fileSet>
+                       <directory>src/files</directory>
+                       <outputDirectory>.</outputDirectory>
+                       <fileMode>755</fileMode>
+               </fileSet>
+       </fileSets>
+       <dependencySets>
+               <dependencySet>
+                       <useTransitiveDependencies>false</useTransitiveDependencies>
+               </dependencySet>
+       </dependencySets>
+</assembly>
diff --git a/packages/install/src/files/base.conf b/packages/install/src/files/base.conf
new file mode 100644 (file)
index 0000000..90128e9
--- /dev/null
@@ -0,0 +1,68 @@
+POLICY_HOME=/opt/app/policy
+JAVA_HOME=/opt/jdk1.8.0_77
+M2_HOME=/opt/app/policy/3rdparty/apache-maven-3.3.1
+
+ENGINE_MANAGEMENT_PORT=9696
+ENGINE_MANAGEMENT_HOST=localhost
+ENGINE_MANAGEMENT_USER=@1b3rt
+ENGINE_MANAGEMENT_PASSWORD=31nst@1n
+
+ENGINE_HEALTHCHECK_HOST=0.0.0.0
+ENGINE_HEALTHCHECK_PORT=9697
+
+JDBC_DRIVER=org.mariadb.jdbc.Driver
+JDBC_URL=jdbc:mysql://localhost:3306/xacml
+JDBC_DROOLS_URL=jdbc:mysql://localhost:3306/drools
+JDBC_USER=policy_user
+JDBC_PASSWORD=
+
+NAGIOS_CONFIG_NAME=policy
+NAGIOS_NRDP_URL=
+NAGIOS_NRDP_TOKEN=bbpguvsohehj
+NAGIOS_NRDP_DISABLED=true
+
+# Integrity Monitor properties
+site_name=site_1
+fp_monitor_interval=30
+failed_counter_threshold=3
+test_trans_interval=20
+write_fpc_interval=5
+max_fpc_update_interval=60
+test_via_jmx=false
+node_type=pdp_drools
+# Dependency groups are groups of resources upon which a node operational state is dependent upon. 
+# Each group is a comma-separated list of resource names and groups are separated by a semicolon.
+dependency_groups=site_1.pap_1,site_1.pap_2;site_1.pdp_1,site_1.pdp_2
+resource_name=pdpd_1
+
+# The (optional) period of time in seconds between executions of the integrity audit.
+# Value < 0 : Audit does not run (default value if property is not present = -1)
+# Value = 0 : Audit runs continuously
+# Value > 0 : The period of time in seconds between execution of the audit on a particular node
+integrity_audit_period_seconds=-1
+
+host_port=0.0.0.0:9981
+
+# To use a Nexus repository for rules artifacts,
+# following properties must be uncommented and set:
+#repositoryID=policy-nexus
+#repositoryUrl=http://....(URL for the repository goes here)
+#repositoryUsername=(nexus username goes here)
+#repositoryPassword=(password goes here)
+
+# just for testing purposes, modify at installation
+PDPD_CONFIGURATION_TOPIC=PDPD_CONFIGURATION
+PDPD_CONFIGURATION_SERVERS=
+PDPD_CONFIGURATION_API_KEY=
+PDPD_CONFIGURATION_API_SECRET=
+PDPD_CONFIGURATION_CONSUMER_GROUP=
+PDPD_CONFIGURATION_CONSUMER_INSTANCE=
+PDPD_CONFIGURATION_PARTITION_KEY=
+
+PAP_HOST=
+PAP_USERNAME=
+PAP_PASSWORD=
+
+PDP_HOST=
+PDP_USERNAME=
+PDP_PASSWORD=
diff --git a/packages/install/src/files/policy-management.conf b/packages/install/src/files/policy-management.conf
new file mode 100644 (file)
index 0000000..609aa86
--- /dev/null
@@ -0,0 +1,5 @@
+CONTROLLER_ARTIFACT_ID=policy-management
+CONTROLLER_NAME=policy-management-controller
+CONTROLLER_PORT=9696
+RULES_ARTIFACT=org.openecomp.policy:dummy-artifact:1.0.0-SNAPSHOT
+UEB_TOPIC=policyengine-develop
diff --git a/packages/pom.xml b/packages/pom.xml
new file mode 100644 (file)
index 0000000..3cde69c
--- /dev/null
@@ -0,0 +1,43 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.openecomp.policy.drools-pdp</groupId>
+               <artifactId>drools-pdp</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>packages</artifactId>
+       <packaging>pom</packaging>
+
+       <name>Policy Packages</name>
+       <description>D2 ECOMP Policy Drools PDP Installation Packages</description>
+
+       <modules>
+               <module>base</module>
+               <!-- <module>root</module> -->
+               <module>install</module>
+       </modules>
+</project>
diff --git a/policy-core/pom.xml b/policy-core/pom.xml
new file mode 100644 (file)
index 0000000..3e4bc68
--- /dev/null
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.openecomp.policy.drools-pdp</groupId>
+  <artifactId>policy-core</artifactId>
+  <parent>
+    <groupId>org.openecomp.policy.drools-pdp</groupId>
+    <artifactId>drools-pdp</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <artifactId>maven-assembly-plugin</artifactId>
+                               <version>2.6</version>
+                               <executions>
+                                       <execution>
+                                               <id>zipfile</id>
+                                               <goals>
+                                                       <goal>single</goal>
+                                               </goals>
+                                               <phase>package</phase>
+                                               <configuration>
+                                                       <attach>true</attach>
+                                                       <finalName>${project.artifactId}-${project.version}</finalName>
+                                                       <descriptors>
+                                                               <descriptor>src/assembly/assemble_zip.xml</descriptor>
+                                                       </descriptors>
+                                                       <appendAssemblyId>false</appendAssemblyId>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-dependency-plugin</artifactId>
+                               <version>2.8</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-dependencies</id>
+                                               <goals>
+                                                       <goal>copy-dependencies</goal>
+                                               </goals>
+                                               <phase>prepare-package</phase>
+                                               <configuration>
+                                                       <transitive>false</transitive>
+                                                       <outputDirectory>${project.build.directory}/assembly/lib</outputDirectory>
+                                                       <overWriteReleases>false</overWriteReleases>
+                                                       <overWriteSnapshots>true</overWriteSnapshots>
+                                                       <overWriteIfNewer>true</overWriteIfNewer>
+                                                       <useRepositoryLayout>false</useRepositoryLayout>
+                                                       <addParentPoms>false</addParentPoms>
+                                                       <copyPom>false</copyPom>
+                                                       <excludeGroupIds>org.opendaylight,com.brocade.odl</excludeGroupIds>
+                                                       <scope>provided</scope>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>2.6</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-version</id>
+                                               <goals>
+                                                       <goal>copy-resources</goal>
+                                               </goals>
+                                               <phase>validate</phase>
+                                               <configuration>
+                                                       <outputDirectory>${basedir}/target/versions</outputDirectory>
+                                                       <resources>
+                                                               <resource>
+                                                                       <directory>src/main/resources/versions</directory>
+                                                                       <includes>
+                                                                               <include>version.properties</include>
+                                                                       </includes>
+                                                                       <filtering>true</filtering>
+                                                               </resource>
+                                                       </resources>
+                                               </configuration>
+                                       </execution>
+                                       <execution>
+                                               <id>copy-resources</id>
+                                               <goals>
+                                                       <goal>copy-resources</goal>
+                                               </goals>
+                                               <phase>validate</phase>
+                                               <configuration>
+                                                       <outputDirectory>${basedir}/target/etc/bvc-extensions</outputDirectory>
+                                                       <resources>
+                                                               <resource>
+                                                                       <directory>src/main/resources/etc/bvc-extensions</directory>
+                                                                       <includes>
+                                                                               <include>feature_config_template.cfg</include>
+                                                                               <include>feature_custom.install</include>
+                                                                       </includes>
+                                                                       <filtering>true</filtering>
+                                                               </resource>
+                                                       </resources>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>1.2.17</version>
+    </dependency>
+    <dependency>
+      <groupId>org.kie</groupId>
+      <artifactId>kie-api</artifactId>
+      <version>6.3.0.Final</version>
+    </dependency>
+    <dependency>
+      <groupId>org.kie</groupId>
+      <artifactId>kie-ci</artifactId>
+      <version>6.3.0.Final</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.drools</groupId>
+      <artifactId>drools-core</artifactId>
+      <version>6.3.0.Final</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.drools</groupId>
+      <artifactId>drools-persistence-jpa</artifactId>
+      <version>6.3.0.Final</version>
+    </dependency>
+    <dependency>
+    <!-- leave this for now, but will remove policy-utils at the end of conversion -->
+       <groupId>org.openecomp.policy.drools-pdp</groupId>
+       <artifactId>policy-utils</artifactId>
+       <version>1.0.0-SNAPSHOT</version>  
+     </dependency>
+     <dependency>
+      <groupId>org.openecomp.policy.common</groupId>
+      <artifactId>ECOMP-Logging</artifactId>
+      <version>${common-modules.version}</version>  
+    </dependency>
+    <dependency>
+      <groupId>org.openecomp.policy.common</groupId>
+      <artifactId>integrity-monitor</artifactId>
+      <version>${common-modules.version}</version>
+    </dependency>
+       <dependency>
+      <groupId>org.openecomp.policy.common</groupId>
+      <artifactId>integrity-audit</artifactId>
+      <version>${common-modules.version}</version>
+       </dependency>
+    <dependency>
+      <groupId>org.mariadb.jdbc</groupId>
+      <artifactId>mariadb-java-client</artifactId>
+      <version>1.2.3</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+      <version>[1.4.186,)</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpcore</artifactId>
+      <version>4.4.1</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.11</version>
+      <scope>test</scope>
+    </dependency>
+       <dependency>
+               <groupId>org.codehaus.btm</groupId>
+               <artifactId>btm</artifactId>
+               <version>2.1.4</version>
+       </dependency>
+       <dependency>
+               <groupId>org.eclipse.persistence</groupId>
+               <artifactId>eclipselink</artifactId>
+               <version>2.6.2</version>
+       </dependency>
+       <dependency>
+               <groupId>org.hibernate</groupId>
+               <artifactId>hibernate-entitymanager</artifactId>
+               <version>5.0.7.Final</version>
+       </dependency>
+       
+       <dependency>
+               <groupId>org.json</groupId>
+               <artifactId>json</artifactId>
+               <version>20160810</version>
+       </dependency>
+  </dependencies>  
+
+  <dependencyManagement>
+       <dependencies>
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpclient</artifactId>
+                       <version>4.5</version>
+               </dependency>
+       </dependencies>
+  </dependencyManagement>
+</project>
diff --git a/policy-core/src/assembly/assemble_zip.xml b/policy-core/src/assembly/assemble_zip.xml
new file mode 100644 (file)
index 0000000..447a527
--- /dev/null
@@ -0,0 +1,85 @@
+<!--
+  ============LICENSE_START=======================================================
+  policy-core
+  ================================================================================
+  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=========================================================
+  -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+       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>
+       <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</outputDirectory>
+                       <includes>
+                               <include>policy-core-${project.version}.jar</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>target/assembly/</directory>
+                       <outputDirectory>.</outputDirectory>
+                       <excludes>
+                       </excludes>
+               </fileSet>
+               <fileSet>
+                       <directory>.</directory>
+                       <outputDirectory>lib</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>
+                       <outputDirectory>config</outputDirectory>
+               </fileSet>
+       </fileSets>
+
+</assembly>
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/core/FeatureAPI.java b/policy-core/src/main/java/org/openecomp/policy/drools/core/FeatureAPI.java
new file mode 100644 (file)
index 0000000..a14c654
--- /dev/null
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core;
+
+import java.util.Properties;
+
+import org.kie.api.runtime.KieSession;
+
+import org.openecomp.policy.drools.utils.OrderedService;
+import org.openecomp.policy.drools.utils.OrderedServiceImpl;
+
+/**
+ * This interface provides a way to invoke optional features at various
+ * points in the code. At appropriate points in the
+ * application, the code iterates through this list, invoking these optional
+ * methods. Most of the methods here are notification only -- these tend to
+ * return a 'void' value. In other cases, such as 'activatePolicySession',
+ * may 
+ */
+public interface FeatureAPI extends OrderedService
+{
+  /**
+   * 'FeatureAPI.impl.getList()' returns an ordered list of objects
+   * implementing the 'FeatureAPI' interface.
+   */
+  static public OrderedServiceImpl<FeatureAPI> impl =
+       new OrderedServiceImpl<FeatureAPI>(FeatureAPI.class);
+
+  /**
+   * This method is called during initialization at a point right after
+   * 'PolicyContainer' initialization has completed.
+   *
+   * @param args standard 'main' arguments, which are currently ignored
+   * @param configDir the relative directory containing configuration files
+   */
+  public void globalInit(String args[], String configDir);
+
+  /**
+   * This method is used to create a 'KieSession' as part of a
+   * 'PolicyContainer'. The caller of this method will iterate over the
+   * implementers of this interface until one returns a non-null value.
+   *
+   * @param policyContainer the 'PolicyContainer' instance containing this
+   *   session
+   * @param name the name of the KieSession (which is also the name of
+   *   the associated PolicySession)
+   * @param kieBaseName the name of the 'KieBase' instance containing
+   *   this session
+   * @return a new KieSession, if one was created, or 'null' if not
+   *   (this depends on the capabilities and state of the object implementing
+   *   this interface)
+   */
+  public KieSession activatePolicySession
+       (PolicyContainer policyContainer, String name, String kieBaseName);
+
+  /**
+   * This method is called after 'KieSession.dispose()' is called
+   *
+   * @param policySession the 'PolicySession' object that wrapped the
+   *   'KieSession'
+   */
+  public void disposeKieSession(PolicySession policySession);
+
+  /**
+   * This method is called after 'KieSession.destroy()' is called
+   *
+   * @param policySession the 'PolicySession' object that wrapped the
+   *   'KieSession'
+   */
+  public void destroyKieSession(PolicySession policySession);
+  
+  /**
+   * called before the Policy Engine is started
+   */
+  public void beforeStartEngine() throws IllegalStateException;
+  
+  /**
+   * called immediately after the Policy Engine is started
+   */
+  public void afterStartEngine();
+  
+  /**
+   * called before the Policy Engine is shut down
+   */
+  public void beforeShutdownEngine();
+  
+  /**
+   * called after the Policy Engine is shut down
+   */
+  public void afterShutdownEngine();
+  
+  /**
+   * called before creating a controller with name 'name'
+   * 
+   * @param name name of the the controller
+   * @param properties configuration properties
+   */
+  public void beforeCreateController(String name, Properties properties);
+
+  /**
+   * NOTE: temporary, should pass the Policy Controller already created
+   * 
+   * called after creating a controller with name 'name'
+   * 
+   * @param name name of the the controller
+   * @param properties configuration properties
+   */
+  public void afterCreateController(String name);
+  
+  /**
+   * NOTE: temporary, should pass the Policy Controller
+   * 
+   * called before starting a controller with name 'name'
+   * 
+   * @param name name of the the controller
+   */
+  public void beforeStartController(String name);
+  
+  /**
+   * NOTE: temporary, should pass the Policy Controller
+   * 
+   * called after starting a controller with name 'name'
+   * 
+   * @param name name of the the controller
+   */
+  public void afterStartController(String name);
+
+  /**
+   * NOTE: this method is probably temporary
+   *
+   * @return 'true' if persistence is enabled, and 'false' if not, or if
+   *   this feature is not related to persistence.
+   */
+  public boolean isPersistenceEnabled();
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/core/PolicyContainer.java b/policy-core/src/main/java/org/openecomp/policy/drools/core/PolicyContainer.java
new file mode 100644 (file)
index 0000000..ae7cd62
--- /dev/null
@@ -0,0 +1,828 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.kie.api.KieBase;
+import org.kie.api.KieServices;
+import org.kie.api.builder.KieScanner;
+import org.kie.api.builder.Message;
+import org.kie.api.builder.ReleaseId;
+import org.kie.api.builder.Results;
+import org.kie.api.runtime.Environment;
+import org.kie.api.runtime.EnvironmentName;
+import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
+import org.kie.api.runtime.KieSessionConfiguration;
+
+import bitronix.tm.Configuration;
+import bitronix.tm.TransactionManagerServices;
+import bitronix.tm.resource.jdbc.PoolingDataSource;
+
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.ia.IntegrityAuditProperties;
+import org.openecomp.policy.drools.properties.Startable;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
+
+/**
+ * This class is a wrapper around 'KieContainer', which adds the ability
+ * to automatically create and track KieSession instances.
+ */
+public class PolicyContainer implements Startable
+{
+       // get an instance of logger 
+  private static Logger  logger = FlexLogger.getLogger(PolicyContainer.class); 
+  // 'KieServices' singleton
+  static private KieServices kieServices = KieServices.Factory.get();
+
+  // set of all 'PolicyContainer' instances
+  static private HashSet<PolicyContainer> containers =
+       new HashSet<PolicyContainer>();
+
+  // maps feature objects to per-PolicyContainer data
+  private ConcurrentHashMap<Object, Object> adjuncts =
+       new ConcurrentHashMap<Object, Object>();
+
+  // 'KieContainer' associated with this 'PolicyContainer'
+  private KieContainer kieContainer;
+
+  // indicates whether the PolicyContainer is 'started'
+  // (started = sessions created, threads running)
+  private volatile boolean isStarted = false;
+
+  // maps session name into the associated 'PolicySession' instance
+  private HashMap<String, PolicySession> sessions =
+       new HashMap<String, PolicySession>();
+
+  // if not null, this is a 'KieScanner' looking for updates
+  private KieScanner scanner = null;
+  
+  // indicates whether the scanner has been started
+  // (it can block for a long time)
+  private boolean scannerStarted = false;
+
+  // Used to set relative pathing to config files for unit test environment
+  public static boolean isUnitTesting = false;
+
+  /**
+   * uses 'groupId', 'artifactId' and 'version', and fetches the associated
+   * artifact and remaining dependencies from the Maven repository to create
+   * the 'PolicyContainer' and associated 'KieContainer'.
+   *
+   * An exception occurs if the creation of the 'KieContainer' fails.
+   *
+   * @param groupId the 'groupId' associated with the artifact
+   * @param artifactId the artifact name
+   * @param version a comma-separated list of possible versions
+   */
+  public PolicyContainer(String groupId, String artifactId, String version)
+  {
+       this(kieServices.newReleaseId(groupId, artifactId, version));
+  }
+
+  /**
+   * uses the 'groupId', 'artifactId' and 'version' information in 'ReleaseId',
+   * and fetches the associated artifact and remaining dependencies from the
+   * Maven repository to create the 'PolicyContainer' and associated
+   * 'KieContainer'.
+   *
+   * An exception occurs if the creation of the 'KieContainer' fails.
+   *
+   * @param releaseId indicates the artifact that is to be installed in this
+   *   container
+   */
+  public PolicyContainer(ReleaseId releaseId)
+  {
+       if (releaseId.getVersion().contains(","))
+         {
+               // this is actually a comma-separated list of release ids
+               releaseId = loadArtifact(releaseId.getGroupId(),
+                                                                releaseId.getArtifactId(),
+                                                                releaseId.getVersion());
+         }
+       else
+         {
+               kieContainer = kieServices.newKieContainer(releaseId);
+         }
+       synchronized(containers)
+         {
+               if(releaseId != null){
+                  logger.info("Add a new kieContainer in containers: releaseId: " + releaseId.toString());
+               }else{
+                  logger.warn("input releaseId is null");
+               }
+               containers.add(this);
+         }
+       startScanner(releaseId);
+  }
+
+  /**
+   * Load an artifact into a new KieContainer. This method handles the
+   * case where the 'version' is actually a comma-separated list of
+   * versions.
+   *
+   * @param groupId the 'groupId' associated with the artifact
+   * @param artifactId the artifact name
+   * @param version a comma-separated list of possible versions
+   */
+  private ReleaseId loadArtifact
+       (String groupId, String artifactId, String version)
+  {
+       String[] versions = version.split(",");
+       if (versions.length > 1)
+         {
+               logger.info("Multiple KieContainer versions are specified: "
+                                                 + version);
+         }
+
+       // indicates a 'newKieContainer' call failed
+       RuntimeException exception = null;
+
+       // set prior to every 'newKieContainer' invocation
+       // (if we are able to create the container, it will be the last
+       // one that was successful)
+       ReleaseId releaseId = null;
+       for (String ver : versions)
+         {
+               try
+                 {
+                       // Create a 'ReleaseId' object describing the artifact, and
+                       // create a 'KieContainer' based upon it.
+                       logger.info("Create new KieContainer start, version = "
+                                                         + ver + " ...");
+
+                       releaseId = kieServices.newReleaseId(groupId, artifactId, ver);
+                       kieContainer = kieServices.newKieContainer(releaseId);
+
+                       // clear any exception, and break out of the loop
+                       exception = null;
+                       break;
+                 }
+               catch (RuntimeException e)
+                 {
+                       exception = e;
+                 }
+         }
+       if (exception != null)
+         {
+               // all of the 'newKieContainer' invocations failed -- throw the
+               // most recent exception
+               throw(exception);
+         }
+       return(releaseId);
+  }
+
+  /**
+   * @return the name of the container, which is the String equivalent of
+   * the 'ReleaseId'. It has the form:
+   *
+   *   (groupId + ":" + artifactId + ":" + version)
+   *
+   * Note that the name changes after a successful call to 'updateToVersion',
+   * although typically only the 'version' part changes.
+   */
+  public String getName()
+  {
+       return(kieContainer.getReleaseId().toString());
+  }
+
+  /**
+   * @return the associated 'KieContainer' instance
+   */
+  public KieContainer getKieContainer()
+  {
+       return(kieContainer);
+  }
+
+  /**
+   * @return the 'ClassLoader' associated with the 'KieContainer' instance
+   */
+  public ClassLoader getClassLoader()
+  {
+       return(kieContainer.getClassLoader());
+  }
+
+  /**
+   * @return the Maven GroupId of the top-level artifact wrapped
+   *   by the container.
+   */
+  public String getGroupId()
+  {
+       return(kieContainer.getReleaseId().getGroupId());
+  }
+
+  /**
+   * @return the Maven ArtifactId of the top-level artifact wrapped
+   *   by the container.
+   */
+  public String getArtifactId()
+  {
+       return(kieContainer.getReleaseId().getArtifactId());
+  }
+
+  /**
+   * @return the version of the top-level artifact wrapped by the
+   *   container (this may change as updates occur)
+   */
+  public String getVersion()
+  {
+       return(kieContainer.getReleaseId().getVersion());
+  }
+
+  /**
+   * Fetch the named 'PolicySession'.
+   *
+   * @param name the name of the KieSession (which is also the name of
+   *   the associated PolicySession)
+   * @return a PolicySession if found, 'null' if not
+   */
+  public PolicySession getPolicySession(String name)
+  {
+       return(sessions.get(name));
+  }
+
+  /**
+   * Internal method to create a PolicySession, possibly restoring it
+   * from persistent storage.
+   *
+   * @param name of the KieSession and PolicySession
+   * @param kieBaseName name of the associated 'KieBase' instance
+   * @return a new or existing PolicySession, or 'null' if not found
+   */
+  private PolicySession activatePolicySession(String name, String kieBaseName)
+  {
+       synchronized(sessions)
+         {
+               logger.info("activatePolicySession:name :" + name);
+               PolicySession session = sessions.get(name);
+               if (session == null)
+                 {
+                       KieSession kieSession = null;
+
+                       // loop through all of the features, and give each one
+                       // a chance to create the 'KieSession'
+                       for (FeatureAPI feature : FeatureAPI.impl.getList())
+                         {
+                               if ((kieSession = feature.activatePolicySession
+                                        (this, name, kieBaseName)) != null)
+                                 break;
+                         }
+
+                       // if none of the features created the session, create one now
+                       if (kieSession == null)
+                         {
+                               kieSession = kieContainer.newKieSession(name);
+                         }
+
+                       if (kieSession != null)
+                         {
+                               // creation of 'KieSession' was successful - build
+                               // a PolicySession
+                               session = new PolicySession(name, this, kieSession);
+                               sessions.put(name, session);
+                               logger.info("activatePolicySession:new session was added in sessions with name " + name);
+                         }
+                 }
+               logger.info("activatePolicySession:session - "
+                                                 + (session == null ? "null" : session.getFullName())
+                                                 + " is returned.");
+               return(session);
+         }
+  }
+
+  /**
+   * This creates a 'PolicySession' instance within this 'PolicyContainer',
+   * and ties it to the specified 'KieSession'. 'name' must not currently
+   * exist within the 'PolicyContainer', and the 'KieBase' object associated
+   * with 'KieSession' must belong to the 'KieContainer'. This method provides
+   * a way for 'KieSession' instances that are created programmatically to fit
+   * into this framework.
+   *
+   * @param name the name for the new 'PolicySession'
+   * @param kieSession a 'KieSession' instance, that will be included in
+   *   this infrastructure
+   * @return the new 'PolicySession'
+   * @throws IllegalArgumentException if 'kieSession' does not reside within
+   *   this container
+   * @throws IllegalStateException if a 'PolicySession' already exists
+   *   with this name
+   */
+  public PolicySession adoptKieSession(String name, KieSession kieSession)
+       throws IllegalArgumentException, IllegalStateException
+  {
+
+       if(name == null){
+               logger.warn("adoptKieSession:input name is null");
+       }else if(kieSession == null){
+               logger.warn("adoptKieSession:input kieSession is null");
+       }else {
+               logger.info("adoptKieSession:name: " + name + " kieSession: " + kieSession);
+       }
+       // fetch KieBase, and verify it belongs to this KieContainer
+       boolean match = false;
+       KieBase kieBase = kieSession.getKieBase();
+       logger.info("adoptKieSession:kieBase: " + kieBase);
+       for (String kieBaseName : kieContainer.getKieBaseNames())
+         {
+               logger.info("adoptKieSession:kieBaseName: " + kieBaseName);
+               if (kieBase == kieContainer.getKieBase(kieBaseName))
+                 {
+                       match = true;
+                       break;
+                 }
+         }
+       logger.info("adoptKieSession:match " + match);
+       // if we don't have a match yet, the last chance is to look at the
+       // default KieBase, if it exists
+       if (!match && kieBase != kieContainer.getKieBase())
+         {
+               throw(new IllegalArgumentException
+                         ("KieSession '" + name + "' does not reside within container "
+                          + getName()));
+         }
+
+       synchronized (sessions)
+         {
+               if (sessions.get(name) != null)
+                 {
+                       throw(new IllegalStateException
+                                 ("PolicySession '" + name + "' already exists"));
+                 }
+
+               // create the new 'PolicySession', add it to the table,
+               // and return the object to the caller
+               logger.info("adoptKieSession:create a new policySession with name " + name);
+               PolicySession policySession =
+                 new PolicySession(name, this, kieSession);
+               sessions.put(name, policySession);
+               return(policySession);
+         }
+  }
+
+  /**
+   * This call 'KieContainer.updateToVersion()', and returns the associated
+   * response as a String. If successful, the name of this 'PolicyContainer'
+   * changes to match the new version.
+   *
+   * @param newVersion this is the version to update to (the 'groupId'
+   *   and 'artifactId' remain the same)
+   * @return the list of messages associated with the update (not sure if
+   *   this can be 'null', or how to determine success/failure)
+   */
+  public String updateToVersion(String newVersion)
+  {
+       ReleaseId releaseId = kieContainer.getReleaseId();
+       Results results = this.updateToVersion
+         (kieServices.newReleaseId(releaseId.getGroupId(),
+                                                               releaseId.getArtifactId(),
+                                                               newVersion));
+
+       List<Message> messages = (results == null ? null : results.getMessages());
+       return(messages == null ? null : messages.toString());
+  }
+
+  /**
+   * This calls 'KieContainer.updateToVersion()', and returns the associated
+   * response. If successful, the name of this 'PolicyContainer' changes to
+   * match the new version.
+   *
+   * @param releaseId the new artifact (usually new version) to be installed
+   * @return the 'Results' parameter from 'KieContainer.updateToVersion'
+   */
+  public Results updateToVersion(ReleaseId releaseId)
+  {
+    if(releaseId == null){
+          logger.warn("updateToVersion:input releaseId is null");
+    }else {
+       logger.info("updateToVersion:releaseId " + releaseId.toString());
+    }
+       return(kieContainer.updateToVersion(releaseId));
+  }
+
+  /**
+   * @return all existing 'PolicyContainer' instances
+   */
+  public static Collection<PolicyContainer> getPolicyContainers()
+  {
+       synchronized(containers)
+         {
+               return(new HashSet<PolicyContainer>(containers));
+         }
+  }
+
+  /**
+   * @return all of the 'PolicySession' instances
+   */
+  public Collection<PolicySession> getPolicySessions()
+  {
+       // KLUDGE WARNING: this is a temporary workaround -- if there are
+       // no features, we don't have persistence, and 'activate' is never
+       // called. In this case, make sure the container is started.
+       if (FeatureAPI.impl.getList().size() == 0)
+         {
+               start();
+         }
+
+       // return current set of PolicySessions
+       synchronized(sessions)
+         {
+               return(new HashSet<PolicySession>(sessions.values()));
+         }
+  }
+
+  /**
+   * This method will start a 'KieScanner' (if not currently running),
+   * provided that the ReleaseId version is 'LATEST' or 'RELEASE',
+   * or refers to a SNAPSHOT version.
+   *
+   * @param releaseId the release id used to create the container
+   */
+  public synchronized void startScanner(ReleaseId releaseId)
+  {
+       String version = releaseId.getVersion();
+       if (scannerStarted == false && scanner == null && version != null
+               && (version.equals("LATEST") || version.equals("RELEASE")
+                       || version.endsWith("-SNAPSHOT")))
+         {
+               // create the scanner, and poll at 60 second intervals
+               try
+                 {
+                       scannerStarted = true;
+
+                       // start this in a separate thread -- it can block for a long time
+                       new Thread("Scanner Starter " + getName())
+                       {
+                         public void run()
+                         {
+                               scanner = kieServices.newKieScanner(kieContainer);
+                               scanner.start(60000L);
+                         }
+                       }.start();
+                 }
+               catch (Exception e)
+                 {
+                       // sometimes the scanner initialization fails for some reason
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "main", "startServer");
+                 }
+         }
+  }
+
+  /**
+   * Insert a fact into a specific named session
+   *
+   * @param name this is the session name
+   * @param object this is the fact to be inserted into the session
+   * @return 'true' if the named session was found, 'false' if not
+   */
+  public boolean insert(String name, Object object)
+  {
+       // TODO: Should the definition of 'name' be expanded to include an
+       // alternate entry point as well? For example, 'name.entryPoint' (or
+       // something other than '.' if that is a problem).
+       synchronized (sessions)
+         {
+               PolicySession session = sessions.get(name);
+               if (session != null)
+                 {
+                       session.getKieSession().insert(object);
+                       return(true);
+                 }
+         }
+       return(false);
+  }
+
+  /**
+   * Insert a fact into all sessions associated with this container
+   *
+   * @param object this is the fact to be inserted into the sessions
+   * @return 'true' if the fact was inserted into at least one session,
+   *   'false' if not
+   */
+  public boolean insertAll(Object object)
+  {
+       boolean rval = false;
+       synchronized (sessions)
+         {
+               for (PolicySession session : sessions.values())
+                 {
+                       session.getKieSession().insert(object);
+                       rval = true;
+                 }
+         }
+       return(rval);
+  }
+
+  /*************************/
+  /* 'Startable' interface */
+  /*************************/
+
+  /**
+   * {@inheritDoc}
+   */
+  public synchronized boolean start()
+  {
+       if (!isStarted)
+         {
+               // This will create all 'PolicySession' instances specified in the
+               // 'kmodule.xml' file that don't exist yet
+               for (String kieBaseName : kieContainer.getKieBaseNames())
+                 {
+                       for (String kieSessionName :
+                                  kieContainer.getKieSessionNamesInKieBase(kieBaseName))
+                         {
+                               // if the 'PolicySession' does not currently exist, this method
+                               // call will attempt to create it
+                               PolicySession session =
+                                 activatePolicySession(kieSessionName, kieBaseName);
+                               if (session != null)
+                                 {
+                                       session.startThread();
+                                 }
+                         }
+                 }
+               isStarted = true;
+         }
+       return(true);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public synchronized boolean stop()
+  {
+       if (isStarted)
+         {
+               Collection<PolicySession> localSessions;
+
+               synchronized (sessions)
+                 {
+                       // local set containing all of the sessions
+                       localSessions = new HashSet<PolicySession>(sessions.values());
+
+                       // clear the 'name->session' map in 'PolicyContainer'
+                       sessions.clear();
+                 }
+               for (PolicySession session : localSessions)
+                 {
+                       // stop session thread
+                       session.stopThread();
+
+                       // free KieSession resources
+                       session.getKieSession().dispose();
+
+                       // notify features
+                       for (FeatureAPI feature : FeatureAPI.impl.getList())
+                         {
+                               feature.disposeKieSession(session);
+                         }
+                 }
+               isStarted = false;
+         }
+       return(true);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public synchronized void shutdown()
+  {
+       // Note that this method does not call 'destroy' on the 'KieSession'
+       // instances, which would remove any associated information in persistent
+       // storage. Should it do this?
+
+       stop();
+       synchronized(containers)
+         {
+               containers.remove(this);
+         }
+
+       // How do we free the resources associated with the KieContainer?
+       // Is garbage collection sufficient?
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isAlive()
+  {
+       return(isStarted);
+  }
+
+  /*************************/
+
+  /**
+   * This method is similar to 'shutdown', but it also frees any persistence
+   * resources as well.
+   */
+  public synchronized void destroy()
+  {
+       // we need all KieSession instances running in order to free
+       // resources associated with persistence
+       start();
+       Collection<PolicySession> localSessions;
+
+       synchronized (sessions)
+         {
+               // local set containing all of the sessions
+               localSessions = new HashSet<PolicySession>(sessions.values());
+
+               // clear the 'name->session' map in 'PolicyContainer'
+               sessions.clear();
+         }
+       for (PolicySession session : localSessions)
+         {
+               // stop session thread
+               session.stopThread();
+
+               // free KieSession resources
+               session.getKieSession().destroy();
+
+               // notify features
+               for (FeatureAPI feature : FeatureAPI.impl.getList())
+                 {
+                       feature.destroyKieSession(session);
+                 }
+         }
+       isStarted = false;
+
+       synchronized(containers)
+         {
+               containers.remove(this);
+         }
+
+       // How do we free the resources associated with the KieContainer?
+       // Is garbage collection sufficient?
+  }
+
+  /**
+   * This method is called when the host goes from the 'standby->active' state.
+   */
+  static public void activate()
+  {
+       // start all of the 'PolicyContainer' instances
+       for (PolicyContainer container : containers)
+         {
+               try
+                 {
+                       container.start();
+                 }
+               catch (Exception e)
+                 {
+                       e.printStackTrace();
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e,
+                                                          "activate",
+                                                          "PolicyContainer.start()");
+                 }
+         }
+  }
+
+  /**
+   * This method is called when the host goes from the 'active->standby' state.
+   */
+  static public void deactivate()
+  {
+       // deactivate all of the 'PolicyContainer' instances
+       for (PolicyContainer container : containers)
+         {
+               try
+                 {
+                       container.stop();
+                 }
+               catch (Exception e)
+                 {
+                       e.printStackTrace();
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e,
+                                                          "deactivate",
+                                                          "PolicyContainer.stop()");
+                 }
+         }
+  }
+
+  /**
+   * This method does the following:
+   *
+   *   1) Initializes logging
+   *   2) Starts the DroolsPDP Integrity Monitor
+   *   3) Initilaizes persistence
+   *
+   * It no longer reads in properties files, o creates 'PolicyContainer'
+   * instances.
+   *
+   * @param args standard 'main' arguments, which are currently ignored
+   */
+  public static void globalInit(String args[])
+  {
+         
+       /*
+        * When JUnit testing, working directory should be
+        * "../policy-management". In test environment, command line argument
+        * should specify the relative path from this directory to the config
+        * directory ("src/test/server/config")
+        */
+       String configDir = "config";
+       if (isUnitTesting) {
+               configDir = "src/test/server/config";
+       } 
+       System.out.println("PolicyContainer.main: configDir=" + configDir);
+       
+       logger.info("Calling initlogger");
+       
+       initlogger(configDir);
+       logger.info("initlogger returned");
+
+       // invoke 'globalInit' on all of the features
+       for (FeatureAPI feature : FeatureAPI.impl.getList())
+         {
+               feature.globalInit(args, configDir);
+         }
+  }
+
+  /**
+   * Read in the logger properties
+   */
+  private static void initlogger(String configDir){
+               try {
+                       Properties properties =
+                                         PropertyUtil.getProperties(configDir + "/policyLogger.properties");                   
+                       try {
+                               
+                               PolicyLogger.init(properties);
+                               
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.MISS_PROPERTY_ERROR, e, "initlogger");
+                       }
+               } catch (IOException e1) {
+                       logger.error(MessageCodes.MISS_PROPERTY_ERROR, e1, "initlogger");
+               }
+  }
+       
+  /**
+   * Fetch the adjunct object associated with a given feature
+   *
+   * @param object this is typically the singleton feature object that is
+   *   used as a key, but it might also be useful to use nested objects
+   *   within the feature as keys.
+   * @return a feature-specific object associated with the key, or 'null'
+   *   if it is not found.
+   */
+  public Object getAdjunct(Object object)
+  {
+       return(adjuncts.get(object));
+  }
+
+  /**
+   * Store the adjunct object associated with a given feature
+   *
+   * @param object this is typically the singleton feature object that is
+   *   used as a key, but it might also be useful to use nested objects
+   *   within the feature as keys.
+   * @param value a feature-specific object associated with the key, or 'null'
+   *   if the feature-specific object should be removed
+   */
+  public void setAdjunct(Object object, Object value)
+  {
+       if (value == null)
+         {
+               adjuncts.remove(object);
+         }
+       else
+         {
+               adjuncts.put(object, value);
+         }
+  }
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/core/PolicySession.java b/policy-core/src/main/java/org/openecomp/policy/drools/core/PolicySession.java
new file mode 100644 (file)
index 0000000..89341d6
--- /dev/null
@@ -0,0 +1,349 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Properties;
+
+import org.kie.api.runtime.KieSession;
+import org.kie.api.event.rule.AfterMatchFiredEvent;
+import org.kie.api.event.rule.AgendaEventListener;
+import org.kie.api.event.rule.AgendaGroupPoppedEvent;
+import org.kie.api.event.rule.AgendaGroupPushedEvent;
+import org.kie.api.event.rule.BeforeMatchFiredEvent;
+import org.kie.api.event.rule.MatchCancelledEvent;
+import org.kie.api.event.rule.MatchCreatedEvent;
+import org.kie.api.event.rule.ObjectDeletedEvent;
+import org.kie.api.event.rule.ObjectInsertedEvent;
+import org.kie.api.event.rule.ObjectUpdatedEvent;
+import org.kie.api.event.rule.RuleRuntimeEventListener;
+import org.kie.api.event.rule.RuleFlowGroupActivatedEvent;
+import org.kie.api.event.rule.RuleFlowGroupDeactivatedEvent;
+
+import org.openecomp.policy.drools.core.jmx.PdpJmx;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+
+/**
+ * This class is a wrapper around 'KieSession', which adds the following:
+ *
+ * 1) A thread running 'KieSession.fireUntilHalt()'
+ * 2) Access to UEB
+ * 3) Logging of events
+ */
+public class PolicySession
+  implements AgendaEventListener, RuleRuntimeEventListener
+{
+       // get an instance of logger 
+  private static Logger  logger = FlexLogger.getLogger(PolicySession.class);           
+  // name of the 'PolicySession' and associated 'KieSession'
+  private String name;
+
+  // the associated 'PolicyContainer', which may have additional
+  // 'PolicySession' instances in addition to this one
+  private PolicyContainer container;
+
+  // associated 'KieSession' instance
+  private KieSession kieSession;
+
+  // if not 'null', this is the thread running 'kieSession.fireUntilHalt()'
+  private Thread thread = null;
+
+  // supports 'getCurrentSession()' method
+  static private ThreadLocal<PolicySession> policySession =
+       new ThreadLocal<PolicySession>();
+
+  /**
+   * Internal constructor - create a 'PolicySession' instance
+   *
+   * @param name the name of this 'PolicySession' (and 'kieSession')
+   * @param container the 'PolicyContainer' instance containing this session
+   * @param kieSession the associated 'KieSession' instance
+   */
+  protected PolicySession(String name,
+                                                 PolicyContainer container, KieSession kieSession)
+  {
+       this.name = name;
+       this.container = container;
+       this.kieSession = kieSession;
+       kieSession.addEventListener((AgendaEventListener)this);
+       kieSession.addEventListener((RuleRuntimeEventListener)this);
+  }
+
+  /**
+   * @return the 'PolicyContainer' object containing this session
+   */
+  public PolicyContainer getPolicyContainer()
+  {
+       return(container);
+  }
+
+  /**
+   * @return the associated 'KieSession' instance
+   */
+  public KieSession getKieSession()
+  {
+       return(kieSession);
+  }
+
+  /**
+   * @return the local name of this session, which should either match the
+   * name specified in 'kmodule.xml' file associated with this session, or the
+   * name passed on the 'PolicyContainer.adoptKieSession' method.
+   */
+  public String getName()
+  {
+       return(name);
+  }
+
+  /**
+   * @return the 'PolicyContainer' name, followed by ':', followed by the
+   * local name of the session. It should be useful in log messages.
+   */
+  public String getFullName()
+  {
+       return(container.getName() + ":" + name);
+  }
+
+  /**
+   * this starts a separate thread, which invokes 'KieSession.fireUntilHalt()'.
+   * It does nothing if the thread already exists.
+   */
+  public synchronized void startThread()
+  {
+       if (thread == null)
+         {
+               logger.info("startThread with name " + getFullName());
+               thread = new Thread("Session " + getFullName())
+                 {
+                       public void run()
+                         {
+                               // set thread local variable
+                               policySession.set(PolicySession.this);
+
+                               // We want to continue, despite any exceptions that occur
+                               // while rules are fired.
+                               boolean repeat = true;
+                               while (repeat)
+                                 {
+                                       if(this.isInterrupted()){
+                                               break;
+                                       }
+                                       try
+                                         {
+                                               kieSession.fireAllRules();
+                                               
+                                         }
+                                       catch (Throwable e)
+                                         {
+                                               logger.error(MessageCodes.EXCEPTION_ERROR, e, "startThread", "kieSession.fireUntilHalt");                                                       
+                                         }
+                                       try {
+                                               Thread.sleep(5000);
+                                       } catch (InterruptedException e) {
+                                               break;
+                                       }
+                                 }
+                               logger.info("fireUntilHalt() returned");
+                         }
+                 };
+               thread.start();
+         }
+  }
+
+  /**
+   * if a thread is currently running, this invokes 'KieSession.halt()' to
+   * stop it.
+   */
+  public synchronized void stopThread()
+  {
+       if (thread != null)
+         {
+               // this should cause the thread to exit         
+               thread.interrupt();
+               try
+                 {
+                       // wait for the thread to stop
+                       thread.join();
+                 }
+               catch (Exception e)
+                 {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "stopThread", "thread.join");
+                 }
+               thread = null;
+         }
+  }
+
+  /**
+   * @return the 'PolicySession' instance associated with the current thread
+   *   (Note that this only works if the current thread is the one running
+   *   'kieSession.fireUntilHalt()'.)
+   */
+  public static PolicySession getCurrentSession()
+  {
+       return(policySession.get());
+  }
+
+  /***********************************/
+  /* 'AgendaEventListener' interface */
+  /***********************************/
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void afterMatchFired(AfterMatchFiredEvent event)
+  {
+       logger.debug("afterMatchFired: " + getFullName()
+                          + ": AgendaEventListener.afterMatchFired(" + event + ")");
+       PdpJmx.getInstance().ruleFired();
+ }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event)
+  {
+       logger.debug("afterRuleFlowGroupActivated: " + getFullName()
+                          + ": AgendaEventListener.afterRuleFlowGroupActivated(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void afterRuleFlowGroupDeactivated
+       (RuleFlowGroupDeactivatedEvent event)
+  {
+       logger.debug("afterRuleFlowGroupDeactivated: " + getFullName()
+                          + ": AgendaEventListener.afterRuleFlowGroupDeactivated(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void agendaGroupPopped(AgendaGroupPoppedEvent event)
+  {
+       logger.debug("agendaGroupPopped: " + getFullName()
+                          + ": AgendaEventListener.agendaGroupPopped(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void agendaGroupPushed(AgendaGroupPushedEvent event)
+  {
+       logger.debug("agendaGroupPushed: " + getFullName()
+                          + ": AgendaEventListener.agendaGroupPushed(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void beforeMatchFired(BeforeMatchFiredEvent event)
+  {
+       logger.debug("beforeMatchFired: " + getFullName()
+                          + ": AgendaEventListener.beforeMatchFired(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void beforeRuleFlowGroupActivated
+       (RuleFlowGroupActivatedEvent event)
+  {
+       logger.debug("beforeRuleFlowGroupActivated: " + getFullName()
+                          + ": AgendaEventListener.beforeRuleFlowGroupActivated(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void beforeRuleFlowGroupDeactivated
+       (RuleFlowGroupDeactivatedEvent event)
+  {
+       logger.debug("beforeRuleFlowGroupDeactivated: " + getFullName()
+                          + ": AgendaEventListener.beforeRuleFlowGroupDeactivated(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void matchCancelled(MatchCancelledEvent event)
+  {
+       logger.debug("matchCancelled: " + getFullName()
+                          + ": AgendaEventListener.matchCancelled(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void matchCreated(MatchCreatedEvent event)
+  {
+       logger.debug("matchCreated: " + getFullName()
+                          + ": AgendaEventListener.matchCreated(" + event + ")");
+  }
+
+  /****************************************/
+  /* 'RuleRuntimeEventListener' interface */
+  /****************************************/
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void objectDeleted(ObjectDeletedEvent event)
+  {
+       logger.debug("objectDeleted: " + getFullName()
+                          + ": AgendaEventListener.objectDeleted(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void objectInserted(ObjectInsertedEvent event)
+  {
+       logger.debug("objectInserted: " + getFullName()
+                          + ": AgendaEventListener.objectInserted(" + event + ")");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void objectUpdated(ObjectUpdatedEvent event)
+  {
+       logger.debug("objectUpdated: " + getFullName()
+                          + ": AgendaEventListener.objectUpdated(" + event + ")");
+  }
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmx.java b/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmx.java
new file mode 100644 (file)
index 0000000..7fa0dd0
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core.jmx;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+public class PdpJmx implements PdpJmxMBean  {
+
+       private static PdpJmx instance = new PdpJmx();
+       private final AtomicLong updates = new AtomicLong();
+       private final AtomicLong actions = new AtomicLong();
+
+       public static PdpJmx getInstance() {
+               return instance;
+       }
+       
+       public long getUpdates(){
+               return updates.longValue();
+       }
+       public long getRulesFired(){
+               return actions.longValue();
+       }
+       public void updateOccured(){
+               updates.incrementAndGet();
+       }
+       public void ruleFired(){
+               actions.incrementAndGet();
+       }
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxListener.java b/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxListener.java
new file mode 100644 (file)
index 0000000..4b48da0
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core.jmx;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+
+public class PdpJmxListener {
+
+       public static final Logger logger = FlexLogger.getLogger(PdpJmxListener.class);
+       
+       public static void stop() {
+               final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+               try {
+                       server.unregisterMBean(new ObjectName("PolicyEngine:type=PdpJmx"));
+               } catch (MBeanRegistrationException | InstanceNotFoundException
+                               | MalformedObjectNameException e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "PdpJmxListener.stop()", "Could not unregister PolicyEngine:type=PdpJmx MBean with the MBean server");
+               }
+               
+       }
+
+       
+       public static void start() {
+               final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+               try {
+                       server.registerMBean(PdpJmx.getInstance(), new ObjectName("PolicyEngine:type=PdpJmx"));
+               } catch (InstanceAlreadyExistsException | MBeanRegistrationException
+                               | NotCompliantMBeanException | MalformedObjectNameException e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "PdpJmxListener.start()", "Could not register PolicyEngine:type=PdpJmx MBean with the MBean server");
+               }
+               
+       }
+
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxMBean.java b/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxMBean.java
new file mode 100644 (file)
index 0000000..a947e82
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core.jmx;
+
+public interface PdpJmxMBean {
+
+       public long getRulesFired();
+       public long getUpdates();
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/properties/Lockable.java b/policy-core/src/main/java/org/openecomp/policy/drools/properties/Lockable.java
new file mode 100644 (file)
index 0000000..fd8681c
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.properties;
+
+/**
+ * Marks a entity as able to lock and unlock.
+ */
+public interface Lockable {
+       
+       /**
+        * locks this entity
+        * @return true is the lock operation was successful, false otherwise
+        */
+       public boolean lock();
+       
+       /**
+        * unlocks this entity
+        * @return true is the unlock operation was successful, false otherwise
+        */
+       public boolean unlock();
+       
+       /**
+        * is this entity locked?
+        * @return true if the entity is in a locked state, false otherwise
+        */
+       public boolean isLocked();
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java b/policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java
new file mode 100644 (file)
index 0000000..1358021
--- /dev/null
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.properties;
+
+public interface PolicyProperties {
+       
+       /* Controller Properties */
+       
+       public static final String PROPERTY_CONTROLLER_NAME = "controller.name";
+       
+       /* Generic property suffixes */
+       
+       public static final String PROPERTY_TOPIC_SERVERS_SUFFIX = ".servers";
+       public static final String PROPERTY_TOPIC_API_KEY_SUFFIX = ".apiKey";
+       public static final String PROPERTY_TOPIC_API_SECRET_SUFFIX = ".apiSecret";     
+       public static final String PROPERTY_TOPIC_AAF_MECHID_SUFFIX = ".aafMechId";
+       public static final String PROPERTY_TOPIC_AAF_PASSWORD_SUFFIX = ".aafPassword"; 
+       public static final String PROPERTY_TOPIC_EVENTS_SUFFIX =".events";
+       public static final String PROPERTY_TOPIC_EVENTS_FILTER_SUFFIX =".filter";
+       public static final String PROPERTY_TOPIC_EVENTS_CUSTOM_MODEL_CODER_GSON_SUFFIX =".events.custom.gson";
+       public static final String PROPERTY_TOPIC_EVENTS_CUSTOM_MODEL_CODER_JACKSON_SUFFIX =".events.custom.jackson";
+       
+       public static final String PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX = ".consumerGroup";
+       public static final String PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX = ".consumerInstance";
+       public static final String PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX = ".fetchTimeout";
+       public static final String PROPERTY_TOPIC_SOURCE_FETCH_LIMIT_SUFFIX = ".fetchLimit";
+       public static final String PROPERTY_MANAGED_SUFFIX =".managed";
+       
+       public static final String PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX =".partitionKey";
+       
+       /* UEB Properties */
+       
+       public static final String PROPERTY_UEB_SOURCE_TOPICS = "ueb.source.topics";    
+       public static final String PROPERTY_UEB_SINK_TOPICS = "ueb.sink.topics";        
+       
+       /* DMAAP Properties */
+       
+       public static final String PROPERTY_DMAAP_SOURCE_TOPICS = "dmaap.source.topics";
+       public static final String PROPERTY_DMAAP_SINK_TOPICS = "dmaap.sink.topics";
+       
+       /* HTTP Server Properties */
+       
+       public static final String PROPERTY_HTTP_SERVER_SERVICES = "http.server.services";
+       
+       public static final String PROPERTY_HTTP_HOST_SUFFIX = ".host";
+       public static final String PROPERTY_HTTP_PORT_SUFFIX = ".port";
+       public static final String PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX = ".contextUriPath";
+       
+       public static final String PROPERTY_HTTP_AUTH_USERNAME_SUFFIX = ".userName";
+       public static final String PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX = ".password";
+       public static final String PROPERTY_HTTP_AUTH_URIPATH_SUFFIX = ".authUriPath";
+       
+       public static final String PROPERTY_HTTP_REST_CLASSES_SUFFIX = ".restClasses";
+       public static final String PROPERTY_HTTP_REST_PACKAGES_SUFFIX = ".restPackages";
+       public static final String PROPERTY_HTTP_REST_URIPATH_SUFFIX = ".restUriPath";
+       
+       public static final String PROPERTY_HTTP_HTTPS_SUFFIX = ".https";
+       
+       /* HTTP Client Properties */
+       
+       public static final String PROPERTY_HTTP_CLIENT_SERVICES = "http.client.services";
+       
+       public static final String PROPERTY_HTTP_URL_SUFFIX = PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX;
+       
+       /* Drools Properties */
+       
+       public static final String RULES_GROUPID = "rules.groupId";
+       public static final String RULES_ARTIFACTID = "rules.artifactId";
+       public static final String RULES_VERSION = "rules.version";
+       
+       /* Management Server Properties */      
+       
+       public static final String ENV_MANAGEMENT_SERVER_PORT = "ENGINE_MANAGEMENT_PORT";
+       public static final String ENV_MANAGEMENT_SERVER_HOST = "ENGINE_MANAGEMENT_HOST";
+       public static final String ENV_MANAGEMENT_AUTH_USER = "ENGINE_MANAGEMENT_USER";
+       public static final String ENV_MANAGEMENT_AUTH_PASSWD = "ENGINE_MANAGEMENT_PASSWORD";
+       
+}
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/properties/Startable.java b/policy-core/src/main/java/org/openecomp/policy/drools/properties/Startable.java
new file mode 100644 (file)
index 0000000..bb6334a
--- /dev/null
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-core
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.properties;
+
+/**
+ * Declares the Startable property of any class class implementing
+ * this interface.   This implies that the implementing class supports
+ * start-like operations.
+ */
+public interface Startable {
+       
+       /**
+        * Start operation.  This operation starts the entity.
+        * 
+        * @return boolean.  true if the start operation was successful, 
+        * otherwise false.
+        * @throws IllegalStateException. if the element is in a state that
+        * conflicts with the start operation.
+        */
+       public boolean start() throws IllegalStateException;
+       
+       /**
+        * Stop operation.  The entity can be restarted again by invoking
+        * the start operation.
+        * 
+        * @return boolean.  true if the stop operation was successful, 
+        * otherwise false.
+        * @throws IllegalStateException. if the element is in a state that
+        * conflicts with the stop operation.
+        */
+       public boolean stop()throws IllegalStateException;
+       
+       /**
+        * shutdown operation.   The terminate operation yields the entity
+        * unusuable.  It cannot be (re)started.
+        * 
+        * @throws IllegalStateException. if the element is in a state that
+        * conflicts with the stop operation.
+        */
+       public void shutdown()throws IllegalStateException;
+       
+       /**
+        * is it alive?
+        * @return boolean.  true if alive, otherwise false
+        */
+       public boolean isAlive();
+}
diff --git a/policy-core/src/main/resources/META-INF/jndi.properties b/policy-core/src/main/resources/META-INF/jndi.properties
new file mode 100644 (file)
index 0000000..033a08a
--- /dev/null
@@ -0,0 +1,21 @@
+###
+# ============LICENSE_START=======================================================
+# policy-core
+# ================================================================================
+# 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=========================================================
+###
+
+java.naming.factory.initial=bitronix.tm.jndi.BitronixInitialContextFactory
diff --git a/policy-core/src/main/resources/META-INF/persistence.xml b/policy-core/src/main/resources/META-INF/persistence.xml
new file mode 100644 (file)
index 0000000..34685b0
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  policy-core
+  ================================================================================
+  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=========================================================
+  -->
+
+<persistence version="2.1"
+       xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+
+       <persistence-unit name="ncompPU" transaction-type="RESOURCE_LOCAL">
+       <!-- This is for database access by non-drools methods -->
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.openecomp.policy.common.im.jpa.StateManagementEntity</class>
+               <class>org.openecomp.policy.drools.persistence.DroolsPdpEntity</class>
+               <class>org.openecomp.policy.drools.persistence.DroolsSessionEntity</class>
+               <class>org.drools.persistence.info.SessionInfo</class>
+               <class>org.drools.persistence.info.WorkItemInfo</class>
+               <class>org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity</class>
+
+               <properties>
+                       <!-- Properties are passed in -->
+        </properties>
+       </persistence-unit>
+       
+       <persistence-unit name="ncompsessionsPU" transaction-type="JTA">
+       <!-- Used for drools session data access -->
+               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>             
+               <class>org.drools.persistence.info.SessionInfo</class>
+               <class>org.drools.persistence.info.WorkItemInfo</class>
+               <properties>
+                       <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
+                       <property name="hibernate.max_fetch_depth" value="3" />
+                       <property name="hibernate.hbm2ddl.auto" value="update" />
+                       <property name="hibernate.show_sql" value="false" />
+                       <property name="hibernate.transaction.manager_lookup_class"
+                               value="org.hibernate.transaction.BTMTransactionManagerLookup" />
+               </properties>
+       </persistence-unit>
+       
+       
+       <persistence-unit name="schemaPU" transaction-type="RESOURCE_LOCAL">
+       <!-- Limited use for generating the DB and schema files for ncomp DB - uses eclipselink for convenience -->
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.drools.persistence.info.SessionInfo</class>
+               <class>org.drools.persistence.info.WorkItemInfo</class>
+               <class>org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity</class>
+               <properties>
+                       <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
+                       <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/> 
+            <property name="javax.persistence.schema-generation.scripts.create-target" value="./sql/generatedCreateNcomp.ddl"/>
+            <property name="javax.persistence.schema-generation.scripts.drop-target" value="./sql/generatedDropNcomp.ddl"/>
+        </properties>
+       </persistence-unit>
+</persistence>
diff --git a/policy-endpoints/pom.xml b/policy-endpoints/pom.xml
new file mode 100644 (file)
index 0000000..e62853c
--- /dev/null
@@ -0,0 +1,157 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+         
+  <modelVersion>4.0.0</modelVersion>
+  
+  <parent>
+    <groupId>org.openecomp.policy.drools-pdp</groupId>
+    <artifactId>drools-pdp</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  
+  <artifactId>policy-endpoints</artifactId>
+  
+  <name>policy-endpoints</name>
+  <description>Policy UEB support</description>
+
+  <properties>
+          <maven.compiler.source>1.8</maven.compiler.source>
+          <maven.compiler.target>1.8</maven.compiler.target>
+          <cambria.version>0.0.1</cambria.version>
+          <dmaap.version>0.2.12</dmaap.version>
+          <jetty.version>9.3.14.v20161028</jetty.version>
+          <jersey.version>2.22.1</jersey.version>
+          <jackson.version>2.8.4</jackson.version>
+        
+  </properties>
+
+       <dependencies>
+               <dependency>
+                       <groupId>com.att.nsa</groupId>
+                       <artifactId>cambriaClient</artifactId>
+                       <version>${cambria.version}</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>    
+                               <exclusion>
+                                       <groupId>com.att.nsa</groupId>
+                                       <artifactId>saClientLibrary</artifactId>
+                               </exclusion>                                            
+                       </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>com.att.nsa</groupId>
+                       <artifactId>dmaapClient</artifactId>
+                       <version>${dmaap.version}</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>    
+                       </exclusions>
+               </dependency>   
+               <dependency>
+                       <groupId>org.eclipse.jetty</groupId>
+                       <artifactId>jetty-server</artifactId>
+                       <version>${jetty.version}</version>
+               </dependency>
+       
+               <dependency>
+                       <groupId>org.eclipse.jetty</groupId>
+                       <artifactId>jetty-servlet</artifactId>
+                       <version>${jetty.version}</version>
+               </dependency>
+       
+               <dependency>
+                       <groupId>org.glassfish.jersey.core</groupId>
+                       <artifactId>jersey-server</artifactId>
+                       <version>${jersey.version}</version>
+               </dependency>
+       
+               <dependency>
+                       <groupId>org.glassfish.jersey.containers</groupId>
+                       <artifactId>jersey-container-servlet-core</artifactId>
+                       <version>${jersey.version}</version>
+               </dependency>
+       
+               <dependency>
+                       <groupId>org.glassfish.jersey.media</groupId>
+                       <artifactId>jersey-media-json-jackson</artifactId>
+                       <version>${jersey.version}</version>
+               </dependency>
+       
+               <dependency>
+                       <groupId>org.glassfish.jersey.containers</groupId>
+                       <artifactId>jersey-container-jetty-http</artifactId>
+                       <version>${jersey.version}</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.eclipse.jetty</groupId>
+                                       <artifactId>jetty-util</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               
+               <dependency>
+                       <groupId>org.glassfish.jersey.core</groupId>
+                       <artifactId>jersey-client</artifactId>
+                       <version>${jersey.version}</version>
+               </dependency>
+       
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-databind</artifactId>
+                       <version>${jackson.version}</version>
+               </dependency>
+       
+               <dependency>
+                       <groupId>com.fasterxml.jackson.datatype</groupId>
+                       <artifactId>jackson-datatype-jsr310</artifactId>
+                       <version>${jackson.version}</version>
+               </dependency>
+
+           <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpcore</artifactId>
+                       <version>4.4.4</version>
+           </dependency>       
+           <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpclient</artifactId>
+                       <version>4.5</version>
+           </dependency>
+           <dependency>
+               <groupId>org.apache.commons</groupId>
+                       <artifactId>commons-collections4</artifactId>
+                       <version>4.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.policy.drools-pdp</groupId>
+                       <artifactId>policy-core</artifactId>
+                       <version>1.0.0-SNAPSHOT</version>
+               </dependency>
+       </dependencies>
+
+</project>
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/Topic.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/Topic.java
new file mode 100644 (file)
index 0000000..d38bab5
--- /dev/null
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm;
+
+import java.util.List;
+
+/**
+ * Essential Topic Data
+ */
+public interface Topic {
+       
+       public static final String NETWORK_LOGGER = "networkLogger";
+       
+       /**
+        * Underlying Communication infrastructure Types
+        */
+       public enum CommInfrastructure {
+               /**
+                * UEB Communication Infrastructure
+                */
+               UEB,
+               /**
+                * DMAAP Communication Infrastructure
+                */             
+               DMAAP,
+               /**
+                * REST Communication Infrastructure
+                */                             
+               REST
+       }
+       
+       /**
+        * gets the topic name
+        * 
+        * @return topic name
+        */
+       public String getTopic();
+       
+       /**
+        * gets the communication infrastructure type
+        * @return
+        */
+       public CommInfrastructure getTopicCommInfrastructure();
+       
+       /**
+        * return list of servers
+        * @return bus servers
+        */
+       public List<String> getServers();       
+
+       /**
+        * get the more recent events in this topic entity
+        * 
+        * @return list of most recent events
+        */
+       public String[] getRecentEvents();
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicEndpoint.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicEndpoint.java
new file mode 100644 (file)
index 0000000..b3f236f
--- /dev/null
@@ -0,0 +1,692 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.event.comm.bus.DmaapTopicSink;
+import org.openecomp.policy.drools.event.comm.bus.DmaapTopicSource;
+import org.openecomp.policy.drools.event.comm.bus.UebTopicSink;
+import org.openecomp.policy.drools.event.comm.bus.UebTopicSource;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.drools.properties.Lockable;
+import org.openecomp.policy.drools.properties.Startable;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Abstraction to managed the system's Networked Topic Endpoints,
+ * sources of all events input into the System. 
+ */
+public interface TopicEndpoint extends Startable, Lockable {
+       
+       /**
+        * Add Topic Sources to the communication infrastructure initialized per
+        * properties
+        * 
+        * @param properties properties for Topic Source construction
+        * @return a generic Topic Source
+        * @throws IllegalArgumentException when invalid arguments are provided
+        */
+       public List<? extends TopicSource> addTopicSources(Properties properties) 
+                  throws IllegalArgumentException;
+
+       /**
+        * Add Topic Sinks to the communication infrastructure initialized per
+        * properties
+        * 
+        * @param properties properties for Topic Sink construction
+        * @return a generic Topic Sink
+        * @throws IllegalArgumentException when invalid arguments are provided
+        */
+       public List<? extends TopicSink> addTopicSinks(Properties properties) 
+                          throws IllegalArgumentException;
+       
+       /**
+        * gets all Topic Sources
+        * @return the Topic Source List
+        */
+       List<? extends TopicSource> getTopicSources();
+       
+       /**
+        * get the Topic Sources for the given topic name
+        * 
+        * @param topicName the topic name
+        * 
+        * @return the Topic Source List
+        * @throws IllegalStateException if the entity is in an invalid state
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public List<? extends TopicSource> getTopicSources(List<String> topicNames) 
+                       throws IllegalStateException, IllegalArgumentException;
+       
+       /**
+        * gets the Topic Source for the given topic name and 
+        * underlying communication infrastructure type
+        * 
+        * @param commType communication infrastructure type
+        * @param topicName the topic name
+        * 
+        * @return the Topic Source
+        * @throws IllegalStateException if the entity is in an invalid state, for
+        * example multiple TopicReaders for a topic name and communication infrastructure
+        * @throws IllegalArgumentException if invalid parameters are present
+        * @throws UnsupportedOperationException if the operation is not supported.
+        */
+       public TopicSource getTopicSource(Topic.CommInfrastructure commType, 
+                                                 String topicName) 
+                       throws IllegalStateException, IllegalArgumentException, 
+                              UnsupportedOperationException;
+       
+       /**
+        * get the UEB Topic Source for the given topic name
+        * 
+        * @param topicName the topic name
+        * 
+        * @return the UEB Topic Source
+        * @throws IllegalStateException if the entity is in an invalid state, for
+        * example multiple TopicReaders for a topic name and communication infrastructure
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public UebTopicSource getUebTopicSource(String topicName)
+                       throws IllegalStateException, IllegalArgumentException;
+       
+       /**
+        * get the DMAAP Topic Source for the given topic name
+        * 
+        * @param topicName the topic name
+        * 
+        * @return the DMAAP Topic Source
+        * @throws IllegalStateException if the entity is in an invalid state, for
+        * example multiple TopicReaders for a topic name and communication infrastructure
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public DmaapTopicSource getDmaapTopicSource(String topicName)
+                       throws IllegalStateException, IllegalArgumentException;
+       
+       /**
+        * get the Topic Sinks for the given topic name
+        * 
+        * @param topicNames the topic names
+        * @return the Topic Sink List
+        * @throws IllegalStateException
+        * @throws IllegalArgumentException
+        */
+       public List<? extends TopicSink> getTopicSinks(List<String> topicNames) 
+                       throws IllegalStateException, IllegalArgumentException;
+       
+       /**
+        * get the Topic Sinks for the given topic name and 
+        * underlying communication infrastructure type
+        * 
+        * @param topicName the topic name
+        * @param commType communication infrastructure type
+        * 
+        * @return the Topic Sink List
+        * @throws IllegalStateException if the entity is in an invalid state, for
+        * example multiple TopicWriters for a topic name and communication infrastructure
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public TopicSink getTopicSink(Topic.CommInfrastructure commType, 
+                                             String topicName) 
+                       throws IllegalStateException, IllegalArgumentException,
+                              UnsupportedOperationException;
+       
+       /**
+        * get the Topic Sinks for the given topic name and 
+        * all the underlying communication infrastructure type
+        * 
+        * @param topicName the topic name
+        * @param commType communication infrastructure type
+        * 
+        * @return the Topic Sink List
+        * @throws IllegalStateException if the entity is in an invalid state, for
+        * example multiple TopicWriters for a topic name and communication infrastructure
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public List<? extends TopicSink> getTopicSinks(String topicName) 
+                       throws IllegalStateException, IllegalArgumentException;
+       
+       /**
+        * get the UEB Topic Source for the given topic name
+        * 
+        * @param topicName the topic name
+        * 
+        * @return the Topic Source
+        * @throws IllegalStateException if the entity is in an invalid state, for
+        * example multiple TopicReaders for a topic name and communication infrastructure
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public UebTopicSink getUebTopicSink(String topicName)
+                       throws IllegalStateException, IllegalArgumentException;
+       
+       /**
+        * get the DMAAP Topic Source for the given topic name
+        * 
+        * @param topicName the topic name
+        * 
+        * @return the Topic Source
+        * @throws IllegalStateException if the entity is in an invalid state, for
+        * example multiple TopicReaders for a topic name and communication infrastructure
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public DmaapTopicSink getDmaapTopicSink(String topicName)
+                       throws IllegalStateException, IllegalArgumentException;
+       
+       /**
+        * gets only the UEB Topic Sources
+        * @return the UEB Topic Source List
+        */
+       public List<UebTopicSource> getUebTopicSources();
+       
+       /**
+        * gets only the DMAAP Topic Sources
+        * @return the DMAAP Topic Source List
+        */
+       public List<DmaapTopicSource> getDmaapTopicSources();
+       
+       /**
+        * gets all Topic Sinks
+        * @return the Topic Sink List
+        */
+       public List<? extends TopicSink> getTopicSinks();
+       
+       /**
+        * gets only the UEB Topic Sinks
+        * @return the UEB Topic Sink List
+        */
+       public List<UebTopicSink> getUebTopicSinks();
+       
+       /**
+        * gets only the DMAAP Topic Sinks
+        * @return the DMAAP Topic Sink List
+        */
+       public List<DmaapTopicSink> getDmaapTopicSinks();
+       
+       /**
+        * singleton for global access
+        */
+       public static final TopicEndpoint manager = new ProxyTopicEndpointManager();
+}
+
+/*
+ * ----------------- implementation -------------------
+ */
+
+/**
+ * This implementation of the Topic Endpoint Manager, proxies operations to appropriate
+ * implementations according to the communication infrastructure that are supported
+ */
+class ProxyTopicEndpointManager implements TopicEndpoint {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(ProxyTopicEndpointManager.class);
+       /**
+        * Is this element locked?
+        */
+       protected volatile boolean locked = false;
+       
+       /**
+        * Is this element alive?
+        */
+       protected volatile boolean alive = false;
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSource> addTopicSources(Properties properties) throws IllegalArgumentException {
+               
+               // 1. Create UEB Sources
+               // 2. Create DMAAP Sources
+               
+               List<TopicSource> sources = new ArrayList<TopicSource>();       
+               
+               sources.addAll(UebTopicSource.factory.build(properties));
+               sources.addAll(DmaapTopicSource.factory.build(properties));
+               
+               if (this.isLocked()) {
+                       for (TopicSource source : sources) {
+                               source.lock();
+                       }
+               }
+               
+               return sources;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSink> addTopicSinks(Properties properties) throws IllegalArgumentException {
+               // 1. Create UEB Sinks
+               // 2. Create DMAAP Sinks
+               
+               List<TopicSink> sinks = new ArrayList<TopicSink>();     
+               
+               sinks.addAll(UebTopicSink.factory.build(properties));
+               sinks.addAll(DmaapTopicSink.factory.build(properties));
+               
+               if (this.isLocked()) {
+                       for (TopicSink sink : sinks) {
+                               sink.lock();
+                       }
+               }
+               
+               return sinks;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSource> getTopicSources() {
+       
+               List<TopicSource> sources = new ArrayList<TopicSource>();
+               
+               sources.addAll(UebTopicSource.factory.inventory());
+               sources.addAll(DmaapTopicSource.factory.inventory());
+               
+               return sources;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSink> getTopicSinks() {
+               
+               List<TopicSink> sinks = new ArrayList<TopicSink>();     
+               
+               sinks.addAll(UebTopicSink.factory.inventory());
+               sinks.addAll(DmaapTopicSink.factory.inventory());
+               
+               return sinks;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @JsonIgnore
+       @Override
+       public List<UebTopicSource> getUebTopicSources() {
+               return UebTopicSource.factory.inventory();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @JsonIgnore
+       @Override
+       public List<DmaapTopicSource> getDmaapTopicSources() {
+               return DmaapTopicSource.factory.inventory();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @JsonIgnore
+       @Override
+       public List<UebTopicSink> getUebTopicSinks() {
+               return UebTopicSink.factory.inventory();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @JsonIgnore
+       @Override
+       public List<DmaapTopicSink> getDmaapTopicSinks() {
+               return DmaapTopicSink.factory.inventory();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() throws IllegalStateException {
+               
+               synchronized (this) {
+                       if (this.locked) {
+                               throw new IllegalStateException(this + " is locked");
+                       }
+                       
+                       if (this.alive) {
+                               return true;
+                       }
+                       
+                       this.alive = true;
+               }
+               
+               List<Startable> endpoints = getEndpoints();
+               
+               boolean success = true;
+               for (Startable endpoint: endpoints) {
+                       try {
+                               success = endpoint.start() && success;
+                       } catch (Exception e) {
+                               success = false;
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, endpoint.toString(), this.toString());
+                       }
+               }
+               
+               return success;
+       }
+
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() throws IllegalStateException {
+               
+               /* 
+                * stop regardless if it is locked, in other
+                * words, stop operation has precedence over
+                * locks.
+                */
+               synchronized (this) {                   
+                       this.alive = false;
+               }
+               
+               List<Startable> endpoints = getEndpoints();
+               
+               boolean success = true;
+               for (Startable endpoint: endpoints) {
+                       try {
+                               success = endpoint.stop() && success;
+                       } catch (Exception e) {
+                               success = false;
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, endpoint.toString(), this.toString());
+                       }
+               }
+               
+               return success;
+       }
+       
+       /**
+        * 
+        * @return list of managed endpoints
+        */
+       @JsonIgnore
+       protected List<Startable> getEndpoints() {
+               List<Startable> endpoints = new ArrayList<Startable>();
+
+               endpoints.addAll(this.getTopicSources());
+               endpoints.addAll(this.getTopicSinks());
+               
+               return endpoints;
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+               UebTopicSource.factory.destroy();
+               UebTopicSink.factory.destroy();
+               
+               DmaapTopicSource.factory.destroy();
+               DmaapTopicSink.factory.destroy();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               return this.alive;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean lock() {
+               
+               synchronized (this) {
+                       if (locked)
+                               return true;
+                       
+                       this.locked = true;
+               }
+               
+               for (TopicSource source: this.getTopicSources()) {
+                       source.lock();
+               }
+               
+               for (TopicSink sink: this.getTopicSinks()) {
+                       sink.lock();
+               }
+               
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean unlock() {
+               synchronized (this) {
+                       if (!locked)
+                               return true;
+                       
+                       this.locked = false;
+               }
+               
+               for (TopicSource source: this.getTopicSources()) {
+                       source.unlock();
+               }
+               
+               for (TopicSink sink: this.getTopicSinks()) {
+                       sink.unlock();
+               }
+               
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isLocked() {
+               return this.locked;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSource> getTopicSources(List<String> topicNames)
+                       throws IllegalStateException, IllegalArgumentException {
+               
+               if (topicNames == null) {
+                       throw new IllegalArgumentException("must provide a list of topics");
+               }
+               
+               List<TopicSource> sources = new ArrayList<TopicSource>();
+               for (String topic: topicNames) {
+                       try {
+                               TopicSource uebSource = this.getUebTopicSource(topic);
+                               if (uebSource != null)
+                                       sources.add(uebSource);
+                       } catch (Exception e) {
+                               logger.info("No UEB source for topic: " + topic);
+                       }
+                       
+                       try {
+                               TopicSource dmaapSource = this.getDmaapTopicSource(topic);
+                               if (dmaapSource != null)
+                                       sources.add(dmaapSource);
+                       } catch (Exception e) {
+                               logger.info("No DMAAP source for topic: " + topic);
+                       }
+               }
+               return sources;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSink> getTopicSinks(List<String> topicNames)
+                       throws IllegalStateException, IllegalArgumentException {
+               
+               if (topicNames == null) {
+                       throw new IllegalArgumentException("must provide a list of topics");
+               }
+               
+               List<TopicSink> sinks = new ArrayList<TopicSink>();
+               for (String topic: topicNames) {
+                       try {
+                               TopicSink uebSink = this.getUebTopicSink(topic);
+                               if (uebSink != null)
+                                       sinks.add(uebSink);
+                       } catch (Exception e) {
+                               logger.info("No UEB sink for topic: " + topic);
+                       }
+                       
+                       try {
+                               TopicSink dmaapSink = this.getDmaapTopicSink(topic);
+                               if (dmaapSink != null)
+                                       sinks.add(dmaapSink);
+                       } catch (Exception e) {
+                               logger.info("No DMAAP sink for topic: " + topic);
+                       }
+               }
+               return sinks;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public TopicSource getTopicSource(Topic.CommInfrastructure commType, String topicName)
+                       throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+               
+               if (commType == null) {
+                       throw new IllegalArgumentException
+                               ("Invalid parameter: a communication infrastructure required to fetch " + topicName);
+               }
+               
+               if (topicName == null) {
+                       throw new IllegalArgumentException
+                               ("Invalid parameter: a communication infrastructure required to fetch " + topicName);
+               }
+               
+               switch (commType) {
+               case UEB:
+                       return this.getUebTopicSource(topicName);
+               case DMAAP:
+                       return this.getDmaapTopicSource(topicName);
+               case REST:
+               default:
+                       throw new UnsupportedOperationException("Unsupported " + commType.name());
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public TopicSink getTopicSink(Topic.CommInfrastructure commType, String topicName)
+                       throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+               if (commType == null) {
+                       throw new IllegalArgumentException
+                               ("Invalid parameter: a communication infrastructure required to fetch " + topicName);
+               }
+               
+               if (topicName == null) {
+                       throw new IllegalArgumentException
+                               ("Invalid parameter: a communication infrastructure required to fetch " + topicName);
+               }
+               
+               switch (commType) {
+               case UEB:
+                       return this.getUebTopicSink(topicName);
+               case DMAAP:
+                       return this.getDmaapTopicSink(topicName);
+               case REST:
+               default:
+                       throw new UnsupportedOperationException("Unsupported " + commType.name());
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSink> getTopicSinks(String topicName) 
+                       throws IllegalStateException, IllegalArgumentException {
+
+               if (topicName == null) {
+                       throw new IllegalArgumentException
+                               ("Invalid parameter: a communication infrastructure required to fetch " + topicName);
+               }
+               
+               List<TopicSink> sinks = new ArrayList<TopicSink>();
+               
+               try {
+                       sinks.add(this.getUebTopicSink(topicName));
+               } catch (Exception e) {
+                       ;
+               }
+               
+               try {
+                       sinks.add(this.getDmaapTopicSink(topicName));
+               } catch (Exception e) {
+                       ;
+               }
+               
+               return sinks;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSource getUebTopicSource(String topicName) throws IllegalStateException, IllegalArgumentException {
+               return UebTopicSource.factory.get(topicName);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSink getUebTopicSink(String topicName) throws IllegalStateException, IllegalArgumentException {
+               return UebTopicSink.factory.get(topicName);
+       }
+
+       @Override
+       public DmaapTopicSource getDmaapTopicSource(String topicName)
+                       throws IllegalStateException, IllegalArgumentException {
+               return DmaapTopicSource.factory.get(topicName);
+       }
+
+       @Override
+       public DmaapTopicSink getDmaapTopicSink(String topicName) throws IllegalStateException, IllegalArgumentException {
+               return DmaapTopicSink.factory.get(topicName);
+       }
+       
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicListener.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicListener.java
new file mode 100644 (file)
index 0000000..7a2e971
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm;
+
+/**
+ * Listener for event messages entering the Policy Engine
+ */
+public interface TopicListener {
+       
+       /**
+        * Notification of a new Event over a given Topic
+        * 
+        * @param commType communication infrastructure type
+        * @param topic topic name
+        * @param event event message as a string
+        * 
+        * @return boolean.  True if the invoking event dispatcher should continue 
+        * dispatching the event to subsequent listeners.  False if it is requested
+        * to the invoking event dispatcher to stop dispatching the same event to
+        * other listeners of less priority.   This mechanism is generally not used.
+        */
+       public boolean onTopicEvent(Topic.CommInfrastructure commType, String topic, String event);
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicRegisterable.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicRegisterable.java
new file mode 100644 (file)
index 0000000..2ce8e9e
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm;
+
+/**
+ * Marks a Topic entity as registerable
+ */
+public interface TopicRegisterable {
+       
+       /**
+        * Register for notification of events with this Topic Entity
+        * 
+        * @param topicListener the listener of events
+        */
+       public void register(TopicListener topicListener);
+       
+       /**
+        * Unregisters for notification of events with this Topic Entity
+        * 
+        * @param topicListener the listener of events
+        */
+       public void unregister(TopicListener topicListener);
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSink.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSink.java
new file mode 100644 (file)
index 0000000..2250b1e
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm;
+
+import org.openecomp.policy.drools.properties.Lockable;
+import org.openecomp.policy.drools.properties.Startable;
+
+/**
+ * Marks a given Topic Endpoint as able to send messages over a topic
+ */
+public interface TopicSink extends Topic, Startable, Lockable {
+       
+       /**
+        * Sends a string message over this Topic Endpoint
+        * 
+        * @param message message to send
+        * @return true if the send operation succeeded, false otherwise
+        * @throws IllegalArgumentException an invalid message has been provided
+        * @throws IllegalStateException the entity is in an state that prevents
+        * it from sending messages, for example, locked or stopped.
+        */
+       public boolean send(String message) throws IllegalArgumentException, IllegalStateException;
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSource.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSource.java
new file mode 100644 (file)
index 0000000..0dfbe1c
--- /dev/null
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm;
+
+import org.openecomp.policy.drools.properties.Lockable;
+import org.openecomp.policy.drools.properties.Startable;
+
+/**
+ * Marker for a Topic Entity, indicating that the entity is able to read
+ * over a topic
+ */
+public interface TopicSource extends TopicRegisterable, Topic, Startable, Lockable {
+       
+       /**
+        * pushes an event into the source programatically
+        * 
+        * @param event the event in json format
+        * @return true if it can be processed correctly, false otherwise
+        */
+       public boolean offer(String event);
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopic.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopic.java
new file mode 100644 (file)
index 0000000..c38f627
--- /dev/null
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+public interface BusTopic {
+       public String getApiKey();
+       public String getApiSecret();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSink.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSink.java
new file mode 100644 (file)
index 0000000..30978c2
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+import org.openecomp.policy.drools.event.comm.TopicSink;
+
+/**
+ * Topic Sink over Bus Infrastructure (DMAAP/UEB)
+ */
+public interface BusTopicSink extends BusTopic, TopicSink {
+       /**
+        * Log Failures after X number of retries
+        */
+       public static final int DEFAULT_LOG_SEND_FAILURES_AFTER = 1;
+       
+       /**
+        * Sets the UEB partition key for published messages
+        * 
+        * @param partitionKey the partition key
+        */
+       public void setPartitionKey(String partitionKey);
+       
+       /**
+        * return the partition key in used by the system to publish messages
+        * 
+        * @return the partition key
+        */
+       public String getPartitionKey();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSource.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSource.java
new file mode 100644 (file)
index 0000000..e6a46d2
--- /dev/null
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+import org.openecomp.policy.drools.event.comm.TopicSource;
+
+/**
+ * Generic Topic Source for UEB/DMAAP Communication Infrastructure
+ *
+ */
+public interface BusTopicSource extends BusTopic, TopicSource {
+       
+       /**
+        * Default Consumer Instance Value
+        */
+       public static String DEFAULT_CONSUMER_INSTANCE = "0";
+       
+       /**
+        * Default Timeout fetching in milliseconds
+        */
+       public static int DEFAULT_TIMEOUT_MS_FETCH = 15000;
+       
+       /**
+        * Default maximum number of messages fetch at the time
+        */
+       public static int DEFAULT_LIMIT_FETCH = 100;
+       
+       /**
+        * Definition of No Timeout fetching
+        */
+       public static int NO_TIMEOUT_MS_FETCH = -1;
+       
+       /**
+        * Definition of No limit fetching
+        */
+       public static int NO_LIMIT_FETCH = -1;
+       
+       /**
+        * gets the consumer group
+        * 
+        * @return consumer group
+        */
+       public String getConsumerGroup();
+       
+       /**
+        * gets the consumer instance
+        * 
+        * @return consumer instance
+        */
+       public String getConsumerInstance();
+       
+       /**
+        * gets the fetch timeout
+        * 
+        * @return fetch timeout
+        */
+       public int getFetchTimeout();
+       
+       /**
+        * gets the fetch limit
+        * 
+        * @return fetch limit
+        */
+       public int getFetchLimit();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSink.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSink.java
new file mode 100644 (file)
index 0000000..3c55c9f
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+public interface DmaapTopicSink extends BusTopicSink {
+
+       /**
+        * Factory of UebTopicWriter for instantiation and management purposes
+        */
+       
+       public static final DmaapTopicSinkFactory factory = new IndexedDmaapTopicSinkFactory();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSinkFactory.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSinkFactory.java
new file mode 100644 (file)
index 0000000..5b4cfd4
--- /dev/null
@@ -0,0 +1,308 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.event.comm.bus.internal.InlineDmaapTopicSink;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+
+/**
+ * DMAAP Topic Sink Factory
+ */
+public interface DmaapTopicSinkFactory {
+       
+       /**
+        * Instantiates a new DMAAP Topic Sink
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * @param apiKey API Key
+        * @param apiSecret API Secret
+        * @param userName AAF user name
+        * @param password AAF password
+        * @param partitionKey Consumer Group
+        * @param managed is this sink endpoint managed?
+        * 
+        * @return an DMAAP Topic Sink
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public DmaapTopicSink build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret,
+                                                               String userName,
+                                                               String password,
+                                                               String partitionKey,
+                                                               boolean managed)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Creates an DMAAP Topic Sink based on properties files
+        * 
+        * @param properties Properties containing initialization values
+        * 
+        * @return an DMAAP Topic Sink
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public List<DmaapTopicSink> build(Properties properties)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Instantiates a new DMAAP Topic Sink
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * 
+        * @return an DMAAP Topic Sink
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public DmaapTopicSink build(List<String> servers, String topic)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Destroys an DMAAP Topic Sink based on a topic
+        * 
+        * @param topic topic name
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public void destroy(String topic);
+
+       /**
+        * gets an DMAAP Topic Sink based on topic name
+        * @param topic the topic name
+        * 
+        * @return an DMAAP Topic Sink with topic name
+        * @throws IllegalArgumentException if an invalid topic is provided
+        * @throws IllegalStateException if the DMAAP Topic Reader is 
+        * an incorrect state
+        */
+       public DmaapTopicSink get(String topic)
+                          throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * Provides a snapshot of the DMAAP Topic Sinks
+        * @return a list of the DMAAP Topic Sinks
+        */
+       public List<DmaapTopicSink> inventory();
+
+       /**
+        * Destroys all DMAAP Topic Sinks
+        */
+       public void destroy();
+}
+
+/* ------------- implementation ----------------- */
+
+/**
+ * Factory of DMAAP Reader Topics indexed by topic name
+ */
+class IndexedDmaapTopicSinkFactory implements DmaapTopicSinkFactory {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(IndexedDmaapTopicSinkFactory.class);       
+       
+       /**
+        * DMAAP Topic Name Index
+        */
+       protected HashMap<String, DmaapTopicSink> dmaapTopicWriters =
+                       new HashMap<String, DmaapTopicSink>();
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DmaapTopicSink build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret,
+                                                               String userName,
+                                                               String password,
+                                                               String partitionKey,
+                                                               boolean managed) 
+                       throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized (this) {
+                       if (dmaapTopicWriters.containsKey(topic)) {
+                               return dmaapTopicWriters.get(topic);
+                       }
+                       
+                       DmaapTopicSink dmaapTopicSink = 
+                                       new InlineDmaapTopicSink(servers, topic, 
+                                                                                    apiKey, apiSecret,
+                                                                                    userName, password,
+                                                                                    partitionKey);
+                       
+                       if (managed)
+                               dmaapTopicWriters.put(topic, dmaapTopicSink);
+                       return dmaapTopicSink;
+               }
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DmaapTopicSink build(List<String> servers, String topic) throws IllegalArgumentException {
+               return this.build(servers, topic, null, null, null, null, null, true);
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<DmaapTopicSink> build(Properties properties) throws IllegalArgumentException {
+               
+               String writeTopics = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS);
+               if (writeTopics == null || writeTopics.isEmpty()) {
+                       logger.warn("No topic for DMAAP Sink " + properties);
+                       return new ArrayList<DmaapTopicSink>();
+               }
+               List<String> writeTopicList = new ArrayList<String>(Arrays.asList(writeTopics.split("\\s*,\\s*")));
+               
+               synchronized(this) {
+                       List<DmaapTopicSink> dmaapTopicWriters = new ArrayList<DmaapTopicSink>();
+                       for (String topic: writeTopicList) {
+                               
+                               String servers = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS + "." + 
+                                                                       topic + 
+                                                                       PolicyProperties.PROPERTY_TOPIC_SERVERS_SUFFIX);
+                               if (servers == null || servers.isEmpty()) {
+                                       logger.error("No DMAAP servers provided in " + properties);
+                                       continue;
+                               }
+                               
+                               List<String> serverList = new ArrayList<String>(Arrays.asList(servers.split("\\s*,\\s*")));
+                               
+                               String apiKey = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS + 
+                                                                              "." + topic + 
+                                                                              PolicyProperties.PROPERTY_TOPIC_API_KEY_SUFFIX);          
+                               String apiSecret = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS + 
+                                                          "." + topic + 
+                                                          PolicyProperties.PROPERTY_TOPIC_API_SECRET_SUFFIX);
+                               
+                               String aafMechId = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS + 
+                                                          "." + topic + 
+                                                          PolicyProperties.PROPERTY_TOPIC_AAF_MECHID_SUFFIX);
+                               String aafPassword = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS + 
+                                                                           "." + topic + 
+                                                                           PolicyProperties.PROPERTY_TOPIC_AAF_PASSWORD_SUFFIX);
+                               
+                               String partitionKey = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS + 
+                                                             "." + topic + 
+                                                             PolicyProperties.PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX);
+                               
+                               String managedString = properties.getProperty(PolicyProperties.PROPERTY_UEB_SINK_TOPICS + "." + topic +
+                                                                                     PolicyProperties.PROPERTY_MANAGED_SUFFIX);
+                               boolean managed = true;
+                               if (managedString != null && !managedString.isEmpty()) {
+                                       managed = Boolean.parseBoolean(managedString);
+                               }
+                               
+                               DmaapTopicSink dmaapTopicSink = this.build(serverList, topic, 
+                                                                                                          apiKey, apiSecret, aafMechId, aafPassword,
+                                                                                                          partitionKey, managed);
+                               dmaapTopicWriters.add(dmaapTopicSink);
+                       }
+                       return dmaapTopicWriters;
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy(String topic) 
+                  throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               DmaapTopicSink dmaapTopicWriter;
+               synchronized(this) {
+                       if (!dmaapTopicWriters.containsKey(topic)) {
+                               return;
+                       }
+                       
+                       dmaapTopicWriter = dmaapTopicWriters.remove(topic);
+               }
+               
+               dmaapTopicWriter.shutdown();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy() {
+               List<DmaapTopicSink> writers = this.inventory();
+               for (DmaapTopicSink writer: writers) {
+                       writer.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.dmaapTopicWriters.clear();
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DmaapTopicSink get(String topic) 
+                       throws IllegalArgumentException, IllegalStateException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized(this) {
+                       if (dmaapTopicWriters.containsKey(topic)) {
+                               return dmaapTopicWriters.get(topic);
+                       } else {
+                               throw new IllegalStateException("DmaapTopicSink for " + topic + " not found");
+                       }
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized List<DmaapTopicSink> inventory() {
+                List<DmaapTopicSink> writers = 
+                                new ArrayList<DmaapTopicSink>(this.dmaapTopicWriters.values());
+                return writers;
+       }
+       
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSource.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSource.java
new file mode 100644 (file)
index 0000000..8da7906
--- /dev/null
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+public interface DmaapTopicSource extends BusTopicSource {
+
+       /**
+        * factory for managing and tracking DMAAP sources
+        */
+       public static DmaapTopicSourceFactory factory = new IndexedDmaapTopicSourceFactory();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSourceFactory.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSourceFactory.java
new file mode 100644 (file)
index 0000000..f8d85eb
--- /dev/null
@@ -0,0 +1,380 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.event.comm.bus.internal.SingleThreadedDmaapTopicSource;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+/**
+ * DMAAP Topic Source Factory
+ */
+public interface DmaapTopicSourceFactory {
+       
+       /**
+        * Creates an DMAAP Topic Source based on properties files
+        * 
+        * @param properties Properties containing initialization values
+        * 
+        * @return an DMAAP Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public List<DmaapTopicSource> build(Properties properties)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Instantiates a new DMAAP Topic Source
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * @param apiKey API Key
+        * @param apiSecret API Secret
+        * @param userName user name
+        * @param password password
+        * @param consumerGroup Consumer Group
+        * @param consumerInstance Consumer Instance
+        * @param fetchTimeout Read Fetch Timeout
+        * @param fetchLimit Fetch Limit
+        * @param managed is this endpoind managed?
+        * 
+        * @return an DMAAP Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public DmaapTopicSource build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret, 
+                                                               String userName, 
+                                                               String password,
+                                                               String consumerGroup, 
+                                                               String consumerInstance,
+                                                               int fetchTimeout,
+                                                               int fetchLimit,
+                                                               boolean managed)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Instantiates a new DMAAP Topic Source
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * @param apiKey API Key
+        * @param apiSecret API Secret
+        * 
+        * @return an DMAAP Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public DmaapTopicSource build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret)
+                       throws IllegalArgumentException;
+
+       /**
+        * Instantiates a new DMAAP Topic Source
+        * 
+        * @param uebTopicReaderType Implementation type
+        * @param servers list of servers
+        * @param topic topic name
+        * 
+        * @return an DMAAP Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public DmaapTopicSource build(List<String> servers, 
+                                                               String topic)
+                       throws IllegalArgumentException;        
+       
+       /**
+        * Destroys an DMAAP Topic Source based on a topic
+        * 
+        * @param topic topic name
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public void destroy(String topic);
+       
+       /**
+        * Destroys all DMAAP Topic Sources
+        */
+       public void destroy();
+       
+       /**
+        * gets an DMAAP Topic Source based on topic name
+        * @param topic the topic name
+        * @return an DMAAP Topic Source with topic name
+        * @throws IllegalArgumentException if an invalid topic is provided
+        * @throws IllegalStateException if the DMAAP Topic Source is 
+        * an incorrect state
+        */
+       public DmaapTopicSource get(String topic)
+                  throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * Provides a snapshot of the DMAAP Topic Sources
+        * @return a list of the DMAAP Topic Sources
+        */
+       public List<DmaapTopicSource> inventory();
+}
+
+
+/* ------------- implementation ----------------- */
+
+/**
+ * Factory of DMAAP Source Topics indexed by topic name
+ */
+
+class IndexedDmaapTopicSourceFactory implements DmaapTopicSourceFactory {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(IndexedDmaapTopicSourceFactory.class);             
+       /**
+        * UEB Topic Name Index
+        */
+       protected HashMap<String, DmaapTopicSource> dmaapTopicSources =
+                       new HashMap<String, DmaapTopicSource>();
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DmaapTopicSource build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret, 
+                                                               String userName, 
+                                                               String password,
+                                                               String consumerGroup, 
+                                                               String consumerInstance,
+                                                               int fetchTimeout,
+                                                               int fetchLimit,
+                                                               boolean managed) 
+                       throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized(this) {
+                       if (dmaapTopicSources.containsKey(topic)) {
+                               return dmaapTopicSources.get(topic);
+                       }
+                       
+                       DmaapTopicSource dmaapTopicSource = 
+                                       new SingleThreadedDmaapTopicSource(servers, topic, 
+                                                                                                        apiKey, apiSecret, userName, password,
+                                                                                                        consumerGroup, consumerInstance, 
+                                                                                                        fetchTimeout, fetchLimit);
+                       
+                       if (managed)
+                               dmaapTopicSources.put(topic, dmaapTopicSource);
+                       
+                       return dmaapTopicSource;
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<DmaapTopicSource> build(Properties properties) 
+                       throws IllegalArgumentException {
+               
+               String readTopics = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS);
+               if (readTopics == null || readTopics.isEmpty()) {
+                       logger.warn("No topic for UEB Source " + properties);
+                       return new ArrayList<DmaapTopicSource>();
+               }
+               List<String> readTopicList = new ArrayList<String>(Arrays.asList(readTopics.split("\\s*,\\s*")));               
+               
+               List<DmaapTopicSource> dmaapTopicSource_s = new ArrayList<DmaapTopicSource>();
+               synchronized(this) {
+                       for (String topic: readTopicList) {
+                               
+                               String servers = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + "." + 
+                                                        topic + 
+                                                        PolicyProperties.PROPERTY_TOPIC_SERVERS_SUFFIX);
+                               
+                               if (servers == null || servers.isEmpty()) {
+                                       logger.error("No UEB servers provided in " + properties);
+                                       continue;
+                               }
+                               
+                               List<String> serverList = new ArrayList<String>(Arrays.asList(servers.split("\\s*,\\s*")));
+                               
+                               String apiKey = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                                  "." + topic + 
+                                                       PolicyProperties.PROPERTY_TOPIC_API_KEY_SUFFIX);
+                               
+                               String apiSecret = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                                 "." + topic + 
+                                                          PolicyProperties.PROPERTY_TOPIC_API_SECRET_SUFFIX);
+                               
+                               String aafMechId = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                                         "." + topic + 
+                                                                                         PolicyProperties.PROPERTY_TOPIC_AAF_MECHID_SUFFIX);
+
+                               String aafPassword = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                                         "." + topic + 
+                                                                                         PolicyProperties.PROPERTY_TOPIC_AAF_PASSWORD_SUFFIX);
+                               
+                               String consumerGroup = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                                     "." + topic + 
+                                                              PolicyProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX);
+                               
+                               String consumerInstance = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                                        "." + topic + 
+                                                                 PolicyProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX);
+                               
+                               String fetchTimeoutString = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                                          "." + topic + 
+                                                                   PolicyProperties.PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX);
+                               int fetchTimeout = DmaapTopicSource.DEFAULT_TIMEOUT_MS_FETCH;
+                               if (fetchTimeoutString != null && !fetchTimeoutString.isEmpty()) {
+                                       try {
+                                               fetchTimeout = Integer.parseInt(fetchTimeoutString);
+                                       } catch (NumberFormatException nfe) {
+                                               logger.warn("Fetch Timeout in invalid format for topic " + topic + ": " + fetchTimeoutString);
+                                       }
+                               }
+                                       
+                               String fetchLimitString = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                                 "." + topic + 
+                                                                 PolicyProperties.PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX);
+                               int fetchLimit = DmaapTopicSource.DEFAULT_LIMIT_FETCH;
+                               if (fetchLimitString != null && !fetchLimitString.isEmpty()) {
+                                       try {
+                                               fetchLimit = Integer.parseInt(fetchLimitString);
+                                       } catch (NumberFormatException nfe) {
+                                               logger.warn("Fetch Limit in invalid format for topic " + topic + ": " + fetchLimitString);
+                                       }
+                               }
+                               
+                               String managedString = properties.getProperty(PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + 
+                                                               "." + topic + 
+                                                              PolicyProperties.PROPERTY_MANAGED_SUFFIX);
+                               boolean managed = true;
+                               if (managedString != null && !managedString.isEmpty()) {
+                                       managed = Boolean.parseBoolean(managedString);
+                               }
+                               
+                               DmaapTopicSource uebTopicSource = this.build(serverList, topic, 
+                                                                                                          apiKey, apiSecret, aafMechId, aafPassword,
+                                                                                                          consumerGroup, consumerInstance, 
+                                                                                                          fetchTimeout, fetchLimit, managed);
+                               dmaapTopicSource_s.add(uebTopicSource);
+                       }
+               }
+               return dmaapTopicSource_s;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DmaapTopicSource build(List<String> servers, 
+                                                               String topic,
+                                                               String apiKey, 
+                                                               String apiSecret) {
+               return this.build(servers, topic, 
+                                                 apiKey, apiSecret, null, null,
+                                                 null, null,
+                                                 DmaapTopicSource.DEFAULT_TIMEOUT_MS_FETCH,
+                                                 DmaapTopicSource.DEFAULT_LIMIT_FETCH,
+                                                 true);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DmaapTopicSource build(List<String> servers, String topic) {
+               return this.build(servers, topic, null, null);
+       }       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy(String topic) 
+                  throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               DmaapTopicSource uebTopicSource;
+               
+               synchronized(this) {
+                       if (!dmaapTopicSources.containsKey(topic)) {
+                               return;
+                       }
+                       
+                       uebTopicSource = dmaapTopicSources.remove(topic);
+               }
+               
+               uebTopicSource.shutdown();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DmaapTopicSource get(String topic) 
+              throws IllegalArgumentException, IllegalStateException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized(this) {
+                       if (dmaapTopicSources.containsKey(topic)) {
+                               return dmaapTopicSources.get(topic);
+                       } else {
+                               throw new IllegalArgumentException("DmaapTopicSource for " + topic + " not found");
+                       }
+               }
+       }
+
+       @Override
+       public synchronized List<DmaapTopicSource> inventory() {
+                List<DmaapTopicSource> readers = 
+                                new ArrayList<DmaapTopicSource>(this.dmaapTopicSources.values());
+                return readers;
+       }
+
+       @Override
+       public void destroy() {
+               List<DmaapTopicSource> readers = this.inventory();
+               for (DmaapTopicSource reader: readers) {
+                       reader.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.dmaapTopicSources.clear();
+               }
+       }
+       
+}
+
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSink.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSink.java
new file mode 100644 (file)
index 0000000..efa4dc5
--- /dev/null
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+/**
+ * Topic Writer over UEB Infrastructure
+ */
+public interface UebTopicSink extends BusTopicSink {
+       
+       /**
+        * Factory of UebTopicWriter for instantiation and management purposes
+        */
+       public static final UebTopicSinkFactory factory = new IndexedUebTopicSinkFactory();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSinkFactory.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSinkFactory.java
new file mode 100644 (file)
index 0000000..85b9883
--- /dev/null
@@ -0,0 +1,292 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.event.comm.bus.internal.InlineUebTopicSink;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+
+/**
+ * UEB Topic Sink Factory
+ */
+public interface UebTopicSinkFactory {
+       
+       /**
+        * Instantiates a new UEB Topic Writer
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * @param apiKey API Key
+        * @param apiSecret API Secret
+        * @param partitionKey Consumer Group
+        * @param managed is this sink endpoint managed?
+        * 
+        * @return an UEB Topic Writer
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public UebTopicSink build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret,
+                                                               String partitionKey,
+                                                               boolean managed)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Creates an UEB Topic Writer based on properties files
+        * 
+        * @param properties Properties containing initialization values
+        * 
+        * @return an UEB Topic Writer
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public List<UebTopicSink> build(Properties properties)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Instantiates a new UEB Topic Writer
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * 
+        * @return an UEB Topic Writer
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public UebTopicSink build(List<String> servers, String topic)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Destroys an UEB Topic Writer based on a topic
+        * 
+        * @param topic topic name
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public void destroy(String topic);
+
+       /**
+        * gets an UEB Topic Writer based on topic name
+        * @param topic the topic name
+        * 
+        * @return an UEB Topic Writer with topic name
+        * @throws IllegalArgumentException if an invalid topic is provided
+        * @throws IllegalStateException if the UEB Topic Reader is 
+        * an incorrect state
+        */
+       public UebTopicSink get(String topic)
+                          throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * Provides a snapshot of the UEB Topic Writers
+        * @return a list of the UEB Topic Writers
+        */
+       public List<UebTopicSink> inventory();
+
+       /**
+        * Destroys all UEB Topic Writers
+        */
+       public void destroy();
+}
+
+/* ------------- implementation ----------------- */
+
+/**
+ * Factory of UEB Reader Topics indexed by topic name
+ */
+class IndexedUebTopicSinkFactory implements UebTopicSinkFactory {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(IndexedUebTopicSinkFactory.class);         
+       /**
+        * UEB Topic Name Index
+        */
+       protected HashMap<String, UebTopicSink> uebTopicSinks =
+                       new HashMap<String, UebTopicSink>();
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSink build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret,
+                                                               String partitionKey,
+                                                               boolean managed) 
+                       throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized (this) {
+                       if (uebTopicSinks.containsKey(topic)) {
+                               return uebTopicSinks.get(topic);
+                       }
+                       
+                       UebTopicSink uebTopicWriter = 
+                                       new InlineUebTopicSink(servers, topic, 
+                                                                                  apiKey, apiSecret,partitionKey);
+                       
+                       if (managed)
+                               uebTopicSinks.put(topic, uebTopicWriter);
+                       
+                       return uebTopicWriter;
+               }
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSink build(List<String> servers, String topic) throws IllegalArgumentException {
+               return this.build(servers, topic, null, null, null, true);
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<UebTopicSink> build(Properties properties) throws IllegalArgumentException {
+               
+               String writeTopics = properties.getProperty(PolicyProperties.PROPERTY_UEB_SINK_TOPICS);
+               if (writeTopics == null || writeTopics.isEmpty()) {
+                       logger.warn("No topic for UEB Sink " + properties);
+                       return new ArrayList<UebTopicSink>();
+               }
+               List<String> writeTopicList = new ArrayList<String>(Arrays.asList(writeTopics.split("\\s*,\\s*")));
+               
+               synchronized(this) {
+                       List<UebTopicSink> uebTopicWriters = new ArrayList<UebTopicSink>();
+                       for (String topic: writeTopicList) {
+                               
+                               String servers = properties.getProperty(PolicyProperties.PROPERTY_UEB_SINK_TOPICS + "." + 
+                                                                       topic + 
+                                                                       PolicyProperties.PROPERTY_TOPIC_SERVERS_SUFFIX);
+                               if (servers == null || servers.isEmpty()) {
+                                       logger.error("No UEB servers provided in " + properties);
+                                       continue;
+                               }
+                               
+                               List<String> serverList = new ArrayList<String>(Arrays.asList(servers.split("\\s*,\\s*")));
+                               
+                               String apiKey = properties.getProperty(PolicyProperties.PROPERTY_UEB_SINK_TOPICS + 
+                                                                              "." + topic + 
+                                                                              PolicyProperties.PROPERTY_TOPIC_API_KEY_SUFFIX);          
+                               String apiSecret = properties.getProperty(PolicyProperties.PROPERTY_UEB_SINK_TOPICS + 
+                                                          "." + topic + 
+                                                          PolicyProperties.PROPERTY_TOPIC_API_SECRET_SUFFIX);  
+                               String partitionKey = properties.getProperty(PolicyProperties.PROPERTY_UEB_SINK_TOPICS + 
+                                                             "." + topic + 
+                                                             PolicyProperties.PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX);
+                               
+                               String managedString = properties.getProperty(PolicyProperties.PROPERTY_UEB_SINK_TOPICS + "." + topic +
+                                                                                     PolicyProperties.PROPERTY_MANAGED_SUFFIX);
+                               boolean managed = true;
+                               if (managedString != null && !managedString.isEmpty()) {
+                                       managed = Boolean.parseBoolean(managedString);
+                               }
+                               
+                               UebTopicSink uebTopicWriter = this.build(serverList, topic, 
+                                                                                                        apiKey, apiSecret, 
+                                                                                                        partitionKey, managed);
+                               uebTopicWriters.add(uebTopicWriter);
+                       }
+                       return uebTopicWriters;
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy(String topic) 
+                  throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               UebTopicSink uebTopicWriter;
+               synchronized(this) {
+                       if (!uebTopicSinks.containsKey(topic)) {
+                               return;
+                       }
+                       
+                       uebTopicWriter = uebTopicSinks.remove(topic);
+               }
+               
+               uebTopicWriter.shutdown();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy() {
+               List<UebTopicSink> writers = this.inventory();
+               for (UebTopicSink writer: writers) {
+                       writer.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.uebTopicSinks.clear();
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSink get(String topic) 
+                       throws IllegalArgumentException, IllegalStateException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized(this) {
+                       if (uebTopicSinks.containsKey(topic)) {
+                               return uebTopicSinks.get(topic);
+                       } else {
+                               throw new IllegalStateException("UebTopicSink for " + topic + " not found");
+                       }
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized List<UebTopicSink> inventory() {
+                List<UebTopicSink> writers = 
+                                new ArrayList<UebTopicSink>(this.uebTopicSinks.values());
+                return writers;
+       }
+       
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSource.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSource.java
new file mode 100644 (file)
index 0000000..4da0130
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+/**
+ * Topic Source for UEB Communication Infrastructure
+ *
+ */
+public interface UebTopicSource extends BusTopicSource {
+       
+       /**
+        * factory for managing and tracking UEB readers
+        */
+       public static UebTopicSourceFactory factory = 
+                                       new IndexedUebTopicSourceFactory();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSourceFactory.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSourceFactory.java
new file mode 100644 (file)
index 0000000..bf2a403
--- /dev/null
@@ -0,0 +1,362 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.event.comm.bus.internal.SingleThreadedUebTopicSource;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+
+/**
+ * UEB Topic Source Factory
+ */
+public interface UebTopicSourceFactory {
+       
+       /**
+        * Creates an UEB Topic Source based on properties files
+        * 
+        * @param properties Properties containing initialization values
+        * 
+        * @return an UEB Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public List<UebTopicSource> build(Properties properties)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Instantiates a new UEB Topic Source
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * @param apiKey API Key
+        * @param apiSecret API Secret
+        * @param consumerGroup Consumer Group
+        * @param consumerInstance Consumer Instance
+        * @param fetchTimeout Read Fetch Timeout
+        * @param fetchLimit Fetch Limit
+        * @param managed is this source endpoint managed?
+        * 
+        * @return an UEB Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public UebTopicSource build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret, 
+                                                               String consumerGroup, 
+                                                               String consumerInstance,
+                                                               int fetchTimeout,
+                                                               int fetchLimit,
+                                                               boolean managed)
+                       throws IllegalArgumentException;
+       
+       /**
+        * Instantiates a new UEB Topic Source
+        * 
+        * @param servers list of servers
+        * @param topic topic name
+        * @param apiKey API Key
+        * @param apiSecret API Secret
+        * 
+        * @return an UEB Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public UebTopicSource build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret)
+                       throws IllegalArgumentException;
+
+       /**
+        * Instantiates a new UEB Topic Source
+        * 
+        * @param uebTopicSourceType Implementation type
+        * @param servers list of servers
+        * @param topic topic name
+        * 
+        * @return an UEB Topic Source
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public UebTopicSource build(List<String> servers, 
+                                                               String topic)
+                       throws IllegalArgumentException;        
+       
+       /**
+        * Destroys an UEB Topic Source based on a topic
+        * 
+        * @param topic topic name
+        * @throws IllegalArgumentException if invalid parameters are present
+        */
+       public void destroy(String topic);
+       
+       /**
+        * Destroys all UEB Topic Sources
+        */
+       public void destroy();
+       
+       /**
+        * gets an UEB Topic Source based on topic name
+        * @param topic the topic name
+        * @return an UEB Topic Source with topic name
+        * @throws IllegalArgumentException if an invalid topic is provided
+        * @throws IllegalStateException if the UEB Topic Source is 
+        * an incorrect state
+        */
+       public UebTopicSource get(String topic)
+                  throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * Provides a snapshot of the UEB Topic Sources
+        * @return a list of the UEB Topic Sources
+        */
+       public List<UebTopicSource> inventory();
+}
+
+/* ------------- implementation ----------------- */
+
+/**
+ * Factory of UEB Source Topics indexed by topic name
+ */
+class IndexedUebTopicSourceFactory implements UebTopicSourceFactory {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(IndexedUebTopicSourceFactory.class);       
+       /**
+        * UEB Topic Name Index
+        */
+       protected HashMap<String, UebTopicSource> uebTopicSources =
+                       new HashMap<String, UebTopicSource>();
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSource build(List<String> servers, 
+                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret, 
+                                                               String consumerGroup, 
+                                                               String consumerInstance,
+                                                               int fetchTimeout,
+                                                               int fetchLimit,
+                                                               boolean managed) 
+       throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized(this) {
+                       if (uebTopicSources.containsKey(topic)) {
+                               return uebTopicSources.get(topic);
+                       }
+                       
+                       UebTopicSource uebTopicSource = 
+                                       new SingleThreadedUebTopicSource(servers, topic, 
+                                                                                                        apiKey, apiSecret,
+                                                                                                        consumerGroup, consumerInstance, 
+                                                                                                        fetchTimeout, fetchLimit);
+                       
+                       if (managed)
+                               uebTopicSources.put(topic, uebTopicSource);
+                       
+                       return uebTopicSource;
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<UebTopicSource> build(Properties properties) 
+                       throws IllegalArgumentException {
+               
+               String readTopics = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS);
+               if (readTopics == null || readTopics.isEmpty()) {
+                       logger.warn("No topic for UEB Source " + properties);
+                       return new ArrayList<UebTopicSource>();
+               }
+               List<String> readTopicList = new ArrayList<String>(Arrays.asList(readTopics.split("\\s*,\\s*")));               
+               
+               List<UebTopicSource> uebTopicSources = new ArrayList<UebTopicSource>();
+               synchronized(this) {
+                       for (String topic: readTopicList) {
+                               
+                               String servers = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + "." + 
+                                                        topic + 
+                                                        PolicyProperties.PROPERTY_TOPIC_SERVERS_SUFFIX);
+                               
+                               if (servers == null || servers.isEmpty()) {
+                                       logger.error("No UEB servers provided in " + properties);
+                                       continue;
+                               }
+                               
+                               List<String> serverList = new ArrayList<String>(Arrays.asList(servers.split("\\s*,\\s*")));
+                               
+                               String apiKey = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + 
+                                                                                  "." + topic + 
+                                                       PolicyProperties.PROPERTY_TOPIC_API_KEY_SUFFIX);
+                               
+                               String apiSecret = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + 
+                                                                                 "." + topic + 
+                                                          PolicyProperties.PROPERTY_TOPIC_API_SECRET_SUFFIX);
+                               
+                               String consumerGroup = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + 
+                                                                                     "." + topic + 
+                                                              PolicyProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX);
+                               
+                               String consumerInstance = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + 
+                                                                                        "." + topic + 
+                                                                 PolicyProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX);
+                               
+                               String fetchTimeoutString = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + 
+                                                                                          "." + topic + 
+                                                                   PolicyProperties.PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX);
+                               int fetchTimeout = UebTopicSource.DEFAULT_TIMEOUT_MS_FETCH;
+                               if (fetchTimeoutString != null && !fetchTimeoutString.isEmpty()) {
+                                       try {
+                                               fetchTimeout = Integer.parseInt(fetchTimeoutString);
+                                       } catch (NumberFormatException nfe) {
+                                               logger.warn("Fetch Timeout in invalid format for topic " + topic + ": " + fetchTimeoutString);
+                                       }
+                               }
+                                       
+                               String fetchLimitString = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + 
+                                                                 "." + topic + 
+                                                                 PolicyProperties.PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX);
+                               int fetchLimit = UebTopicSource.DEFAULT_LIMIT_FETCH;
+                               if (fetchLimitString != null && !fetchLimitString.isEmpty()) {
+                                       try {
+                                               fetchLimit = Integer.parseInt(fetchLimitString);
+                                       } catch (NumberFormatException nfe) {
+                                               logger.warn("Fetch Limit in invalid format for topic " + topic + ": " + fetchLimitString);
+                                       }
+                               }
+                               
+                               String managedString = properties.getProperty(PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + "." +
+                                                                                     topic + PolicyProperties.PROPERTY_MANAGED_SUFFIX);
+                               boolean managed = true;
+                               if (managedString != null && !managedString.isEmpty()) {
+                                       managed = Boolean.parseBoolean(managedString);
+                               }
+                       
+                               UebTopicSource uebTopicSource = this.build(serverList, topic, 
+                                                                                                          apiKey, apiSecret,
+                                                                                                          consumerGroup, consumerInstance, 
+                                                                                                          fetchTimeout, fetchLimit, managed);
+                               uebTopicSources.add(uebTopicSource);
+                       }
+               }
+               return uebTopicSources;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSource build(List<String> servers, 
+                                                               String topic,
+                                                               String apiKey, 
+                                                               String apiSecret) {
+               return this.build(servers, topic, 
+                                                 apiKey, apiSecret,
+                                                 null, null,
+                                                 UebTopicSource.DEFAULT_TIMEOUT_MS_FETCH,
+                                                 UebTopicSource.DEFAULT_LIMIT_FETCH, true);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSource build(List<String> servers, String topic) {
+               return this.build(servers, topic, null, null);
+       }       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy(String topic) 
+                  throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               UebTopicSource uebTopicSource;
+               
+               synchronized(this) {
+                       if (!uebTopicSources.containsKey(topic)) {
+                               return;
+                       }
+                       
+                       uebTopicSource = uebTopicSources.remove(topic);
+               }
+               
+               uebTopicSource.shutdown();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public UebTopicSource get(String topic) 
+              throws IllegalArgumentException, IllegalStateException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("A topic must be provided");
+               }
+               
+               synchronized(this) {
+                       if (uebTopicSources.containsKey(topic)) {
+                               return uebTopicSources.get(topic);
+                       } else {
+                               throw new IllegalStateException("UebTopiceSource for " + topic + " not found");
+                       }
+               }
+       }
+
+       @Override
+       public synchronized List<UebTopicSource> inventory() {
+                List<UebTopicSource> readers = 
+                                new ArrayList<UebTopicSource>(this.uebTopicSources.values());
+                return readers;
+       }
+
+       @Override
+       public void destroy() {
+               List<UebTopicSource> readers = this.inventory();
+               for (UebTopicSource reader: readers) {
+                       reader.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.uebTopicSources.clear();
+               }
+       }
+       
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusConsumer.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusConsumer.java
new file mode 100644 (file)
index 0000000..6fee5ce
--- /dev/null
@@ -0,0 +1,204 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.net.MalformedURLException;
+import java.security.GeneralSecurityException;
+import java.util.List;
+import java.util.Properties;
+
+import com.att.nsa.cambria.client.CambriaClientBuilders;
+import com.att.nsa.cambria.client.CambriaConsumer;
+import com.att.nsa.mr.client.impl.MRConsumerImpl;
+import com.att.nsa.mr.test.clients.ProtocolTypeConstants;
+import com.att.nsa.cambria.client.CambriaClientBuilders.ConsumerBuilder;
+
+/**
+ * Wrapper around libraries to consume from message bus
+ *
+ */
+public interface BusConsumer {
+       
+       /**
+        * fetch messages
+        * 
+        * @return list of messages
+        * @throws Exception when error encountered by underlying libraries
+        */
+       public Iterable<String> fetch() throws Exception;
+       
+       /**
+        * close underlying library consumer
+        */
+       public void close();
+
+       /**
+        * Cambria based consumer
+        */
+       public static class CambriaConsumerWrapper implements BusConsumer {
+               /**
+                * Cambria client
+                */
+               protected CambriaConsumer consumer;
+               
+               /**
+                * Cambria Consumer Wrapper
+                * 
+                * @param servers messaging bus hosts
+                * @param topic topic
+                * @param apiKey API Key
+                * @param apiSecret API Secret
+                * @param consumerGroup Consumer Group
+                * @param consumerInstance Consumer Instance
+                * @param fetchTimeout Fetch Timeout
+                * @param fetchLimit Fetch Limit
+                * @throws GeneralSecurityException 
+                * @throws MalformedURLException 
+                */
+               public CambriaConsumerWrapper(List<String> servers, String topic, 
+                                                                 String apiKey, String apiSecret,
+                                                                 String consumerGroup, String consumerInstance,
+                                                                 int fetchTimeout, int fetchLimit) 
+                      throws IllegalArgumentException {
+                       
+                       ConsumerBuilder builder = 
+                                       new CambriaClientBuilders.ConsumerBuilder();
+                       
+                       builder.knownAs(consumerGroup, consumerInstance)
+                              .usingHosts(servers)
+                              .onTopic(topic)
+                              .waitAtServer(fetchTimeout)
+                              .receivingAtMost(fetchLimit);
+                       
+                       if (apiKey != null && !apiKey.isEmpty() &&
+                               apiSecret != null && !apiSecret.isEmpty()) {
+                               builder.authenticatedBy(apiKey, apiSecret);
+                       }
+                                       
+                       try {
+                               this.consumer = builder.build();
+                       } catch (MalformedURLException | GeneralSecurityException e) {
+                               throw new IllegalArgumentException(e);
+                       }
+               }
+               
+               /**
+                * {@inheritDoc}
+                */
+               public Iterable<String> fetch() throws Exception {
+                       return this.consumer.fetch();
+               }
+               
+               /**
+                * {@inheritDoc}
+                */
+               public void close() {
+                       this.consumer.close();
+               }
+               
+               @Override
+               public String toString() {
+                       return "CambriaConsumerWrapper []";
+               }
+       }
+       
+       /**
+        * MR based consumer
+        */
+       public static class DmaapConsumerWrapper implements BusConsumer {
+               
+               /**
+                * MR Consumer
+                */
+               protected MRConsumerImpl consumer;
+               
+               /**
+                * MR Consumer Wrapper
+                * 
+                * @param servers messaging bus hosts
+                * @param topic topic
+                * @param apiKey API Key
+                * @param apiSecret API Secret
+                * @param aafLogin AAF Login
+                * @param aafPassword AAF Password
+                * @param consumerGroup Consumer Group
+                * @param consumerInstance Consumer Instance
+                * @param fetchTimeout Fetch Timeout
+                * @param fetchLimit Fetch Limit
+                */
+               public DmaapConsumerWrapper(List<String> servers, String topic, 
+                                                               String apiKey, String apiSecret,
+                                                               String aafLogin, String aafPassword,
+                                                               String consumerGroup, String consumerInstance,
+                                                               int fetchTimeout, int fetchLimit) 
+               throws Exception {
+                                       
+                       this.consumer = new MRConsumerImpl(servers, topic, 
+                                                                                          consumerGroup, consumerInstance, 
+                                                                                          fetchTimeout, fetchLimit, 
+                                                                                  null, apiKey, apiSecret);
+                       
+                       this.consumer.setUsername(aafLogin);
+                       this.consumer.setPassword(aafPassword);
+                       
+                       this.consumer.setProtocolFlag(ProtocolTypeConstants.AAF_AUTH.getValue());
+                       
+                       Properties props = new Properties();
+                       props.setProperty("Protocol", "http");
+                       this.consumer.setProps(props);
+                       this.consumer.setHost(servers.get(0) + ":3904");;
+               }
+               
+               /**
+                * {@inheritDoc}
+                */
+               public Iterable<String> fetch() throws Exception {
+                       return this.consumer.fetch();
+               }
+               
+               /**
+                * {@inheritDoc}
+                */
+               public void close() {
+                       this.consumer.close();
+               }
+               
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.
+                       append("DmaapConsumerWrapper [").
+                       append("consumer.getAuthDate()=").append(consumer.getAuthDate()).
+                       append(", consumer.getAuthKey()=").append(consumer.getAuthKey()).
+                       append(", consumer.getHost()=").append(consumer.getHost()).
+                       append(", consumer.getProtocolFlag()=").append(consumer.getProtocolFlag()).
+                       append(", consumer.getUsername()=").append(consumer.getUsername()).
+                       append("]");
+                       return builder.toString();
+               }
+       }
+
+       
+}
+
+
+
+
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusPublisher.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusPublisher.java
new file mode 100644 (file)
index 0000000..798bf98
--- /dev/null
@@ -0,0 +1,231 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.net.MalformedURLException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import com.att.nsa.cambria.client.CambriaBatchingPublisher;
+import com.att.nsa.cambria.client.CambriaClientBuilders;
+import com.att.nsa.cambria.client.CambriaClientBuilders.PublisherBuilder;
+import com.att.nsa.mr.client.impl.MRSimplerBatchPublisher;
+import com.att.nsa.mr.test.clients.ProtocolTypeConstants;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public interface BusPublisher {
+       
+       /**
+        * sends a message
+        * 
+        * @param partition id
+        * @param message the message
+        * @return true if success, false otherwise
+        * @throws IllegalArgumentException if no message provided
+        */
+       public boolean send(String partitionId, String message) throws IllegalArgumentException;
+       
+       /**
+        * closes the publisher
+        */
+       public void close();
+       
+       /**
+        * Cambria based library publisher
+        */
+       public static class CambriaPublisherWrapper implements BusPublisher {
+
+               /**
+                * The actual Cambria publisher
+                */
+               @JsonIgnore
+               protected volatile CambriaBatchingPublisher publisher;
+               
+               public CambriaPublisherWrapper(List<String> servers, String topic,
+                                                              String apiKey,
+                                                              String apiSecret) 
+                      throws IllegalArgumentException {
+                       PublisherBuilder builder = new CambriaClientBuilders.PublisherBuilder();
+                       
+                       builder.usingHosts(servers)
+                              .onTopic(topic);
+                       
+                                  // Only supported in 0.2.4 version
+                              // .logSendFailuresAfter(DEFAULT_LOG_SEND_FAILURES_AFTER);
+                       
+                       if (apiKey != null && !apiKey.isEmpty() &&
+                               apiSecret != null && !apiSecret.isEmpty()) {
+                               builder.authenticatedBy(apiKey, apiSecret);
+                       }
+                       
+                       try {
+                               this.publisher = builder.build();
+                       } catch (MalformedURLException | GeneralSecurityException e) {
+                               throw new IllegalArgumentException(e);
+                       }
+               }
+               
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public boolean send(String partitionId, String message) 
+                               throws IllegalArgumentException {
+                       if (message == null)
+                               throw new IllegalArgumentException("No message provided");
+                       
+                       try {
+                               this.publisher.send(partitionId, message);
+                       } catch (Exception e) {
+                               PolicyLogger.warn(CambriaPublisherWrapper.class.getName(), 
+                                         "SEND of " + message + " IN " +
+                                         this + " cannot be performed because of " + 
+                                                         e.getMessage());
+                               return false;
+                       }
+                       return true;                    
+               }
+               
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public void close() {
+                       if (PolicyLogger.isInfoEnabled())
+                               PolicyLogger.info(CambriaPublisherWrapper.class.getName(), 
+                                                 "CREATION: " + this);
+                       
+                       try {
+                               this.publisher.close();
+                       } catch (Exception e) {
+                               PolicyLogger.warn(CambriaPublisherWrapper.class.getName(), 
+                                                 "CLOSE on " + this + " FAILED because of " + 
+                                                                 e.getMessage());
+                       }
+               }
+               
+               
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("CambriaPublisherWrapper [").
+                       append("publisher.getPendingMessageCount()=").
+                       append(publisher.getPendingMessageCount()).
+                       append("]");
+                       return builder.toString();
+               }
+               
+       }
+       
+       /**
+        * DmaapClient library wrapper
+        */
+       public static class DmaapPublisherWrapper implements BusPublisher {
+               /**
+                * MR based Publisher
+                */             
+               protected MRSimplerBatchPublisher publisher;
+               
+               public DmaapPublisherWrapper(List<String> servers, String topic,
+                                                    String aafLogin,
+                                                    String aafPassword) {
+                       
+                       ArrayList<String> dmaapServers = new ArrayList<String>();
+                       for (String server: servers) {
+                               dmaapServers.add(server + ":3904");
+                       }
+                                       
+                       this.publisher = 
+                               new MRSimplerBatchPublisher.Builder().
+                                                       againstUrls(dmaapServers).
+                                                       onTopic(topic).
+                                                       build();
+                       
+                       this.publisher.setProtocolFlag(ProtocolTypeConstants.AAF_AUTH.getValue());
+                       
+                       this.publisher.setUsername(aafLogin);
+                       this.publisher.setPassword(aafPassword);  
+                       
+                       Properties props = new Properties();
+                       props.setProperty("Protocol", "http");
+                       props.setProperty("contenttype", "application/json");
+                       
+                       this.publisher.setProps(props);
+                       
+                       this.publisher.setHost(servers.get(0));
+                       
+                       if (PolicyLogger.isInfoEnabled())
+                               PolicyLogger.info(DmaapPublisherWrapper.class.getName(), 
+                                                         "CREATION: " + this);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public void close() {
+                       if (PolicyLogger.isInfoEnabled())
+                               PolicyLogger.info(DmaapPublisherWrapper.class.getName(), 
+                                                 "CREATION: " + this);
+                       
+                       try {
+                               this.publisher.close(1, TimeUnit.SECONDS);
+                       } catch (Exception e) {
+                               PolicyLogger.warn(DmaapPublisherWrapper.class.getName(), 
+                                                 "CLOSE: " + this + " because of " + 
+                                                                 e.getMessage());
+                       }
+               }
+               
+               /**
+                * {@inheritDoc}
+                */
+               @Override
+               public boolean send(String partitionId, String message) 
+                               throws IllegalArgumentException {
+                       if (message == null)
+                               throw new IllegalArgumentException("No message provided");
+                       
+                       this.publisher.send(partitionId, message);
+                       return true;
+                       
+               }
+               
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("DmaapPublisherWrapper [").
+                       append("publisher.getAuthDate()=").append(publisher.getAuthDate()).
+                       append(", publisher.getAuthKey()=").append(publisher.getAuthKey()).
+                       append(", publisher.getHost()=").append(publisher.getHost()).
+                       append(", publisher.getProtocolFlag()=").append(publisher.getProtocolFlag()).
+                       append(", publisher.getUsername()=").append(publisher.getUsername()).
+                       append(", publisher.getPendingMessageCount()=").append(publisher.getPendingMessageCount()).
+                       append("]");
+                       return builder.toString();
+               }
+       }
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusTopicBase.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusTopicBase.java
new file mode 100644 (file)
index 0000000..e36e3af
--- /dev/null
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.util.List;
+
+import org.apache.commons.collections4.queue.CircularFifoQueue;
+
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.bus.BusTopic;
+
+public abstract class BusTopicBase implements BusTopic, Topic {
+       
+       protected List<String> servers;
+
+       protected String topic;
+       
+       protected String apiKey;
+       protected String apiSecret;
+       
+       protected CircularFifoQueue<String> recentEvents = new CircularFifoQueue<String>(10);
+       
+       public BusTopicBase(List<String> servers, 
+                                                 String topic, 
+                                                 String apiKey, 
+                                                 String apiSecret) 
+       throws IllegalArgumentException {
+               
+               if (servers == null || servers.isEmpty()) {
+                       throw new IllegalArgumentException("UEB Server(s) must be provided");
+               }
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("An UEB Topic must be provided");
+               }
+               
+               this.servers = servers;
+               this.topic = topic;
+               
+               this.apiKey = apiKey;
+               this.apiSecret = apiSecret;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getTopic() {
+               return topic;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<String> getServers() {
+               return servers;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getApiKey() {
+               return apiKey;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getApiSecret() {
+               return apiSecret;
+       }
+       
+       /**
+        * @return the recentEvents
+        */
+       @Override
+       public synchronized String[] getRecentEvents() {
+               String[] events = new String[recentEvents.size()];
+               return recentEvents.toArray(events);
+       }
+
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("UebTopicBase [servers=").append(servers).append(", topic=").append(topic).append(", apiKey=")
+                               .append(apiKey).append(", apiSecret=").append(apiSecret).append("]");
+               return builder.toString();
+       }
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineBusTopicSink.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineBusTopicSink.java
new file mode 100644 (file)
index 0000000..bd88818
--- /dev/null
@@ -0,0 +1,284 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+
+import org.openecomp.policy.drools.event.comm.bus.BusTopicSink;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+
+/**
+ * Transport Agnostic Bus Topic Sink to carry out the core functionality
+ * to interact with a sink regardless if it is UEB or DMaaP.
+ *
+ */
+public abstract class InlineBusTopicSink extends BusTopicBase implements BusTopicSink {
+       
+       /**
+        * logger 
+        */
+       private static org.openecomp.policy.common.logging.flexlogger.Logger logger = 
+                                                                               FlexLogger.getLogger(InlineBusTopicSink.class);
+       
+       /**
+        * Not to be converted to PolicyLogger.
+        * This will contain all in/out traffic and only that in a single file in a concise format.
+        */
+       protected static final Logger networkLogger = Logger.getLogger(NETWORK_LOGGER);
+       
+       /**
+        * The partition key to publish to
+        */
+       protected String partitionId;
+       
+       /**
+        * Am I running?
+        * reflects invocation of start()/stop() 
+        * !locked & start() => alive
+        * stop() => !alive
+        */
+       protected volatile boolean alive = false;
+       
+       /**
+        * Am I locked?
+        * reflects invocation of lock()/unlock() operations
+        * locked => !alive (but not in the other direction necessarily)
+        * locked => !offer, !run, !start, !stop (but this last one is obvious
+        *                                        since locked => !alive)
+        */
+       protected volatile boolean locked = false;
+       
+       /**
+        * message bus publisher
+        */
+       protected BusPublisher publisher;
+
+       /**
+        * constructor for abstract sink
+        * 
+        * @param servers servers
+        * @param topic topic
+        * @param apiKey api secret
+        * @param apiSecret api secret
+        * @param partitionId partition id
+        * @throws IllegalArgumentException in invalid parameters are passed in
+        */
+       public InlineBusTopicSink(List<String> servers, String topic, 
+                                         String apiKey, String apiSecret, String partitionId)
+                       throws IllegalArgumentException {
+               
+               super(servers, topic, apiKey, apiSecret);               
+               
+               if (partitionId == null || partitionId.isEmpty()) {
+                       this.partitionId = UUID.randomUUID ().toString();
+               }
+       }
+       
+       /**
+        * Initialize the Bus publisher
+        */
+       public abstract void init();
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() throws IllegalStateException {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("START: " + this);
+               
+               synchronized(this) {
+                       
+                       if (this.alive)
+                               return true;
+                       
+                       if (locked)
+                               throw new IllegalStateException(this + " is locked.");
+                       
+                       this.alive = true;
+               }
+                               
+               this.init();
+               return true;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() {
+               
+               BusPublisher publisherCopy;
+               synchronized(this) {
+                       this.alive = false;
+                       publisherCopy = this.publisher;
+                       this.publisher = null;
+               }
+               
+               if (publisherCopy != null) {
+                       try {
+                               publisherCopy.close();
+                       } catch (Exception e) {
+                               logger.warn(MessageCodes.EXCEPTION_ERROR, e, "PUBLISHER.CLOSE", this.toString());
+                               e.printStackTrace();
+                       }
+               } else {
+                       logger.warn("No publisher to close: " + this);
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean lock() {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("LOCK: " + this);   
+               
+               synchronized (this) {
+                       if (this.locked)
+                               return true;
+                       
+                       this.locked = true;
+               }
+               
+               return this.stop();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean unlock() {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("UNLOCK: " + this);
+               
+               synchronized(this) {
+                       if (!this.locked)
+                               return true;
+                       
+                       this.locked = false;
+               }
+               
+               try {
+                       return this.start();
+               } catch (Exception e) {
+                       logger.warn("can't start after unlocking " + this + 
+                                            " because of " + e.getMessage());
+                       e.printStackTrace();
+                       return false;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isLocked() {
+               return this.locked;
+       }       
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               return this.alive;
+       }       
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean send(String message) throws IllegalArgumentException, IllegalStateException {
+               
+               if (message == null || message.isEmpty()) {
+                       throw new IllegalArgumentException("Message to send is empty");
+               }
+
+               if (!this.alive) {
+                       throw new IllegalStateException(this + " is stopped");
+               }
+               
+               try {
+                       synchronized (this) {
+                               this.recentEvents.add(message);
+                       }
+                       
+                       if (networkLogger.isInfoEnabled()) {
+                               networkLogger.info("[OUT|" + this.getTopicCommInfrastructure() + "|" + 
+                                              this.topic + "]:" + 
+                                              message);
+                       }
+                       
+                       publisher.send(this.partitionId, message);
+               } catch (Exception e) {
+                       logger.error("can't start after unlocking " + this + 
+                                        " because of " + e.getMessage());
+                       e.printStackTrace();
+                       return false;
+               }
+               
+               return true;
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void setPartitionKey(String partitionKey) {
+               this.partitionId = partitionKey;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getPartitionKey() {
+               return this.partitionId;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+               this.stop();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public abstract CommInfrastructure getTopicCommInfrastructure();
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineDmaapTopicSink.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineDmaapTopicSink.java
new file mode 100644 (file)
index 0000000..417c6d4
--- /dev/null
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.util.List;
+
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.bus.DmaapTopicSink;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ * This implementation publishes events for the associated DMAAP topic,
+ * inline with the calling thread.
+ */
+public class InlineDmaapTopicSink extends InlineBusTopicSink implements DmaapTopicSink {
+       
+       protected static Logger logger = 
+                       FlexLogger.getLogger(InlineDmaapTopicSink.class);
+       
+       protected final String userName;
+       protected final String password;
+       
+       public InlineDmaapTopicSink(List<String> servers, String topic, 
+                                           String apiKey, String apiSecret,
+                                   String userName, String password,
+                                           String partitionKey) 
+               throws IllegalArgumentException {
+               
+               super(servers, topic, apiKey, apiSecret, partitionKey);
+               
+               this.userName = userName;
+               this.password = password;
+       }
+       
+
+       @Override
+       public void init() {
+               this.publisher = 
+                               new BusPublisher.DmaapPublisherWrapper(this.servers, 
+                                                                              this.topic, 
+                                                                              this.userName, 
+                                                                              this.password);
+               if (logger.isInfoEnabled())
+                       logger.info("DMAAP SINK TOPIC created " + this);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public CommInfrastructure getTopicCommInfrastructure() {
+               return Topic.CommInfrastructure.DMAAP;
+       }
+
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("InlineDmaapTopicSink [userName=").append(userName).append(", password=").append(password)
+                               .append(", getTopicCommInfrastructure()=").append(getTopicCommInfrastructure()).append(", toString()=")
+                               .append(super.toString()).append("]");
+               return builder.toString();
+       }
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineUebTopicSink.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineUebTopicSink.java
new file mode 100644 (file)
index 0000000..2d4b155
--- /dev/null
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.util.List;
+
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.bus.UebTopicSink;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+
+/**
+ * This implementation publishes events for the associated UEB topic,
+ * inline with the calling thread.
+ */
+public class InlineUebTopicSink extends InlineBusTopicSink implements UebTopicSink {
+       
+       /**
+        * logger 
+        */
+       private static org.openecomp.policy.common.logging.flexlogger.Logger logger = 
+                                                                               FlexLogger.getLogger(InlineUebTopicSink.class);
+       
+       /**
+        * Argument-based UEB Topic Writer instantiation
+        * 
+        * @param servers list of UEB servers available for publishing
+        * @param topic the topic to publish to
+        * @param apiKey the api key (optional)
+        * @param apiSecret the api secret (optional)
+        * @param partitionId the partition key (optional, autogenerated if not provided)
+        * 
+        * @throws IllegalArgumentException if invalid arguments are detected
+        */
+       public InlineUebTopicSink(List<String> servers, 
+                                                               String topic, 
+                                               String apiKey, 
+                                               String apiSecret,
+                                               String partitionId) 
+    throws IllegalArgumentException {          
+               super(servers, topic, apiKey, apiSecret, partitionId);
+       }
+       
+       /**
+        * Instantiation of internal resources
+        */
+       @Override
+       public void init() {    
+               
+               this.publisher = 
+                               new BusPublisher.CambriaPublisherWrapper(this.servers, 
+                                                                                this.topic, 
+                                                                                this.apiKey, 
+                                                                                this.apiSecret);
+               if (logger.isInfoEnabled())
+                       logger.info("UEB SINK TOPIC created " + this);
+       }
+       
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("InlineUebTopicSink [getTopicCommInfrastructure()=").append(getTopicCommInfrastructure())
+                               .append(", toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public CommInfrastructure getTopicCommInfrastructure() {
+               return Topic.CommInfrastructure.UEB;
+       }
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedBusTopicSource.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedBusTopicSource.java
new file mode 100644 (file)
index 0000000..f37c349
--- /dev/null
@@ -0,0 +1,477 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+
+import org.openecomp.policy.drools.event.comm.TopicListener;
+import org.openecomp.policy.drools.event.comm.bus.BusTopicSource;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+/**
+ * This topic source implementation specializes in reading messages
+ * over a bus topic source and notifying its listeners
+ */
+public abstract class SingleThreadedBusTopicSource 
+       extends BusTopicBase
+       implements Runnable, BusTopicSource {
+          
+       private String className = SingleThreadedBusTopicSource.class.getName();
+       /**
+        * Not to be converted to PolicyLogger.
+        * This will contain all instract /out traffic and only that in a single file in a concise format.
+        */
+       protected static final Logger networkLogger = Logger.getLogger(NETWORK_LOGGER);
+       
+       /**
+        * Bus consumer group
+        */
+       protected final String consumerGroup;
+       
+       /**
+        * Bus consumer instance
+        */
+       protected final String consumerInstance;
+       
+       /**
+        * Bus fetch timeout
+        */
+       protected final int fetchTimeout;
+       
+       /**
+        * Bus fetch limit
+        */
+       protected final int fetchLimit;
+       
+       /**
+        * Message Bus Consumer
+        */
+       protected BusConsumer consumer;
+       
+       /**
+        * Am I running?
+        * reflects invocation of start()/stop() 
+        * !locked & start() => alive
+        * stop() => !alive
+        */
+       protected volatile boolean alive = false;
+       
+       /**
+        * Am I locked?
+        * reflects invocation of lock()/unlock() operations
+        * locked => !alive (but not in the other direction necessarily)
+        * locked => !offer, !run, !start, !stop (but this last one is obvious
+        *                                        since locked => !alive)
+        */
+       protected volatile boolean locked = false;
+       
+       /**
+        * Independent thread reading message over my topic
+        */
+       protected Thread busPollerThread;
+       
+       /**
+        * All my subscribers for new message notifications
+        */
+       protected final ArrayList<TopicListener> topicListeners = new ArrayList<TopicListener>();
+       
+       /**
+        * 
+        * @param servers Bus servers
+        * @param topic Bus Topic to be monitored
+        * @param apiKey Bus API Key (optional)
+        * @param apiSecret Bus API Secret (optional)
+        * @param consumerGroup Bus Reader Consumer Group
+        * @param consumerInstance Bus Reader Instance
+        * @param fetchTimeout Bus fetch timeout
+        * @param fetchLimit Bus fetch limit
+        * @throws IllegalArgumentException An invalid parameter passed in
+        */
+       public SingleThreadedBusTopicSource(List<String> servers, 
+                                                                               String topic, 
+                                                               String apiKey, 
+                                                               String apiSecret, 
+                                                               String consumerGroup, 
+                                                               String consumerInstance,
+                                                               int fetchTimeout,
+                                                               int fetchLimit) 
+       throws IllegalArgumentException {
+               
+               super(servers, topic, apiKey, apiSecret);
+               
+               if (consumerGroup == null || consumerGroup.isEmpty()) {
+                       this.consumerGroup = UUID.randomUUID ().toString();
+               } else {
+                       this.consumerGroup = consumerGroup;
+               }
+               
+               if (consumerInstance == null || consumerInstance.isEmpty()) {
+                       this.consumerInstance = DEFAULT_CONSUMER_INSTANCE;
+               } else {
+                       this.consumerInstance = consumerInstance;
+               }
+               
+               if (fetchTimeout <= 0) {
+                       this.fetchTimeout = NO_TIMEOUT_MS_FETCH;
+               } else {
+                       this.fetchTimeout = fetchTimeout;
+               }
+               
+               if (fetchLimit <= 0) {
+                       this.fetchLimit = NO_LIMIT_FETCH;
+               } else {
+                       this.fetchLimit = fetchLimit;
+               }
+       }
+       
+       /**
+        * Initialize the Bus client
+        */
+       public abstract void init() throws Exception;
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void register(TopicListener topicListener) 
+               throws IllegalArgumentException {               
+               
+               PolicyLogger.info(className,"REGISTER: " + topicListener + " INTO " + this);
+               
+               synchronized(this) {
+                       if (topicListener == null)
+                               throw new IllegalArgumentException("TopicListener must be provided");
+                       
+                       /* check that this listener is not registered already */
+                       for (TopicListener listener: this.topicListeners) {
+                               if (listener == topicListener) {
+                                       // already registered
+                                       return;
+                               }
+                       }
+                       
+                       this.topicListeners.add(topicListener);
+               }
+               
+               try {
+                       this.start();
+               } catch (Exception e) {
+                       PolicyLogger.info(className, "new registration of " + topicListener +  
+                                                 ",but can't start source because of " + e.getMessage());
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void unregister(TopicListener topicListener) {
+               
+               PolicyLogger.info(className, "UNREGISTER: " + topicListener + " FROM " + this);
+               
+               boolean stop = false;
+               synchronized (this) {
+                       if (topicListener == null)
+                               throw new IllegalArgumentException("TopicListener must be provided");
+                       
+                       this.topicListeners.remove(topicListener);
+                       stop = (this.topicListeners.isEmpty());
+               }
+               
+               if (stop) {             
+                       this.stop();
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean lock() { 
+               PolicyLogger.info(className, "LOCK: " + this);
+               
+               synchronized (this) {
+                       if (this.locked)
+                               return true;
+                       
+                       this.locked = true;
+               }
+               
+               return this.stop();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean unlock() {
+               PolicyLogger.info(className, "UNLOCK: " + this);
+               
+               synchronized(this) {
+                       if (!this.locked)
+                               return true;
+                       
+                       this.locked = false;
+               }
+               
+               try {
+                       return this.start();
+               } catch (Exception e) {
+                       PolicyLogger.warn("can't start after unlocking " + this + 
+                                                 " because of " + e.getMessage());
+                       return false;
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() throws IllegalStateException {
+               
+               PolicyLogger.info(className, "START: " + this);
+               
+               synchronized(this) {
+                       
+                       if (alive) {
+                               return true;
+                       }
+                       
+                       if (locked) {
+                               throw new IllegalStateException(this + " is locked.");
+                       }
+                       
+                       if (this.busPollerThread == null || 
+                               !this.busPollerThread.isAlive() || 
+                               this.consumer == null) {
+                               
+                               try {
+                                       this.init();
+                                       this.alive = true;
+                                       this.busPollerThread = new Thread(this);
+                                       this.busPollerThread.setName(this.getTopicCommInfrastructure() + "-source-" + this.getTopic());
+                                       busPollerThread.start();
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                                       throw new IllegalStateException(e);
+                               }
+                       }
+               }
+               
+               return this.alive;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() {
+               PolicyLogger.info(className, "STOP: " + this);
+               
+               synchronized(this) {
+                       BusConsumer consumerCopy = this.consumer;
+                       
+                       this.alive = false;
+                       this.consumer = null;
+                       
+                       if (consumerCopy != null) {
+                               try {
+                                       consumerCopy.close();
+                               } catch (Exception e) {
+                                       PolicyLogger.warn(MessageCodes.EXCEPTION_ERROR, e, "CONSUMER.CLOSE", this.toString());
+                               }
+                       }
+               }
+                                                       
+               Thread.yield();
+                               
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isLocked() {
+               return this.locked;
+       }
+       
+       /**
+        * broadcast event to all listeners
+        * 
+        * @param message the event
+        * @return true if all notifications are performed with no error, false otherwise
+        */
+       protected boolean broadcast(String message) {
+               
+               /* take a snapshot of listeners */
+               List<TopicListener> snapshotListeners = this.snapshotTopicListeners();
+               
+               boolean success = true;
+               for (TopicListener topicListener: snapshotListeners) {
+                       try {
+                               topicListener.onTopicEvent(this.getTopicCommInfrastructure(), this.topic, message);
+                       } catch (Exception e) {
+                               PolicyLogger.warn(this.className, "ERROR notifying " + topicListener.toString() + 
+                                                         " because of " + e.getMessage() + " @ " + this.toString());
+                               success = false;
+                       }
+               }
+               return success;
+       }
+       
+       /**
+        * take a snapshot of current topic listeners
+        * 
+        * @return the topic listeners
+        */
+       protected synchronized List<TopicListener> snapshotTopicListeners() {
+               @SuppressWarnings("unchecked")
+               List<TopicListener> listeners = (List<TopicListener>) topicListeners.clone();
+               return listeners;
+       }
+       
+       /**
+        * Run thread method for the Bus Reader
+        */
+       @Override
+       public void run() {
+               while (this.alive) {
+                       try {
+                               for (String event: this.consumer.fetch()) {                                     
+                                       synchronized (this) {
+                                               this.recentEvents.add(event);
+                                       }
+                                       
+                                       if (networkLogger.isInfoEnabled()) {
+                                               networkLogger.info("IN[" + this.getTopicCommInfrastructure() + "|" + 
+                                                                  this.topic + "]:" + 
+                                                                  event);
+                                       }
+                                       
+                                       PolicyLogger.info(className, this.topic + " <-- " + event);
+                                       broadcast(event);
+                                       
+                                       if (!this.alive)
+                                               break;
+                               }
+                       } catch (Exception e) {
+                               PolicyLogger.error( MessageCodes.EXCEPTION_ERROR, className, e, "CONSUMER.FETCH", this.toString());
+                       }
+               }
+               
+               PolicyLogger.warn(this.className, "Exiting: " + this);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean offer(String event) {
+               PolicyLogger.info(className, "OFFER: " + event + " TO " + this);
+               
+               if (!this.alive) {
+                       throw new IllegalStateException(this + " is not alive.");
+               }
+               
+               synchronized (this) {
+                       this.recentEvents.add(event);
+               }
+               
+               if (networkLogger.isInfoEnabled()) {
+                       networkLogger.info("IN[" + this.getTopicCommInfrastructure() + "|" + 
+                                           this.topic + "]:" + 
+                                           event);
+               }
+               
+               
+               return broadcast(event);
+       }
+       
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("SingleThreadedBusTopicSource [consumerGroup=").append(consumerGroup)
+                               .append(", consumerInstance=").append(consumerInstance).append(", fetchTimeout=").append(fetchTimeout)
+                               .append(", fetchLimit=").append(fetchLimit)
+                               .append(", consumer=").append(this.consumer).append(", alive=")
+                               .append(alive).append(", locked=").append(locked).append(", uebThread=").append(busPollerThread)
+                               .append(", topicListeners=").append(topicListeners.size()).append(", toString()=").append(super.toString())
+                               .append("]");
+               return builder.toString();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               return alive;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getConsumerGroup() {
+               return consumerGroup;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getConsumerInstance() {
+               return consumerInstance;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+               this.stop();
+               this.topicListeners.clear();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public int getFetchTimeout() {
+               return fetchTimeout;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public int getFetchLimit() {
+               return fetchLimit;
+       }
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedDmaapTopicSource.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedDmaapTopicSource.java
new file mode 100644 (file)
index 0000000..e65d44a
--- /dev/null
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.util.List;
+
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.bus.DmaapTopicSource;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+/**
+ * This topic reader implementation specializes in reading messages
+ * over DMAAP topic and notifying its listeners
+ */
+public class SingleThreadedDmaapTopicSource extends SingleThreadedBusTopicSource
+                                            implements DmaapTopicSource, Runnable {
+       
+       protected final String userName;
+       protected final String password;
+       private String className = SingleThreadedDmaapTopicSource.class.getName();
+
+       /**
+        * 
+        * @param servers DMaaP servers
+        * @param topic DMaaP Topic to be monitored
+        * @param apiKey DMaaP API Key (optional)
+        * @param apiSecret DMaaP API Secret (optional)
+        * @param consumerGroup DMaaP Reader Consumer Group
+        * @param consumerInstance DMaaP Reader Instance
+        * @param fetchTimeout DMaaP fetch timeout
+        * @param fetchLimit DMaaP fetch limit
+        * @throws IllegalArgumentException An invalid parameter passed in
+        */
+       public SingleThreadedDmaapTopicSource(List<String> servers, String topic, 
+                                                     String apiKey, String apiSecret,
+                                                     String userName, String password,
+                                                     String consumerGroup, String consumerInstance, 
+                                                     int fetchTimeout, int fetchLimit)
+                       throws IllegalArgumentException {
+               
+               
+               super(servers, topic, apiKey, apiSecret, 
+                         consumerGroup, consumerInstance, 
+                         fetchTimeout, fetchLimit);
+               
+               this.userName = userName;
+               this.password = password;               
+               
+               try {
+                       this.init();
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       throw new IllegalArgumentException(e);
+               }
+       }
+       
+
+       /**
+        * Initialize the Cambria or MR Client
+        */
+       @Override
+       public void init() throws Exception {
+               
+               if (this.userName == null || this.userName.isEmpty() || 
+                       this.password == null || this.password.isEmpty()) {
+                       this.consumer =
+                                       new BusConsumer.CambriaConsumerWrapper(this.servers, this.topic, 
+                                                                                  this.apiKey, this.apiSecret,
+                                                                                  this.consumerGroup, this.consumerInstance,
+                                                                                  this.fetchTimeout, this.fetchLimit);                 
+               } else {
+                       this.consumer =
+                                       new BusConsumer.DmaapConsumerWrapper(this.servers, this.topic, 
+                                                                                   this.apiKey, this.apiSecret,
+                                                                                   this.userName, this.password,
+                                                                                   this.consumerGroup, this.consumerInstance,
+                                                                                   this.fetchTimeout, this.fetchLimit);
+               }
+                       
+               PolicyLogger.info(className, "CREATION: " + this);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public CommInfrastructure getTopicCommInfrastructure() {
+               return Topic.CommInfrastructure.DMAAP;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("SingleThreadedDmaapTopicSource [userName=").append(userName).append(", password=")
+                               .append((password == null || password.isEmpty()) ? "-" : password.length())
+                               .append(", getTopicCommInfrastructure()=").append(getTopicCommInfrastructure())
+                               .append(", toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedUebTopicSource.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedUebTopicSource.java
new file mode 100644 (file)
index 0000000..edb55c7
--- /dev/null
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.event.comm.bus.internal;
+
+import java.util.List;
+
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.bus.UebTopicSource;
+
+/**
+ * This topic source implementation specializes in reading messages
+ * over an UEB Bus topic source and notifying its listeners
+ */
+public class SingleThreadedUebTopicSource extends SingleThreadedBusTopicSource 
+                                          implements UebTopicSource {
+
+       /**
+        * 
+        * @param servers UEB servers
+        * @param topic UEB Topic to be monitored
+        * @param apiKey UEB API Key (optional)
+        * @param apiSecret UEB API Secret (optional)
+        * @param consumerGroup UEB Reader Consumer Group
+        * @param consumerInstance UEB Reader Instance
+        * @param fetchTimeout UEB fetch timeout
+        * @param fetchLimit UEB fetch limit
+        * @throws IllegalArgumentException An invalid parameter passed in
+        */
+       public SingleThreadedUebTopicSource(List<String> servers, String topic, 
+                                                   String apiKey, String apiSecret,
+                                                   String consumerGroup, String consumerInstance, 
+                                                   int fetchTimeout, int fetchLimit)
+                       throws IllegalArgumentException {
+               
+               super(servers, topic, apiKey, apiSecret, 
+                         consumerGroup, consumerInstance, 
+                         fetchTimeout, fetchLimit);
+               
+               
+               this.init();
+       }
+       
+       /**
+        * Initialize the Cambria client
+        */
+       @Override
+       public void init() {
+               this.consumer =
+                       new BusConsumer.CambriaConsumerWrapper(this.servers, this.topic, 
+                                                                  this.apiKey, this.apiSecret,
+                                                                  this.consumerGroup, this.consumerInstance,
+                                                                  this.fetchTimeout, this.fetchLimit);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public CommInfrastructure getTopicCommInfrastructure() {
+               return Topic.CommInfrastructure.UEB;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("SingleThreadedUebTopicSource [getTopicCommInfrastructure()=")
+                               .append(getTopicCommInfrastructure()).append(", toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClient.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClient.java
new file mode 100644 (file)
index 0000000..2e81b2c
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.drools.http.client;
+
+import javax.ws.rs.core.Response;
+
+import org.openecomp.policy.drools.properties.Startable;
+
+public interface HttpClient extends Startable {
+       
+       public Response get(String path);
+       
+       public Response get();
+       
+       public static <T> T getBody(Response response, Class<T> entityType) {
+               return response.readEntity(entityType);
+       }
+
+       public String getName();
+       public boolean isHttps();
+       public boolean isSelfSignedCerts();
+       public String getHostname();
+       public int getPort();
+       public String getBasePath();
+       public String getUserName();
+       public String getPassword();
+       public String getBaseUrl();
+       
+       
+       public static final HttpClientFactory factory = new IndexedHttpClientFactory();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClientFactory.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClientFactory.java
new file mode 100644 (file)
index 0000000..53a8c2b
--- /dev/null
@@ -0,0 +1,185 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.drools.http.client;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.http.client.internal.JerseyClient;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+
+public interface HttpClientFactory {
+       
+       public HttpClient build(String name, boolean https, 
+                            boolean selfSignedCerts,
+                            String hostname, int port, 
+                            String baseUrl, String userName,
+                            String password, boolean managed) 
+    throws Exception;
+       
+       public ArrayList<HttpClient> build(Properties properties) throws Exception;
+       
+       public HttpClient get(String name);
+       
+       public List<HttpClient> inventory();
+       
+       public void destroy(String name);
+       
+       public void destroy();
+}
+
+class IndexedHttpClientFactory implements HttpClientFactory {
+       
+       protected HashMap<String, HttpClient> clients = new HashMap<String, HttpClient>();
+
+       @Override
+       public synchronized HttpClient build(String name, boolean https, boolean selfSignedCerts, 
+                                                    String hostname, int port,
+                                                    String baseUrl, String userName, String password,
+                                                    boolean managed) 
+       throws Exception {
+               if (clients.containsKey(name))
+                       return clients.get(name);
+               
+               JerseyClient client = 
+                               new JerseyClient(name, https, selfSignedCerts, hostname, port, baseUrl, userName, password);
+               
+               if (managed)
+                       clients.put(name, client);
+               
+               return client;
+       }
+
+       @Override
+       public synchronized ArrayList<HttpClient> build(Properties properties) throws Exception {
+               ArrayList<HttpClient> clientList = new ArrayList<HttpClient>();
+               
+               String clientNames = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES);
+               if (clientNames == null || clientNames.isEmpty()) {
+                       return clientList;
+               }
+               
+               List<String> clientNameList = 
+                               new ArrayList<String>(Arrays.asList(clientNames.split("\\s*,\\s*")));
+               
+               for (String clientName : clientNameList) {
+                       String httpsString = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + 
+                                                        clientName + 
+                                                        PolicyProperties.PROPERTY_HTTP_HTTPS_SUFFIX);
+                       boolean https = false;
+                       if (httpsString != null && !httpsString.isEmpty()) {
+                               https = Boolean.parseBoolean(httpsString);
+                       }
+                       
+                       String hostName = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." +
+                                                                        clientName + 
+                                                     PolicyProperties.PROPERTY_HTTP_HOST_SUFFIX);
+                                       
+                       String servicePortString = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + 
+                                                                     clientName + 
+                                                                     PolicyProperties.PROPERTY_HTTP_PORT_SUFFIX);
+                       int port;
+                       try {
+                               if (servicePortString == null || servicePortString.isEmpty()) {
+                                       continue;
+                               }
+                               port = Integer.parseInt(servicePortString);
+                       } catch (NumberFormatException nfe) {
+                               nfe.printStackTrace();
+                               continue;
+                       }
+                       
+                       String baseUrl = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." +
+                                                                       clientName + 
+                                                    PolicyProperties.PROPERTY_HTTP_URL_SUFFIX);
+                       
+                       String userName = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." +
+                                                                        clientName + 
+                                                     PolicyProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX);
+
+                       String password = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." +
+                                                            clientName + 
+                                                     PolicyProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX);
+                       
+                       String managedString = properties.getProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." +
+                                                                             clientName + 
+                                                                             PolicyProperties.PROPERTY_MANAGED_SUFFIX);
+                       boolean managed = true;
+                       if (managedString != null && !managedString.isEmpty()) {
+                               managed = Boolean.parseBoolean(managedString);
+                       }
+                       
+                       try {
+                               HttpClient client =
+                                               this.build(clientName, https, https, hostName, port, baseUrl, 
+                                                                  userName, password, managed);
+                               clientList.add(client);
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+               
+               return clientList;
+       }
+
+       @Override
+       public synchronized HttpClient get(String name) {
+               if (clients.containsKey(name)) {
+                       return clients.get(name);
+               } 
+               
+               throw new IllegalArgumentException("Http Client " + name + " not found");
+       }
+
+       @Override
+       public synchronized List<HttpClient> inventory() {
+               return new ArrayList<HttpClient>(this.clients.values());
+       }
+
+       @Override
+       public synchronized void destroy(String name) {
+               if (!clients.containsKey(name)) {
+                       return;
+               }
+               
+               HttpClient client = clients.remove(name);
+               try {
+                       client.shutdown();
+               } catch (IllegalStateException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public void destroy() {
+               List<HttpClient> clientsInventory = this.inventory();
+               for (HttpClient client: clientsInventory) {
+                       client.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.clients.clear();
+               }
+       }
+       
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/internal/JerseyClient.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/internal/JerseyClient.java
new file mode 100644 (file)
index 0000000..4fa59dc
--- /dev/null
@@ -0,0 +1,242 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-healthcheck
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.http.client.internal;
+
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.openecomp.policy.drools.http.client.HttpClient;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class JerseyClient implements HttpClient {
+       
+       protected final String name;
+       protected final boolean https;
+       protected final boolean selfSignedCerts;
+       protected final String hostname;
+       protected final int port;
+       protected final String basePath;
+       protected final String userName;
+       protected final String password;
+       
+       protected final Client client;
+       protected final String baseUrl;
+       
+       protected boolean alive = true;
+       
+       
+       public JerseyClient(String name, boolean https, 
+                                   boolean selfSignedCerts,
+                                   String hostname, int port, 
+                                   String basePath, String userName,
+                                   String password) 
+       throws Exception {
+               
+               super();
+               
+               if (name == null || name.isEmpty())
+                       throw new IllegalArgumentException("Name must be provided");
+               
+               if (hostname == null || hostname.isEmpty())
+                       throw new IllegalArgumentException("Hostname must be provided");
+               
+               if (port <= 0 && port >= 65535)
+                       throw new IllegalArgumentException("Invalid Port provided: " + port);
+               
+               this.name = name;
+               this.https = https;
+               this.hostname = hostname;
+               this.port = port;
+               this.basePath = basePath;
+               this.userName = userName;
+               this.password = password;
+               this.selfSignedCerts = selfSignedCerts;
+               
+               StringBuffer tmpBaseUrl = new StringBuffer();
+               if (this.https) {
+                       tmpBaseUrl.append("https://");
+                       ClientBuilder clientBuilder;
+                       SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
+                       if (this.selfSignedCerts) {
+                               sslContext.init(null, new TrustManager[]{new X509TrustManager() {
+                                       @Override
+                               public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
+                                       @Override
+                               public void checkServerTrusted(X509Certificate[]  chain, String authType) throws CertificateException {}
+                                       @Override
+                               public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
+       
+                           }}, new SecureRandom());
+                                clientBuilder = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(new HostnameVerifier() {
+                                       @Override
+                                       public boolean verify(String hostname, SSLSession session) {return true;}
+                                });
+                       } else {
+                               sslContext.init(null, null, null);
+                               clientBuilder = ClientBuilder.newBuilder().sslContext(sslContext);
+                       }
+                       this.client = clientBuilder.build();
+               } else {        
+                       tmpBaseUrl.append("http://");
+                       this.client = ClientBuilder.newClient();
+               }
+               
+               if (this.userName != null && !this.userName.isEmpty() &&
+                       this.password != null && !this.password.isEmpty()) {
+                       HttpAuthenticationFeature authFeature = HttpAuthenticationFeature.basic(userName, password);
+                       this.client.register(authFeature);
+               }
+               
+               this.baseUrl = tmpBaseUrl.append(this.hostname).append(":").
+                                                 append(this.port).append("/").
+                                         append((this.basePath == null) ? "" : this.basePath).
+                                         toString();
+       }
+       
+       @Override
+       public Response get(String path) {              
+               if (path != null && !path.isEmpty())
+                       return this.client.target(this.baseUrl).path(path).request().get();
+               else
+                       return this.client.target(this.baseUrl).request().get();
+       }
+       
+       @Override
+       public Response get() {
+               return this.client.target(this.baseUrl).request().get();
+       }
+       
+
+       @Override
+       public boolean start() throws IllegalStateException {
+               return alive;
+       }
+
+       @Override
+       public boolean stop() throws IllegalStateException {
+               return !alive;
+       }
+
+       @Override
+       public void shutdown() throws IllegalStateException {
+               synchronized(this) {
+                       alive = false;
+               }
+               
+               try {
+                       this.client.close();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public synchronized boolean isAlive() {
+               return this.alive;
+       }
+
+       @Override
+       public String getName() {
+               return name;
+       }
+
+       @Override
+       public boolean isHttps() {
+               return https;
+       }
+
+       @Override
+       public boolean isSelfSignedCerts() {
+               return selfSignedCerts;
+       }
+
+       @Override
+       public String getHostname() {
+               return hostname;
+       }
+
+       public int getPort() {
+               return port;
+       }
+
+       @Override
+       public String getBasePath() {
+               return basePath;
+       }
+
+       @Override
+       public String getUserName() {
+               return userName;
+       }
+
+       @JsonIgnore
+       @Override
+       public String getPassword() {
+               return password;
+       }
+
+       @Override
+       public String getBaseUrl() {
+               return baseUrl;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("JerseyClient [name=");
+               builder.append(name);
+               builder.append(", https=");
+               builder.append(https);
+               builder.append(", selfSignedCerts=");
+               builder.append(selfSignedCerts);
+               builder.append(", hostname=");
+               builder.append(hostname);
+               builder.append(", port=");
+               builder.append(port);
+               builder.append(", basePath=");
+               builder.append(basePath);
+               builder.append(", userName=");
+               builder.append(userName);
+               builder.append(", password=");
+               builder.append(password);
+               builder.append(", client=");
+               builder.append(client);
+               builder.append(", baseUrl=");
+               builder.append(baseUrl);
+               builder.append(", alive=");
+               builder.append(alive);
+               builder.append("]");
+               return builder.toString();
+       }
+
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java
new file mode 100644 (file)
index 0000000..5f5dd78
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.drools.http.server;
+
+import org.openecomp.policy.drools.properties.Startable;
+
+/**
+ * A Jetty Server to server REST Requests
+ */
+public interface HttpServletServer extends Startable {
+
+       /**
+        * 
+        * @return port
+        */
+       public int getPort();
+       
+       /**
+        * enables basic authentication with user and password on the the relative path relativeUriPath
+        * 
+        * @param user
+        * @param password
+        * @param relativeUriPath
+        */
+       public void setBasicAuthentication(String user, String password, String relativeUriPath);
+
+       /**
+        * adds a JAX-RS servlet class to serve REST requests
+        * 
+        * @param servletPath
+        * @param restClass
+        * @throws IllegalArgumentException
+        * @throws IllegalStateException
+        */
+       public void addServletClass(String servletPath, String restClass) 
+                       throws IllegalArgumentException, IllegalStateException;
+
+       /**
+        * adds a package containing JAX-RS classes to serve REST requests
+        * 
+        * @param servletPath
+        * @param restPackage
+        * @throws IllegalArgumentException
+        * @throws IllegalStateException
+        */
+       public void addServletPackage(String servletPath, String restPackage) 
+                       throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * blocking start of the http server
+        * 
+        * @param maxWaitTime max time to wait for the start to take place
+        * @return true if start was successful
+        * 
+        * @throws IllegalArgumentException if arguments are invalid
+        */
+       public boolean waitedStart(long maxWaitTime) throws IllegalArgumentException;
+       
+       
+       /**
+        * factory for managing and tracking DMAAP sources
+        */
+       public static HttpServletServerFactory factory = new IndexedHttpServletServerFactory();
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java
new file mode 100644 (file)
index 0000000..bd5ae24
--- /dev/null
@@ -0,0 +1,206 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.drools.http.server;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.http.server.internal.JettyJerseyServer;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+
+/**
+ * Jetty Server Factory
+ */
+public interface HttpServletServerFactory {
+
+       public HttpServletServer build(String name, String host, int port, String contextPath, boolean managed)
+               throws IllegalArgumentException;
+       
+       public ArrayList<HttpServletServer> build(Properties properties) throws IllegalArgumentException;
+       
+       public HttpServletServer get(int port);
+       public List<HttpServletServer> inventory();
+       public void destroy(int port);
+       public void destroy();
+}
+
+class IndexedHttpServletServerFactory implements HttpServletServerFactory {
+       
+       protected static Logger  logger = FlexLogger.getLogger(IndexedHttpServletServerFactory.class);  
+       
+       protected HashMap<Integer, JettyJerseyServer> servers = new HashMap<Integer, JettyJerseyServer>();
+
+       @Override
+       public synchronized HttpServletServer build(String name, String host, int port, 
+                                                           String contextPath, boolean managed) 
+               throws IllegalArgumentException {       
+               
+               if (servers.containsKey(port))
+                       return servers.get(port);
+               
+               JettyJerseyServer server = new JettyJerseyServer(name, host, port, contextPath);
+               if (managed)
+                       servers.put(port, server);
+               
+               return server;
+       }
+       
+       @Override
+       public synchronized ArrayList<HttpServletServer> build(Properties properties) 
+               throws IllegalArgumentException {       
+               
+               ArrayList<HttpServletServer> serviceList = new ArrayList<HttpServletServer>();
+               
+               String serviceNames = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES);
+               if (serviceNames == null || serviceNames.isEmpty()) {
+                       logger.warn("No topic for HTTP Service " + properties);
+                       return serviceList;
+               }
+               
+               List<String> serviceNameList = 
+                               new ArrayList<String>(Arrays.asList(serviceNames.split("\\s*,\\s*")));
+               
+               for (String serviceName : serviceNameList) {
+                       String servicePortString = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + 
+                                                                     serviceName + 
+                                                                     PolicyProperties.PROPERTY_HTTP_PORT_SUFFIX);
+                       
+                       int servicePort;
+                       try {
+                               if (servicePortString == null || servicePortString.isEmpty()) {
+                                       if (logger.isWarnEnabled())
+                                               logger.warn("No HTTP port for service in " + serviceName);
+                                       continue;
+                               }
+                               servicePort = Integer.parseInt(servicePortString);
+                       } catch (NumberFormatException nfe) {
+                               if (logger.isWarnEnabled())
+                                       logger.warn("No HTTP port for service in " + serviceName);
+                               continue;
+                       }
+                       
+                       String hostName = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                     serviceName + 
+                                                     PolicyProperties.PROPERTY_HTTP_HOST_SUFFIX);
+                       
+                       String contextUriPath = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                        serviceName + 
+                                                        PolicyProperties.PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX);
+                       
+                       String userName = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                                        serviceName + 
+                                                     PolicyProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX);
+
+                       String password = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                     serviceName + 
+                                                     PolicyProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX);
+                       
+                       String authUriPath = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                        serviceName + 
+                                                        PolicyProperties.PROPERTY_HTTP_AUTH_URIPATH_SUFFIX);
+                       
+                       String restClasses = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                      serviceName + 
+                                                      PolicyProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX);
+                       
+                       String restPackages = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                        serviceName + 
+                                                        PolicyProperties.PROPERTY_HTTP_REST_PACKAGES_SUFFIX);
+                       String restUriPath = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                         serviceName + 
+                                                         PolicyProperties.PROPERTY_HTTP_REST_URIPATH_SUFFIX);
+                       
+                       String managedString = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+                                                          serviceName + 
+                                                          PolicyProperties.PROPERTY_MANAGED_SUFFIX);           
+                       boolean managed = true;
+                       if (managedString != null && !managedString.isEmpty()) {
+                               managed = Boolean.parseBoolean(managedString);
+                       }
+                       
+                       HttpServletServer service = build(serviceName, hostName, servicePort, contextUriPath, managed);
+                       if (userName != null && !userName.isEmpty() && password != null && !password.isEmpty()) {
+                               service.setBasicAuthentication(userName, password, authUriPath);
+                       }
+                       
+                       if (restClasses != null && !restClasses.isEmpty()) {
+                               List<String> restClassesList = 
+                                               new ArrayList<String>(Arrays.asList(restClasses.split("\\s*,\\s*")));
+                               for (String restClass : restClassesList)
+                                       service.addServletClass(restUriPath, restClass);
+                       }
+                       
+                       if (restPackages != null && !restPackages.isEmpty()) {
+                               List<String> restPackageList = 
+                                               new ArrayList<String>(Arrays.asList(restPackages.split("\\s*,\\s*")));
+                               for (String restPackage : restPackageList)
+                                       service.addServletPackage(restUriPath, restPackage);
+                       }
+                       
+                       serviceList.add(service);
+               }
+               
+               return serviceList;
+       }
+
+       @Override
+       public synchronized HttpServletServer get(int port) throws IllegalArgumentException {
+               
+               if (servers.containsKey(port)) {
+                       return servers.get(port);
+               } 
+               
+               throw new IllegalArgumentException("Http Server for " + port + " not found");
+       }
+
+       @Override
+       public synchronized List<HttpServletServer> inventory() {
+                return new ArrayList<HttpServletServer>(this.servers.values());
+       }
+       
+       @Override
+       public synchronized void destroy(int port) throws IllegalArgumentException, IllegalStateException {
+               
+               if (!servers.containsKey(port)) {
+                       return;
+               }
+               
+               HttpServletServer server = servers.remove(port);
+               server.shutdown();
+       }
+
+       @Override
+       public synchronized void destroy() throws IllegalArgumentException, IllegalStateException {
+               List<HttpServletServer> servers = this.inventory();
+               for (HttpServletServer server: servers) {
+                       server.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.servers.clear();
+               }
+       }
+       
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java
new file mode 100644 (file)
index 0000000..4914a4c
--- /dev/null
@@ -0,0 +1,130 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.drools.http.server.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.jetty.servlet.ServletHolder;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ * REST Jetty Server using Jersey
+ */
+public class JettyJerseyServer extends JettyServletServer {
+       
+       protected static final String JERSEY_PACKAGES_PARAM = "jersey.config.server.provider.packages";
+       protected static final String JERSEY_CLASSNAMES_PARAM = "jersey.config.server.provider.classnames";
+       
+       protected static Logger logger = FlexLogger.getLogger(JettyJerseyServer.class);
+       
+       protected ArrayList<String> packages = new ArrayList<String>();
+       protected HashMap<String, ServletHolder> servlets = 
+                                                       new HashMap<String, ServletHolder>();
+       
+       public JettyJerseyServer(String name, String host, int port, String contextPath) 
+              throws IllegalArgumentException {                
+               super(name, host, port, contextPath);
+       }
+       
+       protected synchronized ServletHolder getServlet(String servletPath) 
+                         throws IllegalArgumentException {
+               
+               if (servletPath == null || servletPath.isEmpty())
+                       servletPath = "/*";
+               
+               ServletHolder jerseyServlet = servlets.get(servletPath);
+               if (jerseyServlet == null) {
+                       jerseyServlet = context.addServlet
+                       (org.glassfish.jersey.servlet.ServletContainer.class, servletPath);  
+                       jerseyServlet.setInitOrder(0);
+                       String initPackages = 
+                                       jerseyServlet.getInitParameter(JERSEY_PACKAGES_PARAM);
+                       if (initPackages == null) {
+                       jerseyServlet.setInitParameter(
+                                       JERSEY_PACKAGES_PARAM,
+                                       "com.jersey.jaxb,com.fasterxml.jackson.jaxrs.json");
+                       }
+                       this.servlets.put(servletPath, jerseyServlet);
+               }
+               
+               return jerseyServlet;
+       }
+       
+       @Override
+       public synchronized void addServletPackage(String servletPath, String restPackage) 
+              throws IllegalArgumentException, IllegalStateException {
+               
+       if (restPackage == null || restPackage.isEmpty())
+                       throw new IllegalArgumentException("No discoverable REST package provided");
+               
+               ServletHolder jerseyServlet = this.getServlet(servletPath);
+               if (jerseyServlet == null)
+                       throw new IllegalStateException("Unexpected, no Jersey Servlet class");
+               
+               String initPackages = 
+                               jerseyServlet.getInitParameter(JERSEY_PACKAGES_PARAM);
+               if (initPackages == null)
+                       throw new IllegalStateException("Unexpected, no Init Parameters loaded");
+               
+        jerseyServlet.setInitParameter(
+                       JERSEY_PACKAGES_PARAM,
+                       initPackages + "," + restPackage);
+        
+        if (logger.isDebugEnabled())
+               logger.debug(this + "Added REST Package: " + jerseyServlet.dump());
+       }
+       
+       @Override
+       public synchronized void addServletClass(String servletPath, String restClass) 
+                      throws IllegalArgumentException, IllegalStateException {
+                       
+       if (restClass == null || restClass.isEmpty())
+                       throw new IllegalArgumentException("No discoverable REST class provided");
+               
+               ServletHolder jerseyServlet = this.getServlet(servletPath);
+               if (jerseyServlet == null)
+                       throw new IllegalStateException("Unexpected, no Jersey Servlet class");
+               
+               String initClasses = 
+                               jerseyServlet.getInitParameter(JERSEY_CLASSNAMES_PARAM);
+               if (initClasses == null)
+                       initClasses = restClass;
+               else
+                       initClasses = initClasses + "," + restClass;
+               
+        jerseyServlet.setInitParameter(
+                       JERSEY_CLASSNAMES_PARAM,
+                       initClasses);
+        
+        if (logger.isDebugEnabled())
+               logger.debug(this + "Added REST Class: " + jerseyServlet.dump());
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("JerseyJettyServer [packages=").append(packages).append(", servlets=").append(servlets)
+                          .append(", toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyServletServer.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyServletServer.java
new file mode 100644 (file)
index 0000000..74360e8
--- /dev/null
@@ -0,0 +1,353 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.drools.http.server.internal;
+
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.security.HashLoginService;
+import org.eclipse.jetty.security.authentication.BasicAuthenticator;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Credential;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.http.server.HttpServletServer;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Http Server implementation using Embedded Jetty
+ */
+public abstract class JettyServletServer implements HttpServletServer, Runnable {
+       
+       private static Logger logger = FlexLogger.getLogger(JettyServletServer.class);
+
+       protected final String name;
+
+       protected final String host;
+       protected final int port;
+       
+       protected String user;
+       protected String password;
+       
+       protected final String contextPath;
+       
+       protected final Server jettyServer;
+       protected final ServletContextHandler context;
+       protected final ServerConnector connector;
+       
+       protected volatile Thread jettyThread;
+       
+       protected Object startCondition = new Object();
+       
+       public JettyServletServer(String name, String host, int port, String contextPath) 
+                  throws IllegalArgumentException {
+                       
+               if (name == null || name.isEmpty())
+                       name = "http-" + port;
+               
+               if (port <= 0 && port >= 65535)
+                       throw new IllegalArgumentException("Invalid Port provided: " + port);
+               
+               if (host == null || host.isEmpty())
+                       host = "localhost";
+               
+               if (contextPath == null || contextPath.isEmpty())
+                       contextPath = "/";
+               
+               this.name = name;
+               
+               this.host = host;
+               this.port = port;
+
+               this.contextPath = contextPath;
+               
+        this.context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+        this.context.setContextPath(contextPath);
+        
+        this.jettyServer = new Server();
+        
+        this.connector = new ServerConnector(this.jettyServer);
+        this.connector.setName(name);
+        this.connector.setReuseAddress(true);
+        this.connector.setPort(port);
+        this.connector.setHost(host);    
+        
+        this.jettyServer.addConnector(this.connector);       
+        this.jettyServer.setHandler(context);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void setBasicAuthentication(String user, String password, String servletPath) {
+        if (user == null || user.isEmpty() || password == null || password.isEmpty()) 
+               throw new IllegalArgumentException("Missing user and/or password");
+        
+        if (servletPath == null || servletPath.isEmpty())
+               servletPath = "/*";
+                       
+       HashLoginService hashLoginService = new HashLoginService();
+        hashLoginService.putUser(user, 
+                                       Credential.getCredential(password), 
+                                       new String[] {"user"});
+        hashLoginService.setName(this.connector.getName() + "-login-service");
+        
+        Constraint constraint = new Constraint();
+        constraint.setName(Constraint.__BASIC_AUTH);
+        constraint.setRoles(new String[]{"user"});
+        constraint.setAuthenticate(true);
+         
+        ConstraintMapping constraintMapping = new ConstraintMapping();
+        constraintMapping.setConstraint(constraint);
+        constraintMapping.setPathSpec(servletPath);
+        
+        ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
+        securityHandler.setAuthenticator(new BasicAuthenticator());
+        securityHandler.setRealmName(this.connector.getName() + "-realm");
+        securityHandler.addConstraintMapping(constraintMapping);
+        securityHandler.setLoginService(hashLoginService);             
+        
+        this.context.setSecurityHandler(securityHandler);
+        
+               this.user = user;
+               this.password = password;
+       }
+       
+       /**
+        * Jetty Server Execution
+        */
+       @Override
+       public void run() {
+        try {          
+               if (logger.isInfoEnabled())
+                       logger.info(this + " STARTING " + this.jettyServer.dump());
+               
+            this.jettyServer.start();
+            
+               synchronized(this.startCondition) {
+                       this.startCondition.notifyAll();
+               }
+               
+            this.jettyServer.join();
+        } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e,  
+                           "Error found while running management server", this.toString());
+               } 
+       }
+       
+       @Override
+       public boolean waitedStart(long maxWaitTime) throws IllegalArgumentException {
+               
+               if (maxWaitTime < 0)
+                       throw new IllegalArgumentException("max-wait-time cannot be negative");
+               
+               long pendingWaitTime = maxWaitTime;
+               
+               if (!this.start())
+                       return false;
+               
+               synchronized (this.startCondition) {
+                       
+                       while (!this.jettyServer.isRunning()) {
+                               try {
+                                       long startTs = System.currentTimeMillis();
+                                       
+                                       this.startCondition.wait(pendingWaitTime);
+                                       
+                                       if (maxWaitTime == 0)
+                                               /* spurious notification */
+                                               continue;
+                                       
+                                       long endTs = System.currentTimeMillis();
+                                       pendingWaitTime = pendingWaitTime - (endTs - startTs);
+                                       
+                                       if (logger.isInfoEnabled())
+                                               logger.info(this + "Pending time is " + pendingWaitTime + 
+                                                                   " ms.");
+                                       
+                                       if (pendingWaitTime <= 0)
+                                               return false;
+                                       
+                               } catch (InterruptedException e) {
+                                       logger.warn("waited-start has been interrupted");
+                                       return false;                   
+                               }
+                       }
+                       
+                       return (this.jettyServer.isRunning());
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() throws IllegalStateException {
+               if (logger.isDebugEnabled())
+                       logger.debug(this + "START");
+               
+               synchronized(this) {                    
+                       if (jettyThread == null || 
+                               !this.jettyThread.isAlive()) {
+                               
+                               this.jettyThread = new Thread(this);
+                               this.jettyThread.setName(this.name + "-" + this.port);
+                               this.jettyThread.start();
+                       }
+               }
+               
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() throws IllegalStateException {
+               logger.info(this + "STOP");
+               
+               synchronized(this) {
+                       if (jettyThread == null) {
+                               return true;
+                       } 
+                       
+                       if (!jettyThread.isAlive()) {
+                               this.jettyThread = null;
+                       } 
+                       
+                       try {
+                               this.connector.stop();
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e,  
+                                          "Error while stopping management server", this.toString());
+                               e.printStackTrace();
+                       }
+                       
+                       try {
+                               this.jettyServer.stop();
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e,  
+                                                          "Error while stopping management server", this.toString());
+                               return false;
+                       }
+                       
+                       Thread.yield();
+               }
+
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+               logger.info(this + "SHUTDOWN");
+               
+               this.stop();
+               
+               if (this.jettyThread == null)
+                       return;
+               
+               Thread jettyThreadCopy = this.jettyThread;
+
+               if (jettyThreadCopy.isAlive()) {
+                       try {
+                               jettyThreadCopy.join(1000L);
+                       } catch (InterruptedException e) {
+                               logger.warn(MessageCodes.EXCEPTION_ERROR, e,  
+                                                 "Error while shutting down management server", this.toString());
+                       }
+                       if (!jettyThreadCopy.isInterrupted()) {
+                               try {
+                                       jettyThreadCopy.interrupt();
+                               } catch(Exception e) {
+                                       // do nothing
+                                       logger.warn("exception while shutting down (OK)");
+                               }
+                       }
+               }
+               
+               this.jettyServer.destroy();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               if (this.jettyThread != null)
+                       return this.jettyThread.isAlive();
+               
+               return false;
+       }
+
+       @Override
+       public int getPort() {
+               return this.port;
+       }
+
+       /**
+        * @return the name
+        */
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * @return the host
+        */
+       public String getHost() {
+               return host;
+       }
+
+       /**
+        * @return the user
+        */
+       public String getUser() {
+               return user;
+       }
+
+       /**
+        * @return the password
+        */
+       @JsonIgnore
+       public String getPassword() {
+               return password;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("JettyServer [name=").append(name).append(", host=").append(host).append(", port=").append(port)
+                               .append(", user=").append(user).append(", password=").append((password != null)).append(", contextPath=")
+                               .append(contextPath).append(", jettyServer=").append(jettyServer).append(", context=").append(this.context)
+                               .append(", connector=").append(connector).append(", jettyThread=").append(jettyThread)
+                               .append("]");
+               return builder.toString();
+       }
+
+}
diff --git a/policy-endpoints/src/main/resources/schema/pdpd-configuration.jsonschema b/policy-endpoints/src/main/resources/schema/pdpd-configuration.jsonschema
new file mode 100644 (file)
index 0000000..34ee199
--- /dev/null
@@ -0,0 +1,61 @@
+{
+       "title": "ENGINE-CONFIGURATION",
+       "type":"object",
+       "$schema": "http://json-schema.org/draft-03/schema",
+       "required":false,
+       "properties":{
+               "requestID": {
+                       "description": "Unique Transaction ID.   This is an UUID.",
+                       "type":"string",
+                       "required":true
+               },
+               "entity": {
+                       "description": "Set of entities on which configuration can be performed: controller",
+                       "type":"string",
+                       "required":true
+               },
+               "controllers": {
+                       "description": "Controller Information, only applicable when the entity is set to controller",
+                       "type":"array",
+                       "required":false,
+                       "items": {
+                               "description": "Drools Related Information",
+                               "type":"object",
+                               "required":true,
+                               "properties":{
+                                       "name": {
+                                               "type":"string",
+                                               "required":true
+                                       },
+                                       "operation": {
+                                               "description": "Set of operations that can be applied to a controller: create, lock",
+                                               "type":"string",
+                                               "required":true
+                                       },
+                                       "drools": {
+                                               "description": "Maven Related Information",
+                                               "type":"object",
+                                               "required":false,
+                                               "properties":{
+                                                       "artifactId": {
+                                                               "description": "Maven Artifact ID",
+                                                               "type":"string",
+                                                               "required":true
+                                                       },
+                                                       "groupId": {
+                                                               "description": "Maven Group ID",
+                                                               "type":"string",
+                                                               "required":true
+                                                       },
+                                                       "version": {
+                                                               "description": "Maven Version",
+                                                               "type":"string",
+                                                               "required":true
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java
new file mode 100644 (file)
index 0000000..ced3dcf
--- /dev/null
@@ -0,0 +1,230 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.http.server.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Test;
+import org.openecomp.policy.drools.http.client.HttpClient;
+import org.openecomp.policy.drools.http.server.HttpServletServer;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+
+public class HttpClientTest {
+       
+       @Test
+       public void testHttpNoAuthClient() throws Exception {           
+               System.out.println("-- testHttpNoAuthClient() --");
+
+               HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", true);
+               server.addServletPackage("/*", this.getClass().getPackage().getName());
+               server.waitedStart(5000);
+               
+               HttpClient client = HttpClient.factory.build("testHttpNoAuthClient", false, false, 
+                                                                    "localhost", 6666, "junit/echo", 
+                                                                    null, null, true);
+               Response response = client.get("hello");
+               String body = HttpClient.getBody(response, String.class);
+               
+               assertTrue(response.getStatus() == 200);
+               assertTrue(body.equals("hello"));
+               
+               HttpServletServer.factory.destroy();
+               HttpClient.factory.destroy();
+       }
+       
+       @Test
+       public void testHttpAuthClient() throws Exception {             
+               System.out.println("-- testHttpAuthClient() --");
+
+               HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", true);
+               server.setBasicAuthentication("x", "y", null);
+               server.addServletPackage("/*", this.getClass().getPackage().getName());
+               server.waitedStart(5000);
+               
+               HttpClient client = HttpClient.factory.build("testHttpAuthClient",false, false, 
+                                                                    "localhost", 6666, "junit/echo", 
+                                                                    "x", "y", true);
+               Response response = client.get("hello");
+               String body = HttpClient.getBody(response, String.class);
+               
+               assertTrue(response.getStatus() == 200);
+               assertTrue(body.equals("hello"));
+               
+               HttpServletServer.factory.destroy();
+               HttpClient.factory.destroy();
+       }
+       
+       @Test
+       public void testHttpAuthClient401() throws Exception {          
+               System.out.println("-- testHttpAuthClient401() --");
+
+               HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", true);
+               server.setBasicAuthentication("x", "y", null);
+               server.addServletPackage("/*", this.getClass().getPackage().getName());
+               server.waitedStart(5000);
+               
+               HttpClient client = HttpClient.factory.build("testHttpAuthClient401",false, false, 
+                                                                    "localhost", 6666, "junit/echo", 
+                                                                    null, null, true);
+               Response response = client.get("hello");
+               assertTrue(response.getStatus() == 401);
+               
+               HttpServletServer.factory.destroy();
+               HttpClient.factory.destroy();
+       }
+       
+  //@Test 
+   public void testHttpAuthClientHttps() throws Exception {                             
+               System.out.println("-- testHttpAuthClientHttps() --");
+
+               HttpClient client = HttpClient.factory.build("testHttpAuthClientHttps", true, true, "somehost.somewhere.com",
+                               9091, "pap/test", "testpap", "alpha123", true);
+               Response response = client.get();
+               assertTrue(response.getStatus() == 200);
+
+               HttpClient client2 = HttpClient.factory.build("testHttpAuthClientHttps2", true, true, "somehost.somewhere.com",
+                               8081, "pdp", "testpdp", "alpha123", true);
+               Response response2 = client2.get("test");
+               assertTrue(response2.getStatus() == 500);
+
+               HttpServletServer.factory.destroy();
+               HttpClient.factory.destroy();
+    }
+    
+    @Test
+    public void testHttpAuthClientProps() throws Exception {
+               System.out.println("-- testHttpAuthClientProps() --");
+               
+               Properties httpProperties = new Properties();
+               
+               httpProperties.setProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES, "PAP,PDP");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_HOST_SUFFIX, 
+                        "localhost");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_PORT_SUFFIX, 
+                        "9091");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX, 
+                        "testpap");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX, 
+                        "alpha123");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX, 
+                        "org.openecomp.policy.drools.http.server.test.RestMockHealthCheck");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_MANAGED_SUFFIX, 
+                        "true");
+               
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_HOST_SUFFIX, 
+                        "localhost");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_PORT_SUFFIX, 
+                        "8081");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX, 
+                        "testpdp");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX, 
+                        "alpha123");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX, 
+                        "org.openecomp.policy.drools.http.server.test.RestMockHealthCheck");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_MANAGED_SUFFIX, 
+                        "true");
+               
+               httpProperties.setProperty(PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES, "PAP,PDP");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_HOST_SUFFIX, 
+                        "localhost");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_PORT_SUFFIX, 
+                        "9091");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_URL_SUFFIX, 
+                        "pap/test");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_HTTPS_SUFFIX, 
+                        "false");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX, 
+                        "testpap");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX, 
+                        "alpha123");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PAP" + PolicyProperties.PROPERTY_MANAGED_SUFFIX, 
+                        "true");
+               
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_HOST_SUFFIX, 
+                        "localhost");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_PORT_SUFFIX, 
+                        "8081");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_URL_SUFFIX, 
+                        "pdp");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_HTTPS_SUFFIX, 
+                        "false");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX, 
+                        "testpdp");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX, 
+                        "alpha123");
+               httpProperties.setProperty
+                       (PolicyProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "PDP" + PolicyProperties.PROPERTY_MANAGED_SUFFIX, 
+                        "true");
+               
+               ArrayList<HttpServletServer> servers = HttpServletServer.factory.build(httpProperties);
+               assertTrue(servers.size() == 2);
+               
+               ArrayList<HttpClient> clients = HttpClient.factory.build(httpProperties);
+               assertTrue(clients.size() == 2);
+               
+               for (HttpServletServer server: servers) {
+                       server.waitedStart(5000);
+               }
+               
+               HttpClient clientPAP = HttpClient.factory.get("PAP");
+               Response response = clientPAP.get();
+               assertTrue(response.getStatus() == 200);
+
+               HttpClient clientPDP = HttpClient.factory.get("PDP");
+               Response response2 = clientPDP.get("test");
+               assertTrue(response2.getStatus() == 500);
+
+               HttpServletServer.factory.destroy();
+               HttpClient.factory.destroy();           
+    }
+
+
+}
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java
new file mode 100644 (file)
index 0000000..94f2980
--- /dev/null
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-endpoints
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.drools.http.server.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.UUID;
+
+import org.junit.Test;
+import org.openecomp.policy.drools.http.server.HttpServletServer;
+
+/**
+ *
+ */
+public class HttpServerTest {
+
+       @Test
+       public void testSingleServer() throws Exception {
+               System.out.println("-- testSingleServer() --");
+               
+               HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 5678, "/", true);
+               server.addServletPackage("/*", this.getClass().getPackage().getName());
+               server.waitedStart(5000);
+               
+               assertTrue(HttpServletServer.factory.get(5678).isAlive());
+               
+               String echo = "hello";
+               URL url = new URL("http://localhost:5678/junit/echo/" + echo);
+               String response = response(url);
+               System.out.println("Received .. " + response);
+               assertTrue(response.equals(echo));
+               
+               HttpServletServer.factory.destroy();
+               assertTrue(HttpServletServer.factory.inventory().size() == 0);
+       }
+       
+       @Test
+       public void testMultipleServers() throws Exception {
+               System.out.println("-- testMultipleServers() --");
+               
+               HttpServletServer server1 = HttpServletServer.factory.build("echo-1", "localhost", 5678, "/", true);
+               server1.addServletPackage("/*", this.getClass().getPackage().getName());
+               server1.waitedStart(5000);
+               
+               HttpServletServer server2 = HttpServletServer.factory.build("echo-2", "localhost", 5679, "/", true);
+               server2.addServletPackage("/*", this.getClass().getPackage().getName());
+               server2.waitedStart(5000);
+               
+               assertTrue(HttpServletServer.factory.get(5678).isAlive());
+               assertTrue(HttpServletServer.factory.get(5679).isAlive());
+               
+               String echo = "hello";
+               
+               URL url1 = new URL("http://localhost:5678/junit/echo/" + echo);
+               String response1 = response(url1);
+               System.out.println("Received .. " + response1);
+               assertTrue(response1.equals(echo));
+               
+               URL url2 = new URL("http://localhost:5679/junit/echo/" + echo);
+               String response2 = response(url2);
+               System.out.println("Received .. " + response2);
+               assertTrue(response2.equals(echo));
+               
+               HttpServletServer.factory.destroy();            
+               assertTrue(HttpServletServer.factory.inventory().size() == 0);
+       }
+       
+       @Test
+       public void testMultiServicePackage() throws Exception {
+               System.out.println("-- testMultiServicePackage() --");
+               
+               String randomName = UUID.randomUUID().toString();
+               
+               HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", true);
+               server.addServletPackage("/*", this.getClass().getPackage().getName());
+               server.waitedStart(5000);
+               
+               assertTrue(HttpServletServer.factory.get(5678).isAlive());
+               
+               String echo = "hello";
+               URL urlService1 = new URL("http://localhost:5678/junit/echo/" + echo);
+               String responseService1 = response(urlService1);
+               System.out.println("Received .. " + responseService1);
+               assertTrue(responseService1.equals(echo));
+               
+               URL urlService2 = new URL("http://localhost:5678/junit/endpoints/http/servers");
+               String responseService2 = response(urlService2);
+               System.out.println("Received .. " + responseService2);
+               assertTrue(responseService2.contains(randomName));
+               
+               HttpServletServer.factory.destroy();            
+               assertTrue(HttpServletServer.factory.inventory().size() == 0);
+       }
+       
+       @Test
+       public void testServiceClass() throws Exception {
+               System.out.println("-- testServiceClass() --");
+               String randomName = UUID.randomUUID().toString();
+               
+               HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", true);
+               server.addServletClass("/*", RestEchoService.class.getCanonicalName());
+               server.waitedStart(5000);
+               
+               assertTrue(HttpServletServer.factory.get(5678).isAlive());
+               
+               String echo = "hello";
+               URL urlService1 = new URL("http://localhost:5678/junit/echo/" + echo);
+               String responseService1 = response(urlService1);
+               System.out.println("Received .. " + responseService1);
+               assertTrue(responseService1.equals(echo));
+               
+               HttpServletServer.factory.destroy();            
+               assertTrue(HttpServletServer.factory.inventory().size() == 0);
+       }
+       
+       @Test
+       public void testMultiServiceClass() throws Exception {
+               System.out.println("-- testMultiServiceClass() --");
+               
+               String randomName = UUID.randomUUID().toString();
+               
+               HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", true);
+               server.addServletClass("/*", RestEchoService.class.getCanonicalName());
+               server.addServletClass("/*", RestEndpoints.class.getCanonicalName());
+               server.waitedStart(5000);
+               
+               assertTrue(HttpServletServer.factory.get(5678).isAlive());
+               
+               String echo = "hello";
+               URL urlService1 = new URL("http://localhost:5678/junit/echo/" + echo);
+               String responseService1 = response(urlService1);
+               System.out.println("Received .. " + responseService1);
+               assertTrue(responseService1.equals(echo));
+               
+               URL urlService2 = new URL("http://localhost:5678/junit/endpoints/http/servers");
+               String responseService2 = response(urlService2);
+               System.out.println("Received .. " + responseService2);
+               assertTrue(responseService2.contains(randomName));
+               
+               HttpServletServer.factory.destroy();            
+               assertTrue(HttpServletServer.factory.inventory().size() == 0);
+       }
+
+       /**
+        * @param url
+        * @throws IOException
+        */
+       protected String response(URL url) throws IOException {
+               BufferedReader ioReader = new BufferedReader(new InputStreamReader(url.openStream()));
+               String response = "";
+               String line;
+               while ((line = ioReader.readLine()) != null) {
+                       response += line; 
+               }
+               return response;
+       }
+       
+       
+
+}
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java
new file mode 100644 (file)
index 0000000..a0320a0
--- /dev/null
@@ -0,0 +1,19 @@
+package org.openecomp.policy.drools.http.server.test;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/junit/echo")
+public class RestEchoService {
+       
+    @GET
+    @Path("{word}")
+    @Produces(MediaType.TEXT_PLAIN)
+    public String echo(@PathParam("word") String word) {   
+       return word;
+    }
+
+}
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEndpoints.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEndpoints.java
new file mode 100644 (file)
index 0000000..a00f2ff
--- /dev/null
@@ -0,0 +1,25 @@
+package org.openecomp.policy.drools.http.server.test;
+
+import java.util.List;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.openecomp.policy.drools.http.server.HttpServletServer;
+
+@Path("/junit/endpoints")
+public class RestEndpoints {
+
+    @GET
+    @Path("http/servers")
+    @Produces(MediaType.TEXT_PLAIN)
+    public String httpServers() {   
+       List<HttpServletServer> servers = 
+                       HttpServletServer.factory.inventory();
+       return servers.toString();
+    }
+    
+    
+}
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestMockHealthCheck.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestMockHealthCheck.java
new file mode 100644 (file)
index 0000000..ff1b498
--- /dev/null
@@ -0,0 +1,28 @@
+package org.openecomp.policy.drools.http.server.test;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+@Path("/")
+public class RestMockHealthCheck {
+       
+    @GET
+    @Path("pap/test")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response papHealthCheck() {   
+               return Response.status(Status.OK).entity("All Alive").build();
+    }
+    
+    @GET
+    @Path("pdp/test")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response pdpHealthCheck() {   
+               return Response.status(Status.INTERNAL_SERVER_ERROR).entity("At least some Dead").build();
+    }
+
+
+}
diff --git a/policy-healthcheck/pom.xml b/policy-healthcheck/pom.xml
new file mode 100644 (file)
index 0000000..c279cd1
--- /dev/null
@@ -0,0 +1,157 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+         
+  <modelVersion>4.0.0</modelVersion>
+  
+  <parent>
+    <groupId>org.openecomp.policy.drools-pdp</groupId>
+    <artifactId>drools-pdp</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  
+  <artifactId>policy-healthcheck</artifactId>
+  
+  <name>policy-healthcheck</name>
+  <description>Separately loadable module with healthcheck code</description>
+
+  <properties>
+          <maven.compiler.source>1.8</maven.compiler.source>
+          <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.6</version>
+        <executions>
+          <execution>
+            <id>zipfile</id>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <attach>true</attach>
+              <finalName>${project.artifactId}-${project.version}</finalName>
+              <descriptors>
+                <descriptor>src/assembly/assemble_zip.xml</descriptor>
+              </descriptors>
+              <appendAssemblyId>false</appendAssemblyId>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.8</version>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <phase>prepare-package</phase>
+            <configuration>
+              <transitive>false</transitive>
+              <outputDirectory>${project.build.directory}/assembly/lib</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>true</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+              <useRepositoryLayout>false</useRepositoryLayout>
+              <addParentPoms>false</addParentPoms>
+              <copyPom>false</copyPom>
+              <excludeGroupIds>org.opendaylight,com.brocade.odl</excludeGroupIds>
+              <scope>provided</scope>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>2.6</version>
+        <executions>
+          <execution>
+            <id>copy-version</id>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <phase>validate</phase>
+            <configuration>
+              <outputDirectory>${basedir}/target/versions</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/main/resources/versions</directory>
+                  <includes>
+                    <include>version.properties</include>
+                  </includes>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+          <execution>
+            <id>copy-resources</id>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <phase>validate</phase>
+            <configuration>
+              <outputDirectory>${basedir}/target/etc/bvc-extensions</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/main/resources/etc/bvc-extensions</directory>
+                  <includes>
+                    <include>feature_config_template.cfg</include>
+                    <include>feature_custom.install</include>
+                  </includes>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.openecomp.policy.drools-pdp</groupId>
+      <artifactId>policy-core</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.openecomp.policy.drools-pdp</groupId>
+      <artifactId>policy-endpoints</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.openecomp.policy.drools-pdp</groupId>
+      <artifactId>policy-management</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/policy-healthcheck/src/assembly/assemble_zip.xml b/policy-healthcheck/src/assembly/assemble_zip.xml
new file mode 100644 (file)
index 0000000..266e1d0
--- /dev/null
@@ -0,0 +1,85 @@
+<!--
+  ============LICENSE_START=======================================================
+  policy-persistence
+  ================================================================================
+  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=========================================================
+  -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+       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>
+       <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>
+                       <includes>
+                               <include>policy-healthcheck-${project.version}.jar</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>target/assembly/</directory>
+                       <outputDirectory>.</outputDirectory>
+                       <excludes>
+                       </excludes>
+               </fileSet>
+               <fileSet>
+                       <directory>.</directory>
+                       <outputDirectory>lib</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>
+                       <outputDirectory>config</outputDirectory>
+               </fileSet>
+       </fileSets>
+
+</assembly>
diff --git a/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheck.java b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheck.java
new file mode 100644 (file)
index 0000000..2ed2e07
--- /dev/null
@@ -0,0 +1,178 @@
+package org.openecomp.policy.drools.healthcheck;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+import javax.ws.rs.core.Response;
+
+import org.openecomp.policy.drools.http.client.HttpClient;
+import org.openecomp.policy.drools.http.server.HttpServletServer;
+import org.openecomp.policy.drools.persistence.SystemPersistence;
+import org.openecomp.policy.drools.properties.Startable;
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+public interface HealthCheck extends Startable {
+       
+       public static class Report {
+               public String name;
+               public String url;
+               public boolean healthy;
+               public int code;
+               public String message;
+               
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("Report [name=");
+                       builder.append(name);
+                       builder.append(", url=");
+                       builder.append(url);
+                       builder.append(", healthy=");
+                       builder.append(healthy);
+                       builder.append(", code=");
+                       builder.append(code);
+                       builder.append(", message=");
+                       builder.append(message);
+                       builder.append("]");
+                       return builder.toString();
+               }
+       }
+       
+       public static class Reports {
+               public boolean healthy;
+               public ArrayList<Report> details = new ArrayList<>();
+               
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("Reports [healthy=");
+                       builder.append(healthy);
+                       builder.append(", details=");
+                       builder.append(details);
+                       builder.append("]");
+                       return builder.toString();
+               }
+       }
+       
+       public Reports healthCheck();
+
+       public static final HealthCheck monitor = new HealthCheckMonitor();
+}
+
+class HealthCheckMonitor implements HealthCheck {
+
+       protected volatile ArrayList<HttpServletServer> servers = new ArrayList<>();
+       protected volatile ArrayList<HttpClient> clients = new ArrayList<>();
+       protected volatile Properties healthCheckProperties = null; 
+       
+       public Reports healthCheck() {
+               Reports reports = new Reports();
+               reports.healthy = PolicyEngine.manager.isAlive();
+               
+               HealthCheck.Report engineReport = new Report();
+               engineReport.healthy = PolicyEngine.manager.isAlive();
+               engineReport.name = "PDP-D";
+               engineReport.url = "self";
+               engineReport.code = (PolicyEngine.manager.isAlive()) ? 200 : 500;
+               engineReport.message = (PolicyEngine.manager.isAlive()) ? "alive" : "not alive";
+               reports.details.add(engineReport);
+               
+               for (HttpClient client : clients) {
+                       HealthCheck.Report report = new Report();
+                       report.name = client.getName();
+                       report.url = client.getBaseUrl();
+                       report.healthy = true;
+                       try {
+                               Response response = client.get();
+                               report.code = response.getStatus();
+                               if (report.code != 200) {
+                                       report.healthy = false;
+                                       reports.healthy = false;
+                               }
+                                       
+                               try {
+                                       report.message = HttpClient.getBody(response, String.class);
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                       } catch (Exception e) {
+                               report.healthy = false;
+                               reports.healthy = false;
+                       }
+                       reports.details.add(report);
+               }
+               return reports;
+       }
+       
+       @Override
+       public boolean start() throws IllegalStateException {
+               try {
+                       this.healthCheckProperties = SystemPersistence.manager.getProperties(HealthCheckFeature.CONFIGURATION_PROPERTIES_NAME);
+                       this.servers = HttpServletServer.factory.build(healthCheckProperties);
+                       this.clients = HttpClient.factory.build(healthCheckProperties);
+                       
+                       for (HttpServletServer server : servers) {
+                               try {
+                                       server.start();
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                       }
+               } catch (Exception e) {
+                       return false;
+               }
+               
+               return true;
+       }
+
+       @Override
+       public boolean stop() throws IllegalStateException {
+               for (HttpServletServer server : servers) {
+                       try {
+                               server.stop();
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+               
+               for (HttpClient client : clients) {
+                       try {
+                               client.stop();
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+               
+               return true;
+       }
+
+       @Override
+       public void shutdown() throws IllegalStateException {
+               this.stop();
+       }
+
+       @Override
+       public synchronized boolean isAlive() {
+               return this.healthCheckProperties != null;
+       }
+       
+       public ArrayList<HttpServletServer> getServers() {
+               return this.servers;
+       }
+       
+       public ArrayList<HttpClient> getClients() {
+               return this.clients;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("HealthCheckMonitor [servers=");
+               builder.append(servers);
+               builder.append(", clients=");
+               builder.append(clients);
+               builder.append("]");
+               return builder.toString();
+       }
+       
+}
diff --git a/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheckFeature.java b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheckFeature.java
new file mode 100644 (file)
index 0000000..ce1dd90
--- /dev/null
@@ -0,0 +1,92 @@
+package org.openecomp.policy.drools.healthcheck;
+
+import java.util.Properties;
+
+import org.kie.api.runtime.KieSession;
+import org.openecomp.policy.drools.core.FeatureAPI;
+import org.openecomp.policy.drools.core.PolicyContainer;
+import org.openecomp.policy.drools.core.PolicySession;
+
+public class HealthCheckFeature implements FeatureAPI {
+       
+       public static final String CONFIGURATION_PROPERTIES_NAME = "policy-healthcheck";
+
+       @Override
+       public int getSequenceNumber() {
+               return 2;
+       }
+
+       @Override
+       public void globalInit(String[] args, String configDir) {
+               return;
+       }
+
+       @Override
+       public KieSession activatePolicySession(PolicyContainer policyContainer, String name, String kieBaseName) {
+               return null;
+       }
+
+       @Override
+       public void disposeKieSession(PolicySession policySession) {
+               return;
+       }
+
+       @Override
+       public void destroyKieSession(PolicySession policySession) {
+               return;
+       }
+
+       @Override
+       public void beforeStartEngine() throws IllegalStateException {
+               return;
+       }
+
+       @Override
+       public void afterStartEngine() {
+               try {
+                       HealthCheck.monitor.start();
+               } catch (IllegalStateException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public void beforeShutdownEngine() {
+               return;
+       }
+
+       @Override
+       public void afterShutdownEngine() {
+               try {
+                       HealthCheck.monitor.stop();
+               } catch (IllegalStateException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public void beforeCreateController(String name, Properties properties) {
+               return;
+       }
+
+       @Override
+       public void afterCreateController(String name) {
+               return;
+       }
+
+       @Override
+       public void beforeStartController(String name) {
+               return;
+       }
+
+       @Override
+       public void afterStartController(String name) {
+               return;
+       }
+
+       @Override
+       public boolean isPersistenceEnabled() {
+               return false;
+       }
+
+}
diff --git a/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java
new file mode 100644 (file)
index 0000000..e37e758
--- /dev/null
@@ -0,0 +1,27 @@
+package org.openecomp.policy.drools.healthcheck;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.openecomp.policy.drools.healthcheck.HealthCheck.Reports;
+
+@Path("/")
+public class RestHealthCheck {
+       
+    @GET
+    @Path("{a:healthcheck|test}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Reports healthcheck() {  
+       Reports reports = HealthCheck.monitor.healthCheck(); 
+               return reports;
+    }
+    
+    @GET
+    @Path("healthcheck/configuration")
+    @Produces(MediaType.APPLICATION_JSON)
+    public HealthCheck configuration() {  
+       return HealthCheck.monitor;
+    }
+}
diff --git a/policy-healthcheck/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI b/policy-healthcheck/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI
new file mode 100644 (file)
index 0000000..7e307d0
--- /dev/null
@@ -0,0 +1 @@
+org.openecomp.policy.drools.healthcheck.HealthCheckFeature
diff --git a/policy-management/config/policy-engine.properties b/policy-management/config/policy-engine.properties
new file mode 100644 (file)
index 0000000..41456c2
--- /dev/null
@@ -0,0 +1,26 @@
+# Policy Engine Configuration
+
+# Configuration Channel Settings: PDPD_CONFIGURATION
+
+ueb.source.topics=PDPD_CONFIGURATION
+ueb.source.topics.PDPD_CONFIGURATION.servers=
+ueb.source.topics.PDPD_CONFIGURATION.apiKey=
+ueb.source.topics.PDPD_CONFIGURATION.apiSecret=
+ueb.source.topics.PDPD_CONFIGURATION.consumerGroup=
+ueb.source.topics.PDPD_CONFIGURATION.consumerInstance=
+ueb.source.topics.PDPD_CONFIGURATION.managed=false
+
+ueb.sink.topics=PDPD_CONFIGURATION
+ueb.sink.topics.PDPD_CONFIGURATION.servers=
+ueb.sink.topics.PDPD_CONFIGURATION.apiKey=
+ueb.sink.topics.PDPD_CONFIGURATION.apiSecret=
+ueb.sink.topics.PDPD_CONFIGURATION.partitionKey=
+ueb.sink.topics.PDPD_CONFIGURATION.managed=false
+
+http.server.services=CONFIG
+http.server.services.CONFIG.host=localhost
+http.server.services.CONFIG.port=9696
+http.server.services.CONFIG.userName=x
+http.server.services.CONFIG.password=y
+http.server.services.CONFIG.restPackages=org.openecomp.policy.drools.server.restful
+http.server.services.CONFIG.managed=false
diff --git a/policy-management/config/policyLogger.properties b/policy-management/config/policyLogger.properties
new file mode 100644 (file)
index 0000000..f8f31d8
--- /dev/null
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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 
+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
diff --git a/policy-management/pom.xml b/policy-management/pom.xml
new file mode 100644 (file)
index 0000000..2983f1f
--- /dev/null
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.openecomp.policy.drools-pdp</groupId>
+    <artifactId>drools-pdp</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>policy-management</artifactId>
+
+  <name>policy-management</name>
+  <description>Policy Management</description>
+
+  <properties>
+          <maven.compiler.source>1.8</maven.compiler.source>
+          <maven.compiler.target>1.8</maven.compiler.target>
+          <jetty.version>9.3.8.v20160314</jetty.version>
+          <jersey.version>2.22.2</jersey.version>
+          <jackson.version>2.8.4</jackson.version>
+          <gson.version>2.8.0</gson.version>
+  </properties>
+
+
+  <build>
+    <plugins>
+                       <plugin>
+                               <artifactId>maven-assembly-plugin</artifactId>
+                               <version>2.6</version>
+                               <executions>
+                                       <execution>
+                                               <id>zipfile</id>
+                                               <goals>
+                                                       <goal>single</goal>
+                                               </goals>
+                                               <phase>package</phase>
+                                               <configuration>
+                                                       <attach>true</attach>
+                                                       <finalName>${project.artifactId}-${project.version}</finalName>
+                                                       <descriptors>
+                                                               <descriptor>src/assembly/assemble_zip.xml</descriptor>
+                                                       </descriptors>
+                                                       <appendAssemblyId>false</appendAssemblyId>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-dependency-plugin</artifactId>
+                               <version>2.8</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-dependencies</id>
+                                               <goals>
+                                                       <goal>copy-dependencies</goal>
+                                               </goals>
+                                               <phase>prepare-package</phase>
+                                               <configuration>
+                                                       <transitive>false</transitive>
+                                                       <outputDirectory>${project.build.directory}/assembly/lib</outputDirectory>
+                                                       <overWriteReleases>false</overWriteReleases>
+                                                       <overWriteSnapshots>true</overWriteSnapshots>
+                                                       <overWriteIfNewer>true</overWriteIfNewer>
+                                                       <useRepositoryLayout>false</useRepositoryLayout>
+                                                       <addParentPoms>false</addParentPoms>
+                                                       <copyPom>false</copyPom>
+                                                       <excludeGroupIds>org.opendaylight,com.brocade.odl</excludeGroupIds>
+                                                       <scope>provided</scope>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>2.6</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-version</id>
+                                               <goals>
+                                                       <goal>copy-resources</goal>
+                                               </goals>
+                                               <phase>validate</phase>
+                                               <configuration>
+                                                       <outputDirectory>${basedir}/target/versions</outputDirectory>
+                                                       <resources>
+                                                               <resource>
+                                                                       <directory>src/main/resources/versions</directory>
+                                                                       <includes>
+                                                                               <include>version.properties</include>
+                                                                       </includes>
+                                                                       <filtering>true</filtering>
+                                                               </resource>
+                                                       </resources>
+                                               </configuration>
+                                       </execution>
+                                       <execution>
+                                               <id>copy-resources</id>
+                                               <goals>
+                                                       <goal>copy-resources</goal>
+                                               </goals>
+                                               <phase>validate</phase>
+                                               <configuration>
+                                                       <outputDirectory>${basedir}/target/etc/bvc-extensions</outputDirectory>
+                                                       <resources>
+                                                               <resource>
+                                                                       <directory>src/main/resources/etc/bvc-extensions</directory>
+                                                                       <includes>
+                                                                               <include>feature_config_template.cfg</include>
+                                                                               <include>feature_custom.install</include>
+                                                                       </includes>
+                                                                       <filtering>true</filtering>
+                                                               </resource>
+                                                       </resources>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    
+    <dependency>
+      <groupId>org.openecomp.policy.drools-pdp</groupId>
+      <artifactId>policy-core</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.openecomp.policy.drools-pdp</groupId>
+      <artifactId>policy-endpoints</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+
+       <dependency>
+               <groupId>org.eclipse.jetty</groupId>
+               <artifactId>jetty-server</artifactId>
+               <version>${jetty.version}</version>
+       </dependency>
+
+       <dependency>
+               <groupId>org.eclipse.jetty</groupId>
+               <artifactId>jetty-servlet</artifactId>
+               <version>${jetty.version}</version>
+       </dependency>
+                       
+       <dependency>
+               <groupId>org.glassfish.jersey.core</groupId>
+               <artifactId>jersey-server</artifactId>
+               <version>${jersey.version}</version>
+       </dependency>
+       
+       <dependency>
+               <groupId>org.glassfish.jersey.containers</groupId>
+               <artifactId>jersey-container-servlet-core</artifactId>
+               <version>${jersey.version}</version>
+       </dependency>
+       
+       <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-json-jackson</artifactId>
+        <version>${jersey.version}</version>
+    </dependency>
+    
+       <dependency>
+               <groupId>org.glassfish.jersey.containers</groupId>
+               <artifactId>jersey-container-jetty-http</artifactId>
+               <version>${jersey.version}</version>
+               <exclusions>
+                       <exclusion>
+                               <groupId>org.eclipse.jetty</groupId>
+                               <artifactId>jetty-util</artifactId>
+                       </exclusion>
+               </exclusions>
+       </dependency>
+       
+       <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
+        <version>${jackson.version}</version>
+       </dependency>
+       
+       <dependency>
+         <groupId>com.fasterxml.jackson.datatype</groupId>
+         <artifactId>jackson-datatype-jsr310</artifactId>
+         <version>${jackson.version}</version>
+       </dependency> 
+       
+       <dependency>
+           <groupId>com.fasterxml.jackson.core</groupId>
+           <artifactId>jackson-annotations</artifactId>
+           <version>${jackson.version}</version>
+       </dependency>    
+       
+       <dependency>
+        <groupId>com.google.code.gson</groupId>
+        <artifactId>gson</artifactId>
+        <version>${gson.version}</version>
+       </dependency>
+       
+       <dependency>
+         <groupId>com.fatboyindustrial.gson-javatime-serialisers</groupId>
+         <artifactId>gson-javatime-serialisers</artifactId>
+         <version>1.1.1</version>
+       </dependency>
+       
+       <dependency>
+               <groupId>org.apache.commons</groupId>
+               <artifactId>commons-collections4</artifactId>
+               <version>4.1</version>
+       </dependency>
+       
+       <!-- This entry is necessary to support import "org.apache.commons.lang3.time.DateUtils" 
+                reference in StandbyStateManagementTest.java -->
+       <dependency>
+               <groupId>org.apache.commons</groupId>
+               <artifactId>commons-lang3</artifactId>
+               <version>3.4</version>
+       </dependency>
+    
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>1.2.17</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.11</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+</project>
diff --git a/policy-management/src/assembly/assemble_zip.xml b/policy-management/src/assembly/assemble_zip.xml
new file mode 100644 (file)
index 0000000..85a1dbf
--- /dev/null
@@ -0,0 +1,85 @@
+<!--
+  ============LICENSE_START=======================================================
+  policy-management
+  ================================================================================
+  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=========================================================
+  -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+       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>
+       <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</outputDirectory>
+                       <includes>
+                               <include>policy-management-${project.version}.jar</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>target/assembly/</directory>
+                       <outputDirectory>.</outputDirectory>
+                       <excludes>
+                       </excludes>
+               </fileSet>
+               <fileSet>
+                       <directory>.</directory>
+                       <outputDirectory>lib</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>
+                       <outputDirectory>config</outputDirectory>
+               </fileSet>
+       </fileSets>
+
+</assembly>
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java
new file mode 100644 (file)
index 0000000..72f8e0b
--- /dev/null
@@ -0,0 +1,170 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.controller;
+
+import java.util.List;
+
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.properties.Lockable;
+import org.openecomp.policy.drools.properties.Startable;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration;
+
+/**
+ * Drools Controller is the abstractions that wraps the
+ * drools layer (policy-core)
+ */
+public interface DroolsController extends Startable, Lockable {        
+       
+       /**
+        * No Group ID identifier
+        */
+       public static final String NO_GROUP_ID = "NO-GROUP-ID";
+
+       /**
+        * No Artifact ID identifier
+        */
+       public static final String NO_ARTIFACT_ID = "NO-ARTIFACT-ID";
+       
+       /**
+        * No version identifier
+        */
+       public static final String NO_VERSION = "NO-VERSION";
+       
+       /**
+        * get group id
+        * @return group id
+        */
+       public String getGroupId();
+       
+       /**
+        * get artifact id
+        * @return artifact id
+        */     
+       public String getArtifactId();
+       
+       /**
+        * get version
+        * @return version
+        */
+       public String getVersion();
+       
+
+       /**
+        * return the policy session names
+        * 
+        * @return policy session
+        */
+       public List<String> getSessionNames();
+       
+       /**
+        * offers an event to this controller for processing
+        * 
+        * @param topic topic associated with the event
+        * @param event the event
+        * 
+        * @return true if the operation was successful
+        */
+       public boolean offer(String topic, String event);
+       
+       /**
+        * delivers "event" to "sink"
+        * 
+        * @param sink destination
+        * @param event 
+        * @return true if successful, false if a failure has occurred.
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        * @throws IllegalStateException when the engine is in a state where
+        *         this operation is not permitted (ie. locked or stopped).
+        * @throws UnsupportedOperationException when the engine cannot deliver due
+        *         to the functionality missing (ie. communication infrastructure
+        *         not supported.
+        */
+       public boolean deliver(TopicSink sink, Object event)
+                       throws IllegalArgumentException, IllegalStateException, 
+                          UnsupportedOperationException;
+       
+       /**
+        * 
+        * @return the most recent received events
+        */
+       public Object[] getRecentSourceEvents();
+
+       /**
+        * 
+        * @return the most recent delivered events 
+        */
+       public String[] getRecentSinkEvents();
+       
+       /**
+        * Supports this encoder?
+        * 
+        * @param encodedObject
+        * @return
+        */
+       public boolean ownsCoder(Class<? extends Object> coderClass, int modelHash) throws IllegalStateException;
+       
+       /**
+        * fetches a class from the model
+        * 
+        * @param className the class to fetch
+        * @return the actual class object, or null if not found
+        */
+       public Class<?> fetchModelClass(String className) throws IllegalArgumentException;
+       
+       /**
+        * is this controller Smart?
+        */
+       public boolean isBrained();
+       
+       /**
+        * update the new version of the maven jar rules file
+        * 
+        * @param newGroupId - new group id
+        * @param newArtifactId - new artifact id
+        * @param newVersion - new version
+        * @param decoderConfigurations - decoder configurations
+        * @param encoderConfigurations - encoder configurations
+        * 
+        * @throws Exception from within drools libraries
+        * @throws LinkageError from within drools libraries
+        * @throws ArgumentException bad parameter passed in
+        */
+       public void updateToVersion(String newGroupId, String newArtifactId, String newVersion,
+                       List<TopicCoderFilterConfiguration> decoderConfigurations,
+                       List<TopicCoderFilterConfiguration> encoderConfigurations)
+       throws IllegalArgumentException, LinkageError, Exception;
+       
+       
+       /**
+        * halts and permanently releases all resources
+        * @throws IllegalStateException
+        */
+       public void halt() throws IllegalStateException;
+       
+       /**
+        * Factory to track and manage drools controllers
+        */
+       public static final DroolsControllerFactory factory = 
+                                                                       new IndexedDroolsControllerFactory();
+
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsControllerFactory.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsControllerFactory.java
new file mode 100644 (file)
index 0000000..d94e773
--- /dev/null
@@ -0,0 +1,540 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.controller;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.controller.internal.MavenDroolsController;
+import org.openecomp.policy.drools.controller.internal.NullDroolsController;
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.Topic.CommInfrastructure;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.event.comm.TopicSource;
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+import org.openecomp.policy.drools.protocol.coders.JsonProtocolFilter;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomGsonCoder;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomJacksonCoder;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.PotentialCoderFilter;
+import org.openecomp.policy.drools.utils.Pair;
+
+/**
+ * Drools Controller Factory to manage controller creation, destruction,
+ * and retrieval for management interfaces
+ */
+public interface DroolsControllerFactory {
+       
+       /**
+        * Constructs a Drools Controller based on properties
+        * 
+        * @param properties properties containing initialization parameters
+        * @param eventSources list of event sources
+        * @param eventSinks list of event sinks
+        * 
+        * @return the instantiated Drools Controller
+        * @throws IllegalArgumentException with invalid parameters
+        * @throws LinkageError Failure to link rules and models in Drools Libraries
+        * @throws Exception Exception from Drools Libraries
+        */
+       public DroolsController build(Properties properties,
+                                                                 List<? extends TopicSource> eventSources, 
+                                                                 List<? extends TopicSink> eventSinks)
+                       throws IllegalArgumentException, LinkageError, Exception;
+       
+       /**
+        * Explicit construction of a Drools Controller
+        * 
+        * @param groupId maven group id of drools artifact
+        * @param artifactId maven artifact id of drools artifact
+        * @param version maven version id of drools artifact
+        * @param decoderConfigurations list of decoder configurations
+        * @param encoderConfigurations list of encoder configurations
+        * 
+        * @return the instantiated Drools Controller
+        * @throws IllegalArgumentException with invalid parameters
+        * @throws LinkageError Failure to link rules and models in Drools Libraries
+        * @throws Exception Exception from Drools Libraries
+        */
+       public DroolsController build(String groupId, 
+                                                                 String artifactId, 
+                                                                 String version,
+                                                                 List<TopicCoderFilterConfiguration> decoderConfigurations,
+                                                                 List<TopicCoderFilterConfiguration> encoderConfigurations)
+                       throws IllegalArgumentException, LinkageError, Exception;
+       
+       /**
+        * Releases the Drools Controller from operation
+        * 
+        * @param controller the Drools Controller to shut down
+        */
+       public void shutdown(DroolsController controller);
+       
+       /**
+        * Disables all Drools Controllers from operation
+        */
+       public void shutdown();
+       
+       /**
+        * Destroys and releases resources for a Drools Controller
+        * 
+        * @param controller the Drools Controller to destroy
+        */
+       public void destroy(DroolsController controller);
+       
+       /**
+        * Destroys all Drools Controllers
+        */
+       public void destroy();
+       
+       /**
+        * Gets the Drools Controller associated with the maven group 
+        * and artifact id
+        * 
+        * @param groupId maven group id of drools artifact
+        * @param artifactId maven artifact id of drools artifact
+        * @param version maven version id of drools artifact
+        * 
+        * @return the Drools Controller
+        * @throws IllegalArgumentException with invalid parameters
+        */
+       public DroolsController get(String groupId, 
+                                                           String artifactId,
+                                                               String version)
+                       throws IllegalArgumentException;
+
+       /**
+        * returns the current inventory of Drools Controllers
+        * 
+        * @return a list of Drools Controllers
+        */
+       public List<DroolsController> inventory();
+}
+
+/* ---------------- implementation -----------------*/
+
+/**
+ * Factory of Drools Controllers indexed by the Maven coordinates 
+ */
+class IndexedDroolsControllerFactory implements DroolsControllerFactory {
+       
+       /**
+        * logger 
+        */
+       private static Logger logger = FlexLogger.getLogger(MavenDroolsController.class);
+       
+       /**
+        * Policy Controller Name Index
+        */
+       protected HashMap<String, DroolsController> droolsControllers =
+                                                                       new HashMap<String, DroolsController>();
+       
+       /**
+        * Null Drools Controller
+        */
+       protected NullDroolsController nullDroolsController = new NullDroolsController();
+       
+       
+       public IndexedDroolsControllerFactory() {
+               
+               /* Add a NULL controller which will always be present in the hash */
+               
+               DroolsController controller = new NullDroolsController();
+               String controllerId = controller.getGroupId() + ":" + controller.getArtifactId();
+
+               synchronized(this) {
+                       droolsControllers.put(controllerId, controller);
+               }       
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DroolsController build(Properties properties,
+                                                                 List<? extends TopicSource> eventSources,
+                                                                 List<? extends TopicSink> eventSinks) 
+                       throws IllegalArgumentException, LinkageError, Exception {
+               
+               String groupId = properties.getProperty(PolicyProperties.RULES_GROUPID);
+               if (groupId == null || groupId.isEmpty())
+                       groupId =  DroolsController.NO_GROUP_ID;        
+       
+               String artifactId = properties.getProperty(PolicyProperties.RULES_ARTIFACTID);
+               if (artifactId == null || artifactId.isEmpty())
+                       artifactId =  DroolsController.NO_ARTIFACT_ID;
+               
+               String version = properties.getProperty(PolicyProperties.RULES_VERSION);
+               if (version == null || version.isEmpty())
+                       version =  DroolsController.NO_VERSION;
+               
+               List<TopicCoderFilterConfiguration> 
+                       topics2DecodedClasses2Filters = codersAndFilters(properties, eventSources);
+               
+               List<TopicCoderFilterConfiguration> 
+                       topics2EncodedClasses2Filters = codersAndFilters(properties, eventSinks);
+               
+               return this.build(groupId, artifactId, version, 
+                                                 topics2DecodedClasses2Filters,
+                                         topics2EncodedClasses2Filters);
+       }
+
+       /**
+        * find out decoder classes and filters
+        * 
+        * @param properties properties with information about decoders
+        * @param topicEntities topic sources
+        * @return list of topics, each with associated decoder classes, each
+        *         with a list of associated filters
+        * @throws IllegalArgumentException invalid input data
+        */
+       protected List<TopicCoderFilterConfiguration> codersAndFilters
+                                       (Properties properties, List<? extends Topic> topicEntities) 
+                               throws IllegalArgumentException {
+               
+               String PROPERTY_TOPIC_ENTITY_PREFIX;
+               
+               List<TopicCoderFilterConfiguration>
+                       topics2DecodedClasses2Filters =
+                                       new ArrayList<TopicCoderFilterConfiguration>();
+               
+               if (topicEntities.isEmpty())
+                       return topics2DecodedClasses2Filters;
+                               
+               for (Topic topic: topicEntities) {
+                       
+                       /* source or sink ? ueb or dmaap? */
+                       boolean isSource = (topic instanceof TopicSource);
+                       CommInfrastructure commInfra = topic.getTopicCommInfrastructure();
+                       if (commInfra == CommInfrastructure.UEB) {
+                               if (isSource) {
+                                       PROPERTY_TOPIC_ENTITY_PREFIX = PolicyProperties.PROPERTY_UEB_SOURCE_TOPICS + ".";
+                               } else {
+                                       PROPERTY_TOPIC_ENTITY_PREFIX = PolicyProperties.PROPERTY_UEB_SINK_TOPICS + ".";
+                               }
+                       } else if (commInfra == CommInfrastructure.DMAAP) {
+                               if (isSource) {
+                                       PROPERTY_TOPIC_ENTITY_PREFIX = PolicyProperties.PROPERTY_DMAAP_SOURCE_TOPICS + ".";
+                               } else {
+                                       PROPERTY_TOPIC_ENTITY_PREFIX = PolicyProperties.PROPERTY_DMAAP_SINK_TOPICS + ".";
+                               }
+                       } else {
+                               throw new IllegalArgumentException("Invalid Communication Infrastructure: " + commInfra);
+                       }
+                       
+                       // 1. first the topic
+                       
+                       String aTopic = topic.getTopic();
+                       
+                       // 2.  check if there is a custom decoder for this topic that the user prefers to use
+                       //     instead of the ones provided in the platform
+
+                       String customGson = properties.getProperty
+                                       (PROPERTY_TOPIC_ENTITY_PREFIX + 
+                                        aTopic + 
+                                        PolicyProperties.PROPERTY_TOPIC_EVENTS_CUSTOM_MODEL_CODER_GSON_SUFFIX);
+                       
+                       CustomGsonCoder customGsonCoder = null;
+                       if (customGson != null && !customGson.isEmpty()) {
+                               try {
+                                       customGsonCoder =  new CustomGsonCoder(customGson);
+                               } catch (IllegalArgumentException e) {
+                                       e.printStackTrace();
+                               }
+                       }
+                       
+                       String customJackson = properties.getProperty
+                                       (PROPERTY_TOPIC_ENTITY_PREFIX + 
+                                        aTopic + 
+                                        PolicyProperties.PROPERTY_TOPIC_EVENTS_CUSTOM_MODEL_CODER_JACKSON_SUFFIX);
+                       
+                       CustomJacksonCoder customJacksonCoder = null;
+                       if (customJackson != null && !customJackson.isEmpty()) {
+                               try {
+                                       customJacksonCoder =  new CustomJacksonCoder(customJackson);
+                               } catch (IllegalArgumentException e) {
+                                       e.printStackTrace();
+                               }
+                       }
+                       
+                       // 3. second the list of classes associated with each topic
+                       
+                       String eventClasses = 
+                                       properties.getProperty(PROPERTY_TOPIC_ENTITY_PREFIX + aTopic + PolicyProperties.PROPERTY_TOPIC_EVENTS_SUFFIX);
+                       
+                       if (eventClasses == null || eventClasses.isEmpty()) {
+                               // TODO warn
+                               continue;
+                       }
+                       
+                       List<PotentialCoderFilter> classes2Filters = new ArrayList<PotentialCoderFilter>();
+                       
+                       List<String> aTopicClasses = 
+                                       new ArrayList<String>(Arrays.asList(eventClasses.split("\\s*,\\s*")));
+                       
+                       for (String aClass: aTopicClasses) {
+                               
+                               
+                               // 4. third, for each coder class, get the list of field filters
+                               
+                               String filter = properties.getProperty
+                                               (PROPERTY_TOPIC_ENTITY_PREFIX + 
+                                                aTopic + 
+                                                PolicyProperties.PROPERTY_TOPIC_EVENTS_SUFFIX + 
+                                                "." + aClass + 
+                                                PolicyProperties.PROPERTY_TOPIC_EVENTS_FILTER_SUFFIX);
+                               
+                               List<Pair<String,String>> filters = new ArrayList<Pair<String,String>>();
+                               
+                               if (filter == null || filter.isEmpty()) {
+                                       // 4. topic -> class -> with no filters
+                                       
+                                       JsonProtocolFilter protocolFilter = JsonProtocolFilter.fromRawFilters(filters);
+                                       PotentialCoderFilter class2Filters = 
+                                                       new PotentialCoderFilter(aClass, protocolFilter);
+                                       classes2Filters.add(class2Filters);
+                                       continue;
+                               }
+                               
+                               // There are filters associated with the applicability of
+                               // this class for decoding.
+                               List<String> listOfFilters = 
+                                               new ArrayList<String>(Arrays.asList(filter.split("\\s*,\\s*")));
+                               
+                               for (String nameValue: listOfFilters) {
+                                       String fieldName;
+                                       String regexValue;
+                                       
+                                       String[] nameValueSplit = nameValue.split("\\s*=\\s*");
+                                       if (nameValueSplit.length <= 0 || nameValueSplit.length > 2) {
+                                               // TODO warn
+                                               // skip
+                                               continue;
+                                       }
+                                       
+                                       if (nameValueSplit.length == 2) {
+                                               fieldName = nameValueSplit[0];
+                                               regexValue = nameValueSplit[1];
+                                       } else if (nameValueSplit.length == 1) {
+                                               fieldName = nameValueSplit[0];
+                                               regexValue = null;
+                                       } else {
+                                               // unreachable 
+                                               continue;
+                                       }
+                                       
+                                       filters.add(new Pair<String,String>(fieldName, regexValue));
+                               }
+                               
+                               JsonProtocolFilter protocolFilter = JsonProtocolFilter.fromRawFilters(filters);
+                               PotentialCoderFilter class2Filters = 
+                                               new PotentialCoderFilter(aClass, protocolFilter);
+                               classes2Filters.add(class2Filters);
+                       }
+                       
+                       TopicCoderFilterConfiguration topic2Classes2Filters =
+                                               new TopicCoderFilterConfiguration(aTopic,classes2Filters, customGsonCoder, customJacksonCoder);
+                       topics2DecodedClasses2Filters.add(topic2Classes2Filters);
+               }
+               
+               return topics2DecodedClasses2Filters;
+       }
+
+       /**
+        * {@inheritDoc}
+        * @param decoderConfiguration 
+        */
+       @Override
+       public DroolsController build(String newGroupId, 
+                                                                 String newArtifactId, 
+                                             String newVersion, 
+                                             List<TopicCoderFilterConfiguration> decoderConfigurations,
+                                             List<TopicCoderFilterConfiguration> encoderConfigurations)
+                       throws IllegalArgumentException, LinkageError, Exception {
+               
+               if (newGroupId == null || newArtifactId == null || newVersion == null ||
+                       newGroupId.isEmpty() || newArtifactId.isEmpty() || newVersion.isEmpty()) {
+                               throw new IllegalArgumentException("Missing maven coordinates: " + 
+                                                                          newGroupId + ":" + newArtifactId + ":" + 
+                                                                          newVersion);
+               }
+               
+               String controllerId = newGroupId + ":" + newArtifactId;
+               DroolsController controllerCopy = null;
+               synchronized (this) {
+                       /*
+                        * The Null Drools Controller for no maven coordinates is always here
+                        * so when no coordinates present, this is the return point
+                        * 
+                        * assert (controllerCopy instanceof NullDroolsController)
+                        */
+                       if (droolsControllers.containsKey(controllerId)) {
+                               controllerCopy = droolsControllers.get(controllerId);
+                               if (controllerCopy.getVersion().equalsIgnoreCase(newVersion)) {
+                                       return controllerCopy;
+                               }
+                       }       
+               }
+               
+               if (controllerCopy != null) {
+                       /* 
+                        * a controller keyed by group id + artifact id exists
+                        * but with different version => version upgrade/downgrade 
+                        */
+                       
+                       controllerCopy.updateToVersion(newGroupId, newArtifactId, newVersion, 
+                                                              decoderConfigurations, encoderConfigurations);
+                       
+                       return controllerCopy;                  
+               }
+               
+               /* new drools controller */
+               
+               DroolsController controller = new MavenDroolsController
+                                                                                               (newGroupId, newArtifactId, newVersion, 
+                                                                                            decoderConfigurations,
+                                                                                            encoderConfigurations);
+               
+               synchronized(this) {
+                       droolsControllers.put(controllerId, controller);
+               }
+
+               return controller;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy(DroolsController controller) throws IllegalArgumentException {
+               unmanage(controller);
+               controller.halt();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy() {
+               List<DroolsController> controllers = this.inventory();
+               for (DroolsController controller: controllers) {
+                       controller.halt();
+               }
+               
+               synchronized(this) {
+                       this.droolsControllers.clear();
+               }
+       }
+
+       /**
+        * unmanage the drools controller
+        * 
+        * @param controller
+        * @return
+        * @throws IllegalArgumentException
+        */
+       protected void unmanage(DroolsController controller) throws IllegalArgumentException {
+               if (controller == null) {
+                       throw new IllegalArgumentException("No controller provided");
+               }
+               
+               if (!controller.isBrained()) {  
+                       logger.info("Drools Controller is NOT OPERATIONAL - nothing to destroy");
+                       return;
+               }
+               
+               String controllerId = controller.getGroupId() + ":" + controller.getArtifactId();
+               synchronized(this) {
+                       if (!this.droolsControllers.containsKey(controllerId)) {
+                               return;
+                       }
+                       
+                       droolsControllers.remove(controllerId);
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown(DroolsController controller) throws IllegalArgumentException {
+               this.unmanage(controller);
+               controller.shutdown();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() {
+               List<DroolsController> controllers = this.inventory();
+               for (DroolsController controller: controllers) {
+                       controller.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.droolsControllers.clear();
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DroolsController get(String groupId, 
+                                           String artifactId, 
+                                           String version)
+                       throws IllegalArgumentException, IllegalStateException {
+               
+               if (groupId == null || artifactId == null ||
+                       groupId.isEmpty() || artifactId.isEmpty()) {
+                       throw new IllegalArgumentException("Missing maven coordinates: " + 
+                                                                              groupId + ":" + artifactId);
+               }
+               
+               String controllerId = groupId + ":" + artifactId;
+               
+               synchronized(this) {
+                       if (this.droolsControllers.containsKey(controllerId)) {
+                               return droolsControllers.get(controllerId);
+                       } else {
+                               throw new IllegalStateException("DroolController for " + 
+                                                                                               controllerId + " not found");
+                       }
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<DroolsController> inventory() {
+                List<DroolsController> controllers = 
+                                new ArrayList<DroolsController>(this.droolsControllers.values());
+                return controllers;
+       }
+       
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java
new file mode 100644 (file)
index 0000000..2c5708d
--- /dev/null
@@ -0,0 +1,718 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.controller.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.collections4.queue.CircularFifoQueue;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.core.PolicyContainer;
+import org.openecomp.policy.drools.core.PolicySession;
+import org.openecomp.policy.drools.core.jmx.PdpJmx;
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.protocol.coders.EventProtocolCoder;
+import org.openecomp.policy.drools.protocol.coders.JsonProtocolFilter;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomGsonCoder;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomJacksonCoder;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.PotentialCoderFilter;
+import org.openecomp.policy.drools.utils.ReflectionUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Maven-based Drools Controller that interacts with the 
+ * policy-core PolicyContainer and PolicySession to manage
+ * Drools containers instantiated using Maven.
+ */
+public class MavenDroolsController implements DroolsController {
+       
+       /**
+        * logger 
+        */
+       private static Logger  logger = FlexLogger.getLogger(MavenDroolsController.class);
+       
+       /**
+        * Policy Container, the access object to the policy-core layer
+        */
+       @JsonIgnore
+       protected final PolicyContainer policyContainer;
+       
+       /**
+        * alive status of this drools controller, 
+        * reflects invocation of start()/stop() only
+        */
+       protected volatile boolean alive = false;
+       
+       /**
+        * locked status of this drools controller,
+        * reflects if i/o drools related operations are permitted,
+        * more specifically: offer() and deliver().
+        * It does not affect the ability to start and stop 
+        * underlying drools infrastructure
+        */
+       protected volatile boolean locked = false;
+       
+       /**
+        * list of topics, each with associated decoder classes, each
+        * with a list of associated filters.
+        */
+       protected List<TopicCoderFilterConfiguration> decoderConfigurations;
+       
+       /**
+        * list of topics, each with associated encoder classes, each
+        * with a list of associated filters.
+        */
+       protected List<TopicCoderFilterConfiguration> encoderConfigurations;
+       
+       /**
+        * recent source events processed
+        */
+       protected final CircularFifoQueue<Object> recentSourceEvents = new CircularFifoQueue<Object>(10);
+       
+       /**
+        * recent sink events processed
+        */
+       protected final CircularFifoQueue<String> recentSinkEvents = new CircularFifoQueue<String>(10);
+       
+       /**
+        * original Drools Model/Rules classloader hash
+        */
+       protected int modelClassLoaderHash;
+
+       /**
+        * Expanded version of the constructor 
+        * 
+        * @param groupId maven group id
+        * @param artifactId maven artifact id
+        * @param version maven version
+        * @param decoderConfiguration list of topic -> decoders -> filters mapping
+        * @param encoderConfiguration list of topic -> encoders -> filters mapping
+        * 
+        * @throws IllegalArgumentException invalid arguments passed in
+        */
+       public MavenDroolsController(String groupId, 
+                                                                String artifactId, 
+                                                                String version,
+                                                                List<TopicCoderFilterConfiguration> decoderConfigurations,
+                                                                List<TopicCoderFilterConfiguration> encoderConfigurations) 
+                  throws IllegalArgumentException {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("DROOLS CONTROLLER: instantiation " +  this + 
+                                           " -> {" + groupId + ":" + artifactId + ":" + version + "}");
+               
+               if (groupId == null || artifactId == null || version == null ||
+                       groupId.isEmpty() || artifactId.isEmpty() || version.isEmpty()) {
+                       throw new IllegalArgumentException("Missing maven coordinates: " + 
+                                                                  groupId + ":" + artifactId + ":" + 
+                                                                  version);
+               }
+               
+               this.policyContainer= new PolicyContainer(groupId, artifactId, version);
+               this.init(decoderConfigurations, encoderConfigurations);
+               
+               if (logger.isInfoEnabled())
+                       logger.info("DROOLS CONTROLLER: instantiation completed " +  this);
+       }
+       
+       /**
+        * init encoding/decoding configuration
+        * @param decoderConfiguration list of topic -> decoders -> filters mapping
+        * @param encoderConfiguration list of topic -> encoders -> filters mapping
+        */
+       protected void init(List<TopicCoderFilterConfiguration> decoderConfigurations,
+                                   List<TopicCoderFilterConfiguration> encoderConfigurations) {
+               
+               this.decoderConfigurations = decoderConfigurations;
+               this.encoderConfigurations = encoderConfigurations;
+               
+               this.initCoders(decoderConfigurations, true);
+               this.initCoders(encoderConfigurations, false);
+               
+               this.modelClassLoaderHash = this.policyContainer.getClassLoader().hashCode();           
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void updateToVersion(String newGroupId, String newArtifactId, String newVersion,
+                                           List<TopicCoderFilterConfiguration> decoderConfigurations,
+                                           List<TopicCoderFilterConfiguration> encoderConfigurations) 
+               throws IllegalArgumentException, LinkageError, Exception {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("UPDATE-TO-VERSION: " +  this + " -> {" + newGroupId + ":" + newArtifactId + ":" + newVersion + "}");
+               
+               if (newGroupId == null || newArtifactId == null || newVersion == null ||
+                       newGroupId.isEmpty() || newArtifactId.isEmpty() || newVersion.isEmpty()) {
+                               throw new IllegalArgumentException("Missing maven coordinates: " + 
+                                                                          newGroupId + ":" + newArtifactId + ":" + 
+                                                                          newVersion);
+               }
+               
+               if (newGroupId.equalsIgnoreCase(DroolsController.NO_GROUP_ID) || 
+                       newArtifactId.equalsIgnoreCase(DroolsController.NO_ARTIFACT_ID) || 
+                       newVersion.equalsIgnoreCase(DroolsController.NO_VERSION)) {
+                               throw new IllegalArgumentException("BRAINLESS maven coordinates provided: " + 
+                                                                          newGroupId + ":" + newArtifactId + ":" + 
+                                                                          newVersion);
+               }
+               
+               if (newGroupId.equalsIgnoreCase(this.getGroupId()) && 
+                       newArtifactId.equalsIgnoreCase(this.getArtifactId()) &&
+                       newVersion.equalsIgnoreCase(this.getVersion())) {
+                               logger.warn("Al in the right version: " + newGroupId + ":" + 
+                                       newArtifactId + ":" +  newVersion + " vs. " + this);
+                               return;
+               }
+               
+               if (!newGroupId.equalsIgnoreCase(this.getGroupId()) || 
+                       !newArtifactId.equalsIgnoreCase(this.getArtifactId())) {
+                               throw new IllegalArgumentException("Group ID and Artifact ID maven coordinates must be identical for the upgrade: " + 
+                                                                              newGroupId + ":" + newArtifactId + ":" + 
+                                                                              newVersion + " vs. " + this);
+               }
+
+               /* upgrade */
+               String messages = this.policyContainer.updateToVersion(newVersion);
+               if (logger.isWarnEnabled())
+                       logger.warn(this + "UPGRADE results: " + messages);
+               
+               /*
+                * If all sucessful (can load new container), now we can remove all coders from previous sessions
+                */
+               this.removeCoders();
+               
+               /*
+                * add the new coders
+                */
+               this.init(decoderConfigurations, encoderConfigurations);
+               
+               if (logger.isInfoEnabled())
+                       logger.info("UPDATE-TO-VERSION: completed " +  this);
+       }
+
+       /**
+        * initialize decoders for all the topics supported by this controller
+        * Note this is critical to be done after the Policy Container is
+        * instantiated to be able to fetch the corresponding classes.
+        * 
+        * @param decoderConfiguration list of topic -> decoders -> filters mapping
+        */
+       protected void initCoders(List<TopicCoderFilterConfiguration> coderConfigurations, 
+                                         boolean decoder) 
+                 throws IllegalArgumentException {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("INIT-CODERS: " +  this);
+               
+               if (coderConfigurations == null) {
+                       return;
+               }
+                       
+
+               for (TopicCoderFilterConfiguration coderConfig: coderConfigurations) {
+                       String topic = coderConfig.getTopic();
+                       
+                       CustomGsonCoder customGsonCoder = coderConfig.getCustomGsonCoder();
+                       if (coderConfig.getCustomGsonCoder() != null && 
+                               coderConfig.getCustomGsonCoder().getClassContainer() != null &&
+                               !coderConfig.getCustomGsonCoder().getClassContainer().isEmpty()) {
+                                       
+                               String customGsonCoderClass = coderConfig.getCustomGsonCoder().getClassContainer();
+                               if (!ReflectionUtil.isClass(this.policyContainer.getClassLoader(),
+                                                                  customGsonCoderClass)) {
+                                       logger.error(customGsonCoderClass + " cannot be retrieved");
+                                       throw new IllegalArgumentException(customGsonCoderClass + " cannot be retrieved");
+                               } else {
+                                       if (logger.isInfoEnabled())
+                                               logger.info("CLASS FETCHED " + customGsonCoderClass);
+                               }
+                       }
+                       
+                       CustomJacksonCoder customJacksonCoder = coderConfig.getCustomJacksonCoder();
+                       if (coderConfig.getCustomJacksonCoder() != null && 
+                               coderConfig.getCustomJacksonCoder().getClassContainer() != null &&
+                               !coderConfig.getCustomJacksonCoder().getClassContainer().isEmpty()) {
+                               
+                               String customJacksonCoderClass = coderConfig.getCustomJacksonCoder().getClassContainer();
+                               if (!ReflectionUtil.isClass(this.policyContainer.getClassLoader(),
+                                                                  customJacksonCoderClass)) {
+                                       logger.error(customJacksonCoderClass + " cannot be retrieved");
+                                       throw new IllegalArgumentException(customJacksonCoderClass + " cannot be retrieved");
+                               } else {
+                                       if (logger.isInfoEnabled())
+                                               logger.info("CLASS FETCHED " + customJacksonCoderClass);
+                               }
+                       }       
+                       
+                       List<PotentialCoderFilter> coderFilters = coderConfig.getCoderFilters();
+                       if (coderFilters == null || coderFilters.isEmpty()) {
+                               continue;
+                       }
+                       
+                       for (PotentialCoderFilter coderFilter : coderFilters) {
+                               String potentialCodedClass = coderFilter.getCodedClass();
+                               JsonProtocolFilter protocolFilter = coderFilter.getFilter();
+                               
+                               if (!ReflectionUtil.isClass(this.policyContainer.getClassLoader(), 
+                                                                  potentialCodedClass)) {
+                                       logger.error(potentialCodedClass + " cannot be retrieved");
+                                       throw new IllegalArgumentException(potentialCodedClass + " cannot be retrieved");
+                               } else {
+                                       if (logger.isInfoEnabled())
+                                               logger.info("CLASS FETCHED " + potentialCodedClass);
+                               }                       
+                               
+                               if (decoder)
+                                       EventProtocolCoder.manager.addDecoder(this.getGroupId(), this.getArtifactId(), 
+                                                                                     topic, potentialCodedClass, protocolFilter,
+                                                                                     customGsonCoder,
+                                                                                     customJacksonCoder,
+                                                                                     this.policyContainer.getClassLoader().hashCode());
+                               else
+                                       EventProtocolCoder.manager.addEncoder(this.getGroupId(), this.getArtifactId(), 
+                                                          topic, potentialCodedClass, protocolFilter,
+                                                                                     customGsonCoder,
+                                                                                     customJacksonCoder,
+                                                                                     this.policyContainer.getClassLoader().hashCode());
+                       }
+               }
+       }
+       
+
+       /**
+        * remove decoders.
+        */
+       protected void removeDecoders() 
+                 throws IllegalArgumentException {
+               if (logger.isInfoEnabled())
+                       logger.info("REMOVE-DECODERS: " +  this);
+               
+               if (this.decoderConfigurations == null) {
+                       return;
+               }
+                       
+
+               for (TopicCoderFilterConfiguration coderConfig: decoderConfigurations) {
+                       String topic = coderConfig.getTopic();                                                          
+                       EventProtocolCoder.manager.removeDecoders
+                                               (this.getGroupId(), this.getArtifactId(), topic);
+               }
+       }
+       
+       /**
+        * remove decoders.
+        */
+       protected void removeEncoders() 
+                 throws IllegalArgumentException {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("REMOVE-ENCODERS: " +  this);
+               
+               if (this.encoderConfigurations == null)
+                       return;
+                       
+
+               for (TopicCoderFilterConfiguration coderConfig: encoderConfigurations) {
+                       String topic = coderConfig.getTopic();                                                          
+                       EventProtocolCoder.manager.removeEncoders
+                                               (this.getGroupId(), this.getArtifactId(), topic);
+               }
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean ownsCoder(Class<? extends Object> coderClass, int modelHash) throws IllegalStateException {
+               if (!ReflectionUtil.isClass
+                               (this.policyContainer.getClassLoader(), coderClass.getCanonicalName())) {
+                       logger.error(this + coderClass.getCanonicalName() + " cannot be retrieved. ");
+                       return false;
+               }
+               
+               if (modelHash == this.modelClassLoaderHash) {
+                       if (logger.isInfoEnabled())
+                               logger.info(coderClass.getCanonicalName() + 
+                                                   this + " class loader matches original drools controller rules classloader " +
+                                       coderClass.getClassLoader());
+                       return true;
+               } else {
+                       if (logger.isWarnEnabled())
+                               logger.warn(this + coderClass.getCanonicalName() + " class loaders don't match  " +
+                               coderClass.getClassLoader() + " vs " + 
+                                                   this.policyContainer.getClassLoader());
+                       return false;
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() {
+               
+               if (logger.isInfoEnabled())
+                       logger.info("START: " + this);
+               
+               synchronized (this) {                   
+                       if (this.alive)
+                               return true;
+                       
+                       this.alive = true;
+               }
+               
+               return this.policyContainer.start();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() {
+               
+               logger.info("STOP: " + this);
+               
+               synchronized (this) {
+                       if (!this.alive)
+                               return true;
+                       
+                       this.alive = false;
+               }
+               
+               return this.policyContainer.stop();
+       }
+
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+               
+               if (logger.isInfoEnabled())
+                       logger.info(this + "SHUTDOWN");
+               
+               try {
+                       this.stop();
+                       this.removeCoders();
+               } catch (Exception e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "stop", this.toString());
+               } finally {
+                       this.policyContainer.shutdown();
+               }
+
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void halt() throws IllegalStateException {
+               if (logger.isInfoEnabled())
+                       logger.info(this + "SHUTDOWN");
+               
+               try {
+                       this.stop();
+                       this.removeCoders();
+               } catch (Exception e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "halt", this.toString());
+               } finally {
+                       this.policyContainer.destroy();
+               }       
+       }
+       
+       /**
+        * removes this drools controllers and encoders and decoders from operation
+        */
+       protected void removeCoders() {
+               
+               if (logger.isInfoEnabled())
+                       logger.info(this + "REMOVE-CODERS");
+               
+               try {
+                       this.removeDecoders();
+               } catch (IllegalArgumentException e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "removeDecoders", this.toString());
+               }
+               
+               try {
+                       this.removeEncoders();
+               } catch (IllegalArgumentException e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "removeEncoders", this.toString());
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               return this.alive;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean offer(String topic, String event) {
+
+               if (logger.isInfoEnabled())
+                       logger.info("OFFER: " + topic + ":" + event + " INTO " + this);
+               
+               if (this.locked)
+                       return true;
+               
+               if (!this.alive)
+                       return true;
+               
+               // 0. Check if the policy container has any sessions
+               
+               if (this.policyContainer.getPolicySessions().size() <= 0) {
+                       // no sessions
+                       return true;
+               }
+               
+               // 1. Now, check if this topic has a decoder:
+               
+               if (!EventProtocolCoder.manager.isDecodingSupported(this.getGroupId(), 
+                                                                             this.getArtifactId(), 
+                                                                             topic)) {
+                       
+                       logger.warn("DECODING-UNSUPPORTED: " + ":" + this.getGroupId() + 
+                                                 ":" + this.getArtifactId() + ":" + topic + " IN " + this);
+                       return true;
+               }
+               
+               // 2. Decode
+               
+               Object anEvent;
+               try {
+                       anEvent = EventProtocolCoder.manager.decode(this.getGroupId(), 
+                                                                             this.getArtifactId(), 
+                                                                             topic, 
+                                                                             event);
+               } catch (Exception e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, 
+                                                  "DECODE:"+ this.getGroupId() + ":" + 
+                                                  this.getArtifactId() + ":" + topic + ":" + event, 
+                                                  this.toString());
+                       return true;
+               }
+               
+               synchronized(this.recentSourceEvents) {
+                       this.recentSourceEvents.add(anEvent);
+               }
+               
+               // increment event count for Nagios monitoring
+               PdpJmx.getInstance().updateOccured();  
+               
+               // Broadcast
+               
+               if (logger.isInfoEnabled())
+                       logger.info(this + "BROADCAST-INJECT of " + event + " FROM " + topic + " INTO " + this.policyContainer.getName());              
+               
+               if (!this.policyContainer.insertAll(anEvent))
+                       logger.warn(this + "Failed to inject into PolicyContainer " + this.getSessionNames());
+               
+               return true;
+       }       
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean deliver(TopicSink sink, Object event) 
+                       throws IllegalArgumentException, 
+                              IllegalStateException, 
+                          UnsupportedOperationException {
+               
+               if (logger.isInfoEnabled())
+                       logger.info(this + "DELIVER: " +  event + " FROM " + this + " TO " + sink);
+               
+               if (sink == null)
+                       throw new IllegalArgumentException
+                                               (this +  " invalid sink");
+               
+               if (event == null)
+                       throw new IllegalArgumentException
+                                               (this +  " invalid event");
+               
+               if (this.locked)
+                       throw new IllegalStateException
+                                                       (this +  " is locked");
+               
+               if (!this.alive)
+                       throw new IllegalStateException
+                                                       (this +  " is stopped");
+               
+               String json =
+                               EventProtocolCoder.manager.encode(sink.getTopic(), event, this);
+               
+               synchronized(this.recentSinkEvents) {
+                       this.recentSinkEvents.add(json);
+               }
+               
+               return sink.send(json);
+               
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getVersion() {
+               return this.policyContainer.getVersion();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getArtifactId() {
+               return this.policyContainer.getArtifactId();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getGroupId() {
+               return this.policyContainer.getGroupId();
+       }
+
+       /**
+        * @return the modelClassLoaderHash
+        */
+       public int getModelClassLoaderHash() {
+               return modelClassLoaderHash;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized boolean lock() {
+               logger.info("LOCK: " +  this);
+               
+               this.locked = true;
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized boolean unlock() {
+               logger.info("UNLOCK: " +  this);
+               
+               this.locked = false;
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isLocked() {
+               return this.locked;
+       }
+       
+       @Override
+       public List<String> getSessionNames() {
+               List<String> sessionNames = new ArrayList<String>();
+               try {
+                       for (PolicySession session: this.policyContainer.getPolicySessions()) {
+                               sessionNames.add(session.getFullName());
+                       }
+               } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                   "Can't retrieve POLICY-CORE sessions: " + e.getMessage(), 
+                                   this.toString());
+                       sessionNames.add(e.getMessage());
+               }
+               return sessionNames;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Class<?> fetchModelClass(String className) throws IllegalStateException {
+               Class<?> modelClass = 
+                       ReflectionUtil.fetchClass(this.policyContainer.getClassLoader(), className);
+               return modelClass;
+       }
+
+       /**
+        * @return the recentSourceEvents
+        */
+       @Override
+       public Object[] getRecentSourceEvents() {
+               synchronized(this.recentSourceEvents) {
+                       Object[] events = new Object[recentSourceEvents.size()];
+                       return recentSourceEvents.toArray(events);
+               }
+       }
+
+       /**
+        * @return the recentSinkEvents
+        */
+       @Override
+       public String[] getRecentSinkEvents() {
+               synchronized(this.recentSinkEvents) {
+                       String[] events = new String[recentSinkEvents.size()];
+                       return recentSinkEvents.toArray(events);
+               }
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isBrained() {
+               return true;
+       }
+       
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("MavenDroolsController [policyContainer=")
+                      .append((policyContainer != null) ? policyContainer.getName() : "NULL").append(":")
+                      .append(", alive=")
+                          .append(alive).append(", locked=").append(locked).append(", decoderConfigurations=")
+                          .append(decoderConfigurations).append(", encoderConfigurations=").append(encoderConfigurations)
+                          .append(", modelClassLoaderHash=").append(modelClassLoaderHash).append("]");
+               return builder.toString();
+       }
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java
new file mode 100644 (file)
index 0000000..f0c0f47
--- /dev/null
@@ -0,0 +1,219 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.controller.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration;
+
+/**
+ * no-op Drools Controller
+ */
+public class NullDroolsController implements DroolsController {
+       
+       /**
+        * empty cached events
+        */
+       protected static final String[] emptyRecentEvents = new String[0];      
+       
+       /**
+        * empty session names
+        */
+       protected static final List<String> emptySessionNames = new ArrayList<String>();
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() throws IllegalStateException {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() throws IllegalStateException {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+               return;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void halt() throws IllegalStateException {
+               return;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean lock() {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean unlock() {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isLocked() {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getGroupId() {
+               return NO_GROUP_ID;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getArtifactId() {
+               return NO_ARTIFACT_ID;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getVersion() {
+               return NO_VERSION;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<String> getSessionNames() {
+               return new ArrayList<String>();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean offer(String topic, String event) {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean deliver(TopicSink sink, Object event)
+                       throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException {
+               throw new IllegalArgumentException(this.getClass().getCanonicalName() + " invoked");
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Object[] getRecentSourceEvents() {
+               return NullDroolsController.emptyRecentEvents;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String[] getRecentSinkEvents() {
+               return NullDroolsController.emptyRecentEvents;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean ownsCoder(Class<? extends Object> coderClass, int modelHash) throws IllegalStateException {
+               throw new IllegalArgumentException(this.getClass().getCanonicalName() + " invoked");
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Class<?> fetchModelClass(String className) throws IllegalArgumentException {
+               throw new IllegalArgumentException(this.getClass().getCanonicalName() + " invoked");
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isBrained() {
+               return false;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("NullDroolsController []");
+               return builder.toString();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void updateToVersion(String newGroupId, String newArtifactId, String newVersion,
+                       List<TopicCoderFilterConfiguration> decoderConfigurations,
+                       List<TopicCoderFilterConfiguration> encoderConfigurations)
+                       throws IllegalArgumentException, LinkageError, Exception {
+               throw new IllegalArgumentException(this.getClass().getCanonicalName() + " invoked");
+       }
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/persistence/SystemPersistence.java b/policy-management/src/main/java/org/openecomp/policy/drools/persistence/SystemPersistence.java
new file mode 100644 (file)
index 0000000..6bb1185
--- /dev/null
@@ -0,0 +1,255 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Properties;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.drools.utils.PropertyUtil;
+
+public interface SystemPersistence {
+       
+       /**
+        * configuration directory
+        */
+       public static String CONFIG_DIR_NAME = "config";
+       
+       /**
+        * policy controllers suffix
+        */
+       public final static String CONTROLLER_SUFFIX_IDENTIFIER = "-controller";
+               
+       /**
+        * policy controller properties file suffix
+        */
+       public final static String PROPERTIES_FILE_CONTROLLER_SUFFIX = 
+                                                       CONTROLLER_SUFFIX_IDENTIFIER + ".properties"; 
+       
+       /**
+        * policy engine properties file name
+        */
+       public final static String PROPERTIES_FILE_ENGINE = "policy-engine.properties";
+       
+       
+       /**
+        * backs up a controller configuration.
+        * 
+        * @param controllerName the controller name
+        * @return true if the configuration is backed up
+        */
+       public boolean backupController(String controllerName);
+       
+       /**
+        * persists controller configuration
+        * 
+        * @param controllerName the controller name
+        * @param configuration object containing the configuration
+        * @return true if storage is succesful, false otherwise
+        * @throws IllegalArgumentException if the configuration cannot be handled by the persistence manager
+        */
+       public boolean storeController(String controllerName, Object configuration)
+               throws IllegalArgumentException;
+       
+       /**
+        * delete controller configuration
+        * 
+        * @param controllerName the controller name
+        * @return true if storage is succesful, false otherwise
+        */
+       public boolean deleteController(String controllerName);
+       
+       /**
+        * get controller properties
+        * 
+        * @param controllerName controller name
+        * @return properties for this controller
+        * @throws IllegalArgumentException if the controller name does not lead to a properties configuration
+        */
+       public Properties getControllerProperties(String controllerName)
+                       throws IllegalArgumentException;
+       
+       /**
+        * get properties by name
+        * 
+        * @param name 
+        * @return properties 
+        * @throws IllegalArgumentException if the name does not lead to a properties configuration
+        */
+       public Properties getProperties(String name) throws IllegalArgumentException;
+       
+       /**
+        * Persistence Manager.   For now it is a file-based properties management,
+        * In the future, it will probably be DB based, so manager implementation
+        * will change.
+        */
+       public static final SystemPersistence manager = new SystemPropertiesPersistence();
+}
+
+/** 
+ * Properties based Persistence
+ */
+class SystemPropertiesPersistence implements SystemPersistence {
+       
+       /**
+        * logger 
+        */
+       private static Logger logger = FlexLogger.getLogger(SystemPropertiesPersistence.class);
+       
+       /**
+        * backs up the properties-based controller configuration
+        * @param controllerName the controller name
+        * @return true if the configuration is backed up in disk or back up does not apply, false otherwise.
+        */
+       @Override
+       public boolean backupController(String controllerName) {
+               Path controllerPropertiesPath = 
+                               Paths.get(CONFIG_DIR_NAME, controllerName + PROPERTIES_FILE_CONTROLLER_SUFFIX);
+               
+               if (Files.exists(controllerPropertiesPath)) {
+                       try {
+                               logger.warn("There is an existing configuration file at " + 
+                                       controllerPropertiesPath.toString() +
+                                                   " with contents: " + Files.readAllBytes(controllerPropertiesPath));
+                               Path controllerPropertiesBakPath = 
+                                               Paths.get(CONFIG_DIR_NAME, controllerName + 
+                                  PROPERTIES_FILE_CONTROLLER_SUFFIX + ".bak");
+                               Files.copy(controllerPropertiesPath, 
+                                                  controllerPropertiesBakPath, StandardCopyOption.REPLACE_EXISTING);
+                       } catch (Exception e) {
+                               logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                   controllerName, "SystemPersistenceProperties");
+                       return false;
+                       }
+               } 
+               
+               return true;
+       }
+       
+       /**
+        * persists properties-based controller configuration and makes a backup if necessary
+        * @param controllerName the controller name
+        * @return true if the properties has been stored in disk, false otherwise
+        */
+       @Override
+       public boolean storeController(String controllerName, Object configuration) {
+               if (!(configuration instanceof Properties)) {
+                       throw new IllegalArgumentException("configuration must be of type properties to be handled by this manager");
+               }
+               
+               Properties properties = (Properties) configuration;
+               
+               Path controllerPropertiesPath = 
+                               Paths.get(CONFIG_DIR_NAME, controllerName + PROPERTIES_FILE_CONTROLLER_SUFFIX);
+       if (Files.exists(controllerPropertiesPath)) {
+               try {
+                               Properties oldProperties = PropertyUtil.getProperties(controllerPropertiesPath.toFile());
+                               if (oldProperties.equals(properties)) {
+                                       logger.info("A properties file with the same contents already exists for controller " + 
+                                               controllerName + 
+                                               ". No action is taken");
+                                       return true;
+                               } else {
+                                       this.backupController(controllerName);
+                               }
+                       } catch (Exception e) {
+                               logger.info("No existing Properties");
+                               // continue
+                       }
+       }
+               
+               try {
+               File controllerPropertiesFile = controllerPropertiesPath.toFile();
+               FileWriter writer = new FileWriter(controllerPropertiesFile);
+               properties.store(writer, "Machine created Policy Controller Configuration");
+               } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                           controllerName, "SystemPersistenceProperties");
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * deletes properties-based controller configuration
+        * @param controllerName the controller name
+        * @return true if the properties has been deleted from disk, false otherwise
+        */
+       @Override
+       public boolean deleteController(String controllerName) {
+               
+               Path controllerPropertiesPath = 
+                               Paths.get(CONFIG_DIR_NAME, 
+                                                 controllerName + PROPERTIES_FILE_CONTROLLER_SUFFIX);
+
+               if (Files.exists(controllerPropertiesPath)) {
+                       try {
+                               Path controllerPropertiesBakPath = 
+                                               Paths.get(CONFIG_DIR_NAME, controllerName + 
+                                  PROPERTIES_FILE_CONTROLLER_SUFFIX + ".bak");
+                               Files.move(controllerPropertiesPath, 
+                                                  controllerPropertiesBakPath, 
+                                                  StandardCopyOption.REPLACE_EXISTING);
+                       } catch (Exception e) {
+                               logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                                   controllerName, "SystemPersistenceProperties");
+                               return false;
+                       }
+               } 
+               
+               return true;
+       }
+
+       @Override
+       public Properties getControllerProperties(String controllerName) throws IllegalArgumentException {
+               return this.getProperties(controllerName + CONTROLLER_SUFFIX_IDENTIFIER);
+       }
+       
+       @Override
+       public Properties getProperties(String name) throws IllegalArgumentException {
+               Path propertiesPath = 
+                               Paths.get(CONFIG_DIR_NAME, name + ".properties");
+               
+               if (!Files.exists(propertiesPath)) {
+                       throw new IllegalArgumentException("properties for " + name + " are not persisted.");
+               }
+
+               try {
+                       return PropertyUtil.getProperties(propertiesPath.toFile());
+               } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                           name, "SystemPersistenceProperties can't retrieved properties for " + 
+                                   propertiesPath);
+                       e.printStackTrace();
+                       throw new IllegalArgumentException("can't read properties for " + 
+                                                          name + " @ " + 
+                                                                  propertiesPath);
+               }
+       }
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java
new file mode 100644 (file)
index 0000000..8f8a4ba
--- /dev/null
@@ -0,0 +1,1451 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.protocol.coders;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomGsonCoder;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomJacksonCoder;
+import org.openecomp.policy.drools.utils.Pair;
+
+/**
+ * Coder (Encoder/Decoder) of Events.
+ */
+public interface EventProtocolCoder {
+       
+       public static class CoderFilters {
+
+               /**
+                * coder class 
+                */
+               protected String factClass;
+               
+               /**
+                * filters to apply to the selection of the decodedClass;
+                */
+               protected JsonProtocolFilter filter;
+
+               /**
+                * classloader hash
+                */
+               protected int modelClassLoaderHash;
+
+               
+               /**
+                * constructor
+                * 
+                * @param codedClass coder class
+                * @param filter filters to apply
+                */
+               public CoderFilters(String codedClass, JsonProtocolFilter filter, int modelClassLoaderHash) {
+                       this.factClass = codedClass;
+                       this.filter = filter;
+                       this.modelClassLoaderHash = modelClassLoaderHash;
+               }
+
+               /**
+                * @return the codedClass
+                */
+               public String getCodedClass() {
+                       return factClass;
+               }
+
+               /**
+                * @param codedClass the decodedClass to set
+                */
+               public void setCodedClass(String codedClass) {
+                       this.factClass = codedClass;
+               }
+               
+               /**
+                * @return the filter
+                */
+               public synchronized JsonProtocolFilter getFilter() {
+                       return filter;
+               }
+
+               /**
+                * @param filter the filter to set
+                */
+               public synchronized void setFilter(JsonProtocolFilter filter) {
+                       this.filter = filter;
+               }
+
+               public int getModelClassLoaderHash() {
+                       return modelClassLoaderHash;
+               }
+
+               public void setFromClassLoaderHash(int fromClassLoaderHash) {
+                       this.modelClassLoaderHash = fromClassLoaderHash;
+               }
+
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("CoderFilters [factClass=").append(factClass).append(", filter=").append(filter)
+                                       .append(", modelClassLoaderHash=").append(modelClassLoaderHash).append("]");
+                       return builder.toString();
+               }
+
+       }
+       
+       /**
+        * Adds a Decoder class to decode the protocol over this topic
+        *  
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic 
+        * @param eventClass the event class
+        * @param protocolFilter filters to selectively choose a particular decoder
+        * when there are multiples
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */
+       public void addDecoder(String groupId, String artifactId, 
+                                      String topic, 
+                                      String eventClass, 
+                                      JsonProtocolFilter protocolFilter, 
+                                      CustomGsonCoder customGsonCoder,
+                                      CustomJacksonCoder customJacksonCoder,
+                                      int modelClassLoaderHash)
+               throws IllegalArgumentException;
+
+       /**
+        * removes all decoders associated with the controller id
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic of the controller
+        * 
+        * @throws IllegalArgumentException if invalid arguments have been provided
+        */
+       void removeEncoders(String groupId, String artifactId, String topic) throws IllegalArgumentException;
+       
+       /**
+        * removes decoders associated with the controller id and topic
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic
+        * 
+        * @throws IllegalArgumentException if invalid arguments have been provided
+        */
+       public void removeDecoders(String groupId, String artifactId, String topic) throws IllegalArgumentException;
+       
+       /**
+        * Given a controller id and a topic, it gives back its filters
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic
+        * 
+        * return list of decoders
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */
+       public List<CoderFilters> getDecoderFilters(String groupId, String artifactId, String topic)
+               throws IllegalArgumentException;        
+       
+
+       /**
+        * Given a controller id and a topic, it gives back the decoding configuration
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic
+        * 
+        * return decoding toolset
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */
+       public ProtocolCoderToolset getDecoders(String groupId, String artifactId, String topic) 
+                  throws IllegalArgumentException;
+       
+       /**
+        * Given a controller id and a topic, it gives back all the decoding configurations
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic
+        * 
+        * return decoding toolset
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */
+       public List<ProtocolCoderToolset> getDecoders(String groupId, String artifactId)
+                  throws IllegalArgumentException;
+       
+       
+       /**
+        * gets all decoders associated with the group and artifact ids
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * 
+        * @throws IllegalArgumentException if invalid arguments have been provided
+        */
+       public List<CoderFilters> getDecoderFilters(String groupId, String artifactId) throws IllegalArgumentException;
+       
+
+       /**
+        * Given a controller id and a topic, it gives back the classes that implements the encoding
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic
+        * 
+        * return list of decoders
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */
+       public List<CoderFilters> getEncoderFilters(String groupId, String artifactId, String topic) 
+                       throws IllegalArgumentException;
+       
+       /**
+        * gets all encoders associated with the group and artifact ids
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * 
+        * @throws IllegalArgumentException if invalid arguments have been provided
+        */
+       public List<CoderFilters> getEncoderFilters(String groupId, String artifactId) throws IllegalArgumentException;
+       
+       /**
+        * Given a controller id, a topic, and a classname, it gives back the classes that implements the decoding
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic
+        * @param classname classname
+        * 
+        * return list of decoders
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */     
+       public CoderFilters getDecoderFilters(String groupId, String artifactId, String topic, String classname)
+               throws IllegalArgumentException;        
+       
+       /**
+        * is there a decoder supported for the controller id and topic
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic protocol
+        * @return true if supported
+        */
+       public boolean isDecodingSupported(String groupId, String artifactId, String topic);
+       
+       /**
+        * Adds a Encoder class to encode the protocol over this topic
+        *  
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic 
+        * @param eventClass the event class
+        * @param protocolFilter filters to selectively choose a particular decoder
+        * when there are multiples
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */
+       public void addEncoder(String groupId, String artifactId, String topic, 
+                                                  String eventClass, 
+                                      JsonProtocolFilter protocolFilter,
+                                      CustomGsonCoder customGsonCoder,
+                                      CustomJacksonCoder customJacksonCoder,
+                                      int modelClassLoaderHash)
+               throws IllegalArgumentException;
+       
+       /**
+        * is there an encoder supported for the controller id and topic
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic protocol
+        * @return true if supported
+        */
+       public boolean isEncodingSupported(String groupId, String artifactId, String topic);
+       
+       /**
+        * get encoder based on coordinates and classname
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic protocol
+        * @param json event string
+        * @return
+        * @throws IllegalArgumentException invalid arguments passed in
+        */
+       public CoderFilters getEncoderFilters(String groupId, String artifactId, String topic, String classname)
+                       throws IllegalArgumentException;
+       
+       /**
+        * get encoder based on topic and encoded class
+        * 
+        * @param topic topic
+        * @param encodedClass encoded class
+        * @return
+        * @throws IllegalArgumentException invalid arguments passed in
+        */
+       public List<CoderFilters> getReverseEncoderFilters(String topic, String encodedClass)
+                       throws IllegalArgumentException;
+       
+       /**
+        * gets the identifier of the creator of the encoder
+        * 
+        * @param topic topic
+        * @param encodedClass encoded class
+        * @return a drools controller
+        * @throws IllegalArgumentException invalid arguments passed in
+        */
+       public DroolsController getDroolsController(String topic, Object encodedClass)
+                       throws IllegalArgumentException;
+       
+       /**
+        * gets the identifier of the creator of the encoder
+        * 
+        * @param topic topic
+        * @param encodedClass encoded class
+        * @return list of drools controllers
+        * @throws IllegalArgumentException invalid arguments passed in
+        */
+       public List<DroolsController> getDroolsControllers(String topic, Object encodedClass)
+                       throws IllegalArgumentException;
+       
+       /**
+        * decode topic's stringified event (json) to corresponding Event Object.
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic protocol
+        * @param json event string
+        * @return
+        * @throws IllegalArgumentException invalid arguments passed in
+        * @throws UnsupportedOperationException if the operation is not supported
+        * @throws IllegalStateException if the system is in an illegal state
+        */
+       public Object decode(String groupId, String artifactId, String topic, String json) 
+                       throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException;
+
+       /**
+        * encodes topic's stringified event (json) to corresponding Event Object.
+        * 
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic protocol
+        * @param event Object
+        * 
+        * @throws IllegalArgumentException invalid arguments passed in
+        */
+       public String encode(String groupId, String artifactId, String topic, Object event) 
+                       throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException;
+       
+       /**
+        * encodes topic's stringified event (json) to corresponding Event Object.
+        * 
+        * @param topic topic
+        * @param event event object
+        * 
+        * @throws IllegalArgumentException invalid arguments passed in
+        * @throws UnsupportedOperationException operation cannot be performed
+        */
+       public String encode(String topic, Object event) 
+                       throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException;
+       
+       /**
+        * encodes topic's stringified event (json) to corresponding Event Object.
+        * 
+        * @param topic topic
+        * @param event event object
+        * @param droolsController 
+        * 
+        * @throws IllegalArgumentException invalid arguments passed in
+        * @throws UnsupportedOperationException operation cannot be performed
+        */
+       public String encode(String topic, Object event, DroolsController droolsController) 
+                       throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException;
+       
+       /**
+        * singleton reference to the global event protocol coder
+        */
+       public static EventProtocolCoder manager = new MultiplexorEventProtocolCoder();
+}
+
+/**
+ * Protocol Coder that does its best attempt to decode/encode, selecting the best
+ * class and best fitted json parsing tools.
+ */
+class MultiplexorEventProtocolCoder implements EventProtocolCoder {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(MultiplexorEventProtocolCoder.class);      
+       /**
+        * Decoders
+        */
+       protected EventProtocolDecoder decoders = new EventProtocolDecoder();
+       
+       /**
+        * Encoders
+        */
+       protected EventProtocolEncoder encoders = new EventProtocolEncoder();
+       
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void addDecoder(String groupId, String artifactId, String topic, 
+                                      String eventClass, 
+                                      JsonProtocolFilter protocolFilter,
+                                      CustomGsonCoder customGsonCoder,
+                                      CustomJacksonCoder customJacksonCoder,
+                                      int modelClassLoaderHash) 
+                  throws IllegalArgumentException {
+               logger.info("ADD-DECODER: " + groupId + ":" + artifactId + ":" + 
+                                 topic + ":" + eventClass + ":" + 
+                                         protocolFilter + ":" + customGsonCoder + 
+                                         ":" + customJacksonCoder + ":" + modelClassLoaderHash + 
+                                         " INTO " + this);
+               this.decoders.add(groupId, artifactId, topic, eventClass, protocolFilter, 
+                                        customGsonCoder, customJacksonCoder, modelClassLoaderHash);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void addEncoder(String groupId, String artifactId, String topic, 
+                                      String eventClass, 
+                                      JsonProtocolFilter protocolFilter,
+                                      CustomGsonCoder customGsonCoder,
+                                      CustomJacksonCoder customJacksonCoder,
+                                      int modelClassLoaderHash) 
+                  throws IllegalArgumentException {
+               logger.info("ADD-ENCODER: " + groupId + ":" + artifactId + ":" + 
+                                  topic + ":" + eventClass + ":" + 
+                                  protocolFilter + ":" + customGsonCoder + 
+                                  ":" + customJacksonCoder + ":" + modelClassLoaderHash +
+                                  " INTO " + this);
+               this.encoders.add(groupId, artifactId, topic, eventClass, protocolFilter, 
+                                 customGsonCoder, customJacksonCoder, modelClassLoaderHash);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void removeDecoders(String groupId, String artifactId, String topic) 
+                  throws IllegalArgumentException {
+               logger.info("REMOVE-DECODER: " + groupId + ":" + artifactId + ":" + 
+                          topic + " FROM " + this);            
+               this.decoders.remove(groupId, artifactId, topic);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void removeEncoders(String groupId, String artifactId, String topic) 
+                  throws IllegalArgumentException {
+               logger.info("REMOVE-ENCODER: " + groupId + ":" + artifactId + ":" + 
+                          topic + " FROM " + this);    
+               this.encoders.remove(groupId, artifactId, topic);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isDecodingSupported(String groupId, String artifactId, String topic) {   
+               return this.decoders.isCodingSupported(groupId, artifactId, topic);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isEncodingSupported(String groupId, String artifactId, String topic) {
+               return this.encoders.isCodingSupported(groupId, artifactId, topic);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Object decode(String groupId, String artifactId, String topic, String json) 
+                       throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException {
+               logger.info("DECODE: " + groupId + ":" + artifactId + ":" + 
+                          topic + ":" + json + " WITH " + this);
+               return this.decoders.decode(groupId, artifactId, topic, json);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String encode(String groupId, String artifactId, String topic, Object event) 
+                       throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException {
+               logger.info("ENCODE: " + groupId + ":" + artifactId + ":" + 
+                           topic + ":" + event + " WITH " + this);
+               return this.encoders.encode(groupId, artifactId, topic, event);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String encode(String topic, Object event) 
+                       throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException {
+               logger.info("ENCODE: " + topic + ":" + event + " WITH " + this);
+               return this.encoders.encode(topic, event);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String encode(String topic, Object event, DroolsController droolsController) 
+                       throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException {
+               logger.info("ENCODE: " + topic + ":" + event + ":" + droolsController + " WITH " + this);
+               return this.encoders.encode(topic, event, droolsController);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<CoderFilters> getDecoderFilters(String groupId, String artifactId, String topic) 
+                       throws IllegalArgumentException {
+               
+               return this.decoders.getFilters(groupId, artifactId, topic);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public ProtocolCoderToolset getDecoders(String groupId, String artifactId, String topic) 
+                       throws IllegalArgumentException {
+               
+               Pair<ProtocolCoderToolset,ProtocolCoderToolset> decoderToolsets = this.decoders.getCoders(groupId, artifactId, topic);
+               if (decoderToolsets == null)
+                       throw new IllegalArgumentException("Decoders not found for " + groupId + ":" + artifactId + ":" + topic);
+               
+               return decoderToolsets.first();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<CoderFilters> getEncoderFilters(String groupId, String artifactId, String topic) 
+                       throws IllegalArgumentException {
+               
+               return this.encoders.getFilters(groupId, artifactId, topic);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public CoderFilters getDecoderFilters(String groupId, String artifactId, String topic, String classname)
+                       throws IllegalArgumentException {
+               
+               return this.decoders.getFilters(groupId, artifactId, topic, classname);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public CoderFilters getEncoderFilters(String groupId, String artifactId, String topic, String classname)
+                       throws IllegalArgumentException {
+               
+               return this.encoders.getFilters(groupId, artifactId, topic, classname);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<CoderFilters> getReverseEncoderFilters(String topic, String encodedClass) throws IllegalArgumentException {
+               return this.encoders.getReverseFilters(topic, encodedClass);
+       }
+
+       /**
+        * get all deocders by maven coordinates and topic
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * 
+        * @return list of decoders
+        * @throws IllegalArgumentException if invalid input
+        */
+       @Override
+       public List<ProtocolCoderToolset> getDecoders(String groupId, String artifactId) 
+                       throws IllegalArgumentException {
+
+               List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>> decoderToolsets = this.decoders.getCoders(groupId, artifactId);
+               if (decoderToolsets == null)
+                       throw new IllegalArgumentException("Decoders not found for " + groupId + ":" + artifactId);
+               
+               List<ProtocolCoderToolset> parser1CoderToolset = new ArrayList<>();
+               for (Pair<ProtocolCoderToolset,ProtocolCoderToolset> coderToolsetPair : decoderToolsets) {
+                       parser1CoderToolset.add(coderToolsetPair.first());
+               }
+               
+               return parser1CoderToolset;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<CoderFilters> getDecoderFilters(String groupId, String artifactId) throws IllegalArgumentException {
+               return this.decoders.getFilters(groupId, artifactId);
+               
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<CoderFilters> getEncoderFilters(String groupId, String artifactId) throws IllegalArgumentException {
+               return this.encoders.getFilters(groupId, artifactId);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DroolsController getDroolsController(String topic, Object encodedClass) throws IllegalArgumentException {
+               return this.encoders.getDroolsController(topic, encodedClass);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<DroolsController> getDroolsControllers(String topic, Object encodedClass) throws IllegalArgumentException {
+               return this.encoders.getDroolsControllers(topic, encodedClass);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("MultiplexorEventProtocolCoder [decoders=").append(decoders).append(", encoders=")
+                               .append(encoders).append("]");
+               return builder.toString();
+       }
+}
+
+/**
+ * This protocol Coder that does its best attempt to decode/encode, selecting the best
+ * class and best fitted json parsing tools.
+ */
+abstract class GenericEventProtocolCoder  {
+       private static Logger  logger = FlexLogger.getLogger(GenericEventProtocolCoder.class);  
+       
+       /**
+        * Mapping topic:controller-id -> <protocol-decoder-toolset-pair> 
+        * where protocol-coder-toolset-pair contains both a jackson-protocol-coder-toolset
+        * and a gson-protocol-coder-toolset.   The first value of the pair will the 
+        * protocol coder toolset most likely to be successful with the encoding or decoding,
+        * and consequently the second value will be the less likely.
+        */
+       protected final HashMap<String, Pair<ProtocolCoderToolset,ProtocolCoderToolset>> coders = 
+                       new HashMap<String, Pair<ProtocolCoderToolset,ProtocolCoderToolset>>();
+       
+       /**
+        * Mapping topic + classname -> Protocol Set 
+        */
+       protected final HashMap<String, List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>>> reverseCoders = 
+                       new HashMap<String, List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>>>();
+       
+       protected boolean multipleToolsetRetries = false;
+       
+       GenericEventProtocolCoder(boolean multipleToolsetRetries) {
+               this.multipleToolsetRetries = multipleToolsetRetries;
+       }
+       
+       /**
+        * Index a new coder
+        *  
+        * @param groupId of the controller
+        * @param artifactId of the controller
+        * @param topic the topic 
+        * @param eventClass the event class
+        * @param protocolFilter filters to selectively choose a particular decoder
+        * when there are multiples
+        * 
+        * @throw IllegalArgumentException if an invalid parameter is passed
+        */
+       public void add(String groupId, String artifactId, 
+                               String topic, 
+                               String eventClass, 
+                               JsonProtocolFilter protocolFilter, 
+                               CustomGsonCoder customGsonCoder, 
+                               CustomJacksonCoder customJacksonCoder,
+                               int modelClassLoaderHash)
+                  throws IllegalArgumentException {
+               if (groupId == null || groupId.isEmpty()) {                     
+                       throw new IllegalArgumentException("Invalid group id");
+               }
+               
+               if (artifactId == null || artifactId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid artifact id");
+               }
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid Topic");
+               }
+               
+               if (eventClass == null) {
+                       throw new IllegalArgumentException("Invalid Event Class");
+               }
+               
+               String key = this.codersKey(groupId, artifactId, topic);
+               String reverseKey = this.reverseCodersKey(topic, eventClass);
+               
+               synchronized(this) {
+                       if (coders.containsKey(key)) {                          
+                               Pair<ProtocolCoderToolset, ProtocolCoderToolset> toolsets = coders.get(key);
+                               
+                               if (logger.isInfoEnabled())
+                                       logger.info("ADDING CODER TO EXISTING: " + toolsets + " for " + key);
+                               
+                               toolsets.first().addCoder(eventClass, protocolFilter, modelClassLoaderHash);
+                               toolsets.second().addCoder(eventClass, protocolFilter, modelClassLoaderHash);
+                               
+                               if (!reverseCoders.containsKey(reverseKey)) {
+                                       if (logger.isInfoEnabled())
+                                               logger.info("Multiple coder classes case: " + toolsets.first() + 
+                                                                          " for " + reverseKey + " - " + key);
+                                       
+                                       List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>> reverseMappings =
+                                                       new ArrayList<Pair<ProtocolCoderToolset,ProtocolCoderToolset>>();
+                                       reverseMappings.add(toolsets);
+                                       reverseCoders.put(reverseKey, reverseMappings);
+                               }
+                               return;
+                       }
+               
+                       GsonProtocolCoderToolset gsonCoderTools = 
+                                                                               new GsonProtocolCoderToolset
+                                                                                                               (topic, key, 
+                                                                                                                groupId, artifactId, 
+                                                                                                                eventClass, protocolFilter,
+                                                                                                                customGsonCoder,
+                                                                                                                modelClassLoaderHash);
+                       
+                       JacksonProtocolCoderToolset jacksonCoderTools = 
+                                                                               new JacksonProtocolCoderToolset
+                                                                                                               (topic, key, 
+                                                                                                                groupId, artifactId, 
+                                                                                                                eventClass, protocolFilter,
+                                                                                                                customJacksonCoder,
+                                                                                                                modelClassLoaderHash);
+                       
+                       // Use Gson as the first priority encoding/decoding toolset, and Jackson
+                       // as second.  This is because it has been observed that they can diverge
+                       // somewhat in the encoding/decoding data types, which can produce json
+                       // that may result incompatible with what some network elements are 
+                       // expecting.   As decoding takes place, this element will reconfigure
+                       // itself to set the jackson one as the favoured one first, if errors
+                       // are detected in the gson encoding
+                       
+                       Pair<ProtocolCoderToolset,ProtocolCoderToolset> coderTools = 
+                                       new Pair<ProtocolCoderToolset,ProtocolCoderToolset>(gsonCoderTools, 
+                                                                                                   jacksonCoderTools);
+                       
+                       logger.info("ADDED TOOLSET: " + key + " : " + 
+                                         coderTools + ":" + this);
+                       
+                       coders.put(key, coderTools);
+                       
+                       if (reverseCoders.containsKey(reverseKey)) {
+                               // There is another controller (different group id/artifact id/topic)
+                               // that shares the class and the topic.
+                               
+                               List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>> toolsets = 
+                                                                                                                       reverseCoders.get(reverseKey);
+                               boolean present = false;
+                               for (Pair<ProtocolCoderToolset,ProtocolCoderToolset> parserSet: toolsets) {
+                                       // just doublecheck
+                                       present = parserSet.first().getControllerId().equals(key);
+                                       if (present) {
+                                               /* anomaly */
+                                               logger.error("UNEXPECTED TOOLSET REVERSE MAPPING FOUND: " + parserSet.first() + 
+                                                                          " for " + reverseKey + " - " + key);
+                                       }
+                               }
+                               
+                               if (present) {
+                                       return;
+                               } else {
+                                       logger.info("ADDING TOOLSET REVERSE MAPPING: " + reverseKey + " : " + 
+                                                     toolsets + ":" + coderTools + ":" + this);
+                                       toolsets.add(coderTools);
+                               }
+                       } else {
+                               List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>> toolsets =
+                                       new ArrayList<Pair<ProtocolCoderToolset,ProtocolCoderToolset>>();
+                               logger.info("ADDING TOOLSET REVERSE MAPPING: " + reverseKey + " : " + 
+                                                     toolsets + ":" + coderTools + ":" +  this);
+                               toolsets.add(coderTools);
+                               reverseCoders.put(reverseKey, toolsets);
+                       }
+                       
+               }
+       }
+
+       /**
+        * produces key for indexing toolset entries
+        * 
+        * @param group group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @return index key
+        */
+       protected String codersKey(String groupId, String artifactId, String topic) {
+               return groupId + ":" + artifactId + ":" + topic;
+       }
+       
+       /**
+        * produces a key for the reverse index
+        * 
+        * @param topic topic 
+        * @param eventClass coded class
+        * @return reverse index key
+        */
+       protected String reverseCodersKey(String topic, String eventClass) {
+               return topic + ":" + eventClass;
+       }
+       
+       /**
+        * remove coder 
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @throws IllegalArgumentException if invalid input
+        */
+       public void remove(String groupId, String artifactId, String topic) 
+                  throws IllegalArgumentException {
+               
+               if (groupId == null || groupId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid group id");
+               }
+               
+               if (artifactId == null || artifactId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid artifact id");
+               }
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid Topic");
+               }
+               
+               String key = this.codersKey(groupId, artifactId, topic);
+               
+               synchronized(this) {
+                       if (coders.containsKey(key)) {
+                               Pair<ProtocolCoderToolset, ProtocolCoderToolset> p = coders.remove(key);
+                               logger.info("REMOVED TOOLSET: " + key + " : " + p + " FROM " + 
+                                                 coders + " : " +  this);
+                               
+                               for (CoderFilters codeFilter : p.first().getCoders()) {
+                                       String className = codeFilter.getCodedClass();
+                                       String reverseKey = this.reverseCodersKey(topic, className);
+                                       if (this.reverseCoders.containsKey(reverseKey) ) {
+                                               List<Pair<ProtocolCoderToolset, ProtocolCoderToolset>> toolsets = 
+                                                                                                                               this.reverseCoders.get(reverseKey);
+                                               Iterator<Pair<ProtocolCoderToolset, ProtocolCoderToolset>> toolsetsIter = 
+                                                                                                                                                               toolsets.iterator();
+                                               while (toolsetsIter.hasNext()) {
+                                                       Pair<ProtocolCoderToolset, ProtocolCoderToolset> toolset = toolsetsIter.next();
+                                                       if (toolset.first().getControllerId().equals(key)) {
+                                                               logger.info("REMOVED CODER FROM REVERSE MAPPING of TOOLSET: " + reverseKey + " : " + toolset + " FROM " + 
+                                                                                         reverseCoders);
+                                                               toolsetsIter.remove();
+                                                       }
+                                               }
+                                               
+                                               if (this.reverseCoders.get(reverseKey).isEmpty()) {
+                                                       logger.info("REMOVE FULL REVERSE MAPPING of TOOLSET: " + reverseKey + " FROM " + 
+                                                                         reverseCoders);                                                       
+                                                       this.reverseCoders.remove(reverseKey);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * does it support coding?
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @return true if its is codable
+        */
+       public boolean isCodingSupported(String groupId, String artifactId, String topic) {
+               
+               if (groupId == null || groupId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid group id");
+               }
+               
+               if (artifactId == null || artifactId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid artifact id");
+               }
+               
+               if (topic == null || topic.isEmpty())
+                       return false;
+               
+               String key = this.codersKey(groupId, artifactId, topic);
+               synchronized(this) {
+                       return (coders.containsKey(key));
+               }
+       }
+       
+       /**
+        * decode a json string into an Object
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @param json json string to convert to object
+        * @return the decoded object
+        * @throws IllegalArgumentException if invalid argument is provided
+        * @throws UnsupportedOperationException if the operation cannot be performed
+        */
+       public Object decode(String groupId, String artifactId, String topic, String json) 
+                       throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException {
+               
+               if (!isCodingSupported(groupId, artifactId, topic)) {
+                       throw new IllegalArgumentException("Unsupported:" + codersKey(groupId, artifactId, topic) + " for encoding");
+               }
+               
+               String key = this.codersKey(groupId, artifactId, topic);
+               Pair<ProtocolCoderToolset,ProtocolCoderToolset> coderTools = coders.get(key);
+               try {
+                       Object event = coderTools.first().decode(json);
+                       if (event != null)
+                               return event;
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       logger.warn("Can't decode @ " + this);
+               }
+               
+               if (multipleToolsetRetries) {
+                       // try the less favored toolset
+                       try {
+                               Object event = coderTools.second().decode(json);
+                               if (event != null) {
+                                       // change the priority of the toolset
+                                       synchronized(this) {
+                                               ProtocolCoderToolset first = coderTools.first();
+                                               ProtocolCoderToolset second = coderTools.second();
+                                               coderTools.first(second);
+                                               coderTools.second(first);
+                                       }
+                                       
+                                       return event;
+                               }
+                       } catch (Exception e2) {
+                               // TODO Auto-generated catch block
+                               e2.printStackTrace();
+                               throw new UnsupportedOperationException(e2);
+                       }
+               } 
+               
+               throw new UnsupportedOperationException("Cannot decode neither with gson or jackson");
+       }
+
+       /**
+        * encode an object into a json string
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @param event object to convert to string
+        * @return the json string
+        * @throws IllegalArgumentException if invalid argument is provided
+        * @throws UnsupportedOperationException if the operation cannot be performed
+        */
+       public String encode(String groupId, String artifactId, String topic, Object event) 
+                       throws IllegalArgumentException, UnsupportedOperationException {
+               
+               if (!isCodingSupported(groupId, artifactId, topic)) {
+                       throw new IllegalArgumentException
+                               ("Unsupported:" + codersKey(groupId, artifactId, topic));
+               }
+               
+               if (event == null) {
+                       throw new IllegalArgumentException("Unsupported topic:" + topic);
+               }
+               
+               // reuse the decoder set, since there must be affinity in the model
+               String key = this.codersKey(groupId, artifactId, topic);
+               return this.encodeInternal(key, event);
+       }
+       
+       /**
+        * encode an object into a json string
+        * 
+        * @param key identifier
+        * @param event object to convert to string
+        * @return the json string
+        * @throws IllegalArgumentException if invalid argument is provided
+        * @throws UnsupportedOperationException if the operation cannot be performed
+        */
+       protected String encodeInternal(String key, Object event) 
+                       throws IllegalArgumentException, UnsupportedOperationException {
+               
+               logger.debug("ENCODE: " + key + ":" + event + this);
+               
+               Pair<ProtocolCoderToolset,ProtocolCoderToolset> coderTools = coders.get(key);
+               try {
+                       String json = coderTools.first().encode(event);
+                       if (json != null && !json.isEmpty())
+                               return json;
+               } catch (Exception e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "FIRST-ENCODE-INTERNAL: " + 
+                                      key + ":" + event, this.toString());
+               }
+               
+               if (multipleToolsetRetries) {
+                       // try the less favored toolset
+                       try {
+                               String json = coderTools.second().encode(event);
+                               if (json != null) {
+                                       // change the priority of the toolset
+                                       synchronized(this) {
+                                               ProtocolCoderToolset first = coderTools.first();
+                                               ProtocolCoderToolset second = coderTools.second();
+                                               coderTools.first(second);
+                                               coderTools.second(first);
+                                       }
+                                       
+                                       return json;
+                               }
+                       } catch (Exception e2) {
+                               // TODO Auto-generated catch block
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e2, "SECOND-ENCODE-INTERNAL: " + 
+                                      key + ":" + event, this.toString());
+                               throw new UnsupportedOperationException(e2);
+                       }
+               }
+               
+               throw new UnsupportedOperationException("Cannot decode neither with gson or jackson");
+       }
+       
+       /**
+        * encode an object into a json string
+        * 
+        * @param topic topic
+        * @param encodedClass object to convert to string
+        * @return the json string
+        * @throws IllegalArgumentException if invalid argument is provided
+        * @throws UnsupportedOperationException if the operation cannot be performed
+        */
+       public String encode(String topic, Object encodedClass) 
+                       throws IllegalArgumentException, IllegalArgumentException, UnsupportedOperationException {
+               
+               if (encodedClass == null) {
+                       throw new IllegalArgumentException("Invalid encoded class");
+               }
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid topic");
+               }
+               
+               logger.info("ENCODE: " + topic + ":" + 
+                                 encodedClass.getClass().getCanonicalName() + ":" + 
+                                         encodedClass);
+               
+               List<DroolsController> droolsControllers = droolsCreators(topic, encodedClass);
+               if (droolsControllers.size() > 1) {
+                       // unexpected
+                       logger.warn("MULTIPLE DROOLS CONTROLLERS FOUND for: " + topic + ":" + 
+                              encodedClass.getClass().getCanonicalName() + ":" + 
+                              droolsControllers + " IN " + this);              
+                       // continue
+               }
+               
+               String key = codersKey(droolsControllers.get(0).getGroupId(), droolsControllers.get(0).getArtifactId(), topic);
+               return this.encodeInternal(key, encodedClass);
+       }
+       
+       /**
+        * encode an object into a json string
+        * 
+        * @param topic topic
+        * @param encodedClass object to convert to string
+        * @return the json string
+        * @throws IllegalArgumentException if invalid argument is provided
+        * @throws UnsupportedOperationException if the operation cannot be performed
+        */
+       public String encode(String topic, Object encodedClass, DroolsController droolsController) 
+                       throws IllegalArgumentException, IllegalArgumentException, UnsupportedOperationException {
+               
+               if (encodedClass == null) {
+                       throw new IllegalArgumentException("Invalid encoded class");
+               }
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid topic");
+               }
+               
+               logger.info("ENCODE: " + topic + ":" + 
+                                 encodedClass.getClass().getCanonicalName() + ":" + 
+                                         encodedClass + ":" + droolsController);
+               
+               String key = codersKey(droolsController.getGroupId(), droolsController.getArtifactId(), topic);
+               return this.encodeInternal(key, encodedClass);
+       }
+
+       /**
+        * @param topic
+        * @param encodedClass
+        * @param reverseKey
+        * @return
+        * @throws IllegalStateException
+        * @throws IllegalArgumentException
+        */
+       protected List<DroolsController> droolsCreators(String topic, Object encodedClass)
+                       throws IllegalStateException, IllegalArgumentException {
+               
+               List<DroolsController> droolsControllers = new ArrayList<DroolsController>();
+               
+               String reverseKey = this.reverseCodersKey(topic, encodedClass.getClass().getCanonicalName());
+               if (!this.reverseCoders.containsKey(reverseKey)) {
+                       logger.warn("NO MAPPING for REVERSE KEY: " + topic + ":" + 
+                    encodedClass.getClass().getCanonicalName() + ":" + 
+                    encodedClass + ":" + reverseKey + " : " + this);
+                       return droolsControllers;
+               }
+               
+               List<Pair<ProtocolCoderToolset, ProtocolCoderToolset>> 
+                                       toolsets = this.reverseCoders.get(reverseKey);
+               
+               // There must be multiple toolset pairs associated with <topic,classname> reverseKey
+               // case 2 different controllers use the same models and register the same encoder for
+               // the same topic.  This is assumed not to occur often but for the purpose of encoding
+               // but there should be no side-effects.  Ownership is crosscheck against classname and 
+               // classloader reference.
+               
+               if (toolsets == null || toolsets.isEmpty()) {
+                       logger.warn("ENCODE: " + topic + ":" + 
+                                     encodedClass.getClass().getCanonicalName() + ":" + 
+                                         encodedClass + " ENCODER NOT FOUND");
+                       throw new IllegalStateException("No Encoders toolsets available for topic "+ topic +
+                                                               " encoder " + encodedClass.getClass().getCanonicalName());
+               }
+               
+               for (Pair<ProtocolCoderToolset, ProtocolCoderToolset> encoderSet : toolsets) {
+                       // figure out the right toolset
+                       String groupId = encoderSet.first().getGroupId();
+                       String artifactId = encoderSet.first().getArtifactId();
+                       List<CoderFilters> coders = encoderSet.first().getCoders();
+                       for (CoderFilters coder : coders) {
+                               if (coder.getCodedClass().equals(encodedClass.getClass().getCanonicalName())) {
+                                       DroolsController droolsController = 
+                                                       DroolsController.factory.get(groupId, artifactId, "");
+                                       if (droolsController.ownsCoder(encodedClass.getClass(), coder.getModelClassLoaderHash())) {
+                                               droolsControllers.add(droolsController);
+                                       }
+                               }
+                       }
+               }
+               
+               if (droolsControllers.isEmpty()) {
+                       throw new IllegalStateException("No Encoders toolsets available for topic "+ topic +
+                           " : encoder " + encodedClass.getClass().getCanonicalName());                                
+               }
+               return droolsControllers;
+       }
+
+
+       /**
+        * get all filters by maven coordinates and topic
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @return list of coders
+        * @throws IllegalArgumentException if invalid input
+        */
+       public List<CoderFilters> getFilters(String groupId, String artifactId, String topic) 
+                       throws IllegalArgumentException {
+               
+               if (!isCodingSupported(groupId, artifactId, topic)) {
+                       throw new IllegalArgumentException("Unsupported:" + codersKey(groupId, artifactId, topic));
+               }
+               
+               String key = this.codersKey(groupId, artifactId, topic);
+               Pair<ProtocolCoderToolset,ProtocolCoderToolset> coderTools = coders.get(key);
+               return coderTools.first().getCoders();
+       }
+       
+       /**
+        * get all coders by maven coordinates and topic
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @return list of coders
+        * @throws IllegalArgumentException if invalid input
+        */
+       public Pair<ProtocolCoderToolset,ProtocolCoderToolset> getCoders(String groupId, String artifactId, String topic) 
+                       throws IllegalArgumentException {
+               
+               if (!isCodingSupported(groupId, artifactId, topic)) {
+                       throw new IllegalArgumentException("Unsupported:" + codersKey(groupId, artifactId, topic));
+               }
+               
+               String key = this.codersKey(groupId, artifactId, topic);
+               Pair<ProtocolCoderToolset,ProtocolCoderToolset> coderTools = coders.get(key);
+               return coderTools;
+       }
+       
+       /**
+        * get all coders by maven coordinates and topic
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @return list of coders
+        * @throws IllegalArgumentException if invalid input
+        */
+       public List<CoderFilters> getFilters(String groupId, String artifactId) 
+                       throws IllegalArgumentException {
+               
+               if (groupId == null || groupId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid group id");
+               }
+               
+               if (artifactId == null || artifactId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid artifact id");
+               }
+               
+               String key = this.codersKey(groupId, artifactId, "");
+               
+               List<CoderFilters> codersFilters = new ArrayList<CoderFilters>();
+               for (Map.Entry<String, Pair<ProtocolCoderToolset,ProtocolCoderToolset>> entry : coders.entrySet()) {
+                       if (entry.getKey().startsWith(key)) {
+                               codersFilters.addAll(entry.getValue().first().getCoders());
+                       }
+               }
+               
+               return codersFilters;
+       }
+       
+       /**
+        * get all coders by maven coordinates and topic
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @return list of coders
+        * @throws IllegalArgumentException if invalid input
+        */
+       public List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>> getCoders(String groupId, String artifactId) 
+                       throws IllegalArgumentException {
+               
+               if (groupId == null || groupId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid group id");
+               }
+               
+               if (artifactId == null || artifactId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid artifact id");
+               }
+               
+               String key = this.codersKey(groupId, artifactId, "");
+               
+               List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>> coderToolset = new ArrayList<Pair<ProtocolCoderToolset,ProtocolCoderToolset>>();
+               for (Map.Entry<String, Pair<ProtocolCoderToolset,ProtocolCoderToolset>> entry : coders.entrySet()) {
+                       if (entry.getKey().startsWith(key)) {
+                               coderToolset.add(entry.getValue());
+                       }
+               }
+               
+               return coderToolset;
+       }
+
+
+       /**
+        * get all filters by maven coordinates, topic, and classname
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @param topic topic
+        * @param classname
+        * @return list of coders
+        * @throws IllegalArgumentException if invalid input
+        */
+       public CoderFilters getFilters(String groupId, String artifactId, String topic, String classname)
+                       throws IllegalArgumentException {
+               
+               if (!isCodingSupported(groupId, artifactId, topic)) {
+                       throw new IllegalArgumentException("Unsupported:" + codersKey(groupId, artifactId, topic));
+               }
+               
+               if (classname == null || classname.isEmpty()) {
+                       throw new IllegalArgumentException("classname must be provided");
+               }
+               
+               String key = this.codersKey(groupId, artifactId, topic);
+               Pair<ProtocolCoderToolset,ProtocolCoderToolset> coderTools = coders.get(key);
+               return coderTools.first().getCoder(classname);
+       }
+       
+       /**
+        * get coded based on class and topic
+        * 
+        * @param topic
+        * @param codedClass
+        * @return
+        * @throws IllegalArgumentException
+        */
+       public List<CoderFilters> getReverseFilters(String topic, String codedClass)
+                       throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("Unsupported");
+               }
+               
+               if (codedClass == null) {
+                       throw new IllegalArgumentException("class must be provided");
+               }
+               
+               String key = this.reverseCodersKey(topic, codedClass);
+               List<Pair<ProtocolCoderToolset,ProtocolCoderToolset>> toolsets = this.reverseCoders.get(key);
+               if (toolsets == null)
+                       throw new IllegalArgumentException("No Coder found for " + key);
+               
+               
+               List<CoderFilters> coders = new ArrayList<CoderFilters>();
+               for (Pair<ProtocolCoderToolset,ProtocolCoderToolset> toolset: toolsets) {
+                       coders.addAll(toolset.first().getCoders());
+               }
+               
+               return coders;
+       }
+       
+       /**
+        * returns group and artifact id of the creator of the encoder
+        * 
+        * @param topic
+        * @param fact
+        * @return
+        * @throws IllegalArgumentException
+        */
+       DroolsController getDroolsController(String topic, Object fact)
+                       throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("Unsupported");
+               }
+               
+               if (fact == null) {
+                       throw new IllegalArgumentException("class must be provided");
+               }
+               
+               List<DroolsController> droolsControllers = droolsCreators(topic, fact);
+               if (droolsControllers.size() > 1) {
+                       // unexpected
+                       logger.warn("MULTIPLE DROOLS CONTROLLERS FOUND for: " + topic + ":" + 
+                              fact.getClass().getCanonicalName() + ":" + 
+                              droolsControllers + " IN " + this);              
+                       // continue
+               }
+               return droolsControllers.get(0);
+       }
+       
+       /**
+        * returns group and artifact id of the creator of the encoder
+        * 
+        * @param topic
+        * @param fact
+        * @return
+        * @throws IllegalArgumentException
+        */
+       List<DroolsController> getDroolsControllers(String topic, Object fact)
+                       throws IllegalArgumentException {
+               
+               if (topic == null || topic.isEmpty()) {
+                       throw new IllegalArgumentException("Unsupported");
+               }
+               
+               if (fact == null) {
+                       throw new IllegalArgumentException("class must be provided");
+               }
+               
+               List<DroolsController> droolsControllers = droolsCreators(topic, fact);
+               if (droolsControllers.size() > 1) {
+                       // unexpected
+                       logger.warn("MULTIPLE DROOLS CONTROLLERS FOUND for: " + topic + ":" + 
+                              fact.getClass().getCanonicalName() + ":" + 
+                              droolsControllers + " IN " + this);              
+                       // continue
+               }
+               return droolsControllers;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("GenericEventProtocolCoder [coders=").append(coders.keySet()).append(", reverseCoders=")
+                               .append(reverseCoders.keySet()).append("]");
+               return builder.toString();
+       }
+}
+
+class EventProtocolDecoder extends GenericEventProtocolCoder {
+
+       public EventProtocolDecoder(){super(false);}
+       
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("EventProtocolDecoder [toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+       
+}
+       
+class EventProtocolEncoder extends GenericEventProtocolCoder {
+       
+       public EventProtocolEncoder(){super(false);}
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("EventProtocolEncoder [toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+}
\ No newline at end of file
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/JsonProtocolFilter.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/JsonProtocolFilter.java
new file mode 100644 (file)
index 0000000..a2ce312
--- /dev/null
@@ -0,0 +1,304 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.protocol.coders;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.policy.drools.utils.Pair;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+/**
+ * JSON Protocol Filter.  Evaluates an JSON string and evaluates if it
+ * passes its filters.
+ */
+public class JsonProtocolFilter {
+       
+       /**
+        * Helper class to collect Filter information
+        */
+       public static class FilterRule {
+               /**
+                * Field name
+                */
+               protected String name;
+               
+               /**
+                * Field Value regex
+                */
+               protected String regex;
+               
+               /**
+                * Filter Constructor
+                * 
+                * @param name field name
+                * @param regex field regex value
+                */
+               public FilterRule(String name, String regex) {
+                       this.name = name;
+                       this.regex = regex;
+               }
+
+               /**
+                * Default constructor (for serialization only)
+                */
+               public FilterRule() {
+                       super();
+               }
+
+               /**
+                * gets name
+                * 
+                * @return
+                */
+               public String getName() {
+                       return name;
+               }
+
+               /**
+                * gets regex
+                * 
+                * @return
+                */
+               public String getRegex() {
+                       return regex;
+               }
+
+               /**
+                * sets field name
+                * @param name field name
+                */
+               public void setName(String name) {
+                       this.name = name;
+               }
+
+               /**
+                * sets regex name
+                * @param regex
+                */
+               public void setRegex(String regex) {
+                       this.regex = regex;
+               }
+
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("Filter [name=").append(name).append(", regex=").append(regex).append("]");
+                       return builder.toString();
+               }
+       }
+       
+       /**
+        * all the filters to be applied
+        */
+       protected List<FilterRule> rules = new ArrayList<FilterRule>();
+       
+       /**
+        * 
+        * @param rawFilters raw filter initialization
+        * 
+        * @throws IllegalArgumentException an invalid input has been provided
+        */
+       public static JsonProtocolFilter fromRawFilters(List<Pair<String, String>> rawFilters) 
+               throws IllegalArgumentException {
+               
+               if (rawFilters == null) {
+                       throw new IllegalArgumentException("No raw filters provided");
+               }
+               
+               List<FilterRule> filters = new ArrayList<FilterRule>();
+               for (Pair<String, String> filterPair: rawFilters) {
+                       if  (filterPair.first() == null || filterPair.first().isEmpty()) {
+                               // TODO: warn
+                               continue;
+                       }
+                       
+                       filters.add(new FilterRule(filterPair.first(), filterPair.second()));
+               }
+               return new JsonProtocolFilter(filters);
+       }
+       
+       /**
+        * Create a Protocol Filter
+        * 
+        * @throws IllegalArgumentException an invalid input has been provided
+        */
+       public JsonProtocolFilter() throws IllegalArgumentException {}
+       
+       /**
+        * 
+        * @param rawFilters raw filter initialization
+        * 
+        * @throws IllegalArgumentException an invalid input has been provided
+        */
+       public JsonProtocolFilter(List<FilterRule> filters) throws IllegalArgumentException {
+               this.rules = filters;
+       }
+
+       /**
+        * are there any filters?
+        * 
+        * @return true if there are filters, false otherwise
+        */
+       public boolean isRules() {
+               return !this.rules.isEmpty();
+       }
+
+       /**
+        * accept a JSON string as conformant it if passes all filters
+        * 
+        * @param json json is a JSON object
+        * @return true if json string is conformant
+        * 
+        * @throws IllegalArgumentException an invalid input has been provided
+        */
+       public synchronized boolean accept(JsonElement json) throws IllegalArgumentException {
+               if (json == null) {
+                       throw new IllegalArgumentException("no JSON provided");
+               }
+               
+               if (rules.isEmpty()) {
+                       return true;
+               }
+               
+               try {
+                       if (json == null || !json.isJsonObject()) {
+                               return false;
+                       }
+                       
+                       JsonObject event = json.getAsJsonObject();
+                       for (FilterRule filter: rules) {
+                               if (filter.regex == null || 
+                                       filter.regex.isEmpty() ||  
+                                       filter.regex.equals(".*")) {
+                                       
+                                       // Only check for presence
+                                       if (!event.has(filter.name)) {
+                                               return false;
+                                       }
+                               } else {
+                                       JsonElement field = event.get(filter.name);
+                                       if (field == null) {
+                                               return false;
+                                       }
+                                       
+                                       String fieldValue = field.getAsString();
+                                       if (!fieldValue.matches(filter.regex)) {
+                                               return false;
+                                       }
+                               }
+                       }
+                       return true;
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                       throw new IllegalArgumentException(e);
+               }
+       }
+       
+       /**
+        * accept a JSON string as conformant it if passes all filters
+        * 
+        * @param json json string
+        * @return true if json string is conformant
+        * 
+        * @throws IllegalArgumentException an invalid input has been provided
+        */
+       public synchronized boolean accept(String json) throws IllegalArgumentException {
+               if (json == null || json.isEmpty()) {
+                       throw new IllegalArgumentException("no JSON provided");
+               }
+               
+               if (rules.isEmpty()) {
+                       return true;
+               }
+               
+               try {
+                       JsonElement element = new JsonParser().parse(json);
+                       if (element == null || !element.isJsonObject()) {
+                               return false;
+                       }
+                       
+                       return this.accept(element.getAsJsonObject());
+               } catch (IllegalArgumentException ile) {
+                       throw ile;
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                       throw new IllegalArgumentException(e);                  
+               }
+       }
+
+       public List<FilterRule> getRules() {
+               return rules;
+       }
+
+       public synchronized void setRules(List<FilterRule> rulesFilters) {
+               this.rules = rulesFilters;
+       }
+       
+       public synchronized void deleteRules(String name) {
+               for (FilterRule rule : new ArrayList<>(this.rules)) {
+                   if (rule.name.equals(name)) {
+                       this.rules.remove(rule);
+                   }
+               }
+       }
+       
+       public List<FilterRule> getRules(String name) {
+               ArrayList<FilterRule> temp = new ArrayList<>();
+               for (FilterRule rule : new ArrayList<>(this.rules)) {
+                   if (rule.name.equals(name)) {
+                       temp.add(rule);
+                   }
+               }
+               return temp;
+       }
+       
+       public synchronized void deleteRule(String name, String regex) {
+               for (FilterRule rule : new ArrayList<>(this.rules)) {
+                   if (rule.name.equals(name) && rule.regex.equals(regex)) {
+                       this.rules.remove(rule);
+                   }
+               }
+       }
+       
+       public synchronized void addRule(String name, String regex) {
+               for (FilterRule rule : new ArrayList<>(this.rules)) {
+                   if (rule.name.equals(name) && rule.regex.equals(regex)) {
+                       return;
+                   }
+               }
+               
+               this.rules.add(new FilterRule(name,regex));
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("JsonProtocolFilter [rules=").append(rules).append("]");
+               return builder.toString();
+       }
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/ProtocolCoderToolset.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/ProtocolCoderToolset.java
new file mode 100644 (file)
index 0000000..9e079ff
--- /dev/null
@@ -0,0 +1,668 @@
+package org.openecomp.policy.drools.protocol.coders;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.time.Instant;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomCoder;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomGsonCoder;
+import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomJacksonCoder;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+/**
+ * Protocol Coding/Decoding Toolset
+ */
+public abstract class ProtocolCoderToolset {
+       
+       /**
+        * topic
+        */
+       protected final String topic;
+       
+       /**
+        * controller id
+        */
+       protected final String controllerId;
+       
+       /**
+        * group id
+        */
+       protected final String groupId;
+       
+       /**
+        * artifact id
+        */
+       protected final String artifactId;
+       
+       /**
+        * Protocols and associated Filters
+        */
+       protected final List<CoderFilters> coders = new ArrayList<CoderFilters>();
+       
+       /**
+        * Tree model (instead of class model) generic parsing to be able to inspect elements
+        */
+       protected JsonParser filteringParser = new JsonParser();
+
+       /**
+        * custom coder
+        */
+       protected CustomCoder customCoder;
+       
+       /**
+        * Constructor
+        * 
+        * @param topic the topic
+        * @param controllerId the controller id
+        * @param codedClass the decoded class
+        * @param filters list of filters that apply to the
+        * selection of this decodedClass in case of multiplicity
+        * @throws IllegalArgumentException if invalid data has been passed in
+        */
+       public ProtocolCoderToolset(String topic, 
+                                                               String controllerId, 
+                                           String groupId,
+                                           String artifactId,
+                                           String codedClass, 
+                                           JsonProtocolFilter filters, 
+                                                       CustomCoder customCoder,
+                                                       int modelClassLoaderHash)
+               throws IllegalArgumentException {
+               
+               if (topic == null || controllerId == null || 
+                       groupId == null || artifactId == null ||
+                       codedClass == null || filters == null ||
+                       topic.isEmpty() || controllerId.isEmpty()) {
+                       // TODO
+                       throw new IllegalArgumentException("Invalid input");
+               }
+               
+               this.topic = topic;
+               this.controllerId = controllerId;
+               this.groupId = groupId;
+               this.artifactId = artifactId;
+               this.coders.add(new CoderFilters(codedClass, filters, modelClassLoaderHash));
+               this.customCoder = customCoder;
+       }
+       
+       /**
+        * gets the coder + filters associated with this class name
+        * 
+        * @param classname class name
+        * @return the decoder filters or null if not found
+        */
+       public CoderFilters getCoder(String classname) {
+               for (CoderFilters decoder: this.coders) {
+                       if (decoder.factClass.equals(classname)) {
+                               return decoder;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * get all coder filters in use
+        * 
+        * @return coder filters
+        */
+       public List<CoderFilters> getCoders() {
+               return this.coders;
+       }
+
+       /**
+        * add coder or replace it exists
+        * 
+        * @param eventClass decoder
+        * @param filter filter
+        */
+       public void addCoder(String eventClass, JsonProtocolFilter filter, int modelClassLoaderHash) {
+               synchronized(this) {
+                       for (CoderFilters coder: this.coders) {
+                               if (coder.factClass.equals(eventClass)) {
+                                       // this is a better check than checking pointers, just
+                                       // in case classloader is different and this is just an update
+                                       coder.factClass = eventClass;
+                                       coder.filter = filter;
+                                       coder.modelClassLoaderHash = modelClassLoaderHash;
+                                       return;
+                               }
+                       }
+               }
+               
+               this.coders.add(new CoderFilters(eventClass, filter, modelClassLoaderHash));
+       }
+       
+       /**
+        * remove coder
+        * 
+        * @param eventClass decoder
+        * @param filter filter
+        */
+       public void removeCoders(String eventClass) {
+               synchronized(this) {
+                       Iterator<CoderFilters> codersIt = this.coders.iterator();
+                       while (codersIt.hasNext()) {
+                               CoderFilters coder = codersIt.next();
+                               if (coder.factClass.equals(eventClass)) {
+                                       codersIt.remove();
+                               }
+                       }
+               }
+       }
+
+       /**
+        * gets the topic
+        * 
+        * @return the topic
+        */
+       public String getTopic() {return topic;}
+       
+       /**
+        * gets the controller id
+        * 
+        * @return the controller id
+        */
+       public String getControllerId() {return controllerId;}
+
+       /**
+        * @return the groupId
+        */
+       public String getGroupId() {
+               return groupId;
+       }
+
+       /**
+        * @return the artifactId
+        */
+       public String getArtifactId() {
+               return artifactId;
+       }
+
+       /**
+        * @return the customCoder
+        */
+       public CustomCoder getCustomCoder() {
+               return customCoder;
+       }
+
+       /**
+        * @param customCoder the customCoder to set
+        */
+       public void setCustomCoder(CustomCoder customCoder) {
+               this.customCoder = customCoder;
+       }
+
+       /**
+        * performs filtering on a json string
+        * 
+        * @param json json string
+        * @return the decoder that passes the filter, otherwise null
+        * @throws UnsupportedOperationException can't filter
+        * @throws IllegalArgumentException invalid input
+        */
+       protected CoderFilters filter(String json) 
+                       throws UnsupportedOperationException, IllegalArgumentException, IllegalStateException {
+               
+
+               // 1. Get list of decoding classes for this controller Id and topic
+               // 2. If there are no classes, return error
+               // 3. Otherwise, from the available classes for decoding, pick the first one that
+               //    passes the filters        
+               
+               // Don't parse if it is not necessary
+               
+               if (this.coders.isEmpty()) {
+                       // TODO this is an error
+                       throw new IllegalStateException("No coders available");
+               }
+               
+               if (this.coders.size() == 1) {
+                       JsonProtocolFilter filter = this.coders.get(0).getFilter();
+                       if (!filter.isRules()) {
+                               return this.coders.get(0);
+                       }
+               }
+               
+               JsonElement event;
+               try {
+                       event = this.filteringParser.parse(json);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                       throw new UnsupportedOperationException(e);
+               }
+               
+               for (CoderFilters decoder: this.coders) {
+                       try {
+                               boolean accepted = decoder.getFilter().accept(event);
+                               if (accepted) {
+                                       return decoder;
+                               } 
+                       } catch (Exception e) {
+                               // TODO: handle exception
+                               e.printStackTrace();
+                       }
+               }
+               
+               return null;
+       }
+
+       /**
+        * Decode json into a POJO object
+        * @param json json string
+        * 
+        * @return a POJO object for the json string
+        * @throws IllegalArgumentException if an invalid parameter has been received
+        * @throws UnsupportedOperationException if parsing into POJO is not possible
+        */
+       public abstract Object decode(String json) 
+                       throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException;
+       
+       /**
+        * Encodes a POJO object into a JSON String
+        * 
+        * @param event JSON POJO event to be converted to String
+        * @return JSON string version of POJO object
+        * @throws IllegalArgumentException if an invalid parameter has been received
+        * @throws UnsupportedOperationException if parsing into POJO is not possible
+        */
+       public abstract String encode(Object event) 
+                       throws IllegalArgumentException, UnsupportedOperationException;
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("ProtocolCoderToolset [topic=").append(topic).append(", controllerId=").append(controllerId)
+                               .append(", groupId=").append(groupId).append(", artifactId=").append(artifactId).append(", coders=")
+                               .append(coders).append(", filteringParser=").append(filteringParser).append(", customCoder=")
+                               .append(customCoder).append("]");
+               return builder.toString();
+       }
+}
+
+/**
+ * Tools used for encoding/decoding using Jackson
+ */
+class JacksonProtocolCoderToolset extends ProtocolCoderToolset {
+       private static Logger  logger = FlexLogger.getLogger(JacksonProtocolCoderToolset.class);        
+       /**
+        * decoder
+        */
+       @JsonIgnore
+       protected final ObjectMapper decoder = new ObjectMapper();
+       
+       /**
+        * encoder
+        */
+       @JsonIgnore
+       protected final ObjectMapper encoder = new ObjectMapper();
+       
+       /**
+        * Toolset to encode/decode tools associated with a topic
+        * 
+        * @param topic topic
+        * @param decodedClass decoded class of an event
+        * @param filter 
+        */
+       public JacksonProtocolCoderToolset(String topic, String controllerId, 
+                                                                          String groupId, String artifactId,
+                                                  String decodedClass, 
+                                                  JsonProtocolFilter filter,
+                                                  CustomJacksonCoder customJacksonCoder,
+                                                  int modelClassLoaderHash) {
+               super(topic, controllerId, groupId, artifactId, decodedClass, filter, customJacksonCoder, modelClassLoaderHash);
+               decoder.registerModule(new JavaTimeModule());
+               decoder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 
+                                         false);
+       }
+       
+       /**
+        * gets the Jackson decoder
+        * 
+        * @return the Jackson decoder
+        */
+       @JsonIgnore
+       protected ObjectMapper getDecoder() {return decoder;}
+       
+       /**
+        * gets the Jackson encoder
+        * 
+        * @return the Jackson encoder
+        */
+       @JsonIgnore
+       protected ObjectMapper getEncoder() {return encoder;}
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Object decode(String json) 
+                       throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException {
+
+               // 0. Use custom coder if available
+               
+               if (this.customCoder != null) {
+                       throw new UnsupportedOperationException
+                                       ("Jackon Custom Decoder is not supported at this time");
+               }
+               
+               DroolsController droolsController = 
+                               DroolsController.factory.get(groupId, artifactId, "");
+               if (droolsController == null) {
+                       String error = "NO-DROOLS-CONTROLLER for: " + json + " IN " + this;
+                       logger.warn(error);
+                       throw new IllegalStateException(error);
+               }
+               
+               CoderFilters decoderFilter = filter(json);
+               if (decoderFilter == null) {
+                       String error = "NO-DECODER for: " + json + " IN " + this;
+                       logger.warn(error);
+                       throw new UnsupportedOperationException(error);
+               }
+               
+               Class<?> decoderClass;
+               try {
+                       decoderClass = 
+                                       droolsController.fetchModelClass(decoderFilter.getCodedClass());
+                       if (decoderClass ==  null) {
+                               String error = "DECODE-ERROR FETCHING MODEL CLASS: " + ":" + json + ":" + this;
+                               logger.error(error);
+                               throw new IllegalStateException(error);                         
+                       }
+               } catch (Exception e) {
+                       String error = "DECODE-ERROR FETCHING MODEL CLASS: "+ e.getMessage() + ":" + json + ":" + this;
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, error);
+                       throw new UnsupportedOperationException(error, e);
+               }
+               
+
+               try {
+                       Object fact = this.decoder.readValue(json, decoderClass);
+                       return fact;
+               } catch (Exception e) {
+                       String error = "DECODE-ERROR FROM PDP-D FRAMEWORK: "+ json + ":" + e.getMessage() + ":" + this;
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, error);
+                       throw new UnsupportedOperationException(error, e);
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String encode(Object event) 
+                       throws IllegalArgumentException, UnsupportedOperationException {
+               
+               // 0. Use custom coder if available
+               
+               if (this.customCoder != null) {
+                       throw new UnsupportedOperationException
+                                       ("Jackon Custom Encoder is not supported at this time");
+               }
+               
+               try {
+                       String encodedEvent = this.encoder.writeValueAsString(event);
+                       return encodedEvent;                    
+               } catch (JsonProcessingException e) {
+                       String error = "ENCODE-ERROR: "+ event + " IN " + this;
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, error);
+                       throw new UnsupportedOperationException(error, e);
+               }
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("JacksonProtocolCoderToolset [toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+
+}
+
+/**
+ * Tools used for encoding/decoding using Jackson
+ */
+class GsonProtocolCoderToolset extends ProtocolCoderToolset {
+       
+       private static Logger  logger = FlexLogger.getLogger(GsonProtocolCoderToolset.class);
+       /**
+        * Formatter for JSON encoding/decoding
+        */
+       @JsonIgnore
+       public static DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSxxx");
+       
+       @JsonIgnore
+       public static DateTimeFormatter zuluFormat = DateTimeFormatter.ISO_INSTANT;
+       
+       /**
+        * Adapter for ZonedDateTime
+        */
+
+       public static class GsonUTCAdapter implements JsonSerializer<ZonedDateTime>, JsonDeserializer<ZonedDateTime> {
+
+               public ZonedDateTime deserialize(JsonElement element, Type type, JsonDeserializationContext context)
+                               throws JsonParseException {
+                       try {
+                               return ZonedDateTime.parse(element.getAsString(), format);
+                       } catch (Exception e) {
+                               System.err.println(e);
+                       }
+                       return null;
+               }
+
+               public JsonElement serialize(ZonedDateTime datetime, Type type, JsonSerializationContext context) {
+                       return new JsonPrimitive(datetime.format(format));
+               }       
+       }
+       
+       public static class GsonInstantAdapter implements JsonSerializer<Instant>, JsonDeserializer<Instant> {
+
+               @Override
+               public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+                               throws JsonParseException {
+                       return Instant.ofEpochMilli(json.getAsLong());
+               }
+
+               @Override
+               public JsonElement serialize(Instant src, Type typeOfSrc, JsonSerializationContext context) {
+                       return new JsonPrimitive(src.toEpochMilli());
+               }
+               
+       }
+
+       
+       /**
+        * decoder
+        */
+       @JsonIgnore
+       protected final Gson decoder = new GsonBuilder().disableHtmlEscaping().
+                                                                                                        registerTypeAdapter(ZonedDateTime.class, new GsonUTCAdapter()).
+                                                                                                        create();
+       
+       /**
+        * encoder
+        */
+       @JsonIgnore
+       protected final Gson encoder = new GsonBuilder().disableHtmlEscaping().
+                                                                                                        registerTypeAdapter(ZonedDateTime.class, new GsonUTCAdapter()).
+                                                                                                        create();
+       
+       /**
+        * Toolset to encode/decode tools associated with a topic
+        * 
+        * @param topic topic
+        * @param decodedClass decoded class of an event
+        * @param filter 
+        */
+       public GsonProtocolCoderToolset(String topic, String controllerId, 
+                                                                       String groupId, String artifactId,
+                                                                       String decodedClass, 
+                                                                       JsonProtocolFilter filter,
+                                                               CustomGsonCoder customGsonCoder,
+                                                               int modelClassLoaderHash) {
+               super(topic, controllerId, groupId, artifactId, decodedClass, filter, customGsonCoder, modelClassLoaderHash);
+       }
+       
+       /**
+        * gets the Gson decoder
+        * 
+        * @return the Gson decoder
+        */
+       @JsonIgnore
+       protected Gson getDecoder() {return decoder;}
+       
+       /**
+        * gets the Gson encoder
+        * 
+        * @return the Gson encoder
+        */
+       @JsonIgnore
+       protected Gson getEncoder() {return encoder;}
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Object decode(String json) 
+                       throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException {
+       
+               DroolsController droolsController = 
+                               DroolsController.factory.get(groupId, artifactId, "");
+               if (droolsController == null) {
+                       String error = "NO-DROOLS-CONTROLLER for: " + json + " IN " + this;
+                       logger.warn(error);
+                       throw new IllegalStateException(error);
+               }
+               
+               CoderFilters decoderFilter = filter(json);
+               if (decoderFilter == null) {
+                       String error = "NO-DECODER for: " + json + " IN " + this;
+                       logger.warn(error);
+                       throw new UnsupportedOperationException(error);
+               }
+               
+               Class<?> decoderClass;
+               try {
+                       decoderClass = 
+                                       droolsController.fetchModelClass(decoderFilter.getCodedClass());
+                       if (decoderClass ==  null) {
+                               String error = "DECODE-ERROR FETCHING MODEL CLASS: " + ":" + json + ":" + this;
+                               logger.error(error);
+                               throw new IllegalStateException(error);                         
+                       }
+               } catch (Exception e) {
+                       String error = "DECODE-ERROR FETCHING MODEL CLASS: "+ e.getMessage() + ":" + json + ":" + this;
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, error);
+                       throw new UnsupportedOperationException(error, e);
+               }
+               
+               if (this.customCoder != null) {
+                       try {
+                               Class<?> gsonClassContainer = 
+                                               droolsController.fetchModelClass(this.customCoder.getClassContainer());
+                               Field gsonField = gsonClassContainer.getField(this.customCoder.staticCoderField);
+                               Object gsonObject = gsonField.get(null);
+                               Method fromJsonMethod = gsonObject.getClass().
+                                                                    getDeclaredMethod
+                                                                       ("fromJson", new Class[]{String.class, Class.class});
+                               Object fact = fromJsonMethod.invoke(gsonObject, json, decoderClass);
+                               return fact;
+                       } catch (NoSuchFieldException | SecurityException | IllegalAccessException | 
+                                        NoSuchMethodException | InvocationTargetException e) {
+                               String error = "DECODE-ERROR-FROM-CUSTOM-CODER: " + e.getMessage() + ":" + json + ":" + this;
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, error);
+                               throw new UnsupportedOperationException(error, e);
+                       }                       
+               } else {
+                       try {
+                               Object fact = this.decoder.fromJson(json, decoderClass);
+                               return fact;
+                       } catch (Exception e) {
+                               String error = "DECODE-ERROR FROM PDP-D FRAMEWORK: "+ json + ":" + e.getMessage() + ":" + this;
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, error);
+                               throw new UnsupportedOperationException(error, e);
+                       }                       
+               }
+       }
+
+
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String encode(Object event) 
+                       throws IllegalArgumentException, UnsupportedOperationException {        
+               
+               DroolsController droolsController = 
+                               DroolsController.factory.get(groupId, artifactId, "");
+               if (droolsController == null) {
+                       String error = "NO-DROOLS-CONTROLLER for: " + event + " IN " + this;
+                       logger.warn(error);
+                       throw new IllegalStateException(error);
+               }
+               
+               if (this.customCoder != null) {
+                       try {
+                               Class<?> gsonClassContainer = 
+                                               droolsController.fetchModelClass(this.customCoder.getClassContainer());
+                               Field gsonField = gsonClassContainer.getField(this.customCoder.staticCoderField);
+                               Object gsonObject = gsonField.get(null);
+                               Method toJsonMethod = gsonObject.getClass().
+                                                                    getDeclaredMethod
+                                                                       ("toJson", new Class[]{Object.class});
+                               String encodedJson = (String) toJsonMethod.invoke(gsonObject, event);
+                               return encodedJson;
+                       } catch (NoSuchFieldException | SecurityException | IllegalAccessException | 
+                                        NoSuchMethodException | InvocationTargetException e) {
+                               String error = "DECODE-ERROR-FROM-CUSTOM-CODER: " + e.getMessage() + ":" + event + ":" + this;
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, error);
+                               throw new UnsupportedOperationException(error, e);
+                       }                       
+               } else {
+                       try {
+                               String encodedEvent = this.encoder.toJson(event);
+                               return encodedEvent;                    
+                       } catch (Exception e) {
+                               String error = "ENCODE-ERROR: "+ event + " IN " + this;
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, error);
+                               throw new UnsupportedOperationException(error, e);
+                       }               
+               }
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("GsonProtocolCoderToolset [toString()=").append(super.toString()).append("]");
+               return builder.toString();
+       }
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java
new file mode 100644 (file)
index 0000000..3c11257
--- /dev/null
@@ -0,0 +1,309 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.protocol.coders;
+
+import java.util.List;
+
+public class TopicCoderFilterConfiguration {
+
+       /**
+        * Custom coder, contains class and static field to access parser that the controller
+        * desires to use instead of the framework provided parser
+        */
+       public static abstract class CustomCoder {
+               protected String className;
+               protected String staticCoderField;
+               
+               /**
+                * create custom coder from raw string in the following format
+                * (typically embedded in a property file):
+                * 
+                * Note this is to support decoding/encoding of partial structures that are
+                * only known by the model.
+                * 
+                * @param rawCustomCoder with format: <class-containing-custom-coder>,<static-coder-field>
+                */
+               public CustomCoder(String rawCustomCoder) throws IllegalArgumentException {                     
+                       if (rawCustomCoder != null && !rawCustomCoder.isEmpty()) {
+                               
+                               this.className = rawCustomCoder.substring(0,rawCustomCoder.indexOf(","));
+                               if (this.className == null || this.className.isEmpty()) {
+                                       throw new IllegalArgumentException("No classname to create CustomCoder cannot be created");
+                               }
+                               
+                               this.staticCoderField = rawCustomCoder.substring(rawCustomCoder.indexOf(",")+1);
+                               if (this.staticCoderField == null || this.staticCoderField.isEmpty()) {
+                                       throw new IllegalArgumentException
+                                               ("No staticCoderField to create CustomCoder cannot be created for class " +
+                                                className);
+                               }
+
+                       }
+               }
+               /**
+                * @param classContainer
+                * @param staticCoderField
+                */
+               public CustomCoder(String className, String staticCoderField) throws IllegalArgumentException {
+                       if (className == null || className.isEmpty()) {
+                               throw new IllegalArgumentException("No classname to create CustomCoder cannot be created");
+                       }
+                       
+                       if (staticCoderField == null || staticCoderField.isEmpty()) {
+                               throw new IllegalArgumentException
+                                       ("No staticCoderField to create CustomCoder cannot be created for class " +
+                                        className);
+                       }
+                       
+                       this.className = className;
+                       this.staticCoderField = staticCoderField;
+               }
+
+               /**
+                * @return the className
+                */
+               public String getClassContainer() {
+                       return className;
+               }
+
+               /**
+                * @param className the className to set
+                */
+               public void setClassContainer(String className) {
+                       this.className = className;
+               }
+
+               /**
+                * @return the staticCoderField
+                */
+               public String getStaticCoderField() {
+                       return staticCoderField;
+               }
+
+               /**
+                * @param staticCoderField the staticGson to set
+                */
+               public void setStaticCoderField(String staticCoderField) {
+                       this.staticCoderField = staticCoderField;
+               }
+
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("CustomCoder [className=").append(className).append(", staticCoderField=")
+                                       .append(staticCoderField).append("]");
+                       return builder.toString();
+               }
+       }
+       
+       public static class CustomGsonCoder extends CustomCoder {
+       
+               public CustomGsonCoder(String className, String staticCoderField) {
+                               super(className, staticCoderField);
+               }
+
+               public CustomGsonCoder(String customGson) throws IllegalArgumentException {
+                       super(customGson);
+               }
+
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("CustomGsonCoder [toString()=").append(super.toString()).append("]");
+                       return builder.toString();
+               }
+
+       }
+       
+       public static class CustomJacksonCoder extends CustomCoder {
+               
+               public CustomJacksonCoder(String className, String staticCoderField) {
+                               super(className, staticCoderField);
+               }
+               
+               public CustomJacksonCoder(String customJackson) throws IllegalArgumentException {
+                       super(customJackson);
+               }
+               
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("CustomJacksonCoder [toString()=").append(super.toString()).append("]");
+                       return builder.toString();
+               }
+
+       }
+
+       /**
+        * Coder/Decoder class and Filter container.   The decoder class is potential,
+        * in order to be operational needs to be fetched from an available
+        * class loader.
+        *
+        */
+       public static class PotentialCoderFilter {
+
+               /**
+                * decoder class (pending from being able to be fetched and found 
+                * in some class loader)
+                */
+               protected String codedClass;
+               
+               /**
+                * filters to apply to the selection of the decodedClass;
+                */
+               protected JsonProtocolFilter filter;
+               
+               /**
+                * constructor
+                * 
+                * @param codedClass decoder class
+                * @param filter filters to apply
+                */
+               public PotentialCoderFilter(String codedClass, JsonProtocolFilter filter) {
+                       this.codedClass = codedClass;
+                       this.filter = filter;
+               }
+
+               /**
+                * @return the decodedClass
+                */
+               public String getCodedClass() {
+                       return codedClass;
+               }
+
+               /**
+                * @param decodedClass the decodedClass to set
+                */
+               public void setCodedClass(String decodedClass) {
+                       this.codedClass = decodedClass;
+               }
+
+               /**
+                * @return the filter
+                */
+               public JsonProtocolFilter getFilter() {
+                       return filter;
+               }
+
+               /**
+                * @param filter the filter to set
+                */
+               public void setFilter(JsonProtocolFilter filter) {
+                       this.filter = filter;
+               }
+
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       builder.append("PotentialCoderFilter [codedClass=").append(codedClass).append(", filter=").append(filter)
+                                       .append("]");
+                       return builder.toString();
+               }
+       }
+       
+       /**
+        * the source topic
+        */
+       protected final String topic;
+       
+       /**
+        * List of decoder -> filters
+        */
+       protected final List<PotentialCoderFilter> coderFilters;
+       
+       /**
+        * custom gson coder that this controller prefers to use instead of the framework ones
+        */
+       protected CustomGsonCoder customGsonCoder;
+       
+       /**
+        * custom jackson coder that this controller prefers to use instead of the framework ones
+        */
+       protected CustomJacksonCoder customJacksonCoder;
+
+       /**
+        * Constructor 
+        * 
+        * @param decoderFilters list of decoders and associated filters
+        * @param topic the topic
+        */
+       public TopicCoderFilterConfiguration(String topic, List<PotentialCoderFilter> decoderFilters,
+                                         CustomGsonCoder customGsonCoder, 
+                                         CustomJacksonCoder customJacksonCoder) {
+               this.coderFilters = decoderFilters;
+               this.topic = topic;
+               this.customGsonCoder = customGsonCoder;
+               this.customJacksonCoder = customJacksonCoder;
+       }
+
+       /**
+        * @return the topic
+        */
+       public String getTopic() {
+               return topic;
+       }
+
+       /**
+        * @return the decoderFilters
+        */
+       public List<PotentialCoderFilter> getCoderFilters() {
+               return coderFilters;
+       }
+       
+       /**
+        * @return the customGsonCoder
+        */
+       public CustomGsonCoder getCustomGsonCoder() {
+               return customGsonCoder;
+       }
+
+       /**
+        * @param customGsonCoder the customGsonCoder to set
+        */
+       public void setCustomGsonCoder(CustomGsonCoder customGsonCoder) {
+               this.customGsonCoder = customGsonCoder;
+       }
+
+       /**
+        * @return the customJacksonCoder
+        */
+       public CustomJacksonCoder getCustomJacksonCoder() {
+               return customJacksonCoder;
+       }
+
+       /**
+        * @param customJacksonCoder the customJacksonCoder to set
+        */
+       public void setCustomJacksonCoder(CustomJacksonCoder customJacksonCoder) {
+               this.customJacksonCoder = customJacksonCoder;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("TopicCoderFilterConfiguration [topic=").append(topic).append(", coderFilters=")
+                               .append(coderFilters).append(", customGsonCoder=").append(customGsonCoder)
+                               .append(", customJacksonCoder=").append(customJacksonCoder).append("]");
+               return builder.toString();
+       }
+
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/ControllerConfiguration.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/ControllerConfiguration.java
new file mode 100644 (file)
index 0000000..98af02e
--- /dev/null
@@ -0,0 +1,280 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.protocol.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+
+/**
+ * Drools Related Information
+ * 
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ControllerConfiguration {
+
+       public static final String CONFIG_CONTROLLER_OPERATION_CREATE = "create";
+       public static final String CONFIG_CONTROLLER_OPERATION_UPDATE = "update";
+       public static final String CONFIG_CONTROLLER_OPERATION_LOCK = "lock";
+       public static final String CONFIG_CONTROLLER_OPERATION_UNLOCK = "unlock";
+       
+    /**
+     * 
+     * (Required)
+     * 
+     */
+    @JsonProperty("name")
+    private String name;
+    /**
+     * Set of operations that can be applied to a controller: create, lock
+     * (Required)
+     * 
+     */
+    @JsonProperty("operation")
+    private String operation;
+    /**
+     * Maven Related Information
+     * 
+     */
+    @JsonProperty("drools")
+    private DroolsConfiguration drools;
+    @JsonIgnore
+    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+    protected final static Object NOT_FOUND_VALUE = new Object();
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public ControllerConfiguration() {
+    }
+
+    /**
+     * 
+     * @param name
+     * @param drools
+     * @param operation
+     */
+    public ControllerConfiguration(String name, String operation, DroolsConfiguration drools) {
+        this.name = name;
+        this.operation = operation;
+        this.drools = drools;
+    }
+
+    /**
+     * 
+     * (Required)
+     * 
+     * @return
+     *     The name
+     */
+    @JsonProperty("name")
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 
+     * (Required)
+     * 
+     * @param name
+     *     The name
+     */
+    @JsonProperty("name")
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public ControllerConfiguration withName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * Set of operations that can be applied to a controller: create, lock
+     * (Required)
+     * 
+     * @return
+     *     The operation
+     */
+    @JsonProperty("operation")
+    public String getOperation() {
+        return operation;
+    }
+
+    /**
+     * Set of operations that can be applied to a controller: create, lock
+     * (Required)
+     * 
+     * @param operation
+     *     The operation
+     */
+    @JsonProperty("operation")
+    public void setOperation(String operation) {
+        this.operation = operation;
+    }
+
+    public ControllerConfiguration withOperation(String operation) {
+        this.operation = operation;
+        return this;
+    }
+
+    /**
+     * Maven Related Information
+     * 
+     * @return
+     *     The drools
+     */
+    @JsonProperty("drools")
+    public DroolsConfiguration getDrools() {
+        return drools;
+    }
+
+    /**
+     * Maven Related Information
+     * 
+     * @param drools
+     *     The drools
+     */
+    @JsonProperty("drools")
+    public void setDrools(DroolsConfiguration drools) {
+        this.drools = drools;
+    }
+
+    public ControllerConfiguration withDrools(DroolsConfiguration drools) {
+        this.drools = drools;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+    @JsonAnyGetter
+    public Map<String, Object> getAdditionalProperties() {
+        return this.additionalProperties;
+    }
+
+    @JsonAnySetter
+    public void setAdditionalProperty(String name, Object value) {
+        this.additionalProperties.put(name, value);
+    }
+
+    public ControllerConfiguration withAdditionalProperty(String name, Object value) {
+        this.additionalProperties.put(name, value);
+        return this;
+    }
+
+    protected boolean declaredProperty(String name, Object value) {
+        switch (name) {
+            case "name":
+                if (value instanceof String) {
+                    setName(((String) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"name\" is of type \"java.lang.String\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            case "operation":
+                if (value instanceof String) {
+                    setOperation(((String) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"operation\" is of type \"java.lang.String\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            case "drools":
+                if (value instanceof DroolsConfiguration) {
+                    setDrools(((DroolsConfiguration) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"drools\" is of type \"org.openecomp.policy.drools.protocol.configuration.Drools\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    protected Object declaredPropertyOrNotFound(String name, Object notFoundValue) {
+        switch (name) {
+            case "name":
+                return getName();
+            case "operation":
+                return getOperation();
+            case "drools":
+                return getDrools();
+            default:
+                return notFoundValue;
+        }
+    }
+
+    @SuppressWarnings({
+        "unchecked"
+    })
+    public<T >T get(String name) {
+        Object value = declaredPropertyOrNotFound(name, ControllerConfiguration.NOT_FOUND_VALUE);
+        if (ControllerConfiguration.NOT_FOUND_VALUE!= value) {
+            return ((T) value);
+        } else {
+            return ((T) getAdditionalProperties().get(name));
+        }
+    }
+
+    public void set(String name, Object value) {
+        if (!declaredProperty(name, value)) {
+            getAdditionalProperties().put(name, ((Object) value));
+        }
+    }
+
+    public ControllerConfiguration with(String name, Object value) {
+        if (!declaredProperty(name, value)) {
+            getAdditionalProperties().put(name, ((Object) value));
+        }
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().append(name).append(operation).append(drools).append(additionalProperties).toHashCode();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if ((other instanceof ControllerConfiguration) == false) {
+            return false;
+        }
+        ControllerConfiguration rhs = ((ControllerConfiguration) other);
+        return new EqualsBuilder().append(name, rhs.name).append(operation, rhs.operation).append(drools, rhs.drools).append(additionalProperties, rhs.additionalProperties).isEquals();
+    }
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/DroolsConfiguration.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/DroolsConfiguration.java
new file mode 100644 (file)
index 0000000..87cf234
--- /dev/null
@@ -0,0 +1,278 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.protocol.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+
+/**
+ * Maven Related Information
+ * 
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class DroolsConfiguration {
+
+    /**
+     * Maven Artifact ID
+     * (Required)
+     * 
+     */
+    @JsonProperty("artifactId")
+    private String artifactId;
+    /**
+     * Maven Group ID
+     * (Required)
+     * 
+     */
+    @JsonProperty("groupId")
+    private String groupId;
+    /**
+     * Maven Version
+     * (Required)
+     * 
+     */
+    @JsonProperty("version")
+    private String version;
+    @JsonIgnore
+    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+    protected final static Object NOT_FOUND_VALUE = new Object();
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public DroolsConfiguration() {
+    }
+
+    /**
+     * 
+     * @param groupId
+     * @param artifactId
+     * @param version
+     */
+    public DroolsConfiguration(String artifactId, String groupId, String version) {
+        this.artifactId = artifactId;
+        this.groupId = groupId;
+        this.version = version;
+    }
+
+    /**
+     * Maven Artifact ID
+     * (Required)
+     * 
+     * @return
+     *     The artifactId
+     */
+    @JsonProperty("artifactId")
+    public String getArtifactId() {
+        return artifactId;
+    }
+
+    /**
+     * Maven Artifact ID
+     * (Required)
+     * 
+     * @param artifactId
+     *     The artifactId
+     */
+    @JsonProperty("artifactId")
+    public void setArtifactId(String artifactId) {
+        this.artifactId = artifactId;
+    }
+
+    public DroolsConfiguration withArtifactId(String artifactId) {
+        this.artifactId = artifactId;
+        return this;
+    }
+
+    /**
+     * Maven Group ID
+     * (Required)
+     * 
+     * @return
+     *     The groupId
+     */
+    @JsonProperty("groupId")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    /**
+     * Maven Group ID
+     * (Required)
+     * 
+     * @param groupId
+     *     The groupId
+     */
+    @JsonProperty("groupId")
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    public DroolsConfiguration withGroupId(String groupId) {
+        this.groupId = groupId;
+        return this;
+    }
+
+    /**
+     * Maven Version
+     * (Required)
+     * 
+     * @return
+     *     The version
+     */
+    @JsonProperty("version")
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Maven Version
+     * (Required)
+     * 
+     * @param version
+     *     The version
+     */
+    @JsonProperty("version")
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public DroolsConfiguration withVersion(String version) {
+        this.version = version;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+    @JsonAnyGetter
+    public Map<String, Object> getAdditionalProperties() {
+        return this.additionalProperties;
+    }
+
+    @JsonAnySetter
+    public void setAdditionalProperty(String name, Object value) {
+        this.additionalProperties.put(name, value);
+    }
+
+    public DroolsConfiguration withAdditionalProperty(String name, Object value) {
+        this.additionalProperties.put(name, value);
+        return this;
+    }
+
+    protected boolean declaredProperty(String name, Object value) {
+        switch (name) {
+            case "artifactId":
+                if (value instanceof String) {
+                    setArtifactId(((String) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"artifactId\" is of type \"java.lang.String\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            case "groupId":
+                if (value instanceof String) {
+                    setGroupId(((String) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"groupId\" is of type \"java.lang.String\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            case "version":
+                if (value instanceof String) {
+                    setVersion(((String) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"version\" is of type \"java.lang.String\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    protected Object declaredPropertyOrNotFound(String name, Object notFoundValue) {
+        switch (name) {
+            case "artifactId":
+                return getArtifactId();
+            case "groupId":
+                return getGroupId();
+            case "version":
+                return getVersion();
+            default:
+                return notFoundValue;
+        }
+    }
+
+    @SuppressWarnings({
+        "unchecked"
+    })
+    public<T >T get(String name) {
+        Object value = declaredPropertyOrNotFound(name, DroolsConfiguration.NOT_FOUND_VALUE);
+        if (DroolsConfiguration.NOT_FOUND_VALUE!= value) {
+            return ((T) value);
+        } else {
+            return ((T) getAdditionalProperties().get(name));
+        }
+    }
+
+    public void set(String name, Object value) {
+        if (!declaredProperty(name, value)) {
+            getAdditionalProperties().put(name, ((Object) value));
+        }
+    }
+
+    public DroolsConfiguration with(String name, Object value) {
+        if (!declaredProperty(name, value)) {
+            getAdditionalProperties().put(name, ((Object) value));
+        }
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().append(artifactId).append(groupId).append(version).append(additionalProperties).toHashCode();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if ((other instanceof DroolsConfiguration) == false) {
+            return false;
+        }
+        DroolsConfiguration rhs = ((DroolsConfiguration) other);
+        return new EqualsBuilder().append(artifactId, rhs.artifactId).append(groupId, rhs.groupId).append(version, rhs.version).append(additionalProperties, rhs.additionalProperties).isEquals();
+    }
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/PdpdConfiguration.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/PdpdConfiguration.java
new file mode 100644 (file)
index 0000000..65de665
--- /dev/null
@@ -0,0 +1,283 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.protocol.configuration;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+
+/**
+ * ENGINE-CONFIGURATION
+ * <p>
+ * 
+ * 
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class PdpdConfiguration {
+       
+       /**
+        * Controller Entity ID
+        */
+       public static final String CONFIG_ENTITY_CONTROLLER = "controller";
+
+    /**
+     * Unique Transaction ID.   This is an UUID.
+     * (Required)
+     * 
+     */
+    @JsonProperty("requestID")
+    private String requestID;
+    /**
+     * Set of entities on which configuration can be performed: controller
+     * (Required)
+     * 
+     */
+    @JsonProperty("entity")
+    private String entity;
+    /**
+     * Controller Information, only applicable when the entity is set to controller
+     * 
+     */
+    @JsonProperty("controllers")
+    private List<ControllerConfiguration> controllers = new ArrayList<ControllerConfiguration>();
+    @JsonIgnore
+    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+    protected final static Object NOT_FOUND_VALUE = new Object();
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public PdpdConfiguration() {
+    }
+
+    /**
+     * 
+     * @param controller
+     * @param requestID
+     * @param entity
+     */
+    public PdpdConfiguration(String requestID, String entity, List<ControllerConfiguration> controllers) {
+        this.requestID = requestID;
+        this.entity = entity;
+        this.controllers = controllers;
+    }
+
+    /**
+     * Unique Transaction ID.   This is an UUID.
+     * (Required)
+     * 
+     * @return
+     *     The requestID
+     */
+    @JsonProperty("requestID")
+    public String getRequestID() {
+        return requestID;
+    }
+
+    /**
+     * Unique Transaction ID.   This is an UUID.
+     * (Required)
+     * 
+     * @param requestID
+     *     The requestID
+     */
+    @JsonProperty("requestID")
+    public void setRequestID(String requestID) {
+        this.requestID = requestID;
+    }
+
+    public PdpdConfiguration withRequestID(String requestID) {
+        this.requestID = requestID;
+        return this;
+    }
+
+    /**
+     * Set of entities on which configuration can be performed: controller
+     * (Required)
+     * 
+     * @return
+     *     The entity
+     */
+    @JsonProperty("entity")
+    public String getEntity() {
+        return entity;
+    }
+
+    /**
+     * Set of entities on which configuration can be performed: controller
+     * (Required)
+     * 
+     * @param entity
+     *     The entity
+     */
+    @JsonProperty("entity")
+    public void setEntity(String entity) {
+        this.entity = entity;
+    }
+
+    public PdpdConfiguration withEntity(String entity) {
+        this.entity = entity;
+        return this;
+    }
+
+    /**
+     * Controller Information, only applicable when the entity is set to controller
+     * 
+     * @return
+     *     The controller
+     */
+    @JsonProperty("controller")
+    public List<ControllerConfiguration> getControllers() {
+        return controllers;
+    }
+
+    /**
+     * Controller Information, only applicable when the entity is set to controller
+     * 
+     * @param controller
+     *     The controller
+     */
+    @JsonProperty("controller")
+    public void setControllers(List<ControllerConfiguration> controllers) {
+        this.controllers = controllers;
+    }
+
+    public PdpdConfiguration withController(List<ControllerConfiguration> controllers) {
+        this.controllers = controllers;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+    @JsonAnyGetter
+    public Map<String, Object> getAdditionalProperties() {
+        return this.additionalProperties;
+    }
+
+    @JsonAnySetter
+    public void setAdditionalProperty(String name, Object value) {
+        this.additionalProperties.put(name, value);
+    }
+
+    public PdpdConfiguration withAdditionalProperty(String name, Object value) {
+        this.additionalProperties.put(name, value);
+        return this;
+    }
+
+    @SuppressWarnings("unchecked")
+       protected boolean declaredProperty(String name, Object value) {
+        switch (name) {
+            case "requestID":
+                if (value instanceof String) {
+                    setRequestID(((String) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"requestID\" is of type \"java.lang.String\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            case "entity":
+                if (value instanceof String) {
+                    setEntity(((String) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"entity\" is of type \"java.lang.String\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            case "controllers":
+                if (value instanceof List) {
+                    setControllers(((List<ControllerConfiguration> ) value));
+                } else {
+                    throw new IllegalArgumentException(("property \"controllers\" is of type \"java.util.List<org.openecomp.policy.drools.protocol.configuration.Controller>\", but got "+ value.getClass().toString()));
+                }
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    protected Object declaredPropertyOrNotFound(String name, Object notFoundValue) {
+        switch (name) {
+            case "requestID":
+                return getRequestID();
+            case "entity":
+                return getEntity();
+            case "controllers":
+                return getControllers();
+            default:
+                return notFoundValue;
+        }
+    }
+
+    @SuppressWarnings({
+        "unchecked"
+    })
+    public<T >T get(String name) {
+        Object value = declaredPropertyOrNotFound(name, PdpdConfiguration.NOT_FOUND_VALUE);
+        if (PdpdConfiguration.NOT_FOUND_VALUE!= value) {
+            return ((T) value);
+        } else {
+            return ((T) getAdditionalProperties().get(name));
+        }
+    }
+
+    public void set(String name, Object value) {
+        if (!declaredProperty(name, value)) {
+            getAdditionalProperties().put(name, ((Object) value));
+        }
+    }
+
+    public PdpdConfiguration with(String name, Object value) {
+        if (!declaredProperty(name, value)) {
+            getAdditionalProperties().put(name, ((Object) value));
+        }
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().append(requestID).append(entity).append(controllers).append(additionalProperties).toHashCode();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if ((other instanceof PdpdConfiguration) == false) {
+            return false;
+        }
+        PdpdConfiguration rhs = ((PdpdConfiguration) other);
+        return new EqualsBuilder().append(requestID, rhs.requestID).append(entity, rhs.entity).append(controllers, rhs.controllers).append(additionalProperties, rhs.additionalProperties).isEquals();
+    }
+
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java b/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java
new file mode 100644 (file)
index 0000000..48e6313
--- /dev/null
@@ -0,0 +1,1181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.server.restful;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.event.comm.TopicEndpoint;
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.event.comm.TopicSource;
+import org.openecomp.policy.drools.event.comm.bus.DmaapTopicSink;
+import org.openecomp.policy.drools.event.comm.bus.DmaapTopicSource;
+import org.openecomp.policy.drools.event.comm.bus.UebTopicSink;
+import org.openecomp.policy.drools.event.comm.bus.UebTopicSource;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+import org.openecomp.policy.drools.protocol.coders.EventProtocolCoder;
+import org.openecomp.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters;
+import org.openecomp.policy.drools.protocol.coders.JsonProtocolFilter;
+import org.openecomp.policy.drools.protocol.coders.JsonProtocolFilter.FilterRule;
+import org.openecomp.policy.drools.protocol.coders.ProtocolCoderToolset;
+import org.openecomp.policy.drools.protocol.configuration.ControllerConfiguration;
+import org.openecomp.policy.drools.protocol.configuration.PdpdConfiguration;
+import org.openecomp.policy.drools.system.PolicyController;
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+
+/**
+ * REST Endpoint for management of the Drools PDP
+ */
+@Path("/policy/pdp")
+public class RestManager {
+       /**
+        * Logger
+        */
+       private static Logger  logger = FlexLogger.getLogger(RestManager.class);  
+       
+       /**
+        * gets the Policy Engine
+        * 
+        * @return the Policy Engine
+        */
+    @GET
+    @Path("engine")
+    @Produces(MediaType.APPLICATION_JSON)
+    public PolicyEngine engine() {     
+       return PolicyEngine.manager;
+    }
+    
+    
+    /**
+     * Updates the Policy Engine
+     * 
+     * @param configuration configuration
+     * @return Policy Engine
+     */
+    @PUT
+    @Path("engine")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateEngine(PdpdConfiguration configuration) {
+       PolicyController controller = null;
+       boolean success = true;
+               try {
+                       success = PolicyEngine.manager.configure(configuration);
+               } catch (Exception e) {
+                       success = false;
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                              "PolicyEngine", this.toString());
+               }
+       
+               if (!success)
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                    entity(new Error("cannot perform operation")).build();
+               else
+                       return Response.status(Response.Status.OK).entity(controller).build();
+    }
+    
+    /**
+     * Activates the Policy Engine
+     * 
+     * @param configuration configuration
+     * @return Policy Engine
+     */
+    @PUT
+    @Path("engine/activation")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response activateEngine() {
+       boolean success = true;
+               try {
+                       PolicyEngine.manager.activate();
+               } catch (Exception e) {
+                       success = false;
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                              "PolicyEngine", this.toString());
+               }
+       
+               if (!success)
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                    entity(new Error("cannot perform operation")).build();
+               else
+                       return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
+    }
+    
+    /**
+     * Activates the Policy Engine
+     * 
+     * @param configuration configuration
+     * @return Policy Engine
+     */
+    @PUT
+    @Path("engine/deactivation")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response deactivateEngine() {
+       boolean success = true;
+               try {
+                       PolicyEngine.manager.deactivate();
+               } catch (Exception e) {
+                       success = false;
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                              "PolicyEngine", this.toString());
+               }
+       
+               if (!success)
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                    entity(new Error("cannot perform operation")).build();
+               else
+                       return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
+    }
+    
+    @DELETE
+    @Path("engine")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response engineShutdown() { 
+       try {
+                       PolicyEngine.manager.shutdown();
+               } catch (IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                                 "shutdown: " + PolicyEngine.manager);
+               return Response.status(Response.Status.BAD_REQUEST).
+                               entity(PolicyEngine.manager).
+                               build();
+               }
+       
+               return Response.status(Response.Status.OK).
+                               entity(PolicyEngine.manager).
+                               build();
+    }   
+    
+    @PUT
+    @Path("engine/lock")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response lockEngine() {
+       boolean success = PolicyEngine.manager.lock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Policy Engine is locked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Policy Engine cannot be locked").
+                                       build();
+    }
+    
+    @DELETE
+    @Path("engine/unlock")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response unlockEngine() {
+       boolean success = PolicyEngine.manager.unlock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Policy Engine is unlocked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Policy Engine cannot be unlocked").
+                                       build();
+    }
+    
+    @GET
+    @Path("engine/controllers")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<PolicyController> controllers() {
+        return PolicyEngine.manager.getPolicyControllers();
+    }
+    
+    @POST
+    @Path("engine/controllers")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response addController(Properties config) {
+       if (config == null)
+               return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error("A configuration must be provided")).
+                                       build();
+       
+       String controllerName = config.getProperty(PolicyProperties.PROPERTY_CONTROLLER_NAME);
+       if (controllerName == null || controllerName.isEmpty())
+               return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error
+                                                               ("Configuration must have an entry for " + 
+                                                    PolicyProperties.PROPERTY_CONTROLLER_NAME)).
+                                       build();
+       
+       PolicyController controller;
+               try {
+                       controller = PolicyController.factory.get(controllerName);
+                       if (controller != null)
+                               return Response.status(Response.Status.NOT_MODIFIED).
+                                                       entity(controller).
+                                                       build();
+               } catch (IllegalArgumentException e) {
+                       // This is OK
+               } catch (IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                              controllerName, this.toString());
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                            entity(new Error(controllerName + " not found")).build();
+               }
+       
+       try {
+                       controller = PolicyEngine.manager.createPolicyController
+                                       (config.getProperty(PolicyProperties.PROPERTY_CONTROLLER_NAME), config);
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                         controllerName, this.toString());
+               return Response.status(Response.Status.BAD_REQUEST).
+                                                               entity(new Error(e.getMessage())).
+                                                               build();
+               }
+       
+       try {
+                       boolean success = controller.start();
+                       if (!success) {
+                               logger.warn("Can't start " + controllerName + ": " + controller.toString());
+                               return Response.status(Response.Status.PARTIAL_CONTENT).
+                                       entity(new Error(controllerName + " can't be started")).build();
+                       }
+               } catch (IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                    controllerName, this.toString());
+                       return Response.status(Response.Status.PARTIAL_CONTENT).
+                                   entity(controller).build();
+               }
+       
+               return Response.status(Response.Status.CREATED).
+                entity(controller).
+                build();
+    }    
+    
+    @GET
+    @Path("engine/controllers/{controllerName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response controller(@PathParam("controllerName") String controllerName) {
+       PolicyController controller = null;
+               try {
+                       controller = PolicyController.factory.get(controllerName);
+               } catch (IllegalArgumentException e) {
+                       logger.info("Can't retrieve controller " + controllerName + 
+                                                 ".  Reason: " + e.getMessage());
+               } catch (IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                              controllerName, this.toString());
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                            entity(new Error(controllerName + " not acceptable")).build();
+               }
+       
+               if (controller != null)
+               return Response.status(Response.Status.OK).
+                               entity(controller).build();
+               else
+                       return Response.status(Response.Status.NOT_FOUND).
+                                          entity(new Error(controllerName + " not found")).build();
+    }
+    
+    @DELETE
+    @Path("engine/controllers/{controllerName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response deleteController(@PathParam("controllerName") String controllerName) {
+       
+       if (controllerName == null || controllerName.isEmpty())
+               return Response.status(Response.Status.BAD_REQUEST).
+                                       entity("A controller name must be provided").
+                                       build();
+       
+       PolicyController controller;
+       try {
+               controller =
+                               PolicyController.factory.get(controllerName);
+               if (controller == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                               entity(new Error(controllerName + "  does not exist")).
+                                               build();
+               } catch (IllegalArgumentException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                               entity(new Error(controllerName +  " not found: " + e.getMessage())).
+                                                               build();
+               } catch (IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                              controllerName, this.toString());
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                                   entity(new Error(controllerName + " not acceptable")).build();
+               }
+       
+       try {
+                       PolicyEngine.manager.removePolicyController(controllerName);
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                         controllerName + controller);
+               return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
+                                                              entity(new Error(e.getMessage())).
+                                                              build();
+               }
+       
+               return Response.status(Response.Status.OK).
+                entity(controller).
+                build();
+    }
+    
+    /**
+     * Updates the Policy Engine
+     * 
+     * @param configuration configuration
+     * @return Policy Engine
+     */
+    @PUT
+    @Path("engine/controllers/{controllerName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateController(@PathParam("controllerName") String controllerName,
+                                        ControllerConfiguration controllerConfiguration) {
+       
+       if (controllerName == null || controllerName.isEmpty() || 
+           controllerConfiguration == null || 
+           controllerConfiguration.getName().intern() != controllerName)
+               return Response.status(Response.Status.BAD_REQUEST).
+                                       entity("A valid or matching controller names must be provided").
+                                       build();
+       
+       PolicyController controller;
+       try {
+               controller = PolicyEngine.manager.updatePolicyController(controllerConfiguration);
+               if (controller == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                               entity(new Error(controllerName + "  does not exist")).
+                                               build();
+               } catch (IllegalArgumentException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                               entity(new Error(controllerName +  " not found: " + e.getMessage())).
+                                                               build();
+               } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                              controllerName, this.toString());
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                                   entity(new Error(controllerName + " not acceptable")).build();
+               }
+       
+               return Response.status(Response.Status.OK).
+                entity(controller).
+                build();
+    }
+    
+    public DroolsController getDroolsController(String controllerName) throws IllegalArgumentException {
+               PolicyController controller = PolicyController.factory.get(controllerName);
+       if (controller == null)
+               throw new IllegalArgumentException(controllerName + "  does not exist");
+
+               DroolsController drools = controller.getDrools();
+       if (drools == null)
+               throw new IllegalArgumentException(controllerName + "  has no drools configuration");
+       
+       return drools;
+    }
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/decoders")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoders(@PathParam("controllerName") String controllerName) {
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+                       List<ProtocolCoderToolset> decoders = EventProtocolCoder.manager.getDecoders
+                                                                                                               (drools.getGroupId(), drools.getArtifactId());                  
+                       return Response.status(Response.Status.OK).
+                                      entity(decoders).
+                                      build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/decoders/filters")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoderFilters(@PathParam("controllerName") String controllerName) {
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+                       List<CoderFilters> filters = EventProtocolCoder.manager.getDecoderFilters
+                                                       (drools.getGroupId(), drools.getArtifactId());
+                       return Response.status(Response.Status.OK).
+                                   entity(filters).
+                                   build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoder(@PathParam("controllerName") String controllerName,
+                                @PathParam("topicName") String topicName) {
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+                       ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                       (drools.getGroupId(), drools.getArtifactId(), topicName);
+                       return Response.status(Response.Status.OK).
+                                   entity(decoder).
+                                   build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }    
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoderFilter(@PathParam("controllerName") String controllerName,
+                                      @PathParam("topicName") String topicName) {
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+                       ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                                                               (drools.getGroupId(), drools.getArtifactId(), topicName);
+                       if (decoder == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(topicName + "  does not exist")).
+                                       build();
+                       else
+                               return Response.status(Response.Status.OK).
+                           entity(decoder.getCoders()).
+                           build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoderFilter(@PathParam("controllerName") String controllerName,
+                                      @PathParam("topicName") String topicName,
+                                      @PathParam("factClassName") String factClass) {
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+               ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                                                       (drools.getGroupId(), drools.getArtifactId(), topicName);
+                       CoderFilters filters = decoder.getCoder(factClass);
+                       if (filters == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(topicName + ":" + factClass + "  does not exist")).
+                                       build();
+                       else
+                               return Response.status(Response.Status.OK).
+                        entity(filters).
+                        build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @POST
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoderFilter(@PathParam("controllerName") String controllerName,
+                                     @PathParam("topicName") String topicName,
+                                     @PathParam("factClassName") String factClass,
+                                     JsonProtocolFilter configFilters) {
+       
+       if (configFilters == null) {
+               return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error("Configuration Filters not provided")).
+                                       build();
+       }
+       
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+               ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                                                       (drools.getGroupId(), drools.getArtifactId(), topicName);
+               CoderFilters filters = decoder.getCoder(factClass);
+                       if (filters == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(topicName + ":" + factClass + "  does not exist")).
+                                       build();
+                       filters.setFilter(configFilters);
+                       return Response.status(Response.Status.OK).
+                                   entity(filters).
+                                   build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoderFilterRules(@PathParam("controllerName") String controllerName,
+                                         @PathParam("topicName") String topicName,
+                                         @PathParam("factClassName") String factClass) {
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+               ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                                                       (drools.getGroupId(), drools.getArtifactId(), topicName);
+               
+               CoderFilters filters = decoder.getCoder(factClass);
+                       if (filters == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  does not exist")).
+                                       build();
+                       
+                       JsonProtocolFilter filter = filters.getFilter();
+                       if (filter == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  no filters")).
+                                       build();
+                       
+                       return Response.status(Response.Status.OK).
+                                   entity(filter.getRules()).
+                                   build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules/{ruleName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoderFilterRules(@PathParam("controllerName") String controllerName,
+                                         @PathParam("topicName") String topicName,
+                                         @PathParam("factClassName") String factClass,
+                                         @PathParam("ruleName") String ruleName) {
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+               ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                                                       (drools.getGroupId(), drools.getArtifactId(), topicName);
+               
+               CoderFilters filters = decoder.getCoder(factClass);
+                       if (filters == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  does not exist")).
+                                       build();
+                       
+                       JsonProtocolFilter filter = filters.getFilter();
+                       if (filter == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  no filters")).
+                                       build();
+                       
+                       return Response.status(Response.Status.OK).
+                                   entity(filter.getRules(ruleName)).
+                                   build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @DELETE
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules/{ruleName}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response deleteDecoderFilterRule(@PathParam("controllerName") String controllerName,
+                                                 @PathParam("topicName") String topicName,
+                                                 @PathParam("factClassName") String factClass,
+                                                 @PathParam("ruleName") String ruleName,
+                                                 FilterRule rule) {
+               
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+               ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                                                       (drools.getGroupId(), drools.getArtifactId(), topicName);
+               
+               CoderFilters filters = decoder.getCoder(factClass);
+                       if (filters == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  does not exist")).
+                                       build();
+                       
+                       JsonProtocolFilter filter = filters.getFilter();
+                       if (filter == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  no filters")).
+                                       build();
+                       
+                       if (rule == null) {
+                               filter.deleteRules(ruleName);
+                               return Response.status(Response.Status.OK).
+                           entity(filter.getRules()).
+                           build();            
+                       }
+                       
+                       if (rule.getName() == null || !rule.getName().equals(ruleName))
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + ":" + ruleName + 
+                                                                " rule name request inconsistencies (" + rule.getName() + ")")).
+                                       build();
+                       
+                       filter.deleteRule(ruleName, rule.getRegex());
+                       return Response.status(Response.Status.OK).
+                                   entity(filter.getRules()).
+                                   build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @PUT
+    @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decoderFilterRule(@PathParam("controllerName") String controllerName,
+                                             @PathParam("topicName") String topicName,
+                                             @PathParam("factClassName") String factClass,
+                                             JsonProtocolFilter.FilterRule rule) {
+               
+               try {
+                       DroolsController drools = getDroolsController(controllerName);
+               ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
+                                                                                       (drools.getGroupId(), drools.getArtifactId(), topicName);
+               
+               CoderFilters filters = decoder.getCoder(factClass);
+                       if (filters == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  does not exist")).
+                                       build();
+                       
+                       JsonProtocolFilter filter = filters.getFilter();
+                       if (filter == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass + "  no filters")).
+                                       build();
+                       
+                       if (rule.getName() == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                       entity(new Error(controllerName + ":" + topicName + ":" + factClass +  
+                                                                " rule name request inconsistencies (" + rule.getName() + ")")).
+                                       build();
+                       
+                       filter.addRule(rule.getName(), rule.getRegex());
+                       return Response.status(Response.Status.OK).
+                                   entity(filter.getRules()).
+                                   build();
+               } catch (IllegalArgumentException | IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(e.getMessage())).
+                                                      build();
+               }
+    }
+    
+    @GET
+    @Path("engine/controllers/{controllerName}/encoders")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response encoderFilters(@PathParam("controllerName") String controllerName) {       
+               List<CoderFilters> encoders;
+               try {
+                       PolicyController controller = PolicyController.factory.get(controllerName);
+               if (controller == null)
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                               entity(new Error(controllerName + "  does not exist")).
+                                               build();
+                       DroolsController drools = controller.getDrools();
+               if (drools == null)
+                       return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
+                                               entity(new Error(controllerName + "  has not drools component")).
+                                               build();
+                       encoders = EventProtocolCoder.manager.getEncoderFilters
+                                                       (drools.getGroupId(), drools.getArtifactId());
+               } catch (IllegalArgumentException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                         controllerName, this.toString());
+                       return Response.status(Response.Status.BAD_REQUEST).
+                                                      entity(new Error(controllerName +  " not found: " + e.getMessage())).
+                                                      build();
+               } catch (IllegalStateException e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                    controllerName, this.toString());
+                       return Response.status(Response.Status.NOT_ACCEPTABLE).
+                            entity(new Error(controllerName + " is not accepting the request")).build();
+               }
+               
+               return Response.status(Response.Status.OK).
+                               entity(encoders).
+                               build();
+    }
+    
+    @POST
+    @Path("engine/controllers/{controllerName}/decoders/{topic}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response decode(@PathParam("controllerName") String controllerName,
+                                  @PathParam("topic") String topic,
+                                  String json) {
+       
+       PolicyController policyController = PolicyController.factory.get(controllerName);
+       
+       CodingResult result = new CodingResult();
+               result.decoding = false;
+               result.encoding = false;
+               result.jsonEncoding = null;
+
+               Object event;
+       try {
+               event = EventProtocolCoder.manager.decode
+                                       (policyController.getDrools().getGroupId(), 
+                                        policyController.getDrools().getArtifactId(), 
+                                        topic, 
+                                        json);
+               result.decoding = true;
+       } catch (Exception e) {
+               return Response.status(Response.Status.BAD_REQUEST).
+                               entity(new Error(e.getMessage())).
+                               build();
+       }
+       
+       try {
+               result.jsonEncoding = EventProtocolCoder.manager.encode(topic, event);
+               result.encoding = true;
+       } catch (Exception e) {
+               return Response.status(Response.Status.OK).
+                               entity(result).
+                               build();
+       } 
+       
+               return Response.status(Response.Status.OK).
+                entity(result).
+                build();
+    }
+    
+       @GET
+    @Path("engine/topics")
+    @Produces(MediaType.APPLICATION_JSON)
+    public TopicEndpoint topics() {
+       return TopicEndpoint.manager;
+    }
+    
+       @SuppressWarnings("unchecked")
+       @GET
+    @Path("engine/topics/sources")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<TopicSource> sources() {
+       return (List<TopicSource>) TopicEndpoint.manager.getTopicSources();
+    }
+    
+    @SuppressWarnings("unchecked")
+       @GET
+    @Path("engine/topics/sinks")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<TopicSink> sinks() {
+       return (List<TopicSink>) TopicEndpoint.manager.getTopicSinks();
+    }
+    
+       @GET
+    @Path("engine/topics/sources/ueb")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<UebTopicSource> uebSources() {
+       return TopicEndpoint.manager.getUebTopicSources();
+    }
+    
+       @GET
+    @Path("engine/topics/sinks/ueb")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<UebTopicSink> uebSinks() {
+       return (List<UebTopicSink>) TopicEndpoint.manager.getUebTopicSinks();
+    }
+    
+       @GET
+    @Path("engine/topics/sources/dmaap")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<DmaapTopicSource> dmaapSources() {
+       return TopicEndpoint.manager.getDmaapTopicSources();
+    }
+    
+       @GET
+    @Path("engine/topics/sinks/dmaap")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<DmaapTopicSink> dmaapSinks() {
+       return (List<DmaapTopicSink>) TopicEndpoint.manager.getDmaapTopicSinks();
+    }
+    
+    @SuppressWarnings("unchecked")
+    @GET
+    @Path("engine/topics/{topic}/sources")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<TopicSource> sourceTopic(@PathParam("topic") String topic) {
+       List<String> topics = new ArrayList<String>();
+       topics.add(topic);
+       
+       return (List<TopicSource>) TopicEndpoint.manager.getTopicSources(topics);
+    }
+    
+    @SuppressWarnings("unchecked")
+    @GET
+    @Path("engine/topics/{topic}/sinks")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<TopicSink> sinkTopic(@PathParam("topic") String topic) {
+       List<String> topics = new ArrayList<String>();
+       topics.add(topic);
+       
+       return (List<TopicSink>) TopicEndpoint.manager.getTopicSinks(topics);
+    }
+    
+    
+    @GET
+    @Path("engine/topics/{topic}/ueb/source")
+    @Produces(MediaType.APPLICATION_JSON)
+    public UebTopicSource uebSourceTopic(@PathParam("topic") String topic) {
+       return TopicEndpoint.manager.getUebTopicSource(topic);
+    }
+    
+    @GET
+    @Path("engine/topics/{topic}/ueb/sink")
+    @Produces(MediaType.APPLICATION_JSON)
+    public UebTopicSink uebSinkTopic(@PathParam("topic") String topic) {
+       return TopicEndpoint.manager.getUebTopicSink(topic);
+    }
+    
+    @GET
+    @Path("engine/topics/{topic}/dmaap/source")
+    @Produces(MediaType.APPLICATION_JSON)
+    public DmaapTopicSource dmaapSourceTopic(@PathParam("topic") String topic) {
+       return TopicEndpoint.manager.getDmaapTopicSource(topic);
+    }
+    
+    @GET
+    @Path("engine/topics/{topic}/dmaap/sink")
+    @Produces(MediaType.APPLICATION_JSON)
+    public DmaapTopicSink dmaapSinkTopic(@PathParam("topic") String topic) {
+       return TopicEndpoint.manager.getDmaapTopicSink(topic);
+    }
+    
+    @GET
+    @Path("engine/topics/{topic}/ueb/source/events")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response uebSourceEvent(@PathParam("topic") String topicName) {
+       
+       UebTopicSource uebReader = TopicEndpoint.manager.getUebTopicSource(topicName);
+       String[] events = uebReader.getRecentEvents();
+               return Response.status(Status.OK).
+                       entity(events).
+                       build();
+    }
+    
+    @GET
+    @Path("engine/topics/{topic}/ueb/sink/events")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response uebSinkEvent(@PathParam("topic") String topicName) {
+       
+       UebTopicSink uebSink = TopicEndpoint.manager.getUebTopicSink(topicName);
+       String[] events = uebSink.getRecentEvents();
+               return Response.status(Status.OK).
+                       entity(events).
+                       build();
+    }
+    
+    @GET
+    @Path("engine/topics/{topic}/dmaap/source/events")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response dmaapSourcevent(@PathParam("topic") String topicName) {
+       
+       DmaapTopicSource uebReader = TopicEndpoint.manager.getDmaapTopicSource(topicName);
+       String[] events = uebReader.getRecentEvents();
+               return Response.status(Status.OK).
+                       entity(events).
+                       build();
+    }
+    
+    @GET
+    @Path("engine/topics/{topic}/dmaap/sink/events")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response dmaapSinkEvent(@PathParam("topic") String topicName) {
+       
+       DmaapTopicSink uebSink = TopicEndpoint.manager.getDmaapTopicSink(topicName);
+       String[] events = uebSink.getRecentEvents();
+               return Response.status(Status.OK).
+                       entity(events).
+                       build();
+    }
+    
+    @PUT
+    @Path("engine/topics/{topic}/ueb/sources/events")
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response uebOffer(@PathParam("topic") String topicName,
+                                String json) {
+       try {
+                       UebTopicSource uebReader = TopicEndpoint.manager.getUebTopicSource(topicName);
+                       boolean success = uebReader.offer(json);
+                       if (success)
+                               return Response.status(Status.OK).
+                                                       entity("Successfully injected event over " + topicName).
+                                                       build();
+                       else
+                               return Response.status(Status.NOT_ACCEPTABLE).
+                                                       entity("Failure to inject event over " + topicName).
+                                                       build();
+               } catch (Exception e) {
+               return Response.status(Response.Status.BAD_REQUEST).
+                               entity(new Error(e.getMessage())).
+                               build();
+               } 
+    }
+    
+    @PUT
+    @Path("engine/topics/{topic}/dmaap/sources/events")
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response dmaapOffer(@PathParam("topic") String topicName,
+                                  String json) {
+       try {
+                       DmaapTopicSource dmaapReader = TopicEndpoint.manager.getDmaapTopicSource(topicName);
+                       boolean success = dmaapReader.offer(json);
+                       if (success)
+                               return Response.status(Status.OK).
+                                                       entity("Successfully injected event over " + topicName).
+                                                       build();
+                       else
+                               return Response.status(Status.NOT_ACCEPTABLE).
+                                                       entity("Failure to inject event over " + topicName).
+                                                       build();
+               } catch (Exception e) {
+               return Response.status(Response.Status.BAD_REQUEST).
+                               entity(new Error(e.getMessage())).
+                               build();
+               } 
+    }
+    
+    @PUT
+    @Path("engine/topics/lock")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response lockTopics() {
+       boolean success = TopicEndpoint.manager.lock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Endpoints are locked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Endpoints cannot be locked").
+                                       build();
+    }
+    
+    @DELETE
+    @Path("engine/topics/lock")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response unlockTopics() {
+       boolean success = TopicEndpoint.manager.unlock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Endpoints are unlocked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Endpoints cannot be unlocked").
+                                       build();
+    }
+    
+    @PUT
+    @Path("engine/topics/{topic}/ueb/sources/lock")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response lockTopic(@PathParam("topic") String topicName) {
+       UebTopicSource reader = TopicEndpoint.manager.getUebTopicSource(topicName);     
+       boolean success = reader.lock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Endpoints are unlocked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Endpoints cannot be unlocked").
+                                       build();
+    }
+    
+    @PUT
+    @Path("engine/topics/{topic}/ueb/sources/unlock")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response unlockTopic(@PathParam("topic") String topicName) {
+       UebTopicSource reader = TopicEndpoint.manager.getUebTopicSource(topicName);     
+       boolean success = reader.unlock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Endpoints are unlocked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Endpoints cannot be unlocked").
+                                       build();
+    }
+    
+    @PUT
+    @Path("engine/controllers/{controllerName}/lock")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response lockController(@PathParam("controllerName") String controllerName) {
+       PolicyController policyController = PolicyController.factory.get(controllerName);
+       boolean success = policyController.lock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Controller " + controllerName + " is now locked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Controller " + controllerName + " cannot be locked").
+                                       build();
+    }  
+    
+    @DELETE
+    @Path("engine/controllers/{controllerName}/lock")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response unlockController(@PathParam("controllerName") String controllerName) {
+       PolicyController policyController = PolicyController.factory.get(controllerName);
+       boolean success = policyController.unlock();
+       if (success)
+               return Response.status(Status.OK).
+                                       entity("Controller " + controllerName + " is now unlocked").
+                                       build();
+       else
+               return Response.status(Status.SERVICE_UNAVAILABLE).
+                                       entity("Controller " + controllerName + " cannot be unlocked").
+                                       build();
+    }
+    
+    @POST
+    @Path("engine/util/coders/filters/rules/{ruleName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response rules(@DefaultValue("false") @QueryParam("negate") boolean negate,
+                             @PathParam("ruleName") String name,
+                             String regex) {           
+       String literalRegex = Pattern.quote(regex);
+       if (negate)
+               literalRegex = "^(?!" + literalRegex + "$).*";
+       
+               return Response.status(Status.OK).
+                                       entity(new JsonProtocolFilter.FilterRule(name,literalRegex)).
+                                       build();
+    }
+    
+    @GET
+    @Path("engine/util/uuid")
+    public Response uuid() {           
+               return Response.status(Status.OK).
+                       entity(UUID.randomUUID().toString()).
+                       build();
+    }
+    
+    /*
+     * Helper classes for aggregation of results
+     */
+    
+    
+       public static class Endpoints {
+               public List<TopicSource> sources;
+               public List<TopicSink> sinks;
+               
+               public Endpoints(List<TopicSource> sources,
+                                        List<TopicSink> sinks) {
+                       this.sources = sources;
+                       this.sinks = sinks;
+               }
+       }
+       
+       public static class Endpoint {
+               public TopicSource source;
+               public TopicSink sink;
+               
+               public Endpoint(TopicSource source,
+                                          TopicSink sink) {
+                       this.source = source;
+                       this.sink = sink;
+               }
+       }
+       
+       public static class CodingResult {
+               public String jsonEncoding;
+               public Boolean encoding;
+               public Boolean decoding;
+       }
+       
+       public static class Error {
+               public String error;
+
+               /**
+                * @param error
+                */
+               public Error(String error) {
+                       this.error = error;
+               }
+       }
+}
+
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/system/Main.java b/policy-management/src/main/java/org/openecomp/policy/drools/system/Main.java
new file mode 100644 (file)
index 0000000..108600b
--- /dev/null
@@ -0,0 +1,131 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.system;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.core.PolicyContainer;
+import org.openecomp.policy.drools.persistence.SystemPersistence;
+import org.openecomp.policy.drools.utils.PropertyUtil;
+
+/**
+ * Programmatic entry point to the management layer
+ */
+public class Main {
+       
+       /**
+        * logger
+        */
+       private static Logger  logger = FlexLogger.getLogger(Main.class, true);  
+       
+       public static void main(String args[]) {
+               
+               File configDir = new File(SystemPersistence.CONFIG_DIR_NAME);
+               
+               if (!configDir.isDirectory()) {
+                       throw new IllegalArgumentException
+                                               ("config directory: " + configDir.getAbsolutePath() + 
+                                                " not found");
+               }
+               
+               
+               /* 0. Start the CORE layer first */
+
+               try {
+                       PolicyContainer.globalInit(args);
+               } catch (Exception e) {
+                       System.out.println("policy-core startup failed");
+                       logger.warn("policy-core startup failed");
+                       e.printStackTrace();
+               }
+               
+               /* 1. Configure the Engine */
+
+               try {
+                       Path policyEnginePath = Paths.get(configDir.toPath().toString(), SystemPersistence.PROPERTIES_FILE_ENGINE);
+                       Properties properties = PropertyUtil.getProperties(policyEnginePath.toFile());
+                       PolicyEngine.manager.configure(properties);
+               } catch (Exception e) {
+                       String msg = "Policy Engine cannot be configured with properties: " + e.getMessage() + " : " + PolicyEngine.manager;
+                       System.out.println(msg);
+                       logger.warn(msg);
+               }
+               
+               /* 2. Start the Engine with the basic services only (no Policy Controllers) */
+               
+               try {
+                       boolean success = PolicyEngine.manager.start();
+                       if (!success) {
+                               System.out.println("Policy Engine found some problems starting some components: " + PolicyEngine.manager);
+                               logger.warn("Policy Engine is in an invalid state: " + PolicyEngine.manager);                           
+                       }
+               } catch (IllegalStateException e) {
+                       String msg = "Policy Engine is starting in an unexpected state: " + e.getMessage() + " : " + PolicyEngine.manager;
+                       System.out.println(msg);
+                       logger.warn(msg);
+               } catch (Exception e) {
+                       String msg = "Unexpected Situation.  Policy Engine cannot be started: " + e.getMessage() + " : " + PolicyEngine.manager;
+                       System.out.println(msg);
+                       e.printStackTrace();
+                       System.exit(1);
+               }
+               
+               /* 3. Create and start the controllers */
+               
+               File[] controllerFiles = configDir.listFiles();
+               for (File config : controllerFiles) {
+
+                       if (config.getName().endsWith(SystemPersistence.PROPERTIES_FILE_CONTROLLER_SUFFIX)) {
+                               int idxSuffix = 
+                                               config.getName().indexOf(SystemPersistence.PROPERTIES_FILE_CONTROLLER_SUFFIX);
+                               int lastIdxSuffix = 
+                                               config.getName().lastIndexOf(SystemPersistence.PROPERTIES_FILE_CONTROLLER_SUFFIX);
+                               if (idxSuffix != lastIdxSuffix) {
+                                       throw new IllegalArgumentException
+                                                               ("Improper naming of controller properties file: " +
+                                                "Expected <controller-name>" + 
+                                                SystemPersistence.PROPERTIES_FILE_CONTROLLER_SUFFIX);
+                               }
+
+                               String name = 
+                                               config.getName().substring(0, lastIdxSuffix);
+                               try {
+                                       Properties properties = PropertyUtil.getProperties(config);
+                                       PolicyController controller = PolicyEngine.manager.createPolicyController(name, properties);
+                                       controller.start();
+                               } catch (Exception e) {
+                                       System.out.println("can't instantiate Policy Controller based on properties file: " + 
+                                                      config + " with message " + e.getMessage());
+                                       e.printStackTrace();
+                               } catch (LinkageError le) {
+                                       System.out.println("can't instantiate Policy Controller based on properties file: " + 
+                                      config + ". A Linkage Error has been encountered: " + le.getMessage());
+                                       le.printStackTrace();                                   
+                               }
+                       }
+               }
+       }
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyController.java b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyController.java
new file mode 100644 (file)
index 0000000..543fd0e
--- /dev/null
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.system;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.event.comm.TopicSource;
+import org.openecomp.policy.drools.event.comm.Topic.CommInfrastructure;
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.properties.Lockable;
+import org.openecomp.policy.drools.properties.Startable;
+import org.openecomp.policy.drools.protocol.configuration.DroolsConfiguration;
+
+/**
+ * A Policy Controller is the higher level unit of control.  It corresponds to
+ * the ncomp equivalent of a controller.  It provides management of underlying
+ * resources associated with the policy controller, which is a) communication
+ * infrastructure, and b) policy-core (drools) session infrastructure
+ *
+ */
+public interface PolicyController extends Startable, Lockable {
+       
+       /**
+        * name of this Policy Controller
+        */
+       public String getName();
+       
+       /**
+        * Get the topic readers of interest for this controller
+        */
+       public List<? extends TopicSource> getTopicSources();
+       
+       /**
+        * Get the topic readers of interest for this controller
+        */
+       public List<? extends TopicSink> getTopicSinks();
+       
+       /**
+        * Get the Drools Controller
+        */
+       public DroolsController getDrools();
+       
+       /**
+        * update maven configuration
+        * 
+        * @param newDroolsConfiguration new drools configuration
+        * @return true if the update was successful, false otherwise
+        */     
+       public boolean updateDrools(DroolsConfiguration newDroolsConfiguration);
+       
+       /**
+        * Get the Initialization Properties
+        */
+       public Properties getInitializationProperties();
+       
+       /**
+        * Attempts delivering of an String over communication 
+        * infrastructure "busType"
+        * 
+        * @param eventBus Communication infrastructure identifier
+        * @param topic topic
+        * @param event the event object to send
+        * 
+        * @return true if successful, false if a failure has occurred.
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        * @throws IllegalStateException when the engine is in a state where
+        *         this operation is not permitted (ie. locked or stopped).
+        * @throws UnsupportedOperationException when the engine cannot deliver due
+        *         to the functionality missing (ie. communication infrastructure
+        *         not supported.
+        */
+       public boolean deliver(CommInfrastructure busType, String topic, 
+                                      Object event)
+                       throws IllegalArgumentException, IllegalStateException, 
+                              UnsupportedOperationException;
+       
+       /**
+        * halts and permanently releases all resources
+        * @throws IllegalStateException
+        */
+       public void halt() throws IllegalStateException;
+       
+       /**
+        * Factory that tracks and manages Policy Controllers
+        */
+       public static PolicyControllerFactory factory =
+                                               new IndexedPolicyControllerFactory();
+       
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyControllerFactory.java b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyControllerFactory.java
new file mode 100644 (file)
index 0000000..e105bbb
--- /dev/null
@@ -0,0 +1,464 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.system;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.protocol.configuration.DroolsConfiguration;
+import org.openecomp.policy.drools.system.internal.AggregatedPolicyController;
+
+/**
+ * Policy Controller Factory to manage controller creation, destruction,
+ * and retrieval for management interfaces
+ */
+public interface PolicyControllerFactory {
+       /**
+        * Build a controller from a properties file
+        * 
+        * @param name the global name of this controller
+        * @param properties input parameters in form of properties for controller
+        * initialization.
+        * 
+        * @return a Policy Controller
+        * 
+        * @throws IllegalArgumentException invalid values provided in properties
+        */
+       public PolicyController build(String name, Properties properties)
+                       throws IllegalArgumentException;
+       
+       /**
+        * patches (updates) a controller from a critical configuration update.
+        * 
+        * @param name
+        * @param configController
+        * 
+        * @return a Policy Controller
+        */
+       public PolicyController patch(String name, DroolsConfiguration configController);
+       
+       /**
+        * rebuilds (updates) a controller from a configuration update.
+        * 
+        * @param controller
+        * @param configController
+        * 
+        * @return a Policy Controller
+        */
+       public PolicyController patch(PolicyController controller, 
+                                             DroolsConfiguration configController);
+       
+       /**
+        * get PolicyController from DroolsController
+        * 
+        * @param droolsController
+        * @return
+        * @throws IllegalArgumentException
+        * @throws IllegalStateException
+        */
+       public PolicyController get(DroolsController droolsController) 
+                       throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * Makes the Policy Controller identified by controllerName not operational, but
+        * does not delete its associated data
+        * 
+        * @param controllerName  name of the policy controller
+        * @throws IllegalArgumentException invalid arguments
+        */
+       public void shutdown(String controllerName) throws IllegalArgumentException;;
+       
+       /**
+        * Makes the Policy Controller identified by controller not operational, but
+        * does not delete its associated data
+        * 
+        * @param controller a Policy Controller
+        * @throws IllegalArgumentException invalid arguments
+        */
+       public void shutdown(PolicyController controller) throws IllegalArgumentException;
+       
+       /**
+        * Releases all Policy Controllers from operation
+        */
+       public void shutdown();
+
+       /**
+        * Destroys this Policy Controller
+        * 
+        * @param controllerName  name of the policy controller
+        * @throws IllegalArgumentException invalid arguments
+        */
+       public void destroy(String controllerName) throws IllegalArgumentException;;
+       
+       /**
+        * Destroys this Policy Controller
+        * 
+        * @param controller a Policy Controller
+        * @throws IllegalArgumentException invalid arguments
+        */
+       public void destroy(PolicyController controller) throws IllegalArgumentException;
+       
+       /**
+        * Releases all Policy Controller resources
+        */
+       public void destroy();
+       
+       /**
+        * gets the Policy Controller identified by its name
+        * 
+        * @param policyControllerName
+        * @return
+        * @throws IllegalArgumentException
+        * @throws IllegalStateException
+        */
+       public PolicyController get(String policyControllerName)
+                  throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * gets the Policy Controller identified by group and artifact ids
+        * 
+        * @param groupId group id
+        * @param artifactId artifact id
+        * @return
+        * @throws IllegalArgumentException
+        * @throws IllegalStateException
+        */
+       public PolicyController get(String groupId, String artifactId)
+                  throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * returns the current inventory of Policy Controllers
+        * 
+        * @return a list of Policy Controllers
+        */
+       public List<PolicyController> inventory();
+}
+
+/**
+ * Factory of Policy Controllers indexed by the name of the Policy Controller
+ */
+class IndexedPolicyControllerFactory implements PolicyControllerFactory {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(PolicyControllerFactory.class);            
+       
+       /**
+        * Policy Controller Name Index
+        */
+       protected HashMap<String,PolicyController> policyControllers =
+                       new HashMap<String,PolicyController>();
+       
+       /**
+        * Group/Artifact Ids Index
+        */
+       protected HashMap<String,PolicyController> coordinates2Controller = 
+                       new HashMap<String,PolicyController>();
+       
+       /**
+        * produces key for indexing controller names
+        * 
+        * @param group group id
+        * @param artifactId artifact id
+        * @return index key
+        */
+       protected String toKey(String groupId, String artifactId) {
+               return groupId + ":" + artifactId;
+       }
+               
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized PolicyController build(String name, Properties properties) 
+                       throws IllegalArgumentException {
+               
+               if (this.policyControllers.containsKey(name)) {
+                       return this.policyControllers.get(name);
+               }
+               
+               /* A PolicyController does not exist */
+               
+               PolicyController controller =
+                               new AggregatedPolicyController(name, properties);
+               
+               String coordinates = toKey(controller.getDrools().getGroupId(),
+                                                  controller.getDrools().getArtifactId());
+               
+               this.policyControllers.put(name, controller);   
+               
+
+               if (controller.getDrools().isBrained())
+                       this.coordinates2Controller.put(coordinates, controller);
+               
+               return controller;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized PolicyController patch(String name, DroolsConfiguration droolsConfig) 
+                       throws IllegalArgumentException {
+               
+               if (name == null || name.isEmpty() || !this.policyControllers.containsKey(name)) {
+                       throw new IllegalArgumentException("Invalid " + name);
+               }
+               
+               if (droolsConfig == null)
+                       throw new IllegalArgumentException("Invalid Drools Configuration");
+               
+               PolicyController controller = this.get(name);
+               
+               if (controller == null) {
+                       logger.warn("A POLICY CONTROLLER of name " + name + 
+                                           "does not exist for patch operation: " + droolsConfig);
+                       
+                       throw new IllegalArgumentException("Not a valid controller of name " + name);
+               }
+               
+               this.patch(controller, droolsConfig);
+               
+               if (logger.isInfoEnabled())
+                       logger.info("UPDATED drools configuration: " + droolsConfig + " on " + this);
+               
+               return controller;
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public PolicyController patch(PolicyController controller, DroolsConfiguration droolsConfig) 
+                       throws IllegalArgumentException {
+
+               if (controller == null)
+                       throw new IllegalArgumentException("Not a valid controller:  null");
+               
+               if (!controller.updateDrools(droolsConfig)) {
+                       logger.warn("Cannot update drools configuration: " + droolsConfig + " on " + this);
+                       throw new IllegalArgumentException("Cannot update drools configuration Drools Configuration");
+               }
+               
+               if (logger.isInfoEnabled())
+                       logger.info("UPDATED drools configuration: " + droolsConfig + " on " + this);
+               
+               String coordinates = toKey(controller.getDrools().getGroupId(),
+                                                  controller.getDrools().getArtifactId());
+               
+               if (controller.getDrools().isBrained())
+                       this.coordinates2Controller.put(coordinates, controller);
+               
+               return controller;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown(String controllerName) throws IllegalArgumentException {
+               
+               if (controllerName == null || controllerName.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid " + controllerName);
+               }
+               
+               synchronized(this) {
+                       if (!this.policyControllers.containsKey(controllerName)) {
+                               return;
+                       }
+                                       
+                       PolicyController controller = this.policyControllers.get(controllerName);
+                       this.shutdown(controller);
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown(PolicyController controller) throws IllegalArgumentException {             
+               this.unmanage(controller);
+               controller.shutdown();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() {
+               List<PolicyController> controllers = this.inventory();
+               for (PolicyController controller: controllers) {
+                       controller.shutdown();
+               }
+               
+               synchronized(this) {
+                       this.policyControllers.clear();
+                       this.coordinates2Controller.clear();
+               }
+       }
+       
+       /**
+        * unmanage the controller
+        * 
+        * @param controller
+        * @return
+        * @throws IllegalArgumentException
+        */
+       protected void unmanage(PolicyController controller) throws IllegalArgumentException {
+               if (controller == null) {
+                       throw new IllegalArgumentException("Invalid Controller");
+               }
+               
+               synchronized(this) {
+                       if (!this.policyControllers.containsKey(controller.getName())) {
+                               return;
+                       }
+                       controller = this.policyControllers.remove(controller.getName());
+                       
+                       String coordinates = toKey(controller.getDrools().getGroupId(),
+                                       controller.getDrools().getArtifactId());
+                       this.coordinates2Controller.remove(coordinates);
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy(String controllerName) throws IllegalArgumentException {
+               
+               if (controllerName == null || controllerName.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid " + controllerName);
+               }
+               
+               synchronized(this) {
+                       if (!this.policyControllers.containsKey(controllerName)) {
+                               return;
+                       }
+                                       
+                       PolicyController controller = this.policyControllers.get(controllerName);
+                       this.destroy(controller);
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy(PolicyController controller) throws IllegalArgumentException {
+               this.unmanage(controller);
+               controller.halt();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void destroy() {
+               List<PolicyController> controllers = this.inventory();
+               for (PolicyController controller: controllers) {
+                       controller.halt();
+               }
+               
+               synchronized(this) {
+                       this.policyControllers.clear();
+                       this.coordinates2Controller.clear();
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public PolicyController get(String name) throws IllegalArgumentException, IllegalStateException {
+
+               if (name == null || name.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid " + name);
+               }
+               
+               synchronized(this) {
+                       if (this.policyControllers.containsKey(name)) {
+                               return this.policyControllers.get(name);
+                       } else {
+                               throw new IllegalArgumentException("Invalid " + name);
+                       }
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public PolicyController get(String groupId, String artifactId) 
+                       throws IllegalArgumentException, IllegalStateException {
+
+               if (groupId == null || groupId.isEmpty() || 
+                       artifactId == null || artifactId.isEmpty()) {
+                       throw new IllegalArgumentException("Invalid group/artifact ids");
+               }
+               
+               synchronized(this) {
+                       String key = toKey(groupId,artifactId);
+                       if (this.coordinates2Controller.containsKey(key)) {
+                               return this.coordinates2Controller.get(key);
+                       } else {
+                               throw new IllegalArgumentException("Invalid " + key);
+                       }
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public PolicyController get(DroolsController droolsController) 
+                       throws IllegalArgumentException, IllegalStateException {
+
+               if (droolsController == null) {
+                       throw new IllegalArgumentException("No Drools Controller provided");
+               }
+               
+               synchronized(this) {
+                       String key = toKey(droolsController.getGroupId(), droolsController.getArtifactId());
+                       if (this.coordinates2Controller.containsKey(key)) {
+                               return this.coordinates2Controller.get(key);
+                       } else {
+                               logger.error("Drools Controller not associated with Policy Controller " + droolsController + ":" + this);
+                               throw new IllegalStateException("Drools Controller not associated with Policy Controller " + droolsController + ":" + this);
+                       }
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<PolicyController> inventory() {
+                List<PolicyController> controllers = 
+                                new ArrayList<PolicyController>(this.policyControllers.values());
+                return controllers;
+       }
+       
+}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java
new file mode 100644 (file)
index 0000000..33f2a09
--- /dev/null
@@ -0,0 +1,1182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.system;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.core.FeatureAPI;
+import org.openecomp.policy.drools.core.jmx.PdpJmxListener;
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.Topic.CommInfrastructure;
+import org.openecomp.policy.drools.event.comm.TopicEndpoint;
+import org.openecomp.policy.drools.event.comm.TopicListener;
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.event.comm.TopicSource;
+import org.openecomp.policy.drools.http.server.HttpServletServer;
+import org.openecomp.policy.drools.persistence.SystemPersistence;
+import org.openecomp.policy.drools.properties.Lockable;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+import org.openecomp.policy.drools.properties.Startable;
+import org.openecomp.policy.drools.protocol.coders.EventProtocolCoder;
+import org.openecomp.policy.drools.protocol.configuration.ControllerConfiguration;
+import org.openecomp.policy.drools.protocol.configuration.PdpdConfiguration;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Policy Engine, the top abstraction for the Drools PDP Policy Engine.
+ * It abstracts away a Drools PDP Engine from management purposes.
+ * This is the best place to looking at the code from a top down approach. 
+ * Other managed entities can be obtained from the PolicyEngine, hierarchically. 
+ * <br>
+ * PolicyEngine 1 --- * PolicyController 1 --- 1 DroolsController 1 --- 1 PolicyContainer 1 --- * PolicySession
+ * <br>
+ * PolicyEngine 1 --- 1 TopicEndpointManager 1 -- * TopicReader 1 --- 1 UebTopicReader
+ * <br>
+ * PolicyEngine 1 --- 1 TopicEndpointManager 1 -- * TopicReader 1 --- 1 DmaapTopicReader
+ * <br>
+ * PolicyEngine 1 --- 1 TopicEndpointManager 1 -- * TopicWriter 1 --- 1 DmaapTopicWriter
+ * <br>
+ * PolicyEngine 1 --- 1 TopicEndpointManager 1 -- * TopicReader 1 --- 1 RestTopicReader
+ * <br>
+ * PolicyEngine 1 --- 1 TopicEndpointManager 1 -- * TopicWriter 1 --- 1 RestTopicWriter
+ * <br>
+ * PolicyEngine 1 --- 1 ManagementServer
+ */
+public interface PolicyEngine extends Startable, Lockable, TopicListener {
+       
+       /**
+        * Default Config Server Port
+        */
+       public static final int CONFIG_SERVER_DEFAULT_PORT = 9696;
+       
+       /**
+        * Default Config Server Hostname
+        */
+       public static final String CONFIG_SERVER_DEFAULT_HOST = "localhost";
+       
+       /**
+        * configure the policy engine according to the given properties
+        * 
+        * @param properties Policy Engine properties
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        */
+       public void configure(Properties properties)  throws IllegalArgumentException;
+
+       /**
+        * registers a new Policy Controller with the Policy Engine
+        * initialized per properties.
+        * 
+        * @param controller name
+        * @param properties properties to initialize the Policy Controller
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        * @throws IllegalStateException when the engine is in a state where
+        *         this operation is not permitted.
+        * @return the newly instantiated Policy Controller
+        */
+       public PolicyController createPolicyController(String name, Properties properties)
+               throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * updates the Policy Engine with the given configuration
+        * 
+        * @param configuration the configuration
+        * @return success or failure
+        * @throws IllegalArgumentException if invalid argument provided
+        * @throws IllegalStateException if the system is in an invalid state
+        */
+       public boolean configure(PdpdConfiguration configuration)
+               throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * updates a set of Policy Controllers with configuration information
+        * 
+        * @param configuration
+        * @return
+        * @throws IllegalArgumentException
+        * @throws IllegalStateException
+        */
+       public List<PolicyController> updatePolicyControllers(List<ControllerConfiguration> configuration)
+               throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * updates an already existing Policy Controller with configuration information
+        * 
+        * @param configuration configuration
+        * 
+        * @return the updated Policy Controller
+        * @throws IllegalArgumentException in the configuration is invalid
+        * @throws IllegalStateException if the controller is in a bad state
+        * @throws Exception any other reason
+        */
+       public PolicyController updatePolicyController(ControllerConfiguration configuration)
+               throws Exception;
+
+       /**
+        * removes the Policy Controller identified by its name from the Policy Engine
+        * 
+        * @param name name of the Policy Controller
+        * @return the removed Policy Controller
+        */
+       public void removePolicyController(String name);
+       
+       /**
+        * removes a Policy Controller from the Policy Engine
+        * @param controller the Policy Controller to remove from the Policy Engine
+        */
+       public void removePolicyController(PolicyController controller);
+
+       /**
+        * returns a list of the available Policy Controllers
+        * 
+        * @return list of Policy Controllers
+        */
+       public List<PolicyController> getPolicyControllers();
+       
+       /**
+        * get unmanaged sources
+        * 
+        * @return unmanaged sources
+        */
+       public List<TopicSource> getSources();
+       
+       /**
+        * get unmanaged sinks
+        * 
+        * @return unmanaged sinks
+        */
+       public List<TopicSink> getSinks();
+       
+       /**
+        * get unmmanaged http servers list
+        * @return http servers
+        */
+       public List<HttpServletServer> getHttpServers();
+       
+       /**
+        * get properties configuration
+        * 
+        * @return properties objects
+        */
+       public Properties getProperties();
+       
+       /**
+        * Attempts the dispatching of an "event" object
+        * 
+        * @param topic topic
+        * @param event the event object to send
+        * 
+        * @return true if successful, false if a failure has occurred.
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        * @throws IllegalStateException when the engine is in a state where
+        *         this operation is not permitted (ie. locked or stopped).
+        */
+       public boolean deliver(String topic, Object event)
+                       throws IllegalArgumentException, IllegalStateException;
+       
+       /**
+        * Attempts the dispatching of an "event" object over communication 
+        * infrastructure "busType"
+        * 
+        * @param eventBus Communication infrastructure identifier
+        * @param topic topic
+        * @param event the event object to send
+        * 
+        * @return true if successful, false if a failure has occurred.
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        * @throws IllegalStateException when the engine is in a state where
+        *         this operation is not permitted (ie. locked or stopped).
+        * @throws UnsupportedOperationException when the engine cannot deliver due
+        *         to the functionality missing (ie. communication infrastructure
+        *         not supported.
+        */
+       public boolean deliver(String busType, String topic, Object event)
+                       throws IllegalArgumentException, IllegalStateException, 
+                              UnsupportedOperationException;
+       
+       /**
+        * Attempts the dispatching of an "event" object over communication 
+        * infrastructure "busType"
+        * 
+        * @param eventBus Communication infrastructure enum
+        * @param topic topic
+        * @param event the event object to send
+        * 
+        * @return true if successful, false if a failure has occurred.
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        * @throws IllegalStateException when the engine is in a state where
+        *         this operation is not permitted (ie. locked or stopped).
+        * @throws UnsupportedOperationException when the engine cannot deliver due
+        *         to the functionality missing (ie. communication infrastructure
+        *         not supported.
+        */
+       public boolean deliver(CommInfrastructure busType, String topic, Object event)
+                       throws IllegalArgumentException, IllegalStateException, 
+                              UnsupportedOperationException;
+       
+       /**
+        * Attempts delivering of an String over communication 
+        * infrastructure "busType"
+        * 
+        * @param eventBus Communication infrastructure identifier
+        * @param topic topic
+        * @param event the event object to send
+        * 
+        * @return true if successful, false if a failure has occurred.
+        * @throws IllegalArgumentException when invalid or insufficient 
+        *         properties are provided
+        * @throws IllegalStateException when the engine is in a state where
+        *         this operation is not permitted (ie. locked or stopped).
+        * @throws UnsupportedOperationException when the engine cannot deliver due
+        *         to the functionality missing (ie. communication infrastructure
+        *         not supported.
+        */
+       public boolean deliver(CommInfrastructure busType, String topic, 
+                                      String event)
+                       throws IllegalArgumentException, IllegalStateException, 
+                              UnsupportedOperationException;
+       
+       /**
+        * Invoked when the host goes into the active state.
+        */
+       public void activate();
+
+       /**
+        * Invoked when the host goes into the standby state.
+        */
+       public void deactivate();
+
+       /**
+        * get policy controller names
+        * 
+        * @return list of controller names
+        */
+       public List<String> getControllers();
+       
+       /**
+        * Policy Engine Manager
+        */
+       public final static PolicyEngine manager = new PolicyEngineManager();
+}
+
+/**
+ * Policy Engine Manager Implementation
+ */
+class PolicyEngineManager implements PolicyEngine {
+       /**
+        * logger
+        */
+       private static Logger  logger = FlexLogger.getLogger(PolicyEngineManager.class);        
+       
+       /**
+        * Is the Policy Engine running?
+        */
+       protected boolean alive = false;
+       
+       /**
+        * Is the engine locked? 
+        */
+       protected boolean locked = false;       
+       
+       /**
+        * Properties used to initialize the engine
+        */
+       protected Properties properties;
+       
+       /**
+        * Policy Engine Sources
+        */
+       protected List<? extends TopicSource> sources = new ArrayList<>();
+       
+       /**
+        * Policy Engine Sinks
+        */
+       protected List<? extends TopicSink> sinks = new ArrayList<>();
+       
+       /**
+        * Policy Engine HTTP Servers
+        */
+       protected List<HttpServletServer> httpServers = new ArrayList<HttpServletServer>();
+       
+       protected Gson decoder = new GsonBuilder().disableHtmlEscaping().create();
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void configure(Properties properties) throws IllegalArgumentException {
+               
+               if (properties == null) {
+                       logger.warn("No properties provided");
+                       throw new IllegalArgumentException("No properties provided");
+               }
+               
+               this.properties = properties;
+               
+               try {
+                       this.sources = TopicEndpoint.manager.addTopicSources(properties);
+                       for (TopicSource source: this.sources) {
+                               source.register(this);
+                       }
+               } catch (Exception e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine", "configure");
+               }
+               
+               try {
+                       this.sinks = TopicEndpoint.manager.addTopicSinks(properties);
+               } catch (IllegalArgumentException e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine", "configure");
+               }
+               
+               try {
+                       this.httpServers = HttpServletServer.factory.build(properties);
+               } catch (IllegalArgumentException e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine", "configure");
+               }
+               
+               return;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public PolicyController createPolicyController(String name, Properties properties) 
+                       throws IllegalArgumentException, IllegalStateException {
+               
+               // check if a PROPERTY_CONTROLLER_NAME property is present
+               // if so, override the given name
+               
+               String propertyControllerName = properties.getProperty(PolicyProperties.PROPERTY_CONTROLLER_NAME);
+               if (propertyControllerName != null && !propertyControllerName.isEmpty())  {
+                       if (!propertyControllerName.equals(name)) {
+                               throw new IllegalStateException("Proposed name (" + name + 
+                                                                       ") and properties name (" + propertyControllerName + 
+                                                                       ") don't match");
+                       }
+                       name = propertyControllerName;
+               }
+               
+               // feature hook
+               for (FeatureAPI feature : FeatureAPI.impl.getList()) {
+                       feature.beforeCreateController(name, properties);
+               }
+               
+               PolicyController controller = PolicyController.factory.build(name, properties); 
+               if (this.isLocked())
+                       controller.lock();
+               
+               // feature hook
+               for (FeatureAPI feature : FeatureAPI.impl.getList()) {
+                       //  NOTE: this should change to the actual controller object
+                       feature.afterCreateController(name);
+               }
+               
+               return controller;
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean configure(PdpdConfiguration config) throws IllegalArgumentException, IllegalStateException {
+       
+               if (config == null)
+                       throw new IllegalArgumentException("No configuration provided");
+               
+               String entity = config.getEntity();
+               
+               switch (entity) {
+               case PdpdConfiguration.CONFIG_ENTITY_CONTROLLER:
+                       /* only this one supported for now */
+                       List<ControllerConfiguration> configControllers = config.getControllers();
+                       if (configControllers == null || configControllers.isEmpty()) {
+                               if (logger.isInfoEnabled())
+                                       logger.info("No controller configuration provided: " + config);
+                               return false;
+                       }
+                       List<PolicyController> policyControllers = this.updatePolicyControllers(config.getControllers());
+                       if (policyControllers == null || policyControllers.isEmpty())
+                               return false;
+                       else if (policyControllers.size() == configControllers.size())
+                               return true;
+                       
+                       return false;
+               default:
+                       String msg = "Configuration Entity is not supported: " + entity;
+                       logger.warn(msg);
+                       throw new IllegalArgumentException(msg);
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<PolicyController> updatePolicyControllers(List<ControllerConfiguration> configControllers)
+                       throws IllegalArgumentException, IllegalStateException {
+               
+               List<PolicyController> policyControllers = new ArrayList<PolicyController>();
+               if (configControllers == null || configControllers.isEmpty()) {
+                       if (logger.isInfoEnabled())
+                               logger.info("No controller configuration provided: " + configControllers);
+                       return policyControllers;
+               }
+               
+               for (ControllerConfiguration configController: configControllers) {
+                       try {
+                               PolicyController policyController = this.updatePolicyController(configController);
+                               policyControllers.add(policyController);
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine", "updatePolicyControllers");
+                       }
+               }
+               
+               return policyControllers;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public PolicyController updatePolicyController(ControllerConfiguration configController) 
+                  throws Exception {
+               
+               if (configController == null) 
+                       throw new IllegalArgumentException("No controller configuration has been provided");
+               
+               String controllerName = configController.getName();     
+               if (controllerName == null || controllerName.isEmpty()) {
+                       logger.warn("controller-name  must be provided");
+                       throw new IllegalArgumentException("No controller configuration has been provided");
+               }
+               
+               PolicyController policyController = null;
+               try {           
+                       String operation = configController.getOperation();
+                       if (operation == null || operation.isEmpty()) {
+                               logger.warn("operation must be provided");
+                               throw new IllegalArgumentException("operation must be provided");
+                       }
+                       
+                       try {
+                               policyController = PolicyController.factory.get(controllerName);
+                       } catch (IllegalArgumentException e) {
+                               // not found
+                               logger.warn("Policy Controller " + controllerName + " not found");
+                       }
+                       
+                       if (policyController == null) {
+                               
+                               if (operation.equalsIgnoreCase(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK) ||
+                                       operation.equalsIgnoreCase(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK)) {
+                                       throw new IllegalArgumentException(controllerName + " is not available for operation " + operation);
+                               }
+                               
+                               /* Recovery case */
+                               
+                               logger.warn("controller " + controllerName + " does not exist.  " +
+                                           "Attempting recovery from disk");   
+                               
+                               Properties properties = 
+                                               SystemPersistence.manager.getControllerProperties(controllerName);
+                               
+                               /* 
+                                * returned properties cannot be null (per implementation) 
+                                * assert (properties != null)
+                                */
+                               
+                               if (properties == null) {
+                                       throw new IllegalArgumentException(controllerName + " is invalid");
+                               }
+                               
+                               logger.warn("controller " + controllerName + " being recovered. " +
+                                       "Reset controller's bad maven coordinates to brainless");
+                               
+                               /* 
+                                * try to bring up bad controller in brainless mode,
+                                * after having it working, apply the new create/update operation.
+                                */
+                               properties.setProperty(PolicyProperties.RULES_GROUPID, DroolsController.NO_GROUP_ID);
+                               properties.setProperty(PolicyProperties.RULES_ARTIFACTID, DroolsController.NO_ARTIFACT_ID);
+                               properties.setProperty(PolicyProperties.RULES_VERSION, DroolsController.NO_VERSION);
+                               
+                               policyController = PolicyEngine.manager.createPolicyController(controllerName, properties);
+                               
+                               /* fall through to do brain update operation*/
+                       }
+                       
+                       switch (operation) {
+                       case ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_CREATE:
+                               PolicyController.factory.patch(policyController, configController.getDrools());
+                               break;
+                       case ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UPDATE:
+                               policyController.unlock();
+                               PolicyController.factory.patch(policyController, configController.getDrools());
+                               break;
+                       case ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK:
+                               policyController.lock();
+                               break;
+                       case ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK:
+                               policyController.unlock();
+                               break;
+                       default:
+                               String msg = "Controller Operation Configuration is not supported: " + 
+                                    operation + " for " + controllerName;
+                               logger.warn(msg);
+                               throw new IllegalArgumentException(msg);
+                       }
+                       
+                       return policyController;
+               } catch (Exception e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine", "updatePolicyController " + e.getMessage());
+                       throw e;
+               } catch (LinkageError e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine", "updatePolicyController " + e.getMessage());
+                       throw new IllegalStateException(e);
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() throws IllegalStateException {
+               
+               if (this.locked) {
+                       throw new IllegalStateException("Engine is locked");
+               }
+               
+               // Features hook
+               for (FeatureAPI feature : FeatureAPI.impl.getList()) {
+                       feature.beforeStartEngine();
+               }
+               
+               synchronized(this) {
+                       this.alive = true;
+               }
+               
+               boolean success = true;
+
+               /* Start Policy Engine exclusively-owned (unmanaged) http servers */
+               
+               for (HttpServletServer httpServer: this.httpServers) {
+                       try {
+                               if (!httpServer.start())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, httpServer.toString(), this.toString());
+                       }
+               }
+               /* Start Policy Engine exclusively-owned (unmanaged) sources */
+               
+               for (TopicSource source: this.sources) {
+                       try {
+                               if (!source.start())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, source.toString(), this.toString());
+                       }
+               }
+               
+               /* Start Policy Engine owned (unmanaged) sinks */
+               
+               for (TopicSink sink: this.sinks) {
+                       try {
+                               if (!sink.start())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, sink.toString(), this.toString());
+                       }
+               }
+               
+               /* Start Policy Controllers */
+               
+               List<PolicyController> controllers = PolicyController.factory.inventory();
+               for (PolicyController controller : controllers) {
+                       try {
+                               if (!controller.start())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, controller.toString(), this.toString());
+                               success = false;
+                       }
+               }
+               
+               /* Start managed Topic Endpoints */
+               
+               try {
+                       if (!TopicEndpoint.manager.start())
+                               success = false;                        
+               } catch (IllegalStateException e) {
+                       String msg = "Topic Endpoint Manager is in an invalid state: " + e.getMessage() + " : " + this;
+                       logger.warn(msg);                       
+               }
+               
+               
+               // Start the JMX listener
+               
+               PdpJmxListener.start();
+               
+               // Features hook
+               for (FeatureAPI feature : FeatureAPI.impl.getList()) {
+                       feature.afterStartEngine();
+               }
+
+               return success;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() {
+               
+               /* stop regardless of the lock state */
+               
+               synchronized(this) {
+                       if (!this.alive)
+                               return true;
+                       
+                       this.alive = false;                     
+               }
+               
+               boolean success = true;
+               List<PolicyController> controllers = PolicyController.factory.inventory();
+               for (PolicyController controller : controllers) {
+                       try {
+                               if (!controller.stop())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, controller.toString(), this.toString());
+                               success = false;
+                       }
+               }
+               
+               /* Stop Policy Engine owned (unmanaged) sources */
+               for (TopicSource source: this.sources) {
+                       try {
+                               if (!source.stop())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, source.toString(), this.toString());
+                       }
+               }
+               
+               /* Stop Policy Engine owned (unmanaged) sinks */
+               for (TopicSink sink: this.sinks) {
+                       try {
+                               if (!sink.stop())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, sink.toString(), this.toString());
+                       }
+               }
+               
+               /* stop all managed topics sources and sinks */
+               if (!TopicEndpoint.manager.stop())
+                       success = false;
+               
+               /* stop all unmanaged http servers */
+               for (HttpServletServer httpServer: this.httpServers) {
+                       try {
+                               if (!httpServer.stop())
+                                       success = false;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, httpServer.toString(), this.toString());
+                       }
+               }               
+               
+               return success;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+
+               synchronized(this) {
+                       this.alive = false;                     
+               }
+               
+               // feature hook reporting that the Policy Engine is being shut down             
+               for (FeatureAPI feature : FeatureAPI.impl.getList()) {
+                       feature.beforeShutdownEngine();
+               }
+               
+               /* Shutdown Policy Engine owned (unmanaged) sources */
+               for (TopicSource source: this.sources) {
+                       try {
+                               source.shutdown();
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, source.toString(), this.toString());
+                       }
+               }
+               
+               /* Shutdown Policy Engine owned (unmanaged) sinks */
+               for (TopicSink sink: this.sinks) {
+                       try {
+                               sink.shutdown();
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, sink.toString(), this.toString());
+                       }
+               }
+               
+               /* Shutdown managed resources */
+               PolicyController.factory.shutdown();
+               TopicEndpoint.manager.shutdown();
+               HttpServletServer.factory.destroy();
+               
+               // Stop the JMX listener
+               
+               PdpJmxListener.stop();
+               
+               // feature hook reporting that the Policy Engine has being shut down            
+               for (FeatureAPI feature : FeatureAPI.impl.getList()) {
+                       feature.afterShutdownEngine();
+               }
+               
+               new Thread(new Runnable() {
+                   @Override
+                   public void run() {
+                       try {
+                                       Thread.sleep(5000L);
+                               } catch (InterruptedException e) {
+                                       logger.warn("InterruptedException while shutting down management server: " +  this.toString());
+                               }                       
+                               
+                               /* shutdown all unmanaged http servers */
+                               for (HttpServletServer httpServer: getHttpServers()) {
+                                       try {
+                                               httpServer.shutdown();
+                                       } catch (Exception e) {
+                                               logger.error(MessageCodes.EXCEPTION_ERROR, e, httpServer.toString(), this.toString());
+                                       }
+                               } 
+                       
+                       try {
+                                       Thread.sleep(5000L);
+                               } catch (InterruptedException e) {
+                                       logger.warn("InterruptedException while shutting down management server: " +  this.toString());
+                               }
+                       
+                       System.exit(0);
+                   }               
+               }).start();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               return this.alive;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean lock() {
+               
+               synchronized(this) {
+                       if (this.locked)
+                               return true;
+                       
+                       this.locked = true;                     
+               }
+               
+               boolean success = true;
+               List<PolicyController> controllers = PolicyController.factory.inventory();
+               for (PolicyController controller : controllers) {
+                       try {
+                               success = controller.lock() && success;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, controller.toString(), this.toString());
+                               success = false;
+                       }
+               }
+               
+               success = TopicEndpoint.manager.lock();         
+               return success;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean unlock() {
+               synchronized(this) {
+                       if (!this.locked)
+                               return true;
+                       
+                       this.locked = false;                    
+               }
+               
+               boolean success = true;
+               List<PolicyController> controllers = PolicyController.factory.inventory();
+               for (PolicyController controller : controllers) {
+                       try {
+                               success = controller.unlock() && success;
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, controller.toString(), this.toString());
+                               success = false;
+                       }
+               }
+               
+               success = TopicEndpoint.manager.unlock();               
+               return success;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isLocked() {
+               return this.locked;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void removePolicyController(String name) {
+               PolicyController.factory.destroy(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void removePolicyController(PolicyController controller) {
+               PolicyController.factory.destroy(controller);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @JsonIgnore
+       @Override
+       public List<PolicyController> getPolicyControllers() {
+               return PolicyController.factory.inventory();
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<String> getControllers() {
+               List<String> controllerNames = new ArrayList<String>();
+               for (PolicyController controller: PolicyController.factory.inventory()) {
+                       controllerNames.add(controller.getName());
+               }
+               return controllerNames;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Properties getProperties() {
+               return this.properties;
+       }
+       
+
+       /**
+        * {@inheritDoc}
+        */
+       @SuppressWarnings("unchecked")
+       @Override
+       public List<TopicSource> getSources() {
+               return (List<TopicSource>) this.sources;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @SuppressWarnings("unchecked")
+       @Override
+       public List<TopicSink> getSinks() {
+               return (List<TopicSink>) this.sinks;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<HttpServletServer> getHttpServers() {
+               return this.httpServers;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean onTopicEvent(CommInfrastructure commType, String topic, String event) {
+               /* configuration request */
+               try {
+                       PdpdConfiguration configuration = this.decoder.fromJson(event, PdpdConfiguration.class);
+                       this.configure(configuration);
+               } catch (Exception e) {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, "CONFIGURATION ERROR IN PDP-D POLICY ENGINE: "+ event + ":" + e.getMessage() + ":" + this);
+               }
+               
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean deliver(String topic, Object event) 
+                       throws IllegalArgumentException, IllegalStateException {
+               
+               /*
+                * Note this entry point is usually from the DRL
+                */
+               
+               if (topic == null || topic.isEmpty())
+                       throw new IllegalArgumentException("Invalid Topic");
+               
+               if (event == null)
+                       throw new IllegalArgumentException("Invalid Event");
+                       
+               if (!this.isAlive())
+                       throw new IllegalStateException("Policy Engine is stopped");
+               
+               if (this.isLocked())
+                       throw new IllegalStateException("Policy Engine is locked");
+               
+               List<? extends TopicSink> sinks = 
+                               TopicEndpoint.manager.getTopicSinks(topic);
+               if (sinks == null || sinks.isEmpty() || sinks.size() > 1)
+                       throw new IllegalStateException
+                               ("Cannot ensure correct delivery on topic " + topic + ": " + sinks);            
+
+               return this.deliver(sinks.get(0).getTopicCommInfrastructure(), 
+                                           topic, event);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean deliver(String busType, String topic, Object event) 
+                       throws IllegalArgumentException, IllegalStateException,
+                      UnsupportedOperationException {
+               
+               /*
+                * Note this entry point is usually from the DRL (one of the reasons
+                * busType is String.
+                */
+               
+               if (busType == null || busType.isEmpty())
+                       throw new IllegalArgumentException
+                               ("Invalid Communication Infrastructure");
+               
+               if (topic == null || topic.isEmpty())
+                       throw new IllegalArgumentException("Invalid Topic");
+               
+               if (event == null)
+                       throw new IllegalArgumentException("Invalid Event");
+               
+               boolean valid = false;
+               for (Topic.CommInfrastructure comm: Topic.CommInfrastructure.values()) {
+                       if (comm.name().equals(busType)) {
+                               valid = true;
+                       }
+               }
+               
+               if (!valid)
+                       throw new IllegalArgumentException
+                               ("Invalid Communication Infrastructure: " + busType);
+               
+               
+               if (!this.isAlive())
+                       throw new IllegalStateException("Policy Engine is stopped");
+               
+               if (this.isLocked())
+                       throw new IllegalStateException("Policy Engine is locked");
+               
+
+               return this.deliver(Topic.CommInfrastructure.valueOf(busType), 
+                                           topic, event);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean deliver(Topic.CommInfrastructure busType, 
+                                      String topic, Object event) 
+               throws IllegalArgumentException, IllegalStateException,
+                      UnsupportedOperationException {
+               
+               if (topic == null || topic.isEmpty())
+                       throw new IllegalArgumentException("Invalid Topic");
+               
+               if (event == null)
+                       throw new IllegalArgumentException("Invalid Event");
+               
+               if (!this.isAlive())
+                       throw new IllegalStateException("Policy Engine is stopped");
+               
+               if (this.isLocked())
+                       throw new IllegalStateException("Policy Engine is locked");
+               
+               /* Try to send through the controller, this is the
+                * preferred way, since it may want to apply additional
+                * processing
+                */
+               try {
+                       DroolsController droolsController = 
+                                       EventProtocolCoder.manager.getDroolsController(topic, event);
+                       PolicyController controller = PolicyController.factory.get(droolsController);
+                       if (controller != null)
+                               return controller.deliver(busType, topic, event);
+               } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                                 busType + ":" + topic + " :" + event, this.toString());
+                       /* continue (try without routing through the controller) */
+               }
+               
+               /*
+                * cannot route through the controller, send directly through
+                * the topic sink
+                */
+               try {                   
+                       String json = EventProtocolCoder.manager.encode(topic, event);
+                       return this.deliver(busType, topic, json);
+
+               } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                 busType + ":" + topic + " :" + event, this.toString());
+                       throw e;
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean deliver(Topic.CommInfrastructure busType, 
+                                      String topic, String event) 
+               throws IllegalArgumentException, IllegalStateException,
+                      UnsupportedOperationException {
+               
+               if (topic == null || topic.isEmpty())
+                       throw new IllegalArgumentException("Invalid Topic");
+               
+               if (event == null || event.isEmpty())
+                       throw new IllegalArgumentException("Invalid Event");
+               
+               if (!this.isAlive())
+                       throw new IllegalStateException("Policy Engine is stopped");
+               
+               if (this.isLocked())
+                       throw new IllegalStateException("Policy Engine is locked");
+               
+               try {
+                       TopicSink sink = 
+                                       TopicEndpoint.manager.getTopicSink
+                                               (busType, topic);
+                       
+                       if (sink == null)
+                               throw new IllegalStateException("Inconsistent State: " + this);
+                       
+                       return sink.send(event);
+
+               } catch (Exception e) {
+                       logger.warn(MessageCodes.EXCEPTION_ERROR, e, 
+                                 busType + ":" + topic + " :" + event, this.toString());
+                       throw e;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized void activate() {
+
+               // activate 'policy-management'
+               for (PolicyController policyController : getPolicyControllers()) {
+                       try {
+                               policyController.unlock();
+                               policyController.start();
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine.activate: cannot start " + 
+                                    policyController + " because of " + e.getMessage());
+                       } catch (LinkageError e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine.activate: cannot start " + 
+                                        policyController + " because of " + e.getMessage());
+                       }
+               }
+               
+               this.unlock();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public synchronized void deactivate() {
+               
+               this.lock();
+               
+               for (PolicyController policyController : getPolicyControllers()) {
+                       try { 
+                               policyController.stop();
+                       } catch (Exception e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine.deactivate: cannot stop " + 
+                                    policyController + " because of " + e.getMessage());
+                       } catch (LinkageError e) {
+                               logger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyEngine.deactivate: cannot start " + 
+                                        policyController + " because of " + e.getMessage());
+                       }
+               }         
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("PolicyEngineManager [alive=").append(alive).append(", locked=").append(locked).append("]");
+               return builder.toString();
+       }
+       
+}
+
+
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/system/internal/AggregatedPolicyController.java b/policy-management/src/main/java/org/openecomp/policy/drools/system/internal/AggregatedPolicyController.java
new file mode 100644 (file)
index 0000000..96f9e5b
--- /dev/null
@@ -0,0 +1,462 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-management
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.system.internal;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.policy.drools.controller.DroolsController;
+import org.openecomp.policy.drools.event.comm.Topic;
+import org.openecomp.policy.drools.event.comm.TopicEndpoint;
+import org.openecomp.policy.drools.event.comm.TopicListener;
+import org.openecomp.policy.drools.event.comm.TopicSink;
+import org.openecomp.policy.drools.event.comm.TopicSource;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.persistence.SystemPersistence;
+import org.openecomp.policy.drools.properties.PolicyProperties;
+import org.openecomp.policy.drools.protocol.configuration.DroolsConfiguration;
+import org.openecomp.policy.drools.system.PolicyController;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * This implementation of the Policy Controller merely aggregates and tracks for
+ * management purposes all underlying resources that this controller depends upon.
+ */
+public class AggregatedPolicyController implements PolicyController, 
+                                                   TopicListener {
+       
+       /**
+        * Logger
+        */
+       private static Logger  logger = FlexLogger.getLogger(AggregatedPolicyController.class); 
+       
+       /**
+        * identifier for this policy controller
+        */
+       protected final String name;
+       
+       /**
+        * Abstracted Event Sources List regardless communication
+        * technology
+        */
+       protected final List<? extends TopicSource> sources;
+       
+       /**
+        * Abstracted Event Sinks List regardless communication
+        * technology
+        */
+       protected final List<? extends TopicSink> sinks;
+       
+       /**
+        * Mapping topics to sinks
+        */
+       @JsonIgnore
+       protected final HashMap<String, TopicSink> topic2Sinks =
+               new HashMap<String, TopicSink>();
+       
+       /**
+        * Is this Policy Controller running (alive) ?
+        * reflects invocation of start()/stop() only
+        */
+       protected volatile boolean alive;
+       
+       /**
+        * Is this Policy Controller locked ?
+        * reflects if i/o controller related operations and start 
+        * are permitted,
+        * more specifically: start(), deliver() and onTopicEvent().
+        * It does not affect the ability to stop the
+        * underlying drools infrastructure 
+        */
+       protected volatile boolean locked;
+       
+       /**
+        * Policy Drools Controller
+        */
+       protected volatile DroolsController droolsController;
+       
+       /**
+        * Properties used to initialize controller
+        */
+       protected final Properties properties;
+       
+       /**
+        * Constructor version mainly used for bootstrapping at initialization time
+        * a policy engine controller
+        * 
+        * @param name controller name
+        * @param properties
+        * 
+        * @throws IllegalArgumentException when invalid arguments are provided
+        */
+       public AggregatedPolicyController(String name, Properties properties) 
+                       throws IllegalArgumentException {
+               
+               this.name = name;
+               
+               /*
+                * 1. Register read topics with network infrastructure (ueb, dmaap, rest)
+                * 2. Register write topics with network infrastructure (ueb, dmaap, rest)
+                * 3. Register with drools infrastructure
+                */
+               
+               // Create/Reuse Readers/Writers for all event sources endpoints
+               
+               this.sources = TopicEndpoint.manager.addTopicSources(properties);
+               this.sinks = TopicEndpoint.manager.addTopicSinks(properties);
+               
+               initDrools(properties);         
+               initSinks();            
+               
+               /* persist new properties */
+               SystemPersistence.manager.storeController(name, properties);    
+               this.properties = properties;
+       }
+       
+       /**
+        * initialize drools layer
+        * @throws IllegalArgumentException if invalid parameters are passed in
+        */
+       protected void initDrools(Properties properties) throws IllegalArgumentException {
+               try {
+                       // Register with drools infrastructure
+                       this.droolsController = DroolsController.factory.build(properties, sources, sinks);
+               } catch (Exception | LinkageError e) {
+                       logger.error("BUILD-INIT-DROOLS: " + e.getMessage());
+                       e.printStackTrace();
+                       
+                       // throw back exception as input properties cause problems
+                       throw new IllegalArgumentException(e);
+               }
+       }
+       
+       /**
+        * initialize sinks
+        * @throws IllegalArgumentException if invalid parameters are passed in
+        */
+       protected void initSinks() throws IllegalArgumentException {
+               this.topic2Sinks.clear();
+               for (TopicSink sink: sinks) {
+                       this.topic2Sinks.put(sink.getTopic(), sink);
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean updateDrools(DroolsConfiguration newDroolsConfiguration) {
+               
+               DroolsConfiguration oldDroolsConfiguration =
+                               new DroolsConfiguration(this.droolsController.getArtifactId(),
+                                                                               this.droolsController.getGroupId(), 
+                                                       this.droolsController.getVersion());
+               
+               if (oldDroolsConfiguration.getGroupId().equalsIgnoreCase(newDroolsConfiguration.getGroupId()) &&
+                       oldDroolsConfiguration.getArtifactId().equalsIgnoreCase(newDroolsConfiguration.getArtifactId()) &&
+                       oldDroolsConfiguration.getVersion().equalsIgnoreCase(newDroolsConfiguration.getVersion())) {
+                       logger.warn("UPDATE-DROOLS: nothing to do: identical configuration: " + oldDroolsConfiguration +
+                                           " <=> " + newDroolsConfiguration);
+                       return true;
+               }
+               
+               try {
+                       /* Drools Controller created, update initialization properties for restarts */
+                       
+                       this.properties.setProperty(PolicyProperties.RULES_GROUPID, newDroolsConfiguration.getGroupId());
+                       this.properties.setProperty(PolicyProperties.RULES_ARTIFACTID, newDroolsConfiguration.getArtifactId());
+                       this.properties.setProperty(PolicyProperties.RULES_VERSION, newDroolsConfiguration.getVersion());
+                                       
+                       SystemPersistence.manager.storeController(name, this.properties);
+                       
+                       this.initDrools(this.properties);
+                       
+                       /* set drools controller to current locked status */
+                       
+                       if (this.isLocked())
+                               this.droolsController.lock();
+                       else
+                               this.droolsController.unlock();
+                       
+                       /* set drools controller to current alive status */
+                       
+                       if (this.isAlive())
+                               this.droolsController.start();
+                       else
+                               this.droolsController.stop();
+                       
+               } catch (IllegalArgumentException e) {
+                       logger.warn("INIT-DROOLS: " + e.getMessage());
+                       e.printStackTrace();
+                       return false;
+               }       
+               
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getName() {
+               return this.name;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean start() throws IllegalStateException {
+               if (logger.isInfoEnabled())
+                       logger.info("START: " + this);
+               
+               if (this.isLocked())
+                       throw new IllegalStateException("Policy Controller " + name  + " is locked");
+
+               synchronized(this) {
+                       if (this.alive)
+                               return true;
+                       
+                       this.alive = true;
+               }
+
+               boolean success = this.droolsController.start();
+               
+               // register for events
+               
+               for (TopicSource source: sources) {
+                       source.register(this);
+               }
+               
+               for (TopicSink sink: sinks) {
+                       try {
+                               sink.start();
+                       } catch (Exception e) {
+                               logger.warn("can't start sink: " + sink + " because of " + e.getMessage());
+                               e.printStackTrace();
+                       }
+               }
+               
+               return success;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean stop() {
+               
+               logger.info("STOP: " + this);
+               
+               /* stop regardless locked state */
+               
+               synchronized(this) {
+                       if (!this.alive)
+                               return true;
+                       
+                       this.alive = false;
+               }
+               
+               // 1. Stop registration
+               
+               for (TopicSource source: sources) {
+                       source.unregister(this);
+               }
+               
+               boolean success = this.droolsController.stop();
+               return success;
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void shutdown() throws IllegalStateException {
+               if (logger.isInfoEnabled())
+                       logger.info(this  + "SHUTDOWN");
+               
+               this.stop();
+               
+               DroolsController.factory.shutdown(this.droolsController);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public void halt() throws IllegalStateException {
+               if (logger.isInfoEnabled())
+                       logger.info(this + "HALT");
+               
+               this.stop();    
+               DroolsController.factory.destroy(this.droolsController);
+               SystemPersistence.manager.deleteController(this.name);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean onTopicEvent(Topic.CommInfrastructure commType, 
+                                           String topic, String event) {
+
+               logger.info("EVENT NOTIFICATION: " + commType + ":" + topic + ":" + event +  " INTO " + this);
+               
+               if (this.locked)
+                       return false;
+               
+               if (!this.alive)
+                       return true;
+               
+               return this.droolsController.offer(topic, event);
+       }
+       
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean deliver(Topic.CommInfrastructure commType, 
+                                      String topic, Object event)
+               throws IllegalArgumentException, IllegalStateException,
+               UnsupportedOperationException { 
+               
+               logger.info("DELIVER: " + commType + ":" + topic + ":" + event +  " FROM " + this);
+               
+               if (topic == null || topic.isEmpty())
+                       throw new IllegalArgumentException("Invalid Topic");
+               
+               if (event == null)
+                       throw new IllegalArgumentException("Invalid Event");
+               
+               if (!this.isAlive())
+                       throw new IllegalStateException("Policy Engine is stopped");
+               
+               if (this.isLocked())
+                       throw new IllegalStateException("Policy Engine is locked");
+               
+               if (!this.topic2Sinks.containsKey(topic)) {
+                       logger.error("UNDELIVERED: " + commType + ":" + topic + ":" + event +  " FROM " + this);
+                       throw new IllegalArgumentException
+                                       ("Unsuported topic " + topic + " for delivery");
+               }
+               
+               return this.droolsController.deliver
+                               (this.topic2Sinks.get(topic), event);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isAlive() {
+               return this.alive;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean lock() {
+               logger.info("LOCK: " + this);
+               
+               synchronized(this) {
+                       if (this.locked)
+                               return true;
+                       
+                       this.locked = true;
+               }
+               
+               // it does not affect associated sources/sinks, they are
+               // autonomous entities
+               
+               return this.droolsController.lock();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean unlock() {
+               logger.info("UNLOCK: " + this);
+               
+               synchronized(this) {
+                       if (!this.locked)
+                               return true;
+                       
+                       this.locked = false;
+               }
+               
+               return this.droolsController.unlock();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isLocked() {
+               return this.locked;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSource> getTopicSources() {
+               return this.sources;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public List<? extends TopicSink> getTopicSinks() {
+               return this.sinks;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public DroolsController getDrools() {
+               return this.droolsController;
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("AggregatedPolicyController [name=").append(name).append(", sources=").append(sources)
+                               .append(", sinks=").append(sinks).append(", alive=").append(alive).append(", locked=").append(locked)
+                               .append(", droolsController=").append(droolsController).append("]");
+               return builder.toString();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Properties getInitializationProperties() {
+               return this.properties;
+       }
+
+}
+
diff --git a/policy-management/src/main/server-gen/bin/add-secured-participant.sh b/policy-management/src/main/server-gen/bin/add-secured-participant.sh
new file mode 100644 (file)
index 0000000..d6843fe
--- /dev/null
@@ -0,0 +1,122 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+function usage() {
+       echo -n "Usage: $(basename $0) "
+       echo -n "[(-d|--debug)] "
+       echo -n "(-h|--host) <bus-host> "
+       echo -n "[(-p|--port) <bus-port>] "
+       echo -n "(-k|--key) <api-key> "
+       echo -n "(-s|--secret) <api-secret> "
+       echo -n "(-P|--producer-key) <producer-key> "
+       echo -n "(-C|--consumer-key) <consumer-key> "
+       echo "(-t|--topic) <topic> "
+}
+
+BUS_PORT=3904
+
+# command line options parsing
+until [[ -z "$1" ]]; do
+       case $1 in
+               -d|--debug)     set -x
+                               ;;
+               -h|--host)              shift
+                                       BUS_HOST=$1
+                                       ;;                                              
+               -p|--port)              shift
+                                       BUS_PORT=$1
+                                       ;;
+               -k|--key)               shift
+                                       API_KEY=$1
+                                       ;;      
+               -s|--secret)            shift
+                                       API_SECRET=$1
+                                       ;;      
+               -t|--topic)             shift
+                                       TOPIC=$1
+                                       ;;                                                      
+               -P|--producer-key)      shift
+                                       URL_CONTEXT="producers"
+                                       PRODUCER_KEY=$1
+                                       KEY=$1
+                                       ;;      
+               -C|--consumer-key)      shift
+                                       URL_CONTEXT="consumers"
+                                       CONSUMER_KEY=$1
+                                       KEY=$1
+                                       ;;                                                                                                                              
+               *)                      usage
+                                       exit 1
+                                       ;;
+       esac
+       shift
+done
+
+if [[ -z ${BUS_HOST} ]]; then
+       echo "An UEB/DMAAP server must be provided."
+       echo
+       usage
+       exit 1
+fi
+
+if [[ -z ${API_KEY} ]]; then
+       echo "The API Key must be provided."
+       usage
+       exit 2
+fi
+
+if [[ -z ${API_SECRET} ]]; then
+       echo "The API Secret must be provided."
+       usage
+       exit 3
+fi
+
+if [[ -z ${TOPIC} ]]; then
+       echo "The Topic Name must be provided."
+       usage
+       exit 3
+fi
+
+if [[ -z ${PRODUCER_KEY} && -z ${CONSUMER_KEY} ]]; then
+       echo "Either the Producer or Consumer options must be provided."
+       usage
+       exit 4
+fi
+
+if [[ -n ${PRODUCER_KEY} && -n ${CONSUMER_KEY} ]]; then
+       echo "Only and only one of the Producer or Consumer options must be provided."
+       usage
+       exit 5
+fi
+
+
+DATE=$(date)
+DATE_HASH=$(echo -n "${DATE}" | openssl sha1 -hmac "${API_SECRET}" -binary | openssl base64)
+
+unset http_proxy
+curl --silent -X PUT \
+       --header "Accept:" \
+       --header "X-CambriaDate: ${DATE}" \
+       --header "X-CambriaAuth: ${API_KEY}:${DATE_HASH}" \
+       --header "Content-Type: application/json" \
+       --data "{}" \
+       http://${BUS_HOST}:${BUS_PORT}/topics/${TOPIC}/${URL_CONTEXT}/${KEY}
diff --git a/policy-management/src/main/server-gen/bin/create-api-key.sh b/policy-management/src/main/server-gen/bin/create-api-key.sh
new file mode 100644 (file)
index 0000000..ea0ec7a
--- /dev/null
@@ -0,0 +1,76 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+function usage() {
+       echo -n "Usage: $(basename $0) "
+       echo -n "[(-d|--debug)] "
+       echo -n "(-h|--host) <bus-host> "
+       echo -n "[(-p|--port) <bus-port>] "
+       echo    "(-e|--email) <email>"
+}
+
+BUS_PORT=3904
+
+# command line options parsing
+until [[ -z "$1" ]]; do
+       case $1 in
+               -d|--debug)     set -x
+                                               ;;
+               -h|--host)              shift
+                                               BUS_HOST=$1
+                                               ;;                                              
+               -p|--port)              shift
+                                               BUS_PORT=$1
+                                               ;;
+               -e|--email)     shift
+                                               EMAIL=$1
+                                               ;;                                              
+               *)                              usage
+                                               exit 1
+                                               ;;
+       esac
+       shift
+done
+
+if [[ -z ${BUS_HOST} ]]; then
+       echo "An UEB/DMAAP server must be provided."
+       echo
+       usage
+       exit 1
+fi
+
+if [[ -z ${EMAIL} ]]; then
+       echo "An email address must be provided."
+       usage
+       exit 2
+fi
+
+REQUEST_API_KEY_BODY=$(< <(cat <<EOF
+{
+  "email": "${EMAIL}",
+  "description": "Generated by PDP-D $(hostname -f)"
+}
+EOF
+))
+
+unset http_proxy
+curl -s -X POST --data "${REQUEST_API_KEY_BODY}" --header "Content-Type: application/json" http://${BUS_HOST}:${BUS_PORT}/v1/apiKeys/create
diff --git a/policy-management/src/main/server-gen/bin/create-secured-topic.sh b/policy-management/src/main/server-gen/bin/create-secured-topic.sh
new file mode 100644 (file)
index 0000000..b0d4d6f
--- /dev/null
@@ -0,0 +1,130 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+function usage() {
+       echo -n "Usage: $(basename $0) "
+       echo -n "[(-d|--debug)] "
+       echo -n "(-h|--host) <bus-host> "
+       echo -n "[(-p|--port) <bus-port>] "
+       echo -n "(-k|--key) <api-key> "
+       echo -n "(-s|--secret) <api-secret> "
+       echo -n "[(-P|--partition) <partition-count>] "
+       echo -n "[(-R|--replication) <replication-count>] "
+       echo "(-t|--topic) <topic> "
+       echo ""
+}
+
+BUS_PORT=3904
+PARTITION_COUNT=1
+REPLICATION_COUNT=1
+
+# command line options parsing
+until [[ -z "$1" ]]; do
+       case $1 in
+               -d|--debug)     set -x
+                               ;;
+               -h|--host)              shift
+                                       BUS_HOST=$1
+                                       ;;                                              
+               -p|--port)              shift
+                                       BUS_PORT=$1
+                                       ;;
+               -k|--key)               shift
+                                       API_KEY=$1
+                                       ;;      
+               -s|--secret)            shift
+                                       API_SECRET=$1
+                                       ;;      
+               -t|--topic)             shift
+                                       TOPIC=$1
+                                       ;;                                                      
+               -P|--partition-count)   shift
+                                       PARTITION_COUNT=$1
+                                       ;;
+               -R|--replication-count) shift
+                                       REPLICATION_COUNT=$1
+                                       ;;                                                                                                                                      
+               *)                      usage
+                                       exit 1
+                                       ;;
+       esac
+       shift
+done
+
+if [[ -z ${BUS_HOST} ]]; then
+       echo "An UEB/DMAAP server must be provided."
+       echo
+       usage
+       exit 1
+fi
+
+if [[ -z ${API_KEY} ]]; then
+       echo "The API Key must be provided."
+       usage
+       exit 2
+fi
+
+if [[ -z ${API_SECRET} ]]; then
+       echo "The API Secret must be provided."
+       usage
+       exit 3
+fi
+
+if [[ -z ${TOPIC} ]]; then
+       echo "The Topic Name must be provided."
+       usage
+       exit 3
+fi
+
+if [[ -z ${PARTITION_COUNT} ]]; then
+       echo "The Partition Count must be provided."
+       usage
+       exit 4
+fi
+
+if [[ -z ${REPLICATION_COUNT} ]]; then
+       echo "The Replication Count must be provided."
+       usage
+       exit 5
+fi
+
+REQUEST_API_KEY_BODY=$(< <(cat <<EOF
+{
+       "topicName": "${TOPIC}",
+       "topicDescription": "Generated by PDP-D $(hostname -f)",
+       "partitionCount": ${PARTITION_COUNT},
+       "replicationCount": ${REPLICATION_COUNT}
+}
+EOF
+))
+
+DATE=$(date)
+DATE_HASH=$(echo -n "${DATE}" | openssl sha1 -hmac "${API_SECRET}" -binary | openssl base64)
+
+unset http_proxy
+curl --silent -X POST \
+       --header "Accept:" \
+       --header "X-CambriaDate: ${DATE}" \
+       --header "X-CambriaAuth: ${API_KEY}:${DATE_HASH}" \
+       --header "Content-Type: application/json" \
+       --data "${REQUEST_API_KEY_BODY}" \
+       http://${BUS_HOST}:${BUS_PORT}/topics/create
diff --git a/policy-management/src/main/server-gen/bin/options b/policy-management/src/main/server-gen/bin/options
new file mode 100644 (file)
index 0000000..a9ae712
--- /dev/null
@@ -0,0 +1,125 @@
+#! /bin/bash
+
+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-gen/bin/pdpd-configuration.sh b/policy-management/src/main/server-gen/bin/pdpd-configuration.sh
new file mode 100644 (file)
index 0000000..8c55392
--- /dev/null
@@ -0,0 +1,200 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+function usage() {
+       echo -n "Usage: $(basename $0) "
+       echo -n "[(-d|--debug)] "
+       echo -n "(-h|--host) <bus-host> "
+       echo -n "[(-p|--port) <bus-port>] "
+       echo -n "[(-k|--key) <api-key>] "
+       echo -n "[(-s|--secret) <api-secret>] "
+       echo -n "[(-r|--request-id) <request-id>] "
+       echo -n "(-c|--controller-name) <controller-name> "
+       echo -n "(-o|--operation) <create|update|lock|unlock> "
+       echo -n "[(-g|--group-id) <group-id> "
+       echo -n "(-a|--artifact-id) <artifact-id> "
+       echo -n "(-v|--version) <version>] "
+       echo -n "[(-t|--topic) <topic>] "
+       echo ""
+}
+
+BUS_PORT=3904
+ENTITY=controller
+REQUEST_ID="7f5474ca-16a9-42ac-abc0-d86f62296fbc"
+TOPIC="PDPD_CONFIGURATION"
+
+# command line options parsing
+until [[ -z "$1" ]]; do
+       case $1 in
+               -d|--debug)     set -x
+                               ;;
+               -h|--host)              shift
+                                       BUS_HOST=$1
+                                       ;;                                              
+               -p|--port)              shift
+                                       BUS_PORT=$1
+                                       ;;
+               -r|--request-id)                shift
+                                       REQUEST_ID=$1
+                                       ;;
+               -k|--key)               shift
+                                       API_KEY=$1
+                                       ;;      
+               -s|--secret)            shift
+                                       API_SECRET=$1
+                                       ;;      
+               -c|--controller-name)           shift
+                                       CONTROLLER_NAME=$1
+                                       ;;
+               -o|--operation)                 shift
+                                       OPERATION=$1
+                                       ;;                                                      
+               -g|--group-id)  shift
+                                       GROUP_ID=$1
+                                       ;;
+               -a|--artifact-id) shift
+                                       ARTIFACT_ID=$1
+                                       ;;
+               -v|--version) shift
+                                       VERSION=$1
+                                       ;;              
+               -t|--topic) shift
+                                       TOPIC=$1
+                                       ;;                                                                                                                      
+               *)                      usage
+                                       exit 1
+                                       ;;
+       esac
+       shift
+done
+
+if [[ -z ${BUS_HOST} ]]; then
+       echo "An UEB/DMAAP server must be provided."
+       echo
+       usage
+       exit 1
+fi
+
+if [[ -z ${CONTROLLER_NAME} ]]; then
+       echo "The controller-name must be provided."
+       usage
+       exit 2
+fi
+
+if [[ -z ${OPERATION} ]]; then
+       echo "The operation  must be provided: create|update|lock|unlock"
+       usage
+       exit 3
+fi
+
+if [[ ${OPERATION} == "create" ]] || [[ ${OPERATION} == "update" ]]; then
+       if [[ -z ${GROUP_ID} ]]; then
+               echo "The maven group id must be provided when operation is create|update"
+               usage
+               exit 4
+       fi
+       
+       if [[ -z ${ARTIFACT_ID} ]]; then
+               echo "The maven artifact id must be provided when operation is create|update"
+               usage
+               exit 5
+       fi
+       
+       if [[ -z ${VERSION} ]]; then
+               echo "The maven version must be provided when operation is create|update"
+               usage
+               exit 6
+       fi
+fi
+
+UPDATE_BODY=$(< <(cat <<EOF
+{
+      "requestID": "${REQUEST_ID}",
+      "entity": "controller",
+      "controllers": [{
+            "name": "${CONTROLLER_NAME}",
+            "drools": {
+                  "groupId": "${GROUP_ID}",
+                  "artifactId": "${ARTIFACT_ID}",
+                  "version": "${VERSION}"
+            },
+            "operation": "${OPERATION}"
+      }]
+}
+
+EOF
+))
+
+LOCK_BODY=$(< <(cat <<EOF
+{
+      "requestID": "${REQUEST_ID}",
+      "entity": "controller",
+      "controllers": [{
+            "name": "${CONTROLLER_NAME}",
+            "operation": "${OPERATION}"
+      }]
+}
+
+EOF
+))
+
+unset http_proxy
+
+if [[ ${OPERATION} == "lock" ]] || [[ ${OPERATION} == "unlock" ]]; then
+       if [[ -n ${API_KEY} ]]; then
+               DATE=$(date)
+               DATE_HASH=$(echo -n "${DATE}" | openssl sha1 -hmac "${API_SECRET}" -binary | openssl base64)
+               curl --silent -X POST \
+                       --header "Accept:" \
+                       --header "X-CambriaDate: ${DATE}" \
+                       --header "X-CambriaAuth: ${API_KEY}:${DATE_HASH}" \
+                       --header "Content-Type: application/json" \
+                       --data "${LOCK_BODY}" \
+                       http://${BUS_HOST}:${BUS_PORT}/events/${TOPIC}
+       else
+               curl --silent -X POST \
+                       --header "Accept:" \
+                       --header "Content-Type: application/json" \
+                       --data "${LOCK_BODY}" \
+                       http://${BUS_HOST}:${BUS_PORT}/events/${TOPIC}
+       fi
+fi
+
+if [[ ${OPERATION} == "create" ]] || [[ ${OPERATION} == "update" ]]; then
+       if [[ -n ${API_KEY} ]]; then
+               DATE=$(date)
+               DATE_HASH=$(echo -n "${DATE}" | openssl sha1 -hmac "${API_SECRET}" -binary | openssl base64)
+               curl --silent -X POST \
+                       --header "Accept:" \
+                       --header "X-CambriaDate: ${DATE}" \
+                       --header "X-CambriaAuth: ${API_KEY}:${DATE_HASH}" \
+                       --header "Content-Type: application/json" \
+                       --data "${UPDATE_BODY}" \
+                       http://${BUS_HOST}:${BUS_PORT}/events/${TOPIC}
+       else
+               curl --silent -X POST \
+                       --header "Accept:" \
+                       --header "Content-Type: application/json" \
+                       --data "${UPDATE_BODY}" \
+                       http://${BUS_HOST}:${BUS_PORT}/events/${TOPIC}
+       fi
+fi
diff --git a/policy-management/src/main/server-gen/bin/policy-management-controller b/policy-management/src/main/server-gen/bin/policy-management-controller
new file mode 100644 (file)
index 0000000..4d28d94
--- /dev/null
@@ -0,0 +1,191 @@
+#!/bin/bash
+
+SNAME="Policy Management"
+PNAME=policy-management
+CLASS=org.openecomp.policy.drools.system.Main
+
+
+function start() {
+       um_start
+       if [[ ${RETVAL} != 0 ]]; then
+               update_monitor off
+       else
+               update_monitor on
+       fi      
+}
+
+# unmonitored start, does not change monitor status (immutable)
+function um_start() {
+    status
+    if [ "$_RUNNING" = "1" ]; then
+      echo $_STATUS
+      RETVAL=0
+      return
+    fi
+    mkdir -p $_DIR/logs
+    if [ -e $_DIR/logs/$PNAME.out.1 ]; then mv $_DIR/logs/$PNAME.out.1 $_DIR/logs/$PNAME.out.2; fi
+    if [ -e $_DIR/logs/$PNAME.err.1 ]; then mv $_DIR/logs/$PNAME.err.1 $_DIR/logs/$PNAME.err.2; fi
+    if [ -e $_DIR/logs/$PNAME.out ]; then mv $_DIR/logs/$PNAME.out $_DIR/logs/$PNAME.out.1; fi
+    if [ -e $_DIR/logs/$PNAME.err ]; then mv $_DIR/logs/$PNAME.err $_DIR/logs/$PNAME.err.1; fi
+    CP=$(ls $_DIR/lib/*.jar | xargs -I X printf ":%s" X)
+
+    # If 'system.properties' exists, convert it into JVM arguments.
+    # Note that the following also handles property values with spaces.
+    IFS=$'\n'
+    systemProperties=($(
+        if [[ -f $_DIR/config/system.properties ]] ; then
+            sed -n -e 's/^[ \t]*\([^ \t#]*\)[ \t]*=[ \t]*\(.*\)$/-D\1=\2/p' \
+                $_DIR/config/system.properties
+        fi
+    ))
+
+    cd $_DIR
+    (
+       if [[ "${cfg}" != "" ]] ; then
+           # need to make sure that we don't pass the lock file descriptor
+           # to subprocesses
+           exec {cfg}>&-
+       fi
+       nohup $JAVA_HOME/bin/java -Dkie.maven.settings.custom=$_DIR/config/kie_settings.xml -Dlog4j.configuration=file:$_DIR/config/log4j.properties -cp $_DIR/config:$_DIR/lib:$CP "${systemProperties[@]}" "$@" $CLASS > >( while read line; do echo "$(date): ${line}"; done > $_DIR/logs/$PNAME.out) 2> >( while read line; do echo "$(date): ${line}"; done > $_DIR/logs/$PNAME.err) &
+
+       _PID=$!
+       echo $_PID > $_PIDFILE
+    )
+    sleep 5
+    status
+    echo $_STATUS
+    if [ "$_RUNNING" = "1" ]; then
+       RETVAL=0
+    else
+       echo "Failed to start"
+       remove_pid_file
+       RETVAL=1
+    fi
+}
+
+function stop() {
+       um_stop
+       update_monitor off
+}
+
+# unmonitored stop, does not change monitor status (immutable)
+function um_stop() {
+    status
+    if [ "$_RUNNING" = "0" ]; then
+       echo $_STATUS
+       remove_pid_file
+    else
+       if [[ -n ${ENGINE_MANAGEMENT_PASSWORD} ]]; then
+           http_proxy= curl --silent --user ${ENGINE_MANAGEMENT_USER}:${ENGINE_MANAGEMENT_PASSWORD} -X DELETE http://localhost:${ENGINE_MANAGEMENT_PORT}/policy/pdp/engine -o /dev/null
+       else
+           http_proxy= curl --silent -X DELETE http://localhost:${ENGINE_MANAGEMENT_PORT}/policy/pdp/engine -o /dev/null
+       fi
+       sleep 5
+       echo "Stopping $SNAME..."
+       _PID_TO_KILL=$_PID;
+       echo "$SNAME (pid=${_PID_TO_KILL}) is stopping..."
+       kill -TERM $_PID_TO_KILL 2> /dev/null
+       sleep 5
+       check_status_of_pid $_PID_TO_KILL
+       if [ "$_RUNNING" = "1" ]; then
+          kill -TERM $_PID_TO_KILL
+       fi
+       while [ "$_RUNNING" = "1" ]; do
+          sleep 2
+          check_status_of_pid $_PID_TO_KILL
+       done
+       remove_pid_file
+       echo "$SNAME has stopped."
+    fi
+    RETVAL=0
+}
+
+function status() {
+    if [ -f "${_PIDFILE}" ]; then
+        _PID=`cat "${_PIDFILE}"`
+        check_status_of_pid $_PID
+    else
+        _STATUS="$SNAME (no pidfile) is NOT running"
+        _RUNNING=0
+    fi
+    if [[ $_RUNNING = 1 ]]; then
+        RETVAL=0
+    else
+        RETVAL=1
+    fi
+}
+
+
+function check_status_of_pid ()
+{
+    if [ -n "$1" ] && kill -0 $1 2>/dev/null ; then
+        _STATUS="$SNAME (pid $1) is running"
+        _RUNNING=1
+    else
+        _STATUS="$SNAME (pid $1) is NOT running"
+        _RUNNING=0
+    fi
+}
+
+function remove_pid_file ()
+{
+   if [ -f "${_PIDFILE}" ]; then
+      rm "${_PIDFILE}"
+   fi
+}
+
+function update_monitor() {
+       STATUS=$1
+       if [[ -f ${POLICY_HOME}/etc/monitor/monitor.cfg ]]; then
+               /bin/sed -i.bak \
+                       -e "s/^${CONTROLLER}=.*/${CONTROLLER}=${STATUS}/g" \
+                       ${POLICY_HOME}/etc/monitor/monitor.cfg  
+       fi
+}
+
+
+# main
+
+_DIR=${POLICY_HOME}
+CONTROLLER=policy-management-controller
+
+RETVAL=0
+
+_PIDFILE=${POLICY_HOME}/PID
+
+case "$1" in
+    status)
+       status
+       echo "$_STATUS"
+       ;;
+    start)
+       if flock ${cfg} ; then
+           start
+       fi {cfg}>>${POLICY_HOME}/etc/monitor/monitor.cfg.lock
+       ;;
+    umstart)
+       um_start
+       ;;
+    stop)
+       if flock ${cfg} ; then
+           stop
+       fi {cfg}>>${POLICY_HOME}/etc/monitor/monitor.cfg.lock
+       ;;
+    umstop)
+       um_stop
+       ;;
+    restart)
+       if flock ${cfg} ; then
+           stop
+           sleep 2
+           start
+       fi {cfg}>>${POLICY_HOME}/etc/monitor/monitor.cfg.lock
+       ;;
+    *)
+       echo "error: invalid option $@"
+       echo "Usage: $0 status|start|stop|restart"
+       RETVAL=1
+       ;;
+esac
+
+exit ${RETVAL}
diff --git a/policy-management/src/main/server-gen/bin/rest-add-controller.sh b/policy-management/src/main/server-gen/bin/rest-add-controller.sh
new file mode 100644 (file)
index 0000000..187b291
--- /dev/null
@@ -0,0 +1,37 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+source $POLICY_HOME/etc/profile.d/env.sh
+
+json=$1-controller.rest.json
+
+if [ -f ${json} ]; then
+       if [[ -n ${ENGINE_MANAGEMENT_PASSWORD} ]]; then
+       curl --silent --user ${ENGINE_MANAGEMENT_USER}:${ENGINE_MANAGEMENT_PASSWORD} -X POST --data @${json} --header "Content-Type: application/json" \
+                       http://localhost:${ENGINE_MANAGEMENT_PORT}/policy/pdp/engine/controllers
+       else
+               curl --silent -X POST --data @${json} --header "Content-Type: application/json" \
+                       http://localhost:${ENGINE_MANAGEMENT_PORT}/policy/pdp/engine/controllers
+       fi
+else
+       echo "Usage: rest-add-controller.sh closed-loop-sample|reporter|sepc|vsegw|.. (or any other config file ending with *-controller.rest.json)"    
+fi
diff --git a/policy-management/src/main/server-gen/bin/rest-delete-controller.sh b/policy-management/src/main/server-gen/bin/rest-delete-controller.sh
new file mode 100644 (file)
index 0000000..de1d601
--- /dev/null
@@ -0,0 +1,43 @@
+#! /bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+source $POLICY_HOME/etc/profile.d/env.sh
+
+if [[ -n $1 ]]; then
+       if [[ -n ${ENGINE_MANAGEMENT_PASSWORD} ]]; then
+               curl --silent --user ${ENGINE_MANAGEMENT_USER}:${ENGINE_MANAGEMENT_PASSWORD} -X DELETE --header "Content-Type: application/json" \
+                       http://localhost:${ENGINE_MANAGEMENT_PORT}/policy/pdp/engine/controllers/${1}
+       else
+               curl --silent -X DELETE --header "Content-Type: application/json" \
+                       http://localhost:${ENGINE_MANAGEMENT_PORT}/policy/pdp/engine/controllers/${1}
+       fi
+       echo
+       exit    
+fi
+
+
+               
+cat <<-'EOF'
+
+Usage: rest-delete-controller.sh closed-loop-sample|reporter|sepc|vsegw|.. (or any other controller idenfied by name)
+
+EOF
diff --git a/policy-management/src/main/server/config/IntegrityMonitor.properties b/policy-management/src/main/server/config/IntegrityMonitor.properties
new file mode 100644 (file)
index 0000000..1201a9d
--- /dev/null
@@ -0,0 +1,81 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+hostPort = ${{host_port}}
+
+# The following were added as part of US673632
+#
+# Forward Progress Monitor update interval seconds
+fp_monitor_interval = ${{fp_monitor_interval}}
+# Failed counter threshold before failover 
+failed_counter_threshold = ${{failed_counter_threshold}}
+# Interval between test transactions when no traffic seconds
+test_trans_interval = ${{test_trans_interval}}
+# Interval between writes of the FPC to the DB seconds 
+write_fpc_interval = ${{write_fpc_interval}}
+# Name of the site in which this node is hosted 
+site_name = ${{site_name}}
+# Node type
+# Note: Make sure you don't leave any trailing spaces, or you'll get an 'invalid node type' error! 
+node_type = pdp_drools
+# Dependency groups are groups of resources upon which a node operational state is dependent upon. 
+# Each group is a comma-separated list of resource names and groups are separated by a semicolon.  For example:
+dependency_groups=${{dependency_groups}}
+# When set to true, dependent health checks are performed by using JMX to invoke test() on the dependent.
+# The default false is to use state checks for health.
+test_via_jmx=${{test_via_jmx}}
+# This is the max number of seconds beyond which a non incrementing FPC is considered a failure
+max_fpc_update_interval=${{max_fpc_update_interval}}
+
+# Needed by DroolsPdpsElectionHandler
+pdp.checkInterval=7000
+pdp.updateInterval=10000
+#pdp.timeout=3000
+# Need long timeout, because testTransaction is only run every 10 seconds.
+pdp.timeout=15000
+#how long do we wait for the pdp table to populate on initial startup
+pdp.initialWait=20000
+
+# Known as the PDPID in the droolpdpentity table.
+#resource.name=pdp1
+resource.name=${{resource_name}}
+
+# The amount of this a resource (entity) should sleep between audit executions.
+# If not specified, defaults to five seconds.
+# -1 turns off audit
+# zero forces audit to run continuously
+integrity_audit_period_seconds=-1
+
+# Properties needed for repository audit
+repository.audit.id=${{repositoryID}}
+repository.audit.url=${{repositoryUrl}}
+repository.audit.username=${{repositoryUsername}}
+repository.audit.password=${{repositoryPassword}}
+
+# Flag to control the execution of the subsystemTest for the Database
+db.audit.is.active=false
+
+# Flag to control the execution of the subsystemTest for the Nexus Maven repository
+repository.audit.is.active=false
+
+
+
+
+
diff --git a/policy-management/src/main/server/config/controller.properties.README b/policy-management/src/main/server/config/controller.properties.README
new file mode 100644 (file)
index 0000000..8421cf4
--- /dev/null
@@ -0,0 +1,153 @@
+#
+# *-controller.properties configuration
+#
+#
+# The <controller-name>-controller.properties file define the
+# configuration aspects of a give controller at initialization time.
+#
+# It contains 3 major sections:
+#
+# 1. CONTROLLER
+# 2. DMAAP
+# 4. UEB
+# 5. DROOLS
+#
+# 1. CONTROLLER
+#
+# controller.name: controller unique name identifier.
+#
+# 2. DMAAP:
+#    2.1. DMAAP Sources Information
+#         2.1.1. Topics that this controller supports over DMAAP.
+#         2.1.1. DMAAP Network Information for each topic.
+#         2.1.2. Decoders information for each topic to map network input to
+#                an object that will be injected into its appropriate drools
+#                sessions.
+#         2.1.3. Filtering information for each decoder, to filter out from
+#                drools, messages that should not be processed. 
+#    2.2. DMAAP Sinks Information
+#         2.2.1. Topics that this controller supports over DMAAP.
+#         2.2.2. DMAAP Network Information for each topic.
+#         2.2.3. Encoders information for each topic to map a model object
+#                to serialize network output that will be send over the 
+#                appropriate DMAAP topic according to its network information.
+#
+# 2.1 DMAAP Sources
+#
+# dmaap.source.topics:  comma separated list of DMAAP topics source of events.
+# dmaap.source.topics.<aTopic>.servers:  comma separated list of DMAAP servers to poll for events.
+# [optional] dmaap.source.topics.<aTopic>.apiKey=<APIKEY>  : api key       
+# [optional] dmaap.source.topics.<aTopic>.apiSecret=<APISECRET>  : api secret
+# [optional] dmaap.source.topics.<aTopic>.consumerGroup=<CONSUMER-GROUP> : consumer group
+# [optional] dmaap.source.topics.<aTopic>.consumerInstance=<CONSUMER-INSTANCE>  : consumer instance
+# dmaap.source.topics.<aTopic>.events:  comma separated list of classes to which an event can be mapped to,
+#    where <aTopic> must be declared in dmaap.source.topics
+# [optional] dmaap.source.topics.<aTopic>.events.<eventClass>.filter:  comma separated list of conditions in the form of 
+#      pairs of "<field-name>=<field-value-regex>" values, where <field-name> identifies a field of the event, and
+#      <field-value-regex> is a regular expression that that field's value in the event must match
+#      against each particular instantiation of the event for this controller.   Note that multiple 
+#      "<field-name>=<field-value-regex>" are evaluated for acceptance by AND'ing each condition.
+#      Further, <aTopic> must be declared in dmaap.source.topics, and 
+#      <eventClass> in dmaap.source.topics.<aTopic>.events.
+# [optional] dmaap.source.topics.<aTopic>.events.custom.gson:  comma separated pair, where the first item
+#      is a class in the model that contains a gson parser, and the second is the actual gson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+# [optional] dmaap.source.topics.<aTopic>.events.custom.jackson:  comma separated pair, where the first item
+#      is a class in the model that contains a jackson parser, and the second is the actual jackson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+#
+# 2.2 DMAAP Sinks
+#
+# dmaap.sink.topics:  comma separated list of DMAAP topics destination of locally produced events.
+# dmaap.sink.topics.<aTopic>.servers:  comma separated list of DMAAP servers to send events.
+# [optional] dmaap.sink.topics.<aTopic>.apiKey=<API-KEY>  : api key       
+# [optional] dmaap.sink.topics.<aTopic>.apiSecret=<API-SECRET>  : api secret
+# [optional] dmaap.sink.topics.<aTopic>.partitionKey=<PARTITIONKEY> : partition key
+# dmaap.sink.topics.<aTopic>.events:  comma separated list of classes to which an event can be mapped to,
+#    where <aTopic> must be declared in dmaap.sink.topics
+# [optional] dmaap.sink.topics.<aTopic>.events.custom.gson:  comma separated pair, where the first item
+#      is a class in the model that contains a gson parser, and the second is the actual gson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+# [optional] dmaap.sink.topics.<aTopic>.events.custom.jackson:  comma separated pair, where the first item
+#      is a class in the model that contains a jackson parser, and the second is the actual jackson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+#
+# 2. UEB:
+#    2.1. UEB Sources Information
+#         2.1.1. Topics that this controller supports over UEB.
+#         2.1.1. UEB Network Information for each topic.
+#         2.1.2. Decoders information for each topic to map network input to
+#                an object that will be injected into its appropriate drools
+#                sessions.
+#         2.1.3. Filtering information for each decoder, to filter out from
+#                drools, messages that should not be processed. 
+#    2.2. UEB Sinks Information
+#         2.2.1. Topics that this controller supports over UEB.
+#         2.2.2. UEB Network Information for each topic.
+#         2.2.3. Encoders information for each topic to map a model object
+#                to serialize network output that will be send over the 
+#                appropriate UEB topic according to its network information.
+#
+#
+# 2.1 UEB Sources
+#
+# ueb.source.topics:  comma separated list of UEB topics source of events.
+# ueb.source.topics.<aTopic>.servers:  comma separated list of UEB servers to poll for events.
+# [optional] ueb.source.topics.<aTopic>.apiKey=<API-KEY>  : api key       
+# [optional] ueb.source.topics.<aTopic>.apiSecret=<API-SECRET>  : api secret
+# [optional] ueb.source.topics.<aTopic>.consumerGroup=<CONSUMER-GROUP> : consumer group
+# [optional] ueb.source.topics.<aTopic>.consumerInstance=<CONSUMER-INSTANCE>  : consumer instance
+# ueb.source.topics.<aTopic>.events:  comma separated list of classes to which an event can be mapped to,
+#    where <aTopic> must be declared in ueb.source.topics
+# ueb.source.topics.<aTopic>.events.<eventClass>.filter:  comma separated list of conditions in the form of 
+#      pairs of "<field-name>=<field-value-regex>" values, where <field-name> identifies a field of the event, and
+#      <field-value-regex> is a regular expression that that field's value in the event must match
+#      against each particular instantiation of the event for this controller.   Note that multiple 
+#      "<field-name>=<field-value-regex>" are evaluated for acceptance by AND'ing each condition.
+#      Further, <aTopic> must be declared in ueb.source.topics, and 
+#      <eventClass> in ueb.source.topics.<aTopic>.events
+# ueb.source.topics.<aTopic>.events:  comma separated list of classes to which an event can be mapped to,
+#    where <aTopic> must be declared in dmaap.source.topics
+# [optional] ueb.source.topics.<aTopic>.events.<eventClass>.filter:  comma separated list of conditions in the form of 
+#      pairs of "<field-name>=<field-value-regex>" values, where <field-name> identifies a field of the event, and
+#      <field-value-regex> is a regular expression that that field's value in the event must match
+#      against each particular instantiation of the event for this controller.   Note that multiple 
+#      "<field-name>=<field-value-regex>" are evaluated for acceptance by AND'ing each condition.
+#      Further, <aTopic> must be declared in dmaap.source.topics, and 
+#      <eventClass> in dmaap.source.topics.<aTopic>.events.
+# [optional] ueb.source.topics.<aTopic>.events.custom.gson:  comma separated pair, where the first item
+#      is a class in the model that contains a gson parser, and the second is the actual gson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+# [optional] ueb.source.topics.<aTopic>.events.custom.jackson:  comma separated pair, where the first item
+#      is a class in the model that contains a jackson parser, and the second is the actual jackson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+#
+# 2.1 UEB Sinks
+#
+# ueb.sink.topics:  comma separated list of UEB topics destination of locally produced events.
+# ueb.sink.topics.<aTopic>.servers:  comma separated list of UEB servers to send events.
+# [optional] ueb.sink.topics.<aTopic>.apiKey=<APIKEY>  : api key       
+# [optional] ueb.sink.topics.<aTopic>.apiSecret=<APISECRET>  : api secret
+# [optional] ueb.sink.topics.<aTopic>.partitionKey=<PARTITIONKEY> : partition key
+# ueb.sink.topics.<aTopic>.events:  comma separated list of classes to which an event can be mapped to,
+#    where <aTopic> must be declared in ueb.sink.topics
+# [optional] ueb.sink.topics.<aTopic>.events.custom.gson:  comma separated pair, where the first item
+#      is a class in the model that contains a gson parser, and the second is the actual gson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+# [optional] ueb.sink.topics.<aTopic>.events.custom.jackson:  comma separated pair, where the first item
+#      is a class in the model that contains a jackson parser, and the second is the actual jackson parser in
+#      the class.   This setting overrides the PDP-D generic framework parsers with an specific model
+#      provided one
+#
+# 3. DROOLS (Maven Group Coordinates):
+# 
+# rules.groupId: maven group id of rules jar file
+# rules.artifactId: maven artifact id of rules jar file
+# rules.version: comma separated list of versions supported and detected that include the drl.
diff --git a/policy-management/src/main/server/config/droolsPersistence.properties b/policy-management/src/main/server/config/droolsPersistence.properties
new file mode 100644 (file)
index 0000000..60793cd
--- /dev/null
@@ -0,0 +1,51 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+#javax.persistence.jdbc.driver = org.h2.Driver
+#javax.persistence.jdbc.url  = jdbc:h2:file:./sql/drools
+#javax.persistence.jdbc.user = sa
+#javax.persistence.jdbc.password =
+
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://localhost:3306/drools
+#javax.persistence.jdbc.user=root
+#javax.persistence.jdbc.password=policy
+
+javax.persistence.jdbc.driver = ${{JDBC_DRIVER}}
+javax.persistence.jdbc.url  = ${{JDBC_DROOLS_URL}}
+javax.persistence.jdbc.user = ${{JDBC_USER}}
+javax.persistence.jdbc.password = ${{JDBC_PASSWORD}}
+
+# Needed?
+#javax.persistence.jdbc.driver = org.h2.Driver
+#javax.persistence.jdbc.url  = jdbc:h2:file:./sql/ncomp
+#javax.persistence.jdbc.user = sa
+#javax.persistence.jdbc.password =
+#persistenceDisabled=false
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://192.168.56.30:3306/drools
+#javax.persistence.jdbc.user=patb
+#javax.persistence.jdbc.password=policy
+
+hibernate.dataSource=org.mariadb.jdbc.MySQLDataSource
+
+# For testing purposes, it may be convenient to disable persistence
+persistenceDisabled=false
+
diff --git a/policy-management/src/main/server/config/log4j.properties b/policy-management/src/main/server/config/log4j.properties
new file mode 100644 (file)
index 0000000..6ad2564
--- /dev/null
@@ -0,0 +1,48 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+log4j.rootLogger=INFO,stdout
+
+log4j.logger.org.apache.http.headers=INFO,stdout
+log4j.logger.org.apache.http.wire=INFO,stdout
+log4j.logger.networkLogger=INFO,network
+
+log4j.additivity.networkLogger=false
+
+log4j.appender.stdout=org.apache.log4j.RollingFileAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] %m %C:%L%n
+
+log4j.appender.network=org.apache.log4j.RollingFileAppender
+log4j.appender.network.File=logs/network.log
+log4j.appender.network.layout=org.apache.log4j.PatternLayout
+log4j.appender.network.layout.ConversionPattern=[%d|%t]%m%n%n
+log4j.appender.network.MaxFileSize=50MB
+log4j.appender.network.MaxBackupIndex=4
+
+log4j.logger.debugLogger=INFO,debug
+log4j.additivity.debugLogger=false
+log4j.appender.debug=org.apache.log4j.RollingFileAppender
+log4j.appender.debug.File=logs/debug.log
+log4j.appender.debug.layout=org.apache.log4j.PatternLayout
+log4j.appender.debug.layout.ConversionPattern=[%d|%t]%m%n%n
+log4j.appender.debug.MaxFileSize=50MB
+log4j.appender.debug.MaxBackupIndex=4
+
diff --git a/policy-management/src/main/server/config/logback.xml b/policy-management/src/main/server/config/logback.xml
new file mode 100644 (file)
index 0000000..545b6f4
--- /dev/null
@@ -0,0 +1,211 @@
+<!--
+  ============LICENSE_START=======================================================
+  policy-management
+  ================================================================================
+  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=========================================================
+  -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  <property name="logDir" value="logs" />
+  
+  <!-- directory path for debugging type logs -->
+  <property name="debugDir" value="debug-logs" />
+  
+  <!--  specify the component name 
+    <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="Policy"></property>
+  
+  <!--  log file names -->
+  <property name="errorLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  <!-- modified time stamp format -->
+  <property name="defaultPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+  <property name="defaultMetricPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+  <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{TargetVirtualEntity}|%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" />
+  
+  <property name="defaultPatternOld" value="%d{MM/dd-HH:mm:ss.SSS}|%logger|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Timer}|%msg%n" />
+  
+   <property name="debugLoggerPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{RequestId}|%X{ClassName}|%msg%n" />  
+<!--  <property name="debugLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{ServiceName}|%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="debugLoggerPatternOld" value="%d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{Timer}|[%caller{3}]|%msg%n" />
+  
+  <property name="logDirectory" value="${logDir}/${componentName}" />
+  <property name="debugLogDirectory" value="${logDir}/${componentName}" />
+  
+  
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+
+  <!-- The EELFAppender is used to record events to the general application 
+    log -->
+    
+    
+
+  
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+    related logging events. The audit logger and appender are specializations 
+    of the EELF application root logger and appender. This can be used to segregate 
+    Policy engine events from other components, or it can be eliminated to record 
+    these events as part of the application root log. -->
+    
+  <appender name="EELFAudit"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+         <pattern>${defaultAuditPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+
+<appender name="EELFMetrics"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+        %msg%n"</pattern> -->
+      <pattern>${defaultMetricPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+   
+  <appender name="EELFError"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${errorLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>ERROR</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultErrorPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFError"/>
+  </appender>
+  
+   <appender name="EELFDebug"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${debugLogDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>INFO</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${debugLoggerPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>true</includeCallerData>
+  </appender>
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+    <logger name="com.att.eelf.error" level="error" additivity="false">
+  <appender-ref ref="asyncEELFError" />
+  </logger>
+  
+   <logger name="com.att.eelf.debug" level="info" additivity="false">
+        <appender-ref ref="asyncEELFDebug" />
+  </logger>
+  
+  
+  
+  <root level="INFO">
+        <appender-ref ref="asyncEELFDebug" />
+        <appender-ref ref="asyncEELFError" />
+  </root>
+
+</configuration>
diff --git a/policy-management/src/main/server/config/makefile b/policy-management/src/main/server/config/makefile
new file mode 100644 (file)
index 0000000..5a96c54
--- /dev/null
@@ -0,0 +1,9 @@
+
+restart: stop start
+
+start:
+       bin/policy-management-controller start
+stop:
+       bin/policy-management-controller stop
+console:
+       bin/policy-management-controller console
diff --git a/policy-management/src/main/server/config/policy-engine.properties b/policy-management/src/main/server/config/policy-engine.properties
new file mode 100644 (file)
index 0000000..647f736
--- /dev/null
@@ -0,0 +1,46 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+# Policy Engine Configuration
+
+# Configuration Channel Settings: PDPD_CONFIGURATION
+
+ueb.source.topics=${{PDPD_CONFIGURATION_TOPIC}}
+ueb.source.topics.${{PDPD_CONFIGURATION_TOPIC}}.servers=${{PDPD_CONFIGURATION_SERVERS}}
+ueb.source.topics.${{PDPD_CONFIGURATION_TOPIC}}.apiKey=${{PDPD_CONFIGURATION_API_KEY}}
+ueb.source.topics.${{PDPD_CONFIGURATION_TOPIC}}.apiSecret=${{PDPD_CONFIGURATION_API_SECRET}}
+ueb.source.topics.${{PDPD_CONFIGURATION_TOPIC}}.consumerGroup=${{PDPD_CONFIGURATION_CONSUMER_GROUP}}
+ueb.source.topics.${{PDPD_CONFIGURATION_TOPIC}}.consumerInstance=${{PDPD_CONFIGURATION_CONSUMER_INSTANCE}}
+ueb.source.topics.${{PDPD_CONFIGURATION_TOPIC}}.managed=false
+
+ueb.sink.topics=${{PDPD_CONFIGURATION_TOPIC}}
+ueb.sink.topics.${{PDPD_CONFIGURATION_TOPIC}}.servers=${{PDPD_CONFIGURATION_SERVERS}}
+ueb.sink.topics.${{PDPD_CONFIGURATION_TOPIC}}.apiKey=${{PDPD_CONFIGURATION_API_KEY}}
+ueb.sink.topics.${{PDPD_CONFIGURATION_TOPIC}}.apiSecret=${{PDPD_CONFIGURATION_API_SECRET}}
+ueb.sink.topics.${{PDPD_CONFIGURATION_TOPIC}}.partitionKey=${{PDPD_CONFIGURATION_PARTITION_KEY}}
+ueb.sink.topics.${{PDPD_CONFIGURATION_TOPIC}}.managed=false
+
+http.server.services=CONFIG
+http.server.services.CONFIG.host=${{ENGINE_MANAGEMENT_HOST}}
+http.server.services.CONFIG.port=${{ENGINE_MANAGEMENT_PORT}}
+http.server.services.CONFIG.userName=${{ENGINE_MANAGEMENT_USER}}
+http.server.services.CONFIG.password=${{ENGINE_MANAGEMENT_PASSWORD}}
+http.server.services.CONFIG.restPackages=org.openecomp.policy.drools.server.restful
+http.server.services.CONFIG.managed=false
diff --git a/policy-management/src/main/server/config/policy-healthcheck.properties b/policy-management/src/main/server/config/policy-healthcheck.properties
new file mode 100644 (file)
index 0000000..51da7ec
--- /dev/null
@@ -0,0 +1,23 @@
+http.server.services=HEALTHCHECK
+http.server.services.HEALTHCHECK.host=0.0.0.0
+http.server.services.HEALTHCHECK.port=6969
+http.server.services.HEALTHCHECK.restClasses=org.openecomp.policy.drools.healthcheck.RestHealthCheck
+http.server.services.HEALTHCHECK.managed=false
+
+http.client.services=PAP,PDP
+
+http.client.services.PAP.host=${{PAP_HOST}}
+http.client.services.PAP.port=9091
+http.client.services.PAP.contextUriPath=pap/test
+http.client.services.PAP.https=false
+http.client.services.PAP.userName=${{PAP_USERNAME}}
+http.client.services.PAP.password=${{PAP_PASSWORD}}
+http.client.services.PAP.managed=true
+
+http.client.services.PDP.host=${{PDP_HOST}}
+http.client.services.PDP.port=8081
+http.client.services.PDP.contextUriPath=pdp/test
+http.client.services.PDP.https=false
+http.client.services.PDP.userName=${{PDP_USERNAME}}
+http.client.services.PDP.password=${{PDP_PASSWORD}}
+http.client.services.PDP.managed=false
diff --git a/policy-management/src/main/server/config/policyLogger.properties b/policy-management/src/main/server/config/policyLogger.properties
new file mode 100644 (file)
index 0000000..4a97799
--- /dev/null
@@ -0,0 +1,49 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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/policy-management/src/main/server/config/system.properties b/policy-management/src/main/server/config/system.properties
new file mode 100644 (file)
index 0000000..feffbd0
--- /dev/null
@@ -0,0 +1,31 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+# system properties passed to controller
+
+# start JMX server port
+com.sun.management.jmxremote.port = 9991
+com.sun.management.jmxremote.authenticate = false
+com.sun.management.jmxremote.ssl = false
+
+javax.net.ssl.keyStore=/opt/app/policy/etc/ssl/policy-keystore
+javax.net.ssl.keyStorePassword = ${{KEYSTORE_PASSWD}}
+javax.net.ssl.trustStore=/opt/app/policy/etc/ssl/policy-keystore
+javax.net.ssl.trustStorePassword = ${{KEYSTORE_PASSWD}}
diff --git a/policy-management/src/main/server/config/xacmlPersistence.properties b/policy-management/src/main/server/config/xacmlPersistence.properties
new file mode 100644 (file)
index 0000000..e88d8aa
--- /dev/null
@@ -0,0 +1,43 @@
+###
+# ============LICENSE_START=======================================================
+# policy-management
+# ================================================================================
+# 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=========================================================
+###
+
+#javax.persistence.jdbc.driver = org.h2.Driver
+#javax.persistence.jdbc.url  = jdbc:h2:file:./sql/xacml
+#javax.persistence.jdbc.user = sa
+#javax.persistence.jdbc.password =
+
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://127.0.0.1:3306/xacml
+#javax.persistence.jdbc.user=root
+#javax.persistence.jdbc.password=policy
+
+javax.persistence.jdbc.driver = ${{JDBC_DRIVER}}
+javax.persistence.jdbc.url  = ${{JDBC_URL}}
+javax.persistence.jdbc.user = ${{JDBC_USER}}
+javax.persistence.jdbc.password = ${{JDBC_PASSWORD}}
+
+# Needed?
+hibernate.dataSource=org.mariadb.jdbc.MySQLDataSource
+
+# For testing purposes, it may be convenient to disable persistence
+persistenceDisabled=false
+
+
diff --git a/policy-persistence/config/policy-engine.properties b/policy-persistence/config/policy-engine.properties
new file mode 100644 (file)
index 0000000..2c50ba9
--- /dev/null
@@ -0,0 +1,33 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+# Policy Engine Configuration
+
+# Configuration Channel Settings: PDPD_CONFIGURATION
+
+ueb.source.topics=PDPD_CONFIGURATION
+ueb.source.topics.PDPD_CONFIGURATION.servers=
+ueb.source.topics.PDPD_CONFIGURATION.apiKey=
+ueb.source.topics.PDPD_CONFIGURATION.apiSecret=
+
+ueb.sink.topics=PDPD_CONFIGURATION
+ueb.sink.topics.PDPD_CONFIGURATION.servers=
+ueb.sink.topics.PDPD_CONFIGURATION.apiKey=
+ueb.sink.topics.PDPD_CONFIGURATION.apiSecret=
diff --git a/policy-persistence/config/policyLogger.properties b/policy-persistence/config/policyLogger.properties
new file mode 100644 (file)
index 0000000..6ee66fd
--- /dev/null
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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 
+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
diff --git a/policy-persistence/pom.xml b/policy-persistence/pom.xml
new file mode 100644 (file)
index 0000000..074a9d4
--- /dev/null
@@ -0,0 +1,154 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+         
+  <modelVersion>4.0.0</modelVersion>
+  
+  <parent>
+    <groupId>org.openecomp.policy.drools-pdp</groupId>
+    <artifactId>drools-pdp</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  
+  <artifactId>policy-persistence</artifactId>
+  
+  <name>policy-persistence</name>
+  <description>Separately loadable module with persistence code</description>
+
+  <properties>
+          <maven.compiler.source>1.8</maven.compiler.source>
+          <maven.compiler.target>1.8</maven.compiler.target>
+          <cambria.version>0.2.4</cambria.version>
+          <dmaap.version>0.2.9</dmaap.version>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.6</version>
+        <executions>
+          <execution>
+            <id>zipfile</id>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <attach>true</attach>
+              <finalName>${project.artifactId}-${project.version}</finalName>
+              <descriptors>
+                <descriptor>src/assembly/assemble_zip.xml</descriptor>
+              </descriptors>
+              <appendAssemblyId>false</appendAssemblyId>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.8</version>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <phase>prepare-package</phase>
+            <configuration>
+              <transitive>false</transitive>
+              <outputDirectory>${project.build.directory}/assembly/lib</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>true</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+              <useRepositoryLayout>false</useRepositoryLayout>
+              <addParentPoms>false</addParentPoms>
+              <copyPom>false</copyPom>
+              <excludeGroupIds>org.opendaylight,com.brocade.odl</excludeGroupIds>
+              <scope>provided</scope>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>2.6</version>
+        <executions>
+          <execution>
+            <id>copy-version</id>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <phase>validate</phase>
+            <configuration>
+              <outputDirectory>${basedir}/target/versions</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/main/resources/versions</directory>
+                  <includes>
+                    <include>version.properties</include>
+                  </includes>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+          <execution>
+            <id>copy-resources</id>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <phase>validate</phase>
+            <configuration>
+              <outputDirectory>${basedir}/target/etc/bvc-extensions</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/main/resources/etc/bvc-extensions</directory>
+                  <includes>
+                    <include>feature_config_template.cfg</include>
+                    <include>feature_custom.install</include>
+                  </includes>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.openecomp.policy.drools-pdp</groupId>
+      <artifactId>policy-core</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.openecomp.policy.drools-pdp</groupId>
+      <artifactId>policy-management</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/policy-persistence/src/assembly/assemble_zip.xml b/policy-persistence/src/assembly/assemble_zip.xml
new file mode 100644 (file)
index 0000000..e0e22f5
--- /dev/null
@@ -0,0 +1,85 @@
+<!--
+  ============LICENSE_START=======================================================
+  policy-persistence
+  ================================================================================
+  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=========================================================
+  -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+       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>
+       <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>
+                       <includes>
+                               <include>policy-persistence-${project.version}.jar</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>target/assembly/</directory>
+                       <outputDirectory>.</outputDirectory>
+                       <excludes>
+                       </excludes>
+               </fileSet>
+               <fileSet>
+                       <directory>.</directory>
+                       <outputDirectory>lib</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>
+                       <outputDirectory>config</outputDirectory>
+               </fileSet>
+       </fileSets>
+
+</assembly>
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DbAudit.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DbAudit.java
new file mode 100644 (file)
index 0000000..51e92aa
--- /dev/null
@@ -0,0 +1,205 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.drools.persistence.DroolsPersistenceProperties;
+
+/**
+ * This class audits the database
+ */
+public class DbAudit extends DroolsPDPIntegrityMonitor.AuditBase
+{
+       // get an instance of logger 
+  private static Logger  logger = FlexLogger.getLogger(DbAudit.class); 
+  // single global instance of this audit object
+  static private DbAudit instance = new DbAudit();
+
+  // This indicates if 'CREATE TABLE IF NOT EXISTS Audit ...' should be
+  // invoked -- doing this avoids the need to create the table in advance.
+  static private boolean createTableNeeded = true;
+
+  /**
+   * @return the single 'DbAudit' instance
+   */
+  static DroolsPDPIntegrityMonitor.AuditBase getInstance()
+  {
+       return(instance);
+  }
+
+  /**
+   * Constructor - set the name to 'Database'
+   */
+  private DbAudit()
+  {
+       super("Database");
+  }
+
+  /**
+   * Invoke the audit
+   *
+   * @param properties properties to be passed to the audit
+   */
+  @Override
+       public void invoke(Properties droolsPersistenceProperties)
+  {
+       logger.info("Running 'DbAudit.invoke'");
+       boolean isActive = true;
+       String dbAuditIsActive = IntegrityMonitorProperties.getProperty("db.audit.is.active");
+       logger.debug("DbAudit.invoke: dbAuditIsActive = " + dbAuditIsActive);
+       
+       if (dbAuditIsActive != null) {
+               try {
+                       isActive = Boolean.parseBoolean(dbAuditIsActive.trim());
+               } catch (NumberFormatException e) {
+                       logger.warn("DbAudit.invoke: Ignoring invalid property: db.audit.is.active = " + dbAuditIsActive);
+               }
+       }
+       
+       if(!isActive){
+               logger.info("DbAudit.invoke: exiting because isActive = " + isActive);
+               return;
+       }
+       
+       // fetch DB properties from properties file -- they are already known
+       // to exist, because they were verified by the 'IntegrityMonitor'
+       // constructor
+       String url = droolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_URL);
+       String user = droolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_USER);
+       String password =
+                       droolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_PWD);
+
+       // connection to DB
+       Connection connection = null;
+
+       // supports SQL operations
+       PreparedStatement statement = null;
+       ResultSet rs = null;
+
+       // operation phase currently running -- used to construct an error
+       // message, if needed
+       String phase = null;
+
+       try
+         {
+               // create connection to DB
+               phase = "creating connection";
+               logger.info("DbAudit: Creating connection to " + url);
+
+               connection = DriverManager.getConnection(url, user, password);
+
+               // create audit table, if needed
+               if (createTableNeeded)
+                 {
+                       phase = "create table";
+                       logger.info("DbAudit: Creating 'Audit' table, if needed");
+                       statement = connection.prepareStatement
+                         ("CREATE TABLE IF NOT EXISTS Audit (\n"
+                          + " name varchar(64) DEFAULT NULL,\n"
+                          + " UNIQUE KEY name (name)\n"
+                          + ") DEFAULT CHARSET=latin1;");
+                       statement.execute();
+                       createTableNeeded = false;
+                 }
+
+               // insert an entry into the table
+               phase = "insert entry";
+               String key = UUID.randomUUID().toString();
+               statement = connection.prepareStatement
+                 ("INSERT INTO Audit (name) VALUES (?)");
+               statement.setString(1, key);
+               statement.executeUpdate();
+
+               // fetch the entry from the table
+               phase = "fetch entry";
+               statement = connection.prepareStatement
+                 ("SELECT name FROM Audit WHERE name = ?");
+               statement.setString(1, key);
+               rs = statement.executeQuery();
+               if (rs.first())
+                 {
+                       // found entry
+                       logger.info("DbAudit: Found key " + rs.getString(1));
+                 }
+               else
+                 {
+                       logger.error
+                         ("DbAudit: can't find newly-created entry with key " + key);
+                       setResponse("Can't find newly-created entry");
+                 }
+
+               // delete entries from table
+               phase = "delete entry";
+               statement = connection.prepareStatement
+                 ("DELETE FROM Audit WHERE name = ?");
+               statement.setString(1, key);
+               statement.executeUpdate();
+         }
+       catch (Exception e)
+         {
+               String message = "DbAudit: Exception during audit, phase = " + phase;
+               logger.error(MessageCodes.EXCEPTION_ERROR, e, message);
+               setResponse(message);
+         }
+       finally
+         {
+               if (rs != null)
+                 {
+                       try
+                         {
+                               rs.close();
+                         }
+                       catch (Exception e)
+                         {
+                         }
+                 }
+               if (statement != null)
+                 {
+                       try
+                         {
+                               statement.close();
+                         }
+                       catch (Exception e)
+                         {
+                         }
+                 }
+               if (connection != null)
+                 {
+                       try
+                         {
+                               connection.close();
+                         }
+                       catch (Exception e)
+                         {
+                         }
+                 }
+         }
+  }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java
new file mode 100644 (file)
index 0000000..2b6058f
--- /dev/null
@@ -0,0 +1,485 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+
+import org.openecomp.policy.common.im.IntegrityMonitor;
+import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.drools.persistence.DroolsPdpsElectionHandler;
+import org.openecomp.policy.drools.persistence.XacmlPersistenceProperties;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+/**
+ * This class extends 'IntegrityMonitor' for use in the 'Drools PDP'
+ * virtual machine. The included audits are 'Database' and 'Repository'.
+ */
+public class DroolsPDPIntegrityMonitor extends IntegrityMonitor
+{
+       
+       // get an instance of logger 
+  private static Logger  logger = FlexLogger.getLogger(DroolsPDPIntegrityMonitor.class);       
+
+  // static global instance
+  static private DroolsPDPIntegrityMonitor im = null;
+
+  // list of audits to run
+  static private AuditBase[] audits =
+       new AuditBase[]{DbAudit.getInstance(), RepositoryAudit.getInstance()};
+
+  // save initialization properties
+  private Properties droolsPersistenceProperties = null;
+  
+  /**
+   * Static initialization -- create Drools Integrity Monitor, and
+   * an HTTP server to handle REST 'test' requests
+   */
+  static public DroolsPDPIntegrityMonitor init(String configDir) throws Exception
+  {
+                 
+       logger.info("init: Entering and invoking PropertyUtil.getProperties() on '"
+                               + configDir + "'");
+               
+       // read in properties
+       Properties integrityMonitorProperties =
+         PropertyUtil.getProperties(configDir + "/IntegrityMonitor.properties");
+       Properties droolsPersistenceProperties =
+         PropertyUtil.getProperties(configDir + "/droolsPersistence.properties");
+       Properties xacmlPersistenceProperties =
+         PropertyUtil.getProperties(configDir + "/xacmlPersistence.properties");
+
+       // fetch and verify definitions of some properties
+       // (the 'IntegrityMonitor' constructor does some additional verification)
+       String resourceName = integrityMonitorProperties.getProperty("resource.name");
+       String hostPort = integrityMonitorProperties.getProperty("hostPort");
+       String fpMonitorInterval = integrityMonitorProperties.getProperty("fp_monitor_interval");
+       String failedCounterThreshold = integrityMonitorProperties.getProperty("failed_counter_threshold");
+       String testTransInterval = integrityMonitorProperties.getProperty("test_trans_interval");
+       String writeFpcInterval = integrityMonitorProperties.getProperty("write_fpc_interval");
+       String siteName = integrityMonitorProperties.getProperty("site_name");
+       String nodeType = integrityMonitorProperties.getProperty("node_type");
+       String dependencyGroups = integrityMonitorProperties.getProperty("dependency_groups");
+       String droolsJavaxPersistenceJdbcDriver = droolsPersistenceProperties.getProperty("javax.persistence.jdbc.driver");
+       String droolsJavaxPersistenceJdbcUrl = droolsPersistenceProperties.getProperty("javax.persistence.jdbc.url");
+       String droolsJavaxPersistenceJdbcUser = droolsPersistenceProperties.getProperty("javax.persistence.jdbc.user");
+       String droolsJavaxPersistenceJdbcPassword = droolsPersistenceProperties.getProperty("javax.persistence.jdbc.password"); 
+       String xacmlJavaxPersistenceJdbcDriver = xacmlPersistenceProperties.getProperty("javax.persistence.jdbc.driver");
+       String xacmlJavaxPersistenceJdbcUrl = xacmlPersistenceProperties.getProperty("javax.persistence.jdbc.url");
+       String xacmlJavaxPersistenceJdbcUser = xacmlPersistenceProperties.getProperty("javax.persistence.jdbc.user");
+       String xacmlJavaxPersistenceJdbcPassword = xacmlPersistenceProperties.getProperty("javax.persistence.jdbc.password");
+       
+       if (resourceName == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'resource.name'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'resource.name'"));
+         }
+       if (hostPort == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'hostPort'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'hostPort'"));
+         }
+       if (fpMonitorInterval == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'fp_monitor_interval'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'fp_monitor_interval'"));
+         }     
+       if (failedCounterThreshold == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'failed_counter_threshold'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'failed_counter_threshold'"));
+         }     
+       if (testTransInterval == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'test_trans_interval'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'test_trans_interval'"));
+         }     
+       if (writeFpcInterval == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'write_fpc_interval'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'write_fpc_interval'"));
+         }     
+       if (siteName == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'site_name'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'site_name'"));
+         }     
+       if (nodeType == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'node_type'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'node_type'"));
+         }     
+       if (dependencyGroups == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'dependency_groups'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'dependency_groups'"));
+         }     
+       if (droolsJavaxPersistenceJdbcDriver == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.driver for drools DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.driver for drools DB'"));
+         }             
+       if (droolsJavaxPersistenceJdbcUrl == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.url  for drools DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.url for drools DB'"));
+         }                     
+       if (droolsJavaxPersistenceJdbcUser == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.user for drools DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.user for drools DB'"));
+         }                     
+       if (droolsJavaxPersistenceJdbcPassword == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.password for drools DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.password for drools DB'"));
+         }     
+       if (xacmlJavaxPersistenceJdbcDriver == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.driver for xacml DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.driver for xacml DB'"));
+         }             
+       if (xacmlJavaxPersistenceJdbcUrl == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.url  for xacml DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.url  for xacml DB'"));
+         }                     
+       if (xacmlJavaxPersistenceJdbcUser == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.user for xacml DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.user for xacml DB'"));
+         }                     
+       if (xacmlJavaxPersistenceJdbcPassword == null)
+         {
+               logger.error("init: Missing IntegrityMonitor property: 'javax.persistence.jbdc.password for xacml DB'");
+               throw(new Exception
+                         ("Missing IntegrityMonitor property: 'javax.persistence.jbdc.password'  for xacml DB'"));
+         }             
+
+       logger.info("init: loading consolidatedProperties");
+       Properties consolidatedProperties = new Properties();
+       consolidatedProperties.load(new FileInputStream(new File(configDir + "/IntegrityMonitor.properties")));
+       consolidatedProperties.load(new FileInputStream(new File(configDir + "/xacmlPersistence.properties")));
+       // verify that consolidatedProperties has properties from both properties files.
+       logger.info("init: PDP_INSTANCE_ID=" + consolidatedProperties.getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID));
+       logger.info("init: DB_URL=" + consolidatedProperties.getProperty(XacmlPersistenceProperties.DB_URL));
+
+       // Now that we've validated the properties, create Drools Integrity Monitor
+       // with these properties.
+       im = new DroolsPDPIntegrityMonitor(resourceName,
+                               consolidatedProperties, droolsPersistenceProperties);
+       logger.info("init: New DroolsPDPIntegrityMonitor instantiated, hostPort=" + hostPort);
+
+       // determine host and port for HTTP server
+       int index = hostPort.lastIndexOf(':');
+       InetSocketAddress addr;
+
+       if (index < 0)
+         {
+               addr = new InetSocketAddress(Integer.valueOf(hostPort));
+         }
+       else
+         {
+               addr = new InetSocketAddress
+                 (hostPort.substring(0, index),
+                  Integer.valueOf(hostPort.substring(index + 1)));
+         }
+
+       // create http server
+       try {
+               logger.info("init: Starting HTTP server, addr=" + addr);
+               HttpServer server = HttpServer.create(addr, 0);
+               server.createContext("/test", new TestHandler());
+               server.setExecutor(null);
+               server.start();
+                       System.out.println("init: Started server on hostPort=" + hostPort);
+       } catch (Exception e) {
+                       if (PolicyContainer.isUnitTesting) {
+                               System.out
+                                               .println("init: Caught Exception attempting to start server on hostPort="
+                                                               + hostPort + ", message=" + e.getMessage());
+               } else {
+                       throw e;
+               }
+       }
+       
+       logger.info("init: Exiting and returning DroolsPDPIntegrityMonitor");
+       return im;
+  }
+
+  /**
+   * Constructor - pass arguments to superclass, but remember properties
+   * @param resourceName unique name of this Integrity Monitor
+   * @param url the JMX URL of the MBean server
+   * @param properties properties used locally, as well as by
+   *   'IntegrityMonitor'
+   * @throws Exception (passed from superclass)
+   */
+       private DroolsPDPIntegrityMonitor(String resourceName,
+                       Properties consolidatedProperties,
+                       Properties droolsPersistenceProperties) throws Exception {
+       super(resourceName, consolidatedProperties);
+       this.droolsPersistenceProperties = droolsPersistenceProperties;
+  }
+
+  /**
+   * Run tests (audits) unique to Drools PDP VM (Database + Repository)
+   */
+  @Override
+       public void subsystemTest() throws Exception
+  {
+       logger.info("DroolsPDPIntegrityMonitor.subsystemTest called");
+
+       // clear all responses (non-null values indicate an error)
+       for (AuditBase audit : audits)
+         {
+               audit.setResponse(null);
+         }
+
+       // invoke all of the audits
+       for (AuditBase audit : audits)
+         {
+               try
+                 {
+                       // invoke the audit (responses are stored within the audit object)
+                       audit.invoke(droolsPersistenceProperties);
+                 }
+               catch (Exception e)
+                 {
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e,
+                                                          audit.getName() + " audit error");
+                       if (audit.getResponse() == null)
+                         {
+                               // if there is no current response, use the exception message
+                               audit.setResponse(e.getMessage());
+                         }
+                 }
+         }
+       
+         // will contain list of subsystems where the audit failed
+         String responseMsg = "";
+
+         // Loop through all of the audits, and see which ones have failed.
+         // NOTE: response information is stored within the audit objects
+         // themselves -- only one can run at a time.
+         for (AuditBase audit : audits)
+               {
+                 String response = audit.getResponse();
+                 if (response != null)
+                       {
+                         // the audit has failed -- add subsystem and 
+                         // and 'responseValue' with the new information
+                         responseMsg = responseMsg.concat("\n" + audit.getName() + ": " + response);
+                       }
+               }
+         
+         if(!responseMsg.isEmpty()){
+                 throw new Exception(responseMsg);
+         }
+  }
+
+  /* ============================================================ */
+
+  /**
+   * This is the base class for audits invoked in 'subsystemTest'
+   */
+  static public abstract class AuditBase
+  {
+       // name of the audit
+       protected String name;
+
+       // non-null indicates the error response
+       protected String response;
+
+       /**
+        * Constructor - initialize the name, and clear the initial response
+        * @param name name of the audit
+        */
+       public AuditBase(String name)
+       {
+         this.name = name;
+         this.response = null;
+       }
+
+       /**
+        * @return the name of this audit
+        */
+       public String getName()
+       {
+         return(name);
+       }
+
+       /**
+        * @return the response String (non-null indicates the error message)
+        */
+       public String getResponse()
+       {
+         return(response);
+       }
+
+       /**
+        * Set the response string to the specified value
+        * @param value the new value of the response string (null = no errors)
+        */
+       public void setResponse(String value)
+       {
+         response = value;
+       }
+
+       /**
+        * Abstract method to invoke the audit
+        * @param droolsPersistenceProperties Used for DB access
+        * @throws Exception passed in by the audit
+        */
+       abstract void invoke(Properties droolsPersistenceProperties) throws Exception;
+  }
+
+  /* ============================================================ */
+
+  /**
+   * This class is the HTTP handler for the REST 'test' invocation
+   */
+  static class TestHandler implements HttpHandler
+  {
+       /**
+        * Handle an incoming REST 'test' invocation
+        * @param ex used to pass incoming and outgoing HTTP information
+        */
+       @Override
+         public void handle(HttpExchange ex) throws IOException
+       {
+               
+                 System.out.println("TestHandler.handle: Entering");
+
+         // The responses are stored within the audit objects, so we need to
+         // invoke the audits and get responses before we handle another
+         // request.
+         synchronized(TestHandler.class)
+               {
+                 // will include messages associated with subsystem failures
+                 StringBuilder body = new StringBuilder();
+
+                 // 200=SUCCESS, 500=failure
+                 int responseValue = 200;
+
+                 if (im != null)
+                       {
+                         try
+                               {
+                                 // call 'IntegrityMonitor.evaluateSanity()'
+                                 im.evaluateSanity();
+                               }
+                         catch (Exception e)
+                               {
+                                 // this exception isn't coming from one of the audits,
+                                 // because those are caught in 'subsystemTest()'
+                                 logger.error
+                                       (MessageCodes.EXCEPTION_ERROR, e,
+                                        "DroolsPDPIntegrityMonitor.evaluateSanity()");
+
+                                 // include exception in HTTP response
+                                 body.append("\nException: " + e + "\n");
+                                 responseValue = 500;
+                               }
+                       }
+/*
+ * Audit failures are being logged. A string will be generated which captures the 
+ * the audit failures. This string will be included in an exception coming from im.evaluateSanity().
+ * 
+                 // will contain list of subsystems where the audit failed
+                 LinkedList<String> subsystems = new LinkedList<String>();
+
+                 // Loop through all of the audits, and see which ones have failed.
+                 // NOTE: response information is stored within the audit objects
+                 // themselves -- only one can run at a time.
+                 for (AuditBase audit : audits)
+                       {
+                         String response = audit.getResponse();
+                         if (response != null)
+                               {
+                                 // the audit has failed -- update 'subsystems', 'body',
+                                 // and 'responseValue' with the new information
+                                 subsystems.add(audit.getName());
+                                 body
+                                       .append('\n')
+                                       .append(audit.getName())
+                                       .append(":\n")
+                                       .append(response)
+                                       .append('\n');
+                                 responseValue = 500;
+                               }
+                       }
+
+                 if (subsystems.size() != 0)
+                       {
+                         // there is at least one failure -- add HTTP headers
+                         ex.getResponseHeaders().put("X-ECOMP-SubsystemFailure",
+                                                                                 subsystems);
+                       }
+*/
+                 // send response, including the contents of 'body'
+                 // (which is empty if everything is successful)
+                 ex.sendResponseHeaders(responseValue, body.length());
+                 OutputStream os = ex.getResponseBody();
+                 os.write(body.toString().getBytes());
+                 os.close();
+                 System.out.println("TestHandler.handle: Exiting");
+               }
+       }
+  }
+       public static DroolsPDPIntegrityMonitor getInstance() throws Exception{
+               logger.info("getInstance() called");
+               if (im == null) {
+                       String msg = "No DroolsPDPIntegrityMonitor instance exists."
+                                       + " Please use the method DroolsPDPIntegrityMonitor init(String configDir)";
+                       throw new Exception(msg);
+               }else{
+                       return im;
+               }
+       }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorProperties.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorProperties.java
new file mode 100644 (file)
index 0000000..d1b1ad6
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class IntegrityMonitorProperties {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(IntegrityMonitorProperties.class);
+               
+       public static final String PDP_INSTANCE_ID = "resource.name";
+       
+       public static final String PDP_CHECK_INVERVAL = "pdp.checkInterval";
+       public static final String PDP_UPDATE_INTERVAL = "pdp.updateInterval";
+       public static final String PDP_TIMEOUT = "pdp.timeout";
+       public static final String PDP_INITIAL_WAIT_PERIOD = "pdp.initialWait";
+
+       public static final String SITE_NAME = "site_name";
+       
+       private static Properties properties = null;
+       /*
+        * Initialize the parameter values from the droolsPersitence.properties file values
+        * 
+        * This is designed so that the Properties object is obtained from the droolsPersistence.properties
+        * file and then is passed to this method to initialize the value of the parameters.
+        * This allows the flexibility of JUnit tests using getProperties(filename) to get the
+        * properties while runtime methods can use getPropertiesFromClassPath(filename).
+        * 
+        */
+       public static void initProperties (Properties prop){
+               logger.info("IntegrityMonitorProperties.initProperties(Properties): entry");
+               logger.info("\n\nIntegrityMonitorProperties.initProperties: Properties = \n" + prop + "\n\n");
+               
+               properties = prop;
+       }
+
+       public static String getProperty(String key){
+               return properties.getProperty(key);
+       }
+       
+       public static Properties getProperties() {
+               return properties;
+       }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java
new file mode 100644 (file)
index 0000000..86c672e
--- /dev/null
@@ -0,0 +1,524 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.Files;
+import java.nio.file.FileVisitor;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+
+/**
+ * This class audits the Maven repository
+ */
+public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
+{
+  private static final long DEFAULT_TIMEOUT = 60;      // timeout in 60 seconds
+
+  // get an instance of logger
+  private static Logger  logger = FlexLogger.getLogger(RepositoryAudit.class);         
+  // single global instance of this audit object
+  static private RepositoryAudit instance = new RepositoryAudit();
+
+  /**
+   * @return the single 'RepositoryAudit' instance
+   */
+  static DroolsPDPIntegrityMonitor.AuditBase getInstance()
+  {
+       return(instance);
+  }
+
+  /**
+   * Constructor - set the name to 'Repository'
+   */
+  private RepositoryAudit()
+  {
+       super("Repository");
+  }
+
+  /**
+   * Invoke the audit
+   *
+   * @param properties properties to be passed to the audit
+   */
+  @Override
+       public void invoke(Properties properties)
+       throws IOException, InterruptedException
+  {
+       logger.info("Running 'RepositoryAudit.invoke'");
+       
+       boolean isActive = true;
+       String repoAuditIsActive = IntegrityMonitorProperties.getProperty("repository.audit.is.active");
+       logger.debug("RepositoryAudit.invoke: repoAuditIsActive = " + repoAuditIsActive);
+       
+       if (repoAuditIsActive != null) {
+               try {
+                       isActive = Boolean.parseBoolean(repoAuditIsActive.trim());
+               } catch (NumberFormatException e) {
+                       logger.warn("RepositoryAudit.invoke: Ignoring invalid property: repository.audit.is.active = " + repoAuditIsActive);
+               }
+       }
+       
+       if(!isActive){
+               logger.info("RepositoryAudit.invoke: exiting because isActive = " + isActive);
+               return;
+       }
+
+       // Fetch repository information from 'IntegrityMonitorProperties'
+       String repositoryId =
+         IntegrityMonitorProperties.getProperty("repository.audit.id");
+       String repositoryUrl =
+         IntegrityMonitorProperties.getProperty("repository.audit.url");
+       String repositoryUsername =
+         IntegrityMonitorProperties.getProperty("repository.audit.username");
+       String repositoryPassword =
+         IntegrityMonitorProperties.getProperty("repository.audit.password");
+       boolean upload =
+         (repositoryId != null && repositoryUrl != null
+          && repositoryUsername != null && repositoryPassword != null);
+
+       // used to incrementally construct response as problems occur
+       // (empty = no problems)
+       StringBuilder response = new StringBuilder();
+
+       long timeoutInSeconds = DEFAULT_TIMEOUT;
+       String timeoutString =
+         IntegrityMonitorProperties.getProperty("repository.audit.timeout");
+       if (timeoutString != null && !timeoutString.isEmpty())
+         {
+               try
+                 {
+                       timeoutInSeconds = Long.valueOf(timeoutString);
+                 }
+               catch (NumberFormatException e)
+                 {
+                       logger.error
+                         ("RepositoryAudit: Invalid 'repository.audit.timeout' value: '"
+                          + timeoutString + "'");
+                       response.append("Invalid 'repository.audit.timeout' value: '")
+                         .append(timeoutString).append("'\n");
+                       setResponse(response.toString());
+                 }
+         }
+
+       // artifacts to be downloaded
+       LinkedList<Artifact> artifacts = new LinkedList<Artifact>();
+
+       /*
+        * 1) create temporary directory
+        */
+       Path dir = Files.createTempDirectory("auditRepo");
+       logger.info("RepositoryAudit: temporary directory = " + dir);
+
+       // nested 'pom.xml' file and 'repo' directory
+       Path pom = dir.resolve("pom.xml");
+       Path repo = dir.resolve("repo");
+
+       /*
+        * 2) Create test file, and upload to repository
+        *    (only if repository information is specified)
+        */
+       String groupId = null;
+       String artifactId = null;
+       String version = null;
+       if (upload)
+         {
+               groupId = "org.openecomp.policy.audit";
+               artifactId = "repository-audit";
+               version = "0." + System.currentTimeMillis();
+
+               if (repositoryUrl.toLowerCase().contains("snapshot"))
+                 {
+                       // use SNAPSHOT version
+                       version += "-SNAPSHOT";
+                 }
+
+               // create text file to write
+               FileOutputStream fos =
+                 new FileOutputStream(dir.resolve("repository-audit.txt").toFile());
+               try
+                 {
+                       fos.write(version.getBytes());
+                 }
+               finally
+                 {
+                       fos.close();
+                 }
+
+               // try to install file in repository
+               if (runProcess
+                       (timeoutInSeconds, dir.toFile(), null,
+                        "mvn", "deploy:deploy-file",
+                        "-DrepositoryId=" + repositoryId,
+                        "-Durl=" + repositoryUrl,
+                        "-Dfile=repository-audit.txt",
+                        "-DgroupId=" + groupId,
+                        "-DartifactId=" + artifactId,
+                        "-Dversion=" + version,
+                        "-Dpackaging=txt",
+                        "-DgeneratePom=false") != 0)
+                 {
+                       logger.error
+                         ("RepositoryAudit: 'mvn deploy:deploy-file' failed");
+                       response.append("'mvn deploy:deploy-file' failed\n");
+                       setResponse(response.toString());
+                 }
+               else
+                 {
+                       logger.info
+                         ("RepositoryAudit: 'mvn deploy:deploy-file succeeded");
+
+                       // we also want to include this new artifact in the download
+                       // test (steps 3 and 4)
+                       artifacts.add(new Artifact(groupId, artifactId, version, "txt"));
+                 }
+         }
+
+       /*
+        * 3) create 'pom.xml' file in temporary directory
+        */
+       artifacts.add(new Artifact("org.apache.maven/maven-embedder/3.2.2"));
+       
+       StringBuilder sb = new StringBuilder();
+       sb.append
+         ("<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+          + "         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n"
+          + "\n"
+          + "  <modelVersion>4.0.0</modelVersion>\n"
+          + "  <groupId>empty</groupId>\n"
+          + "  <artifactId>empty</artifactId>\n"
+          + "  <version>1.0-SNAPSHOT</version>\n"
+          + "  <packaging>pom</packaging>\n"
+          + "\n"
+          + "  <build>\n"
+          + "    <plugins>\n"
+          + "      <plugin>\n"
+          + "         <groupId>org.apache.maven.plugins</groupId>\n"
+          + "         <artifactId>maven-dependency-plugin</artifactId>\n"
+          + "         <version>2.10</version>\n"
+          + "         <executions>\n"
+          + "           <execution>\n"
+          + "             <id>copy</id>\n"
+          + "             <goals>\n"
+          + "               <goal>copy</goal>\n"
+          + "             </goals>\n"
+          + "             <configuration>\n"
+          + "               <localRepositoryDirectory>")
+         .append(repo)
+         .append("</localRepositoryDirectory>\n")
+         .append("               <artifactItems>\n");
+       for (Artifact artifact : artifacts)
+         {
+               // each artifact results in an 'artifactItem' element
+               sb.append
+                 ("                 <artifactItem>\n"
+                  + "                   <groupId>")
+                 .append(artifact.groupId)
+                 .append
+                 ("</groupId>\n"
+                  + "                   <artifactId>")
+                 .append(artifact.artifactId)
+                 .append
+                 ("</artifactId>\n"
+                  + "                   <version>")
+                 .append(artifact.version)
+                 .append
+                 ("</version>\n"
+                  + "                   <type>")
+                 .append(artifact.type)
+                 .append
+                 ("</type>\n"
+                  + "                 </artifactItem>\n");
+         }
+       sb.append
+         ("               </artifactItems>\n"
+          + "             </configuration>\n"
+          + "           </execution>\n"
+          + "         </executions>\n"
+          + "      </plugin>\n"
+          + "    </plugins>\n"
+          + "  </build>\n"
+          + "</project>\n");
+       FileOutputStream fos = new FileOutputStream(pom.toFile());
+       try
+         {
+               fos.write(sb.toString().getBytes());
+         }
+       finally
+         {
+               fos.close();
+         }
+
+       /*
+        * 4) Invoke external 'mvn' process to do the downloads
+        */
+
+       // output file = ${dir}/out (this supports step '4a')
+       File output = dir.resolve("out").toFile();
+
+       // invoke process, and wait for response
+       int rval = runProcess
+         (timeoutInSeconds, dir.toFile(), output, "mvn", "compile");
+       logger.info("RepositoryAudit: 'mvn' return value = " + rval);
+       if (rval != 0)
+         {
+               logger.error
+                 ("RepositoryAudit: 'mvn compile' invocation failed");
+               response.append("'mvn compile' invocation failed\n");
+               setResponse(response.toString());
+         }
+
+       /*
+        * 4a) Check attempted and successful downloads from output file
+        *     Note: at present, this step just generates log messages,
+        *     but doesn't do any verification.
+        */
+       if (rval == 0)
+         {
+               // place output in 'fileContents' (replacing the Return characters
+               // with Newline)
+               byte[] outputData = new byte[(int)output.length()];
+               FileInputStream fis = new FileInputStream(output);
+               fis.read(outputData);
+               String fileContents = new String(outputData).replace('\r','\n');
+               fis.close();
+
+               // generate log messages from 'Downloading' and 'Downloaded'
+               // messages within the 'mvn' output
+               int index = 0;
+               while ((index = fileContents.indexOf("\nDown", index)) > 0)
+                 {
+                       index += 5;
+                       if (fileContents.regionMatches(index, "loading: ", 0, 9))
+                         {
+                               index += 9;
+                               int endIndex = fileContents.indexOf('\n', index);
+                               logger.info
+                                 ("RepositoryAudit: Attempted download: '"
+                                  + fileContents.substring(index, endIndex) + "'");
+                               index = endIndex;
+                         }
+                       else if (fileContents.regionMatches(index, "loaded: ", 0, 8))
+                         {
+                               index += 8;
+                               int endIndex = fileContents.indexOf(' ', index);
+                               logger.info
+                                 ("RepositoryAudit: Successful download: '"
+                                  + fileContents.substring(index, endIndex) + "'");
+                               index = endIndex;
+                         }
+                 }
+         }
+
+       /*
+        * 5) Check the contents of the directory to make sure the downloads
+        *    were successful
+        */
+       for (Artifact artifact : artifacts)
+         {
+               if (repo.resolve(artifact.groupId.replace('.','/'))
+                       .resolve(artifact.artifactId)
+                       .resolve(artifact.version)
+                       .resolve(artifact.artifactId + "-" + artifact.version + "."
+                                        + artifact.type).toFile().exists())
+                 {
+                       // artifact exists, as expected
+                       logger.info("RepositoryAudit: "
+                                                         + artifact.toString() + ": exists");
+                 }
+               else
+                 {
+                       // Audit ERROR: artifact download failed for some reason
+                       logger.error("RepositoryAudit: "
+                                                          + artifact.toString() + ": does not exist");
+                       response.append("Failed to download artifact: ")
+                         .append(artifact).append('\n');
+                       setResponse(response.toString());
+                 }
+         }
+
+       /*
+        * 6) Use 'curl' to delete the uploaded test file
+        *    (only if repository information is specified)
+        */
+       if (upload)
+         {
+               if (runProcess
+                       (timeoutInSeconds, dir.toFile(), null,
+                        "curl",
+                        "--request", "DELETE",
+                        "--user", repositoryUsername + ":" + repositoryPassword,
+                        (repositoryUrl + "/" + groupId.replace('.', '/') + "/" +
+                         artifactId + "/" + version))
+                       != 0)
+                 {
+                       logger.error
+                         ("RepositoryAudit: delete of uploaded artifact failed");
+                       response.append("delete of uploaded artifact failed\n");
+                       setResponse(response.toString());
+                 }
+               else
+                 {
+                       logger.info
+                         ("RepositoryAudit: delete of uploaded artifact succeeded");
+                       artifacts.add(new Artifact(groupId, artifactId, version, "txt"));
+                 }
+         }
+
+       /*
+        * 7) Remove the temporary directory
+        */
+       Files.walkFileTree
+         (dir,
+          new SimpleFileVisitor<Path>()
+          {
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                  {
+                        // logger.info("RepositoryAudit: Delete " + file);
+                        file.toFile().delete();
+                        return(FileVisitResult.CONTINUE);
+                  }
+
+                public FileVisitResult postVisitDirectory(Path file, IOException e)
+                  throws IOException
+                  {
+                        if (e == null)
+                          {
+                                // logger.info("RepositoryAudit: Delete " + file);
+                                file.toFile().delete();
+                                return(FileVisitResult.CONTINUE);
+                          }
+                        else
+                          {
+                                throw(e);
+                          }
+                  }
+          });
+  }
+
+  /**
+   * Run a process, and wait for the response
+   *
+   * @param timeoutInSeconds the number of seconds to wait for the
+   *   process to terminate
+   * @param directory the execution directory of the process
+   *   (null = current directory)
+   * @param stdout the file to contain the standard output
+   *   (null = discard standard output)
+   * @param command command and arguments
+   * @return the return value of the process
+   * @throws IOException, InterruptedException
+   */
+  static int runProcess(long timeoutInSeconds,
+                                               File directory, File stdout, String... command)
+       throws IOException, InterruptedException
+  {
+       ProcessBuilder pb = new ProcessBuilder(command);
+       if (directory != null)
+         {
+               pb.directory(directory);
+         }
+       if (stdout != null)
+         {
+               pb.redirectOutput(stdout);
+         }
+
+       Process process = pb.start();
+       if (process.waitFor(timeoutInSeconds, TimeUnit.SECONDS))
+         {
+               // process terminated before the timeout
+               return(process.exitValue());
+         }
+       
+       // process timed out -- kill it, and return -1
+       process.destroyForcibly();
+       return(-1);
+  }
+
+  /* ============================================================ */
+
+  /**
+   * An instance of this class exists for each artifact that we are trying
+   * to download.
+   */
+  static class Artifact
+  {
+       String groupId, artifactId, version, type;
+
+       /**
+        * Constructor - populate the 'Artifact' instance
+        *
+        * @param groupId groupId of artifact
+        * @param artifactId artifactId of artifact
+        * @param version version of artifact
+        * @param type type of the artifact (e.g. "jar")
+        */
+       Artifact(String groupId, String artifactId, String version, String type)
+       {
+         this.groupId = groupId;
+         this.artifactId = artifactId;
+         this.version = version;
+         this.type = type;
+       }
+
+       /**
+        * Constructor - populate an 'Artifact' instance
+        *
+        * @param artifact a string of the form:
+        *              "<groupId>/<artifactId>/<version>[/<type>]"
+        * @throws IllegalArgumentException if 'artifact' has the incorrect format
+        */
+       Artifact(String artifact)
+       {
+         String[] segments = artifact.split("/");
+         if (segments.length != 4 && segments.length != 3)
+               {
+                 throw(new IllegalArgumentException("groupId/artifactId/version/type"));
+               }
+         groupId = segments[0];
+         artifactId = segments[1];
+         version = segments[2];
+         type = (segments.length == 4 ? segments[3] : "jar");
+       }
+
+       /**
+        * @return the artifact id in the form:
+        *              "<groupId>/<artifactId>/<version>/<type>"
+        */
+       public String toString()
+       {
+         return(groupId + "/" + artifactId + "/" + version + "/" + type);
+       }
+  }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/im/PMStandbyStateChangeNotifier.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/im/PMStandbyStateChangeNotifier.java
new file mode 100644 (file)
index 0000000..46e5a5e
--- /dev/null
@@ -0,0 +1,280 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.im; 
+/* 
+ * Per MultiSite_v1-10.ppt:
+ * 
+ * Extends the StateChangeNotifier class and overwrites the abstract handleStateChange() method to get state changes 
+ * and do the following: 
+ * 
+ * When the Standby Status changes (from providingservice) to hotstandby or coldstandby, 
+ * the Active/Standby selection algorithm must stand down if the PDP-D is currently the lead/active node 
+ * and allow another PDP-D to take over.  It must also call lock on all engines in the engine management.
+ * 
+ * When the Standby Status changes from (hotstandby) to coldstandby, the Active/Standby algorithm must NOT assume 
+ * the active/lead role.
+ *  
+ * When the Standby Status changes (from coldstandby or providingservice) to hotstandby, 
+ * the Active/Standby algorithm may assume the active/lead role if the active/lead fails.
+ * 
+ * When the Standby Status changes to providingservice (from hotstandby or coldstandby) call unlock on all 
+ * engines in the engine management layer.
+ */
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.openecomp.policy.common.im.StateChangeNotifier;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.drools.controller.internal.MavenDroolsController;
+import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
+import org.openecomp.policy.drools.event.comm.TopicEndpoint;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.drools.persistence.DroolsPdpsConnector;
+import org.openecomp.policy.drools.persistence.PersistenceFeature;
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+/*
+ * Some background:
+ * 
+ * Originally, there was a "StandbyStateChangeNotifier" that belonged to policy-core, and this class's handleStateChange() method
+ * used to take care of invoking conn.standDownPdp().   But testing revealed that when a state change to hot standby occurred 
+ * from a demote() operation, first the PMStandbyStateChangeNotifier.handleStateChange() method would be invoked and then the 
+ * StandbyStateChangeNotifier.handleStateChange() method would be invoked, and this ordering was creating the following problem:
+ * 
+ * When PMStandbyStateChangeNotifier.handleStateChange() was invoked it would take a long time to finish, because it would result
+ * in SingleThreadedUebTopicSource.stop() being invoked, which can potentially do a 5 second sleep for each controller being stopped.   
+ * Meanwhile, as these controller stoppages and their associated sleeps were occurring, the election handler would discover the
+ * demoted PDP in hotstandby (but still designated!) and promote it, resulting in the standbyStatus going from hotstandby
+ * to providingservice.  So then, by the time that PMStandbyStateChangeNotifier.handleStateChange() finished its work and
+ * StandbyStateChangeNotifier.handleStateChange() started executing, the standbyStatus was no longer hotstandby (as effected by
+ * the demote), but providingservice (as reset by the election handling logic) and conn.standDownPdp() would not get called!
+ * 
+ * To fix this bug, we consolidated StandbyStateChangeNotifier and PMStandbyStateChangeNotifier, with the standDownPdp() always 
+ * being invoked prior to the TopicEndpoint.manager.lock().  In this way, when the election handling logic is invoked 
+ * during the controller stoppages, the PDP is in hotstandby and the standdown occurs.
+ * 
+ */
+public class PMStandbyStateChangeNotifier extends StateChangeNotifier {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(PMStandbyStateChangeNotifier.class);
+       private Timer delayActivateTimer;
+       private int pdpUpdateInterval;
+       private boolean isWaitingForActivation;
+       private long startTimeWaitingForActivationMs;
+       private long waitInterval;
+       private boolean isNowActivating;
+       
+       public PMStandbyStateChangeNotifier(){
+               pdpUpdateInterval = Integer.parseInt(IntegrityMonitorProperties.getProperty(IntegrityMonitorProperties.PDP_UPDATE_INTERVAL));
+               isWaitingForActivation = false;
+               startTimeWaitingForActivationMs = new Date().getTime();
+               //delay the activate so the DesignatedWaiter can run twice - give it an extra 2 seconds
+               waitInterval = 2*pdpUpdateInterval + 2000;
+               isNowActivating=false;
+       }
+
+       @Override
+       public void handleStateChange() {
+               /*
+                * A note on synchronization: This method is not synchronized because the caller, stateManagememt, 
+                * has synchronize all of its methods. Only one stateManagement operation can occur at a time. Thus,
+                * only one handleStateChange() call will ever be made at a time.
+                */
+               
+               logger.info("handleStateChange: Entering, message='"
+                               + super.getMessage() + "', standbyStatus='"
+                               + super.getStateManagement().getStandbyStatus() + "'");
+               
+               String standbyStatus = super.getStateManagement().getStandbyStatus();
+               String pdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+               DroolsPdpsConnector conn = PersistenceFeature
+                               .getDroolsPdpsConnector("ncompPU");
+
+               if (standbyStatus == null) {
+                       logger.info("handleStateChange: standbyStatus is null; standing down PDP=" + pdpId);
+                       isWaitingForActivation = false;
+                       try{
+                               try{
+                                       logger.info("handleStateChange: null:  cancelling delayActivationTimer.");
+                                       delayActivateTimer.cancel();
+                               }catch(Exception e){
+                                       logger.info("handleStateChange: null no delayActivationTimer existed.");
+                                       //If you end of here, there was no active timer
+                               }
+                               conn.standDownPdp(pdpId);
+                               //Only want to lock the endpoints, not the controllers.
+                               PolicyEngine.manager.deactivate();
+                       }catch(Exception e){
+                               logger.warn("handleStateChange: standbyStatus == null caught exception: " + e);
+                               e.printStackTrace();
+                       }
+
+               } else if (standbyStatus.equals("null")) {
+                       logger.info("handleStateChange: standbyStatus equals 'null'; standing down PDP=" + pdpId);
+                       isWaitingForActivation = false;
+                       try{
+                               try{
+                                       logger.info("handleStateChange: NULL_VALUE:  cancelling delayActivationTimer.");
+                                       delayActivateTimer.cancel();
+                               }catch(Exception e){
+                                       logger.info("handleStateChange: NULL_VALUE no delayActivationTimer existed.");
+                                       //If you end of here, there was no active timer
+                               }
+                               conn.standDownPdp(pdpId);
+                               //Only want to lock the endpoints, not the controllers.
+                               PolicyEngine.manager.deactivate();
+                       }catch(Exception e){
+                               logger.warn("handleStateChange: standbyStatus == \"null\" caught exception: " + e);
+                               e.printStackTrace();
+                       }
+               } else if (standbyStatus.equals(StateManagement.HOT_STANDBY) || standbyStatus.equals(StateManagement.COLD_STANDBY)) {
+                       logger.info("handleStateChange: standbyStatus=" + standbyStatus + "; standing down PDP=" + pdpId);
+                       isWaitingForActivation = false;
+                       try{
+                               try{
+                                       logger.info("handleStateChange: HOT_STNDBY || COLD_STANDBY:  cancelling delayActivationTimer.");
+                                       delayActivateTimer.cancel();
+                               }catch(Exception e){
+                                       logger.info("handleStateChange: HOT_STANDBY || COLD_STANDBY no delayActivationTimer existed.");
+                                       //If you end of here, there was no active timer
+                               }
+                               //Only want to lock the endpoints, not the controllers.
+                               conn.standDownPdp(pdpId);
+                               PolicyEngine.manager.deactivate();
+                       }catch(Exception e){
+                               logger.warn("handleStateChange: standbyStatus == " + standbyStatus + " caught exception: " + e);
+                               e.printStackTrace();
+                       }
+
+               } else if (standbyStatus.equals(StateManagement.PROVIDING_SERVICE)) {
+                       try{
+                               //UnLock all the endpoints
+                               logger.info("handleStateChange: standbyStatus=" + standbyStatus + "; controllers must be unlocked.");
+                               /*
+                                * Only endpoints should be unlocked. Controllers have not been locked.
+                                * Because, sometimes, it is possible for more than one PDP-D to become active (race conditions)
+                                * we need to delay the activation of the topic endpoint interfaces to give the election algorithm
+                                * time to resolve the conflict.
+                                */
+                               logger.info("handleStateChange: PROVIDING_SERVICE isWaitingForActivation= " +isWaitingForActivation);
+                               //Delay activation for 2*pdpUpdateInterval+2000 ms in case of an election handler conflict.  
+                               //You could have multiple election handlers thinking they can take over.
+                               
+                                // First let's check that the timer has not died
+                               if(isWaitingForActivation){
+                                       logger.info("handleStateChange: PROVIDING_SERVICE isWaitingForActivation = " + isWaitingForActivation);
+                                       long now = new Date().getTime();
+                                       long waitTimeMs = now - startTimeWaitingForActivationMs;
+                                       if(waitTimeMs > 3*waitInterval){
+                                               logger.info("handleStateChange: PROVIDING_SERVICE looks like the activation wait timer may be hung,"
+                                                               + " waitTimeMs = " + waitTimeMs + " and allowable waitInterval = " + waitInterval
+                                                               + " Checking whether it is currently in activation. isNowActivating = " + isNowActivating);
+                                               //Now check that it is not currently executing an activation
+                                               if(!isNowActivating){
+                                                       logger.info("handleStateChange: PROVIDING_SERVICE looks like the activation wait timer died");
+                                                       // This will assure the timer is cancelled and rescheduled.
+                                                       isWaitingForActivation = false;
+                                               }
+                                       }
+                                       
+                               }
+                               
+                               if(!isWaitingForActivation){
+                                       try{
+                                               //Just in case there is an old timer hanging around
+                                               logger.info("handleStateChange: PROVIDING_SERVICE cancelling delayActivationTimer.");
+                                               delayActivateTimer.cancel();
+                                       }catch(Exception e){
+                                               logger.info("handleStateChange: PROVIDING_SERVICE no delayActivationTimer existed.");
+                                               //If you end of here, there was no active timer
+                                       }
+                                       delayActivateTimer = new Timer();
+                                       //delay the activate so the DesignatedWaiter can run twice
+                                       delayActivateTimer.schedule(new DelayActivateClass(), waitInterval);
+                                       isWaitingForActivation = true;
+                                       startTimeWaitingForActivationMs = new Date().getTime();
+                                       logger.info("handleStateChange: PROVIDING_SERVICE scheduling delayActivationTimer in " + waitInterval + " ms");
+                               }else{
+                                       logger.info("handleStateChange: PROVIDING_SERVICE delayActivationTimer is waiting for activation.");
+                               }
+                               
+                       }catch(Exception e){
+                               logger.warn("handleStateChange: PROVIDING_SERVICE standbyStatus == providingservice caught exception: " + e);
+                               e.printStackTrace();
+                       }
+
+               } else {
+                       logger.error("handleStateChange: Unsupported standbyStatus=" + standbyStatus + "; standing down PDP=" + pdpId);
+                       //Only want to lock the endpoints, not the controllers.
+                       isWaitingForActivation = false;
+                       try{
+                               try{
+                                       logger.info("handleStateChange: unsupported standbystatus:  cancelling delayActivationTimer.");
+                                       delayActivateTimer.cancel();
+                               }catch(Exception e){
+                                       logger.info("handleStateChange: unsupported standbystatus: no delayActivationTimer existed.");
+                                       //If you end of here, there was no active timer
+                               }
+                               conn.standDownPdp(pdpId);
+                               PolicyEngine.manager.deactivate();
+                       }catch(Exception e){
+                               logger.warn("handleStateChange: Unsupported standbyStatus == " + standbyStatus + "caught exception: " + e);
+                               e.printStackTrace();
+                       }
+               }
+
+               //if (logger.isDebugEnabled()) {
+                       logger.info("handleStateChange: Exiting");
+               //}
+       }
+
+       private class DelayActivateClass extends TimerTask{
+
+               private Object delayActivateLock = new Object();
+
+
+               @Override
+               public void run() {
+                       isNowActivating = true;
+                       try{
+                               logger.info("DelayActivateClass.run: entry");
+                               synchronized(delayActivateLock){
+                                       PolicyEngine.manager.activate();
+                                       // We want to set this to false here because the activate call can take a while
+                                       isWaitingForActivation = false;
+                                       isNowActivating = false;
+                               }
+                               logger.info("DelayActivateClass.run.exit");
+                       }catch(Exception e){
+                               isWaitingForActivation = false;
+                               isNowActivating = false;
+                               logger.warn("DelayActivateClass.run: caught an unexpected exception "
+                                               + "calling PolicyEngine.manager.activate: " + e);
+                               System.out.println(new Date() + " DelayActivateClass.run: caught an unexpected exception");
+                               e.printStackTrace();
+                       }
+               }
+       }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdp.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdp.java
new file mode 100644 (file)
index 0000000..11cc878
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.util.Date;
+import java.util.List;
+
+public interface DroolsPdp {
+
+       public List<DroolsSessionEntity> getSessions();
+       public void addSession(DroolsSession session);
+       public void removeSession(DroolsSession session);
+       public String getPdpId();
+       public boolean isDesignated();
+       public int getPriority();
+       public Date getUpdatedDate();
+       public void setDesignated(boolean isDesignated);
+       public void setUpdatedDate(Date updatedDate);
+       public int comparePriority(DroolsPdp other);
+       public int comparePriority(DroolsPdp other,String previousSite);
+       public DroolsSession getSession(String sessionName);
+       public void setSessionId(String sessionName, long sessionId);
+       public String getSiteName();
+       public void setSiteName(String siteName);
+       public Date getDesignatedDate();
+       public void setDesignatedDate(Date designatedDate);
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpEntity.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpEntity.java
new file mode 100644 (file)
index 0000000..87b5872
--- /dev/null
@@ -0,0 +1,171 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.openecomp.policy.drools.persistence.DroolsPdpObject;
+
+@Entity
+//@Table(name="DroolsPdpEntity")
+
+@NamedQueries({
+       @NamedQuery(name="DroolsPdpEntity.findAll", query="SELECT e FROM DroolsPdpEntity e "),
+       @NamedQuery(name="DroolsPdpEntity.deleteAll", query="DELETE FROM DroolsPdpEntity WHERE 1=1")
+})
+public class DroolsPdpEntity extends DroolsPdpObject implements Serializable{
+
+       private static final long serialVersionUID = 1L;
+       
+       @Id
+       @Column(name="pdpId", nullable=false)
+       private String pdpId="-1";
+       
+       @Column(name="designated", nullable=false)
+       private boolean designated=false;
+       
+       @Column(name="priority", nullable=false)
+       private int priority=0;
+       
+       @Temporal(TemporalType.TIMESTAMP)
+       @Column(name="updatedDate", nullable=false)
+       private Date updatedDate;
+       
+       @Temporal(TemporalType.TIMESTAMP)
+       @Column(name="designatedDate",nullable=false)
+       private Date designatedDate;
+       
+       @Column(name="site", nullable=true, length = 50)
+       private String site;
+       
+       
+       @OneToMany(mappedBy="pdpEntity")
+       //@OneToMany
+       //@JoinColumn(name="pdpId", referencedColumnName="pdpId")
+       //@JoinColumn(name="pdpId")
+       private List<DroolsSessionEntity> sessions;
+       
+       
+       public DroolsPdpEntity(){
+               updatedDate = new Date();
+               //When this is translated to a TimeStamp in MySQL, it assumes the date is relative
+               //to the local timezone.  So, a value of Date(0) is actually Dec 31 18:00:00 CST 1969
+               //which is an invalid value for the MySql TimeStamp 
+               designatedDate = new Date(864000000);
+       }
+
+       @Override
+       public String getPdpId() {
+               return this.pdpId;
+       }
+       
+       public void setPdpId(String pdpId) {
+               this.pdpId = pdpId;
+       }
+       
+       @Override
+       public boolean isDesignated() {
+               return this.designated;
+       }
+
+       @Override
+       public int getPriority() {
+               return this.priority;
+       }
+
+       public void setPriority(int priority) {
+               this.priority = priority;
+       }
+
+       @Override
+       public Date getUpdatedDate() {
+               return this.updatedDate;
+       }
+
+       @Override
+       public void setDesignated(boolean isDesignated) {               
+               this.designated=isDesignated;           
+       }
+
+       @Override
+       public void setUpdatedDate(Date updatedDate) {
+               this.updatedDate=updatedDate;
+       }
+
+       
+       public List<DroolsSessionEntity> getSessions() {
+               return sessions;
+       }
+
+       public void addSession(DroolsSessionEntity session) {
+               sessions.add(session);
+       }
+       
+       public void removeSession(DroolsSessionEntity session) {
+               sessions.remove(session);
+               
+       }
+
+       @Override
+       public void addSession(DroolsSession session) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void removeSession(DroolsSession session) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public String getSiteName() {
+               return site;
+       }
+
+       @Override
+       public void setSiteName(String siteName) {
+               site = siteName;
+               
+       }
+
+       @Override
+       public Date getDesignatedDate() {
+               return designatedDate;
+       }
+
+       @Override
+       public void setDesignatedDate(Date designatedDate) {
+               this.designatedDate = designatedDate;           
+       }
+
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpImpl.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpImpl.java
new file mode 100644 (file)
index 0000000..e0f5d81
--- /dev/null
@@ -0,0 +1,115 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+
+public class DroolsPdpImpl extends DroolsPdpObject {
+
+       private boolean designated;
+       private int priority;
+       private Date updatedDate;
+       private Date designatedDate;
+       private String pdpId;
+       private String site;
+       private List<DroolsSessionEntity> sessions;
+       
+       public DroolsPdpImpl(String pdpId, boolean designated, int priority, Date updatedDate){
+               this.pdpId = pdpId;
+               this.designated = designated;
+               this.priority = priority;
+               this.updatedDate = updatedDate;
+               //When this is translated to a TimeStamp in MySQL, it assumes the date is relative
+               //to the local timezone.  So, a value of Date(0) is actually Dec 31 18:00:00 CST 1969
+               //which is an invalid value for the MySql TimeStamp 
+               this.designatedDate = new Date(864000000);
+               sessions = new LinkedList<DroolsSessionEntity>();
+
+       }
+       @Override
+       public boolean isDesignated() {
+               
+               return designated;
+       }
+
+       @Override
+       public int getPriority() {              
+               return priority;
+       }
+       @Override
+       public void setUpdatedDate(Date date){
+               this.updatedDate = date;
+       }
+       @Override
+       public Date getUpdatedDate() {          
+               return updatedDate;
+       }
+       
+       @Override
+       public String getPdpId() {              
+               return pdpId;
+       }
+       @Override
+       public void setDesignated(boolean isDesignated) {               
+               this.designated = isDesignated;
+               
+       }
+
+
+       @Override
+       public List<DroolsSessionEntity> getSessions() {
+               // TODO Auto-generated method stub
+               return sessions;
+       }
+       @Override
+       public void addSession(DroolsSession session) {
+               
+               
+       }
+       @Override
+       public void removeSession(DroolsSession session) {
+               // TODO Auto-generated method stub
+               
+       }
+       @Override
+       public String getSiteName() {
+               return site;
+       }
+       @Override
+       public void setSiteName(String siteName) {
+               this.site = siteName;
+               
+       }
+       @Override
+       public Date getDesignatedDate() {
+               return designatedDate;
+       }
+       @Override
+       public void setDesignatedDate(Date designatedDate) {
+               this.designatedDate = designatedDate;
+               
+       }
+
+
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpObject.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpObject.java
new file mode 100644 (file)
index 0000000..7a21914
--- /dev/null
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+
+public abstract class DroolsPdpObject implements DroolsPdp{
+       
+       @Override
+       public boolean equals(Object other){
+               if(other instanceof DroolsPdp){
+               return this.getPdpId().equals(((DroolsPdp)other).getPdpId());
+               }else{
+                       return false;
+               }
+       }
+       private int nullSafeCompare(Comparable one, Comparable two){
+               if(one != null && two != null){
+                       return one.compareTo(two);
+               }
+               if(one == null && two != null){
+                       return -1;
+               }
+               if(one != null && two == null){
+                       return 1;
+               }
+               return 0;
+       }
+       @Override
+       public int comparePriority(DroolsPdp other){
+               if(nullSafeCompare(this.getSiteName(),other.getSiteName()) == 0){
+               if(this.getPriority() != other.getPriority()){
+                       return this.getPriority() - other.getPriority();
+               }
+               return this.getPdpId().compareTo(other.getPdpId());
+               } else {
+                       return nullSafeCompare(this.getSiteName(),other.getSiteName());
+               }
+       }
+       @Override
+       public int comparePriority(DroolsPdp other, String previousSite){
+               if(previousSite == null || previousSite.equals("")){
+                       return comparePriority(other);
+               }
+               if(nullSafeCompare(this.getSiteName(),other.getSiteName()) == 0){
+                       if(this.getPriority() != other.getPriority()){
+                               return this.getPriority() - other.getPriority();
+                       }
+                       return this.getPdpId().compareTo(other.getPdpId());
+               } else {
+                       return nullSafeCompare(this.getSiteName(),other.getSiteName());
+               }
+       }
+       @Override
+       public DroolsSession getSession(String sessionName){
+               for(DroolsSession session : getSessions()){
+                       if(session.getSessionName().equals(sessionName)){
+                               return session;
+                       }
+               }
+               return null;
+       }
+       @Override
+       public void setSessionId(String sessionName, long sessionId){
+               for(DroolsSession session : getSessions()){
+                       if(session.getSessionName().equals(sessionName)){
+                               session.setSessionId(sessionId);
+                               return;
+                       }
+               }
+               DroolsSessionEntity newSession = new DroolsSessionEntity();
+               DroolsPdpEntity pdpEntityWithPdpId = new DroolsPdpEntity();
+               pdpEntityWithPdpId.setPdpId(this.getPdpId());
+               newSession.setPdpEntity(pdpEntityWithPdpId);
+               newSession.setPdpId(getPdpId());
+               newSession.setSessionName(sessionName);
+               newSession.setSessionId(sessionId);
+               getSessions().add(newSession);
+       }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsConnector.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsConnector.java
new file mode 100644 (file)
index 0000000..fa75c2e
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.util.Collection;
+
+public interface DroolsPdpsConnector {
+
+       
+       //return a list of PDPs, NOT including this PDP
+       public Collection<DroolsPdp> getDroolsPdps();
+       
+       public void update(DroolsPdp pdp);
+       
+       //determines if the DroolsPdp parameter is considered "current" or expired (has it been too long since the Pdp sent an update)
+       public boolean isPdpCurrent(DroolsPdp pdp);
+       
+       // Updates DESIGNATED boolean in PDP record.
+       public void setDesignated(DroolsPdp pdp, boolean designated);
+       
+       // Marks droolspdpentity.DESIGNATED=false, so another PDP-D will go active.
+       public void standDownPdp(String pdpId);
+                       
+       // This is used in a JUnit test environment to manually
+       // insert a PDP
+       public void insertPdp(DroolsPdp pdp);
+       
+       // This is used in a JUnit test environment to manually
+       // delete a PDP
+       public void deletePdp(String pdpId);
+               
+       // This is used in a JUnit test environment to manually
+       // clear the droolspdpentity table.
+       public void deleteAllPdps();
+       
+       // This is used in a JUnit test environment to manually
+       // clear the droolspdpentity table.
+       public void deleteAllSessions();
+
+       // This is used in a JUnit test environment to manually
+       // get a PDP
+       public DroolsPdpEntity getPdp(String pdpId);
+       
+       // Used by DroolsPdpsElectionHandler to determine if the currently designated
+       // PDP has failed.
+       public boolean hasDesignatedPdpFailed(Collection<DroolsPdp> pdps);
+
+       
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java
new file mode 100644 (file)
index 0000000..82ee5d1
--- /dev/null
@@ -0,0 +1,948 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.openecomp.policy.common.im.StandbyStatusException;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.drools.core.DroolsPDPIntegrityMonitor;
+import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+
+public class DroolsPdpsElectionHandler implements ThreadRunningChecker {
+       // get an instance of logger 
+       private final static Logger  logger = FlexLogger.getLogger(DroolsPdpsElectionHandler.class);    
+       private DroolsPdpsConnector pdpsConnector;
+       private Object pdpsConnectorLock = new Object();
+       private Object checkUpdateWorkerLock = new Object();
+       private Object checkWaitTimerLock = new Object();
+       private Object designationWaiterLock = new Object();
+       
+       /*
+        * Must be static, so it can be referenced by JpaDroolsPdpsConnector,
+        * without requiring a reference to the election handler instantiation.
+        */
+       private static DroolsPdp myPdp;
+       
+       private DesignationWaiter designationWaiter;
+       private Timer updateWorker;
+       private Timer waitTimer;
+       private Date updateWorkerLastRunDate;
+       private Date waitTimerLastRunDate;
+       private int pdpCheckInterval;
+       private int pdpUpdateInterval;
+       private volatile boolean isDesignated;
+       DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor;
+       StateManagement stateManagement;
+       
+       public DroolsPdpsElectionHandler(DroolsPdpsConnector pdps, DroolsPdp myPdp, DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor){
+               this.pdpsConnector = pdps;
+               DroolsPdpsElectionHandler.myPdp = myPdp;
+               this.isDesignated = false;
+               this.droolsPdpIntegrityMonitor = droolsPdpIntegrityMonitor;
+               this.stateManagement = droolsPdpIntegrityMonitor.getStateManager();                             
+               pdpCheckInterval = 3000;
+               try{
+                       pdpCheckInterval = Integer.parseInt(IntegrityMonitorProperties.getProperty(IntegrityMonitorProperties.PDP_CHECK_INVERVAL));
+               }catch(Exception e){
+                       logger.error
+                       //System.out.println
+                       (MessageCodes.EXCEPTION_ERROR ,e, "Could not get pdpCheckInterval property. Using default");
+               }
+               pdpUpdateInterval = 2000;
+               try{
+                       pdpUpdateInterval = Integer.parseInt(IntegrityMonitorProperties.getProperty(IntegrityMonitorProperties.PDP_UPDATE_INTERVAL));
+               }catch(Exception e){
+                       logger.error
+                       //System.out.println
+                       (MessageCodes.EXCEPTION_ERROR, e, "Could not get pdpUpdateInterval property. Using default");
+               }       
+               
+               Date now = new Date();
+               
+               // Retrieve the ms since the epoch
+               long nowMs = now.getTime();
+
+               // Create the timer which will update the updateDate in DroolsPdpEntity table.
+               // This is the heartbeat 
+               updateWorker = new Timer();
+               
+               // Schedule the heartbeat to start in 100 ms and run at pdpCheckInterval ms thereafter
+               updateWorker.scheduleAtFixedRate(new TimerUpdateClass(), 100, pdpCheckInterval);
+               updateWorkerLastRunDate = new Date(nowMs + 100);
+               
+               // Create the timer which will run the election algorithm
+               waitTimer = new Timer();
+
+               // Schedule it to start in startMs ms (so it will run after the updateWorker and run at pdpUpdateInterval ms thereafter
+               long startMs = getDWaiterStartMs();
+               designationWaiter = new DesignationWaiter();
+               waitTimer.scheduleAtFixedRate(designationWaiter, startMs, pdpUpdateInterval);
+               waitTimerLastRunDate = new Date(nowMs + startMs);
+       }
+       
+       public List<DroolsSessionEntity> waitForDesignation(){
+               while(isDesignated == false){
+                       try {
+                               Thread.sleep(1000);
+                       } catch (InterruptedException e) {
+                               return null;
+                       }
+               }
+               return designationWaiter.getSessions();
+
+       }
+       public List<DroolsSessionEntity> getSessions(){
+               return designationWaiter.getSessions();
+       }
+       public void updateMyPdp(){
+               synchronized(pdpsConnectorLock){
+                       myPdp.setUpdatedDate(new Date());
+                       pdpsConnector.update(myPdp);
+               }
+       }
+       
+       /*
+        * When the JpaDroolsPdpsConnector.standDown() method is invoked, it needs
+        * access to myPdp, so it can keep its designation status in sync with the
+        * DB.
+        */
+       public static void setMyPdpDesignated(boolean designated) {
+               logger.debug
+               //System.out.println
+                       ("setMyPdpDesignated: designated=" + designated);
+               myPdp.setDesignated(designated);
+       }
+       
+       private class DesignationWaiter extends TimerTask {
+               // get an instance of logger 
+               private Logger  logger = FlexLogger.getLogger(DesignationWaiter.class);
+               private List<DroolsSessionEntity> sessions = null;
+
+               public List<DroolsSessionEntity> getSessions(){
+                       if(sessions != null){
+                               return sessions;
+                       }
+                       return new LinkedList<DroolsSessionEntity>();
+               }
+               public void run() {
+                       try{
+                               logger.debug
+                               //System.out.println
+                               ("DesignatedWaiter.run: Entering");
+                               
+                               // just here initially so code still works
+                               if (pdpsConnector == null) {
+                                       waitTimerLastRunDate = new Date();
+                                       logger.info("DesignatedWaiter.run (pdpsConnector==null) waitTimerLastRunDate = " + waitTimerLastRunDate);
+                                       
+                                       return;
+                               }
+
+                               synchronized (designationWaiterLock) {
+
+                                       logger.debug
+                                       //System.out.println
+                                       ("DesignatedWaiter.run: Entering synchronized block");
+
+                                       checkUpdateWorkerTimer();
+                                       
+                                       //It is possible that multiple PDPs are designated lead.  So, we will make a list of all designated
+                                       //PDPs and then decide which one really should be designated at the end.
+                                       ArrayList<DroolsPdp> listOfDesignated = new ArrayList<DroolsPdp>();
+
+                                       Collection<DroolsPdp> pdps = pdpsConnector.getDroolsPdps();
+                                       DroolsPdp designatedPdp = null;
+                                       DroolsPdp lowestPriorityPdp = null;
+
+                                       logger.debug
+                                       //System.out.println
+                                       ("DesignatedWaiter.run: pdps.size="
+                                                       + pdps.size());
+
+                                       //This is only true if all designated PDPs have failed
+                                       boolean designatedPdpHasFailed = pdpsConnector.hasDesignatedPdpFailed(pdps);
+                                       logger.debug
+                                       //System.out.println
+                                       ("DesignatedWaiter.run: designatedPdpHasFailed="
+                                                       + designatedPdpHasFailed);
+                                       for (DroolsPdp pdp : pdps) {
+                                               logger.debug
+                                               //System.out.println
+                                               ("DesignatedWaiter.run: evaluating pdp ID: " + pdp.getPdpId());
+
+                                               /*
+                                                * Note: side effect of isPdpCurrent is that any stale but
+                                                * designated PDPs will be marked as un-designated.
+                                                */
+                                               boolean isCurrent = pdpsConnector.isPdpCurrent(pdp);
+
+                                               /*
+                                                * We can't use stateManagement.getStandbyStatus() here, because
+                                                * we need the standbyStatus, not for this PDP, but for the PDP
+                                                * being processed by this loop iteration.
+                                                */
+                                               String standbyStatus = stateManagement.getStandbyStatus(pdp.getPdpId());
+                                               if(standbyStatus==null){
+                                                       // Treat this case as a cold standby -- if we
+                                                       // abort here, no sessions will be created in a
+                                                       // single-node test environment.
+                                                       standbyStatus = StateManagement.COLD_STANDBY;
+                                               }
+
+                                               logger.debug
+                                               //System.out.println
+                                               ("DesignatedWaiter.run: PDP="
+                                                               + pdp.getPdpId() + ", isCurrent=" + isCurrent);
+
+                                               /*
+                                                * There are 4 combinations of isDesignated and isCurrent.  We will examine each one in-turn
+                                                * and evaluate the each pdp in the list of pdps against each combination.
+                                                * 
+                                                * This is the first combination of isDesignated and isCurrent
+                                                */
+                                               if (pdp.isDesignated()  &&  isCurrent) { 
+                                                       //It is current, but it could have a standbystatus=coldstandby / hotstandby
+                                                       //If so, we need to stand it down and demote it
+                                                       if(!standbyStatus.equals(StateManagement.PROVIDING_SERVICE)){
+                                                               if(pdp.getPdpId().equals(myPdp.getPdpId())){
+                                                                       logger.debug
+                                                                       //System.out.println
+                                                                       ("\n\nDesignatedWaiter.run: myPdp " + myPdp.getPdpId() + " is current and designated, "
+                                                                                       + "butstandbystatus is not providingservice. "
+                                                                                       + " Executing stateManagement.demote()" + "\n\n");
+                                                                       // So, we must demote it
+                                                                       try {
+                                                                               //Keep the order like this.  StateManagement is last since it triggers controller shutdown
+                                                                               //This will change isDesignated and it can enter another if(combination) below
+                                                                               pdpsConnector.standDownPdp(pdp.getPdpId()); 
+                                                                               myPdp.setDesignated(false);
+                                                                               isDesignated = false;
+                                                                               if(!(standbyStatus.equals(StateManagement.HOT_STANDBY) || 
+                                                                                               standbyStatus.equals(StateManagement.COLD_STANDBY))){
+                                                                                       /*
+                                                                                        * Only demote it if it appears it has not already been demoted. Don't worry
+                                                                                        * about synching with the topic endpoint states.  That is done by the 
+                                                                                        * refreshStateAudit
+                                                                                        */
+                                                                                       stateManagement.demote();
+                                                                               }
+                                                                               //update the standbystatus to check in a later combination of isDesignated and isCurrent
+                                                                               standbyStatus=stateManagement.getStandbyStatus(pdp.getPdpId());
+                                                                       } catch (Exception e) {
+                                                                               logger.error
+                                                                               //System.out.println
+                                                                               ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " Caught Exception attempting to demote myPdp'"
+                                                                                               + myPdp.getPdpId()
+                                                                                               + "', message="
+                                                                                               + e.getMessage());
+                                                                               System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                                               + "from stateManagement.demote()");
+                                                                               e.printStackTrace();
+                                                                       }
+                                                               }else{
+                                                                       // Don't demote a remote PDP that is current.  It should catch itself
+                                                                       logger.debug
+                                                                       //System.out.println
+                                                                       ("\n\nDesignatedWaiter.run: myPdp " + myPdp.getPdpId() + " is current and designated, "
+                                                                                       + "but standbystatus is not providingservice. "
+                                                                                       + " Cannot execute stateManagement.demote() since it it is not myPdp\n\n");
+                                                               }
+
+                                                       }else{
+                                                               // If we get here, it is ok to be on the list
+                                                               logger.debug
+                                                               //System.out.println
+                                                               ("DesignatedWaiter.run: PDP="
+                                                                               + pdp.getPdpId()
+                                                                               + " is designated, current and " + standbyStatus +".  Noting PDP as designated.  standbyStatus=" + standbyStatus);
+                                                               listOfDesignated.add(pdp);
+                                                       }
+
+
+                                               }
+
+
+                                               /*
+                                                * The second combination of isDesignated and isCurrent
+                                                *                                      
+                                                * PDP is designated but not current; it has failed.   So we stand it down (it doesn't matter what
+                                                * its standbyStatus is). None of these go on the list.
+                                                */
+                                               if (pdp.isDesignated()  &&  !isCurrent) {
+                                                       logger.info
+                                                       //System.out.println
+                                                       ("INFO: DesignatedWaiter.run: PDP="
+                                                                       + pdp.getPdpId()
+                                                                       + " is currently designated but is not current; it has failed.  Standing down.  standbyStatus=" + standbyStatus);
+
+                                                       /*
+                                                        * Changes designated to 0 but it is still potentially providing service
+                                                        * Will affect isDesignated, so, it can enter an if(combination) below
+                                                        */
+                                                       pdpsConnector.standDownPdp(pdp.getPdpId()); 
+
+                                                       //need to change standbystatus to coldstandby
+                                                       if (pdp.getPdpId().equals(myPdp.getPdpId())){
+                                                               logger.debug
+                                                               //System.out.println
+                                                               ("\n\nDesignatedWaiter.run: myPdp " + myPdp.getPdpId() + " is not Current. "
+                                                                               + " Executing stateManagement.disableFailed()" + "\n\n");
+                                                               // We found that myPdp is designated but not current
+                                                               // So, we must cause it to disableFail
+                                                               try {
+                                                                       myPdp.setDesignated(false);
+                                                                       //pdpsConnector.setDesignated(myPdp, false);//not needed?
+                                                                       isDesignated = false;
+                                                                       stateManagement.disableFailed();
+                                                                       //stateManagement.demote();
+                                                               } catch (Exception e) {
+                                                                       logger.error
+                                                                       //System.out.println
+                                                                       ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " Caught Exception attempting to disableFail myPdp'"
+                                                                                       + myPdp.getPdpId()
+                                                                                       + "', message="
+                                                                                       + e.getMessage());
+                                                                       System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                                       + "from stateManagement.disableFailed()");
+                                                                       e.printStackTrace();
+                                                               }
+                                                       } else { //it is a remote PDP that is failed
+                                                               logger.debug
+                                                               //System.out.println
+                                                               ("\n\nDesignatedWaiter.run: PDP " + pdp.getPdpId() + " is not Current. "
+                                                                               + " Executing stateManagement.disableFailed(otherResourceName)" + "\n\n");
+                                                               // We found a PDP is designated but not current
+                                                               // We already called standdown(pdp) which will change designated to false
+                                                               // Now we need to disableFail it to get its states in synch.  The standbyStatus
+                                                               // should equal coldstandby
+                                                               try {
+                                                                       stateManagement.disableFailed(pdp.getPdpId());
+                                                                       //stateManagement.demote(pdp.getPdpId());
+                                                               } catch (Exception e) {
+                                                                       logger.error
+                                                                       //System.out.println
+                                                                       ("DesignatedWaiter.run: for PDP" + pdp.getPdpId() 
+                                                                                       + " Caught Exception attempting to disableFail(" + pdp.getPdpId() + ")'"
+                                                                                       + pdp.getPdpId()
+                                                                                       + "', message="
+                                                                                       + e.getMessage());
+                                                                       System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                                       + "from stateManagement.disableFailed()");
+                                                                       e.printStackTrace();
+                                                               }
+
+                                                       }
+                                                       continue; //we are not going to do anything else with this pdp
+                                               } 
+
+                                               /*
+                                                * The third combination of isDesignated and isCurrent
+                                                * /*
+                                                * If a PDP is not currently designated but is providing service (erroneous, but recoverable) or hot standby 
+                                                * we can add it to the list of possible designated if all the designated have failed
+                                                */
+                                               if (!pdp.isDesignated() && isCurrent){
+                                                       if(!(standbyStatus.equals(StateManagement.HOT_STANDBY) ||
+                                                                       standbyStatus.equals(StateManagement.COLD_STANDBY))){
+                                                               logger.info("\n\nDesignatedWaiter.run: PDP " + pdp.getPdpId()
+                                                                               + " is NOT designated but IS current and"
+                                                                               + " has a standbystatus=" + standbyStatus);
+                                                               // Since it is current, we assume it can adjust its own state.
+                                                               // We will demote if it is myPdp
+                                                               if(pdp.getPdpId().equals(myPdp.getPdpId())){
+                                                                       //demote it
+                                                                       logger.info("DesignatedWaiter.run: PDP " + pdp.getPdpId() + " going to "
+                                                                                       + "setDesignated = false and calling stateManagement.demote");
+                                                                       try {
+                                                                               //Keep the order like this.  StateManagement is last since it triggers controller shutdown
+                                                                               pdpsConnector.setDesignated(myPdp, false);
+                                                                               myPdp.setDesignated(false);
+                                                                               isDesignated = false;
+                                                                               //This is definitely not a redundant call.  It is attempting to correct a problem
+                                                                               stateManagement.demote();
+                                                                               //recheck the standbystatus
+                                                                               standbyStatus = stateManagement.getStandbyStatus(pdp.getPdpId());
+                                                                       } catch (Exception e) {
+                                                                               logger.error
+                                                                               //System.out.println
+                                                                               ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " Caught Exception attempting to demote myPdp'"
+                                                                                               + myPdp.getPdpId()
+                                                                                               + "', message="
+                                                                                               + e.getMessage());
+                                                                               System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                                               + "from stateManagement.demote()");
+                                                                               e.printStackTrace();
+                                                                       }
+
+                                                               }
+                                                       }
+                                                       if(standbyStatus.equals(StateManagement.HOT_STANDBY) && designatedPdpHasFailed){
+                                                               //add it to the list
+                                                               logger.info
+                                                               //System.out.println
+                                                               ("INFO: DesignatedWaiter.run: PDP=" + pdp.getPdpId()
+                                                                               + " is not designated but is " + standbyStatus + " and designated PDP has failed.  standbyStatus=" 
+                                                                               + standbyStatus);
+                                                               logger.info
+                                                               //System.out.println
+                                                               ("DesignatedWaiter.run: Designating PDP=" + pdp.getPdpId());
+                                                               listOfDesignated.add(pdp);
+                                                       }
+                                                       continue; //done with this one
+                                               }
+
+                                               /*
+                                                * The fourth combination of isDesignated and isCurrent
+                                                * 
+                                                * We are not going to put any of these on the list since it appears they have failed.
+
+                                                * 
+                                                */
+                                               if(!pdp.isDesignated() && !isCurrent) {
+                                                       logger.info
+                                                       //System.out.println
+                                                       ("INFO: DesignatedWaiter.run: PDP="
+                                                                       + pdp.getPdpId() + ", designated="
+                                                                       + pdp.isDesignated() + ", current="
+                                                                       + isCurrent
+                                                                       + ", designatedPdpHasFailed="
+                                                                       + designatedPdpHasFailed
+                                                                       + ",  standbyStatus=" + standbyStatus);
+                                                       if(!standbyStatus.equals(StateManagement.COLD_STANDBY)){
+                                                               //stand it down
+                                                               //disableFail it
+                                                               pdpsConnector.standDownPdp(pdp.getPdpId()); 
+                                                               if(pdp.getPdpId().equals(myPdp.getPdpId())){
+                                                                       /*
+                                                                        * I don't actually know how this condition could happen, but if it did, we would want
+                                                                        * to declare it failed.
+                                                                        */
+                                                                       logger.debug
+                                                                       //System.out.println
+                                                                       ("\n\nDesignatedWaiter.run: myPdp " + myPdp.getPdpId() + " is !current and !designated, "
+                                                                                       + " Executing stateManagement.disableFailed()" + "\n\n");
+                                                                       // So, we must disableFail it
+                                                                       try {
+                                                                               //Keep the order like this.  StateManagement is last since it triggers controller shutdown
+                                                                               myPdp.setDesignated(false);
+                                                                               isDesignated = false;
+                                                                               stateManagement.disableFailed();
+                                                                               //stateManagement.demote();
+                                                                       } catch (Exception e) {
+                                                                               logger.error
+                                                                               //System.out.println
+                                                                               ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " Caught Exception attempting to disableFail myPdp'"
+                                                                                               + myPdp.getPdpId()
+                                                                                               + "', message="
+                                                                                               + e.getMessage());
+                                                                               System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                                               + "from stateManagement.disableFailed()");
+                                                                               e.printStackTrace();
+                                                                       }
+                                                               }else{//it is remote
+                                                                       logger.debug
+                                                                       //System.out.println
+                                                                       ("\n\nDesignatedWaiter.run: myPdp " + myPdp.getPdpId() + " is !current and !designated, "
+                                                                                       + " Executing stateManagement.disableFailed(" + pdp.getPdpId() + ")" + "\n\n");
+                                                                       // We already called standdown(pdp) which will change designated to false
+                                                                       // Now we need to disableFail it to get its states in sync.  StandbyStatus = coldstandby
+                                                                       try {
+                                                                               stateManagement.disableFailed(pdp.getPdpId());
+                                                                               //stateManagement.demote(pdp.getPdpId());
+                                                                       } catch (Exception e) {
+                                                                               logger.error
+                                                                               //System.out.println
+                                                                               ("DesignatedWaiter.run: for PDP" + pdp.getPdpId() 
+                                                                                               + " Caught Exception attempting to disableFail(" + pdp.getPdpId() + ")'"
+                                                                                               + pdp.getPdpId()
+                                                                                               + "', message="
+                                                                                               + e.getMessage());
+                                                                               System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                                               + "from stateManagement.disableFailed()");
+                                                                               e.printStackTrace();
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+
+                                       } // end pdps loop
+
+                                       /*
+                                        * We have checked the four combinations of isDesignated and isCurrent.  Where appropriate,
+                                        * we added the PDPs to the potential list of designated pdps
+                                        * Check if listOfDesignated is empty, has one entry or has multiple entries
+                                        * If it has multiple designated PDPs, then we must determine if myPdp is on the list and if
+                                        * it is the lowest priority.  If it is on the list and it is not the lowest
+                                        * priority, it must be demoted.  Then, we must find the lowest priority
+                                        * PDP so we can get the right list of sessions
+                                        */
+                                       //we need to give priority to pdps on the same site that is currently being used
+
+
+                                       //we need to figure out the last pdp that was the primary so we can get the last site name and the last session numbers
+                                       DroolsPdp mostRecentPrimary = new DroolsPdpImpl(null, true, 1, new Date(0));
+                                       mostRecentPrimary.setSiteName(null);
+                                       for(DroolsPdp pdp : pdps){
+                                               if(pdp.getDesignatedDate().compareTo(mostRecentPrimary.getDesignatedDate()) > 0){
+                                                       mostRecentPrimary = pdp;
+                                               }
+                                       }
+
+                                       if(listOfDesignated.size() > 1){
+                                               logger.debug
+                                               //System.out.println
+                                               ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated.size():  " + listOfDesignated.size());                                 
+                                               DroolsPdp rejectedPdp = null;
+                                               DroolsPdp lowestPrioritySameSite = null;
+                                               DroolsPdp lowestPriorityDifferentSite = null;
+                                               for(DroolsPdp pdp : listOfDesignated){
+                                                       // We need to determine if another PDP is the lowest priority
+                                                       if(nullSafeEquals(pdp.getSiteName(),mostRecentPrimary.getSiteName())){
+                                                               if(lowestPrioritySameSite == null){
+                                                                       if(lowestPriorityDifferentSite != null){
+                                                                               rejectedPdp = lowestPriorityDifferentSite;
+                                                                       }
+                                                                       lowestPrioritySameSite = pdp;                                                                   
+                                                               }else{
+                                                                       if(pdp.getPdpId().equals((lowestPrioritySameSite.getPdpId()))){
+                                                                               continue;//nothing to compare
+                                                                       }
+                                                                       if(pdp.comparePriority(lowestPrioritySameSite) <0){
+                                                                               logger.debug
+                                                                               //System.out.println
+                                                                               ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId() 
+                                                                                               + " has lower priority than pdp ID: " + lowestPrioritySameSite.getPdpId());
+
+                                                                               //we need to reject lowestPrioritySameSite
+                                                                               rejectedPdp = lowestPrioritySameSite;
+                                                                               lowestPrioritySameSite = pdp;
+                                                                       } else{
+                                                                               //we need to reject pdp and keep lowestPrioritySameSite
+                                                                               logger.debug
+                                                                               //System.out.println
+                                                                               ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId() 
+                                                                                               + " has higher priority than pdp ID: " + lowestPrioritySameSite.getPdpId());
+                                                                               rejectedPdp = pdp;
+                                                                       }
+                                                               }
+                                                       } else{
+                                                               if(lowestPrioritySameSite != null){
+                                                                       //if we already have a candidate for same site, we don't want to bother with different sites
+                                                                       rejectedPdp = pdp;
+                                                               } else{
+                                                                       if(lowestPriorityDifferentSite == null){
+                                                                               lowestPriorityDifferentSite = pdp;
+                                                                               continue;
+                                                                       }
+                                                                       if(pdp.getPdpId().equals((lowestPriorityDifferentSite.getPdpId()))){
+                                                                               continue;//nothing to compare
+                                                                       }
+                                                                       if(pdp.comparePriority(lowestPriorityDifferentSite) <0){
+                                                                               logger.debug
+                                                                               //System.out.println
+                                                                               ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId() 
+                                                                                               + " has lower priority than pdp ID: " + lowestPriorityDifferentSite.getPdpId());
+
+                                                                               //we need to reject lowestPriorityDifferentSite
+                                                                               rejectedPdp = lowestPriorityDifferentSite;
+                                                                               lowestPriorityDifferentSite = pdp;
+                                                                       } else{
+                                                                               //we need to reject pdp and keep lowestPriorityDifferentSite
+                                                                               logger.debug
+                                                                               //System.out.println
+                                                                               ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId() 
+                                                                                               + " has higher priority than pdp ID: " + lowestPriorityDifferentSite.getPdpId());
+                                                                               rejectedPdp = pdp;
+                                                                       }
+                                                               }
+                                                       }
+                                                       // If the rejectedPdp is myPdp, we need to stand it down and demote it.  Each pdp is responsible
+                                                       // for demoting itself
+                                                       if(rejectedPdp != null && nullSafeEquals(rejectedPdp.getPdpId(),myPdp.getPdpId())){
+                                                               logger.debug
+                                                               //System.out.println
+                                                               ("\n\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated myPdp ID: " + myPdp.getPdpId() 
+                                                                               + " is NOT the lowest priority.  Executing stateManagement.demote()" + "\n\n");
+                                                               // We found that myPdp is on the listOfDesignated and it is not the lowest priority
+                                                               // So, we must demote it
+                                                               try {
+                                                                       //Keep the order like this.  StateManagement is last since it triggers controller shutdown
+                                                                       myPdp.setDesignated(false);
+                                                                       pdpsConnector.setDesignated(myPdp, false);
+                                                                       isDesignated = false;
+                                                                       String standbyStatus = stateManagement.getStandbyStatus();
+                                                                       if(!(standbyStatus.equals(StateManagement.HOT_STANDBY) || 
+                                                                                       standbyStatus.equals(StateManagement.COLD_STANDBY))){
+                                                                               /*
+                                                                                * Only call demote if it is not already in the right state.  Don't worry about
+                                                                                * synching the lower level topic endpoint states.  That is done by the
+                                                                                * refreshStateAudit.
+                                                                                */
+                                                                               stateManagement.demote();
+                                                                       }
+                                                               } catch (Exception e) {
+                                                                       myPdp.setDesignated(false);
+                                                                       pdpsConnector.setDesignated(myPdp, false);
+                                                                       isDesignated = false;
+                                                                       logger.error
+                                                                       //System.out.println
+                                                                       ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " Caught Exception attempting to demote myPdp'"
+                                                                                       + myPdp.getPdpId()
+                                                                                       + "', message="
+                                                                                       + e.getMessage());
+                                                                       System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                                       + "from stateManagement.demote()");
+                                                                       e.printStackTrace();
+                                                               }
+                                                       }
+                                               } //end: for(DroolsPdp pdp : listOfDesignated)
+                                               if(lowestPrioritySameSite != null){
+                                                       lowestPriorityPdp = lowestPrioritySameSite;
+                                               } else {
+                                                       lowestPriorityPdp = lowestPriorityDifferentSite;
+                                               }
+                                               //now we have a valid value for lowestPriorityPdp
+                                               logger.debug
+                                               //System.out.println
+                                               ("\n\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated found the LOWEST priority pdp ID: " 
+                                                               + lowestPriorityPdp.getPdpId() 
+                                                               + " It is now the designatedPpd from the perspective of myPdp ID: " + myPdp + "\n\n");
+                                               designatedPdp = lowestPriorityPdp;
+                                               this.sessions = mostRecentPrimary.getSessions();
+
+                                       } else if(listOfDesignated.isEmpty()){
+                                               logger.debug
+                                               //System.out.println
+                                               ("\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated is: EMPTY.");
+                                               designatedPdp = null;
+                                       } else{ //only one in listOfDesignated
+                                               logger.debug
+                                               //System.out.println
+                                               ("\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated has ONE entry. PDP ID: "
+                                                               + listOfDesignated.get(0).getPdpId());
+                                               designatedPdp = listOfDesignated.get(0);
+                                               this.sessions = mostRecentPrimary.getSessions();
+                                       }
+
+
+                                       if (designatedPdp == null) {
+                                               logger.warn
+                                               //System.out.println
+                                               ("WARNING: DesignatedWaiter.run: No viable PDP found to be Designated. designatedPdp still null.");
+                                               // Just to be sure the parameters are correctly set
+                                               myPdp.setDesignated(false);
+                                               pdpsConnector.setDesignated(myPdp,false);
+                                               isDesignated = false;
+                                               
+                                               waitTimerLastRunDate = new Date();
+                                               logger.info("DesignatedWaiter.run (designatedPdp == null) waitTimerLastRunDate = " + waitTimerLastRunDate);
+                                               
+                                               return;
+                                               
+                                       } else if (designatedPdp.getPdpId().equals(myPdp.getPdpId())) {
+                                               logger.debug
+                                               //System.out.println
+                                               ("DesignatedWaiter.run: designatedPdp is PDP=" + myPdp.getPdpId());
+                                               /*
+                                                * update function expects myPdp.isDesignated to be true.
+                                                */
+                                               try {
+                                                       //Keep the order like this.  StateManagement is last since it triggers controller init
+                                                       myPdp.setDesignated(true);
+                                                       pdpsConnector.setDesignated(myPdp, true);
+                                                       isDesignated = true;
+                                                       String standbyStatus = stateManagement.getStandbyStatus();
+                                                       if(!standbyStatus.equals(StateManagement.PROVIDING_SERVICE)){
+                                                               /*
+                                                                * Only call promote if it is not already in the right state.  Don't worry about
+                                                                * synching the lower level topic endpoint states.  That is done by the
+                                                                * refreshStateAudit.
+                                                                */
+                                                               stateManagement.promote();
+                                                       }
+                                               } catch (StandbyStatusException e) {
+                                                       logger.error
+                                                       //System.out.println
+                                                       ("ERROR: DesignatedWaiter.run: Caught StandbyStatusException attempting to promote PDP='"
+                                                                       + myPdp.getPdpId()
+                                                                       + "', message="
+                                                                       + e.getMessage());
+                                                       myPdp.setDesignated(false);
+                                                       pdpsConnector.setDesignated(myPdp,false);
+                                                       isDesignated = false;
+                                                       //If you can't promote it, demote it
+                                                       try {
+                                                               String standbyStatus = stateManagement.getStandbyStatus();
+                                                               if(!(standbyStatus.equals(StateManagement.HOT_STANDBY) || 
+                                                                               standbyStatus.equals(StateManagement.COLD_STANDBY))){
+                                                                       /*
+                                                                        * Only call demote if it is not already in the right state.  Don't worry about
+                                                                        * synching the lower level topic endpoint states.  That is done by the
+                                                                        * refreshStateAudit.
+                                                                        */
+                                                                       stateManagement.demote();
+                                                               }
+                                                       } catch (Exception e1) {
+                                                               logger.error
+                                                               //System.out.println
+                                                               ("ERROR: DesignatedWaiter.run: Caught StandbyStatusException attempting to promote then demote PDP='"
+                                                                               + myPdp.getPdpId()
+                                                                               + "', message="
+                                                                               + e1.getMessage());
+                                                               System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                               + "from stateManagement.demote()");
+                                                               e1.printStackTrace();
+                                                       }
+
+                                               } catch (Exception e) {
+                                                       logger.error
+                                                       //System.out.println
+                                                       ("ERROR: DesignatedWaiter.run: Caught Exception attempting to promote PDP='"
+                                                                       + myPdp.getPdpId()
+                                                                       + "', message="
+                                                                       + e.getMessage());
+                                                       myPdp.setDesignated(false);
+                                                       pdpsConnector.setDesignated(myPdp,false);
+                                                       isDesignated = false;
+                                                       //If you can't promote it, demote it
+                                                       try {
+                                                               String standbyStatus = stateManagement.getStandbyStatus();
+                                                               if(!(standbyStatus.equals(StateManagement.HOT_STANDBY) || 
+                                                                               standbyStatus.equals(StateManagement.COLD_STANDBY))){
+                                                                       /*
+                                                                        * Only call demote if it is not already in the right state.  Don't worry about
+                                                                        * synching the lower level topic endpoint states.  That is done by the
+                                                                        * refreshStateAudit.
+                                                                        */
+                                                                       stateManagement.demote();
+                                                               }
+                                                       } catch (Exception e1) {
+                                                               logger.error
+                                                               //System.out.println
+                                                               ("ERROR: DesignatedWaiter.run: Caught StandbyStatusException attempting to promote then demote PDP='"
+                                                                               + myPdp.getPdpId()
+                                                                               + "', message="
+                                                                               + e1.getMessage());
+                                                               System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+                                                                               + "from stateManagement.demote()");
+                                                               e1.printStackTrace();
+                                                       }
+
+                                               }
+                                               waitTimerLastRunDate = new Date();
+                                               logger.info("DesignatedWaiter.run (designatedPdp.getPdpId().equals(myPdp.getPdpId())) waitTimerLastRunDate = " + waitTimerLastRunDate);
+
+                                               return;
+                                       }
+                                       isDesignated = false;
+
+                               } // end synchronized
+
+                               logger.debug
+                               //System.out.println
+                               ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + "; Returning, isDesignated=" + isDesignated);
+
+                               Date tmpDate = new Date();
+                               logger.info("DesignatedWaiter.run (end of run) waitTimerLastRunDate = " + tmpDate);
+                               
+                               waitTimerLastRunDate = tmpDate;
+                               
+                       }catch(Exception e){
+                               logger.error("DesignatedWaiter.run caught an unexpected exception: " + e);
+                               System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception");
+                               e.printStackTrace();
+                       }
+               } // end run
+       }
+       
+       private class TimerUpdateClass extends TimerTask{
+
+               @Override
+               public void run() {
+                       try{
+                               logger.info("TimerUpdateClass.run: entry");
+                               checkWaitTimer();
+                               synchronized(pdpsConnectorLock){
+                                       
+                                       myPdp.setUpdatedDate(new Date());
+                                       if(myPdp.isDesignated()){
+                                               myPdp.setDesignatedDate(new Date());
+                                       }
+                                       pdpsConnector.update(myPdp);
+                                       
+                                       Date tmpDate = new Date();
+                                       logger.info("TimerUpdateClass.run: updateWorkerLastRunDate = " + tmpDate);
+                                       
+                                       updateWorkerLastRunDate = tmpDate;
+                               }
+                               logger.info("TimerUpdateClass.run.exit");
+                       }catch(Exception e){
+                               logger.error("TimerUpdateClass.run caught an unexpected exception: " + e);
+                               System.out.println(new Date() + " TimerUpdateClass.run caught an unexpected exception");
+                               e.printStackTrace();
+                       }
+               }
+       }
+       @Override
+       public void checkThreadStatus() {
+               checkUpdateWorkerTimer();
+               checkWaitTimer();
+       }
+
+       private void checkUpdateWorkerTimer(){
+               synchronized(checkUpdateWorkerLock){
+                       try{
+                               logger.debug("checkUpdateWorkerTimer: entry");
+                               Date now = new Date();
+                               long nowMs = now.getTime();
+                               long updateWorkerMs = updateWorkerLastRunDate.getTime();
+                               //give it 2 second cushion
+                               if((nowMs - updateWorkerMs)  > pdpCheckInterval + 2000){
+                                       logger.error("checkUpdateWorkerTimer: nowMs - updateWorkerMs = " + (nowMs - updateWorkerMs) 
+                                                       + ", exceeds pdpCheckInterval + 2000 = " + (pdpCheckInterval + 2000) + " Will reschedule updateWorker timer");
+
+                                       try{
+                                               updateWorker.cancel();
+                                               // Recalculate the time because this is a synchronized section and the thread could have
+                                               // been blocked.
+                                               now = new Date();
+                                               nowMs = now.getTime();
+                                               updateWorker = new Timer();
+                                               // reset the updateWorkerLastRunDate
+                                               updateWorkerLastRunDate = new Date(nowMs + 100);
+                                               //execute the first time in 100 ms
+                                               updateWorker.scheduleAtFixedRate(new TimerUpdateClass(), 100, pdpCheckInterval);
+                                               logger.info("checkUpdateWorkerTimer: Scheduling updateWorker timer to start in 100 ms ");
+                                       }catch(Exception e){
+                                               logger.error("checkUpdateWorkerTimer: Caught unexpected Exception: " + e);
+                                               System.out.println(new Date() + " checkUpdateWorkerTimer caught an unexpected exception");
+                                               e.printStackTrace();
+                                               // Recalculate the time because this is a synchronized section and the thread could have
+                                               // been blocked.
+                                               now = new Date();
+                                               nowMs = now.getTime();
+                                               updateWorker = new Timer();
+                                               updateWorkerLastRunDate = new Date(nowMs + 100);
+                                               updateWorker.scheduleAtFixedRate(new TimerUpdateClass(), 100, pdpCheckInterval);
+                                               logger.info("checkUpdateWorkerTimer: Attempting to schedule updateWorker timer in 100 ms");
+                                       }
+
+                               }
+                               logger.debug("checkUpdateWorkerTimer: exit");
+                       }catch(Exception e){
+                               logger.error("checkUpdateWorkerTimer: caught unexpected exception: " + e);
+                               System.out.println(new Date() + " checkUpdateWorkerTimer - top level - caught an unexpected exception");
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       private void checkWaitTimer(){
+               synchronized(checkWaitTimerLock){
+                       try{
+                               logger.debug("checkWaitTimer: entry");
+                               Date now = new Date();
+                               long nowMs = now.getTime();
+                               long waitTimerMs = waitTimerLastRunDate.getTime();
+
+                               //give it 2 times leeway  
+                               if((nowMs - waitTimerMs)  > 2*pdpUpdateInterval){
+                                       logger.error("checkWaitTimer: nowMs - waitTimerMs = " + (nowMs - waitTimerMs) 
+                                                       + ", exceeds pdpUpdateInterval + 2000 = " + (2*pdpUpdateInterval) + " Will reschedule waitTimer timer");
+
+
+                                       try{
+                                               // Recalculate since the thread could have been stalled on the synchronize()
+                                               nowMs = (new Date()).getTime();
+                                               // Time to the start of the next pdpUpdateInterval multiple
+                                               long startMs = getDWaiterStartMs();
+                                               waitTimer.cancel();
+                                               designationWaiter = new DesignationWaiter();
+                                               waitTimer = new Timer();
+                                               waitTimerLastRunDate = new Date(nowMs + startMs);
+                                               waitTimer.scheduleAtFixedRate(designationWaiter, startMs, pdpUpdateInterval);
+                                               logger.info("checkWaitTimer: Scheduling waitTimer timer to start in " + startMs + " ms");
+                                       }catch(Exception e){
+                                               logger.error("checkWaitTimer: Caught unexpected Exception: " + e);
+                                               System.out.println(new Date() + " checkWaitTimer caught an unexpected exception");
+                                               e.printStackTrace();
+                                               // Recalculate since the thread could have been stalled on the synchronize()
+                                               nowMs = (new Date()).getTime();
+                                               // Time to the start of the next pdpUpdateInterval multiple
+                                               long startMs = getDWaiterStartMs();
+                                               designationWaiter = new DesignationWaiter();
+                                               waitTimer = new Timer();
+                                               waitTimerLastRunDate = new Date(nowMs + startMs);
+                                               waitTimer.scheduleAtFixedRate(designationWaiter, startMs, pdpUpdateInterval);
+                                               logger.info("checkWaitTimer: Scheduling waitTimer timer in " + startMs + " ms");
+                                       }
+
+                               }
+                               logger.debug("checkWaitTimer: exit");
+                       }catch(Exception e){
+                               logger.error("checkWaitTimer: caught unexpected exception: " + e);
+                               System.out.println(new Date() + " checkWaitTimer caught an unexpected exception");
+                               e.printStackTrace();
+                       }
+               }
+       }
+       
+       private long getDWaiterStartMs(){
+               Date now = new Date();
+               
+               // Retrieve the ms since the epoch
+               long nowMs = now.getTime();
+               
+               // Time since the end of the last pdpUpdateInterval multiple
+               long nowModMs = nowMs % pdpUpdateInterval;
+               
+               // Time to the start of the next pdpUpdateInterval multiple
+               long startMs = pdpUpdateInterval - nowModMs;
+
+               // Give the start time a minimum of a 5 second cushion
+               if(startMs < 5000){
+                       // Start at the beginning  of following interval
+                       startMs = pdpUpdateInterval + startMs;
+               }
+               return startMs;
+       }
+       
+       private boolean nullSafeEquals(Object one, Object two){
+               if(one == null && two == null){
+                       return true;
+               }
+               if(one != null && two != null){
+                       return one.equals(two);
+               }
+               return false;
+       }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPersistenceProperties.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPersistenceProperties.java
new file mode 100644 (file)
index 0000000..63af53c
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.util.Properties;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class DroolsPersistenceProperties {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(DroolsPersistenceProperties.class);                
+       /*
+        * droolsPersistence.properties parameter key values
+        */
+       public static final String DB_DRIVER = "javax.persistence.jdbc.driver";
+       public static final String DB_DATA_SOURCE  = "hibernate.dataSource";
+       public static final String DB_URL = "javax.persistence.jdbc.url";
+       public static final String DB_USER = "javax.persistence.jdbc.user";
+       public static final String DB_PWD = "javax.persistence.jdbc.password";
+                       
+       private static Properties properties = null;
+       /*
+        * Initialize the parameter values from the droolsPersitence.properties file values
+        * 
+        * This is designed so that the Properties object is obtained from the droolsPersistence.properties
+        * file and then is passed to this method to initialize the value of the parameters.
+        * This allows the flexibility of JUnit tests using getProperties(filename) to get the
+        * properties while runtime methods can use getPropertiesFromClassPath(filename).
+        * 
+        */
+       public static void initProperties (Properties prop){
+               logger.info("DroolsPersistenceProperties.initProperties(Properties): entry");
+               logger.info("\n\nDroolsPersistenceProperties.initProperties: Properties = \n" + prop + "\n\n");
+               
+               properties = prop;
+       }
+
+       public static String getProperty(String key){
+               return properties.getProperty(key);
+       }
+       
+       public static Properties getProperties() {
+               return properties;
+       }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSession.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSession.java
new file mode 100644 (file)
index 0000000..21a480d
--- /dev/null
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+public interface DroolsSession {
+
+       public String getPdpId();
+       public void setPdpId(String pdpId);
+       public String getSessionName();
+       public void setSessionName(String sessionName);
+       public long getSessionId();
+       public void setSessionId(long sessionId);
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSessionEntity.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSessionEntity.java
new file mode 100644 (file)
index 0000000..89e310f
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+@Entity
+public class DroolsSessionEntity implements Serializable, DroolsSession {
+       @Id
+       @Column(name="pdpId", nullable=false)
+       private String pdpId="-1";
+       @Id
+       @Column(name="sessionName", nullable=false)
+       private String sessionName="-1";
+       
+       @Column(name="sessionId", nullable=false)
+       private long sessionId=-1L;
+
+       @ManyToOne
+       private DroolsPdpEntity pdpEntity;
+       public DroolsSessionEntity(){
+               
+       }
+       @Override
+       public String getPdpId() {
+               return pdpId;
+       }
+       @Override
+       public void setPdpId(String pdpId) {
+               this.pdpId = pdpId;
+       }
+       @Override
+       public String getSessionName() {
+               return sessionName;
+       }
+       @Override
+       public void setSessionName(String sessionName) {
+               this.sessionName = sessionName;
+       }
+       @Override
+       public long getSessionId() {
+               return sessionId;
+       }
+
+       @Override
+       public void setSessionId(long sessionId) {
+               this.sessionId = sessionId;
+       }
+       public void setPdpEntity(DroolsPdpEntity pdpEntity){
+               this.pdpEntity = pdpEntity;
+       }
+       @Override
+       public boolean equals(Object other){
+               if(other instanceof DroolsSession){
+               return this.getPdpId().equals(((DroolsSession)other).getPdpId()) && this.getSessionName().equals(((DroolsSession)other).getSessionName());
+               }else{
+                       return false;
+               }
+       }
+       
+       @Override
+       public int hashCode(){
+               String combinedId = this.getPdpId().concat(":").concat(this.getSessionName());
+               return combinedId.hashCode();
+       }
+
+
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java
new file mode 100644 (file)
index 0000000..ac9255a
--- /dev/null
@@ -0,0 +1,688 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.LockModeType;
+import javax.persistence.Query;
+
+import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+
+
+public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
+
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(JpaDroolsPdpsConnector.class);
+       private EntityManagerFactory emf;
+               
+       
+       //not sure if we want to use the same entity manager factory for drools session and pass it in here, or create a new one
+       public JpaDroolsPdpsConnector(EntityManagerFactory emf){
+               this.emf = emf;         
+       }
+       @Override
+       public Collection<DroolsPdp> getDroolsPdps() {
+               //return a list of all the DroolsPdps in the database
+               EntityManager em = emf.createEntityManager();
+               try {
+                       em.getTransaction().begin();
+                       Query droolsPdpsListQuery = em.createQuery("SELECT p FROM DroolsPdpEntity p");
+                       List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.PESSIMISTIC_READ).getResultList();                
+                       LinkedList<DroolsPdp> droolsPdpsReturnList = new LinkedList<DroolsPdp>();
+                       for(Object o : droolsPdpsList){
+                               if(o instanceof DroolsPdp){
+                                       //Make sure it is not a cached version
+                                       em.refresh((DroolsPdpEntity)o);
+                                       droolsPdpsReturnList.add((DroolsPdp)o);
+                                       if (logger.isDebugEnabled()) {
+                                               DroolsPdp droolsPdp = (DroolsPdp)o;
+                                               logger.debug("getDroolsPdps: PDP=" + droolsPdp.getPdpId()
+                                                               + ", isDesignated=" + droolsPdp.isDesignated()
+                                                               + ", updatedDate=" + droolsPdp.getUpdatedDate()
+                                                               + ", priority=" + droolsPdp.getPriority());
+                                       }
+                               }
+                       }
+                       try{
+                       em.getTransaction().commit();
+                       }catch(Exception e){
+                                 logger.error
+                                       (MessageCodes.EXCEPTION_ERROR, e,"Cannot commit getDroolsPdps() transaction");
+                       }
+                       return droolsPdpsReturnList;
+               } finally {
+                       cleanup(em, "getDroolsPdps");
+               }
+       }
+
+       private boolean nullSafeEquals(Object one, Object two){
+               if(one == null && two == null){
+                       return true;
+               }
+               if(one != null && two != null){
+                       return one.equals(two);
+               }
+               return false;
+       }
+       
+       @Override
+       public void update(DroolsPdp pdp) {
+               
+               if (logger.isDebugEnabled()) {
+                       logger.debug("update: Entering, pdpId=" + pdp.getPdpId());
+               }
+               
+               //this is to update our own pdp in the database
+               EntityManager em = emf.createEntityManager();
+               try {
+                       em.getTransaction().begin();
+                       Query droolsPdpsListQuery = em.createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
+                       droolsPdpsListQuery.setParameter("pdpId", pdp.getPdpId());
+                       List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.PESSIMISTIC_WRITE).getResultList();
+                       //em.getTransaction().begin();
+                       DroolsPdpEntity droolsPdpEntity;
+                       if(droolsPdpsList.size() == 1 && (droolsPdpsList.get(0) instanceof DroolsPdpEntity)){                                           
+                               droolsPdpEntity = (DroolsPdpEntity)droolsPdpsList.get(0);                       
+                               //if(pdp.getSessionId() < 0){
+                                       //if its less than 0, then we know it is not a real session number so we want to save the one that the database has for us, to avoid information loss
+                                       //pdp.setSessionId(droolsPdpEntity.getSessionId());
+                               //}
+                               Date currentDate = new Date();
+                               long difference = currentDate.getTime()-droolsPdpEntity.getUpdatedDate().getTime();
+                               //just set some kind of default here
+                               long pdpTimeout = 15000;
+                               try{
+                                       pdpTimeout = Long.parseLong(IntegrityMonitorProperties.getProperty(IntegrityMonitorProperties.PDP_TIMEOUT));
+                               }catch(Exception e){
+                                         logger.error
+                                               (MessageCodes.EXCEPTION_ERROR, e,"Could not get PDP timeout property, using default.");
+                               }
+                               boolean isCurrent = difference<pdpTimeout;
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("update: PDP=" + pdp.getPdpId() + ", isCurrent="
+                                                       + isCurrent + ", difference=" + difference
+                                                       + ", pdpTimeout=" + pdpTimeout + ", designated="
+                                                       + droolsPdpEntity.isDesignated());
+                               }
+                       } else {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("update: For PDP=" + pdp.getPdpId()
+                                                       + ", instantiating new DroolsPdpEntity");
+                               }
+                               droolsPdpEntity = new DroolsPdpEntity();
+                               em.persist(droolsPdpEntity);
+                               droolsPdpEntity.setPdpId(pdp.getPdpId());                               
+                       }
+                       if(droolsPdpEntity.getPriority() != pdp.getPriority()){
+                               droolsPdpEntity.setPriority(pdp.getPriority());
+                       }
+                       if(!droolsPdpEntity.getUpdatedDate().equals(pdp.getUpdatedDate())){
+                               droolsPdpEntity.setUpdatedDate(pdp.getUpdatedDate());
+                       }
+                       if(!droolsPdpEntity.getDesignatedDate().equals(pdp.getDesignatedDate())){
+                               droolsPdpEntity.setDesignatedDate(pdp.getDesignatedDate());
+                       }
+                       if(!nullSafeEquals(droolsPdpEntity.getSiteName(),pdp.getSiteName())){
+                               droolsPdpEntity.setSiteName(pdp.getSiteName());
+                       }
+                       List<DroolsSessionEntity> sessionsToAdd = new LinkedList<DroolsSessionEntity>();
+                       for(DroolsSessionEntity localSession : pdp.getSessions()){
+                               boolean found = false;
+                               for(DroolsSessionEntity dbSession : droolsPdpEntity.getSessions()){
+                                       if(localSession.equals(dbSession)){
+                                               found = true;
+                                               dbSession.setSessionId(localSession.getSessionId());
+                                       }
+                               }
+                               if(!found){
+                                       sessionsToAdd.add(localSession);
+                               }
+
+                       }
+                       for(DroolsSessionEntity sessionToAdd : sessionsToAdd){
+                               em.persist(sessionToAdd);
+                               droolsPdpEntity.getSessions().add(sessionToAdd);
+                       }               
+
+                       
+                       if(droolsPdpEntity.isDesignated() != pdp.isDesignated()){
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("update: pdpId=" + pdp.getPdpId()
+                                                       + ", pdp.isDesignated=" + pdp.isDesignated()
+                                                       + ", droolsPdpEntity.pdpId="
+                                                       + droolsPdpEntity.getPdpId()
+                                                       + ", droolsPdpEntity.isDesignated="
+                                                       + droolsPdpEntity.isDesignated());
+                               }
+                               droolsPdpEntity.setDesignated(pdp.isDesignated());
+                       }
+                       em.getTransaction().commit();
+               } finally {
+                       cleanup(em, "update");
+               }
+               
+               if (logger.isDebugEnabled()) {
+                       logger.debug("update: Exiting");
+               }
+
+       }
+
+       /*
+        * Note: A side effect of this boolean method is that if the PDP is designated but not current, the 
+        * droolspdpentity.DESIGNATED column will be set to false (the PDP will be un-designated, i.e. marked as
+        * being in standby mode)
+        */
+       @Override
+       public boolean isPdpCurrent(DroolsPdp pdp) {
+               
+               boolean isCurrent = isCurrent(pdp);
+               
+               EntityManager em = emf.createEntityManager();
+               try{
+               if(!isCurrent && pdp.isDesignated()){
+                       em.getTransaction().begin();
+                       Query droolsPdpsListQuery = em.createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
+                       droolsPdpsListQuery.setParameter("pdpId", pdp.getPdpId());
+                       List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.PESSIMISTIC_WRITE).getResultList();
+                       if(droolsPdpsList.size() == 1 && droolsPdpsList.get(0) instanceof DroolsPdpEntity){                     
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("isPdpCurrent: PDP=" + pdp.getPdpId() + " designated but not current; setting designated to false");
+                               }
+                               DroolsPdpEntity droolsPdpEntity = (DroolsPdpEntity)droolsPdpsList.get(0);
+                               droolsPdpEntity.setDesignated(false);
+                               em.getTransaction().commit();
+                       } else {
+                               logger.warn("isPdpCurrent: PDP=" + pdp.getPdpId() + " is designated but not current; however it does not have a DB entry, so cannot set DESIGNATED to false!");
+                       }
+               } else {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("isPdpCurrent: For PDP=" + pdp.getPdpId()
+                                               + ", designated="
+                                               + pdp.isDesignated() + ", isCurrent=" + isCurrent);
+                       }
+               }
+               }catch(Exception e){
+                         logger.error
+                               (MessageCodes.EXCEPTION_ERROR, e,"Could not update expired record marked as designated in the database");
+               } finally {
+                       cleanup(em, "isPdpCurrent");
+               }
+               return isCurrent;
+               
+       }
+       
+       @Override
+       public void setDesignated(DroolsPdp pdp, boolean designated) {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("setDesignated: Entering, pdpId='" + pdp.getPdpId()
+                                       + "', designated=" + designated);
+               }
+
+               EntityManager em = null;
+               try {
+                       em = emf.createEntityManager();
+                       em.getTransaction().begin();
+                       Query droolsPdpsListQuery = em
+                                       .createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
+                       droolsPdpsListQuery.setParameter("pdpId", pdp.getPdpId());
+                       List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(
+                                       LockModeType.PESSIMISTIC_WRITE).getResultList();
+                       if (droolsPdpsList.size() == 1
+                                       && droolsPdpsList.get(0) instanceof DroolsPdpEntity) {
+                               DroolsPdpEntity droolsPdpEntity = (DroolsPdpEntity) droolsPdpsList
+                                               .get(0);
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("setDesignated: PDP=" + pdp.getPdpId()
+                                                       + " found, designated="
+                                                       + droolsPdpEntity.isDesignated() + ", setting to "
+                                                       + designated);
+                               }
+                               droolsPdpEntity.setDesignated(designated);
+                               em.getTransaction().commit();
+                       } else {
+                               logger.error("setDesignated: PDP=" + pdp.getPdpId()
+                                               + " not in DB; cannot update designation");
+                       }
+               } catch (Exception e) {
+                       logger.error("setDesignated: Caught Exception, message='"
+                                       + e.getMessage() + "'");
+               } finally {
+                       cleanup(em, "setDesignated");
+               }
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("setDesignated: Exiting");
+               }
+
+       }
+       
+       
+       @Override
+       public void standDownPdp(String pdpId) {
+               
+               logger.info("standDownPdp: Entering, pdpId='" + pdpId + "'");
+
+               EntityManager em = null;
+               try {
+                       /*
+                        * Start transaction.
+                        */
+                       em = emf.createEntityManager();
+                       em.getTransaction().begin();
+
+                       /*
+                        * Get droolspdpentity record for this PDP and mark DESIGNATED as
+                        * false.
+                        */
+                       Query droolsPdpsListQuery = em
+                                       .createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
+                       droolsPdpsListQuery.setParameter("pdpId", pdpId);
+                       List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(
+                                       LockModeType.PESSIMISTIC_WRITE).getResultList();
+                       DroolsPdpEntity droolsPdpEntity;
+                       if (droolsPdpsList.size() == 1
+                                       && (droolsPdpsList.get(0) instanceof DroolsPdpEntity)) {
+                               droolsPdpEntity = (DroolsPdpEntity) droolsPdpsList.get(0);
+                               droolsPdpEntity.setDesignated(false);
+                               em.persist(droolsPdpEntity);
+                               logger.info("standDownPdp: PDP=" + pdpId + " persisted as non-designated.");
+                       } else {
+                               logger.error("standDownPdp: Missing record in droolspdpentity for pdpId="
+                                               + pdpId + "; cannot stand down PDP");
+                       }
+
+                       /*
+                        * End transaction.
+                        */
+                       em.getTransaction().commit();
+                       cleanup(em, "standDownPdp");
+                       em = null;
+                       
+                       // Keep the election handler in sync with the DB
+                       DroolsPdpsElectionHandler.setMyPdpDesignated(false);
+
+               } catch (Exception e) {
+                       logger.error("standDownPdp: Unexpected Exception attempting to mark DESIGNATED as false for droolspdpentity, pdpId="
+                                       + pdpId
+                                       + ".  Cannot stand down PDP; message="
+                                       + e.getMessage());
+               } finally {
+                       cleanup(em, "standDownPdp");
+               }
+               
+               logger.info("standDownPdp: Exiting");
+
+       }
+       
+       /*
+        * Determines whether or not a designated PDP has failed.
+        * 
+        * Note: The update method, which is run periodically by the
+        * TimerUpdateClass, will un-designate a PDP that is stale.
+        */
+       @Override
+       public boolean hasDesignatedPdpFailed(Collection<DroolsPdp> pdps) {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("hasDesignatedPdpFailed: Entering, pdps.size()="
+                                       + pdps.size());
+               }
+
+               boolean failed = true;
+               boolean foundDesignatedPdp = false;
+
+               for (DroolsPdp pdp : pdps) {
+
+                       /*
+                        * Normally, the update method will un-designate any stale PDP, but
+                        * we check here to see if the PDP has gone stale since the update
+                        * method was run.
+                        * 
+                        * Even if we determine that the designated PDP is current, we keep
+                        * going (we don't break), so we can get visibility into the other
+                        * PDPs, when in DEBUG mode.
+                        */
+                       if (pdp.isDesignated() && isCurrent(pdp)) {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("hasDesignatedPdpFailed: Designated PDP="
+                                                       + pdp.getPdpId() + " is current");
+                               }
+                               failed = false;
+                               foundDesignatedPdp = true;
+                       } else if (pdp.isDesignated() && !isCurrent(pdp)) {
+                               logger.error("hasDesignatedPdpFailed: Designated PDP="
+                                               + pdp.getPdpId() + " has failed");
+                               foundDesignatedPdp = true;
+                       } else {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("hasDesignatedPdpFailed: PDP="
+                                                       + pdp.getPdpId() + " is not designated");
+                               }
+                       }
+               }
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("hasDesignatedPdpFailed: Exiting and returning, foundDesignatedPdp="
+                                       + foundDesignatedPdp);
+               }
+               return failed;
+       }
+       
+       
+       private boolean isCurrent(DroolsPdp pdp) {
+       
+               if (logger.isDebugEnabled()) {
+                       logger.debug("isCurrent: Entering, pdpId="
+                                       + pdp.getPdpId());
+               }
+       
+               boolean current = false;
+       
+               // Return if the current PDP is considered "current" based on whatever
+               // time box that may be.
+               // If the the PDP is not current, we should mark it as not primary in
+               // the database
+               Date currentDate = new Date();
+               long difference = currentDate.getTime()
+                               - pdp.getUpdatedDate().getTime();
+               // just set some kind of default here
+               long pdpTimeout = 15000;
+               try {
+                       pdpTimeout = Long.parseLong(IntegrityMonitorProperties
+                                       .getProperty(IntegrityMonitorProperties.PDP_TIMEOUT));
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("isCurrent: pdp.timeout=" + pdpTimeout);
+                       }               
+               } catch (Exception e) {
+                         logger.error
+                               (MessageCodes.EXCEPTION_ERROR, e,
+                                       "isCurrent: Could not get PDP timeout property, using default.");
+               }
+               current = difference < pdpTimeout;
+       
+               if (logger.isDebugEnabled()) {
+                       logger.debug("isCurrent: Exiting, difference="
+                                       + difference + ", pdpTimeout=" + pdpTimeout
+                                       + "; returning current=" + current);
+               }
+       
+               return current;
+       }
+       
+       
+       /*
+        * Currently this method is only used in a JUnit test environment. Gets a
+        * PDP record from droolspdpentity table.
+        */
+       @Override
+       public DroolsPdpEntity getPdp(String pdpId) {
+       
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getPdp: Entering and getting PDP with pdpId='" + pdpId
+                                       + "'");
+               }
+       
+               DroolsPdpEntity droolsPdpEntity = null;
+       
+               EntityManager em = null;
+               try {
+                       em = emf.createEntityManager();
+                       em.getTransaction().begin();
+                       Query droolsPdpsListQuery = em
+                                       .createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
+                       droolsPdpsListQuery.setParameter("pdpId", pdpId);
+                       List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(
+                                       LockModeType.PESSIMISTIC_WRITE).getResultList();
+                       if (droolsPdpsList.size() == 1
+                                       && droolsPdpsList.get(0) instanceof DroolsPdpEntity) {
+                               droolsPdpEntity = (DroolsPdpEntity) droolsPdpsList.get(0);
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("getPdp: PDP=" + pdpId
+                                                       + " found, isDesignated="
+                                                       + droolsPdpEntity.isDesignated() + ", updatedDate="
+                                                       + droolsPdpEntity.getUpdatedDate() + ", priority="
+                                                       + droolsPdpEntity.getPriority());                                                       
+                               }
+                               
+                               // Make sure the droolsPdpEntity is not a cached version
+                               em.refresh(droolsPdpEntity);
+                               
+                               em.getTransaction().commit();
+                       } else {
+                               logger.error("getPdp: PDP=" + pdpId + " not found!?");
+                       }
+               } catch (Exception e) {
+                         logger.error
+                               (MessageCodes.EXCEPTION_ERROR, e,"getPdp: Caught Exception attempting to get PDP, message='"
+                                       + e.getMessage() + "'");
+               } finally {
+                       cleanup(em, "getPdp");
+               }
+       
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getPdp: Returning droolsPdpEntity=" + droolsPdpEntity);
+               }
+               return droolsPdpEntity;
+       
+       }
+       
+       /*
+        * Normally this method should only be used in a JUnit test environment.
+        * Manually inserts a PDP record in droolspdpentity table.
+        */
+       @Override
+       public void insertPdp(DroolsPdp pdp) {
+
+               logger.info("insertPdp: Entering and manually inserting PDP");
+
+               /*
+                * Start transaction
+                */
+               EntityManager em = emf.createEntityManager();
+               try {
+                       em.getTransaction().begin();
+
+                       /*
+                        * Insert record.
+                        */
+                       DroolsPdpEntity droolsPdpEntity = new DroolsPdpEntity();
+                       em.persist(droolsPdpEntity);
+                       droolsPdpEntity.setPdpId(pdp.getPdpId());
+                       droolsPdpEntity.setDesignated(pdp.isDesignated());
+                       droolsPdpEntity.setPriority(pdp.getPriority());
+                       droolsPdpEntity.setUpdatedDate(pdp.getUpdatedDate());
+                       droolsPdpEntity.setSiteName(pdp.getSiteName());
+
+                       /*
+                        * End transaction.
+                        */
+                       em.getTransaction().commit();
+               } finally {
+                       cleanup(em, "insertPdp");
+               }
+
+               logger.info("insertPdp: Exiting");
+
+       }
+       
+       /*
+        * Normally this method should only be used in a JUnit test environment.
+        * Manually deletes all PDP records in droolspdpentity table.
+        */
+       @Override
+       public void deleteAllPdps() {
+       
+               logger.info("deleteAllPdps: Entering");
+       
+               /*
+                * Start transaction
+                */
+               EntityManager em = emf.createEntityManager();
+               try {
+                       em.getTransaction().begin();
+       
+                       Query droolsPdpsListQuery = em
+                                       .createQuery("SELECT p FROM DroolsPdpEntity p");
+                       @SuppressWarnings("unchecked")
+                       List<DroolsPdp> droolsPdpsList = droolsPdpsListQuery.setLockMode(
+                                       LockModeType.NONE).getResultList();
+                       logger.info("deleteAllPdps: Deleting " + droolsPdpsList.size() + " PDPs");
+                       for (DroolsPdp droolsPdp : droolsPdpsList) {
+                               String pdpId = droolsPdp.getPdpId();
+                               deletePdp(pdpId);
+                       }
+       
+                       /*
+                        * End transaction.
+                        */
+                       em.getTransaction().commit();
+               } finally {
+                       cleanup(em, "deleteAllPdps");
+               }
+               
+               logger.info("deleteAllPdps: Exiting");
+       
+       }
+       
+       /*
+        * Normally this method should only be used in a JUnit test environment.
+        * Manually deletes a PDP record in droolspdpentity table.
+        */
+       @Override
+       public void deletePdp(String pdpId) {
+       
+               logger.info("deletePdp: Entering and manually deleting pdpId='" + pdpId
+                               + "'");
+       
+               /*
+                * Start transaction
+                */
+               EntityManager em = emf.createEntityManager();
+               try {
+                       em.getTransaction().begin();
+               
+                       /*
+                        * Delete record.
+                        */
+                       DroolsPdpEntity droolsPdpEntity = em.find(DroolsPdpEntity.class, pdpId);
+                       if (droolsPdpEntity != null) {
+                               logger.info("deletePdp: Removing PDP");
+                               em.remove(droolsPdpEntity);
+                       } else {
+                               logger.info("deletePdp: PDP with ID='" + pdpId
+                                               + "' not currently in DB");
+                       }
+
+                       /*
+                        * End transaction.
+                        */
+                       em.getTransaction().commit();
+               } finally {
+                       cleanup(em, "deletePdp");
+               }
+       
+               logger.info("deletePdp: Exiting");
+       
+       }
+       
+       /*
+        * Normally this method should only be used in a JUnit test environment.
+        * Manually deletes all records in droolsessionentity table.
+        */
+       @Override
+       public void deleteAllSessions() {
+
+               logger.info("deleteAllSessions: Entering");
+
+               /*
+                * Start transaction
+                */
+               EntityManager em = emf.createEntityManager();
+
+               try {
+                       em.getTransaction().begin();
+
+                       Query droolsSessionListQuery = em
+                                       .createQuery("SELECT p FROM DroolsSessionEntity p");
+                       @SuppressWarnings("unchecked")
+                       List<DroolsSession> droolsSessionsList = droolsSessionListQuery.setLockMode(
+                                       LockModeType.NONE).getResultList();
+                       logger.info("deleteAllSessions: Deleting " + droolsSessionsList.size() + " Sessions");
+                       for (DroolsSession droolsSession : droolsSessionsList) {
+                               logger.info("deleteAllSessions: Deleting droolsSession with pdpId="
+                                               + droolsSession.getPdpId() + " and sessionId="
+                                               + droolsSession.getSessionId());
+                               em.remove(droolsSession);
+                       }
+
+                       /*
+                        * End transaction.
+                        */
+                       em.getTransaction().commit();
+               } finally {
+                       cleanup(em, "deleteAllSessions");
+               }               
+               logger.info("deleteAllSessions: Exiting");
+
+       }
+       
+       
+       /*
+        * Close the specified EntityManager, rolling back any pending transaction
+        *
+        * @param em the EntityManager to close ('null' is OK)
+        * @param method the invoking Java method (used for log messages)
+        */
+       private static void cleanup(EntityManager em, String method)
+       {
+               if (em != null) {
+                       if (em.isOpen()) {
+                               if (em.getTransaction().isActive()) {
+                                       // there is an active EntityTransaction -- roll it back
+                                       try {
+                                               em.getTransaction().rollback();
+                                       } catch (Exception e) {
+                                               logger.error(method + ": Caught Exception attempting to rollback EntityTransaction, message='"
+                                                                                  + e.getMessage() + "'");
+                                       }
+                               }
+
+                               // now, close the EntityManager
+                               try {
+                                       em.close();
+                               } catch (Exception e) {
+                                       logger.error(method + ": Caught Exception attempting to close EntityManager, message='"
+                                                                          + e.getMessage() + "'");
+                               }
+                       }
+               }
+       }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java
new file mode 100644 (file)
index 0000000..e2c7f40
--- /dev/null
@@ -0,0 +1,614 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.kie.api.KieServices;
+import org.kie.api.runtime.Environment;
+import org.kie.api.runtime.EnvironmentName;
+import org.kie.api.runtime.KieSession;
+import org.kie.api.runtime.KieSessionConfiguration;
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.ia.IntegrityAuditProperties;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
+import org.openecomp.policy.drools.core.DroolsPDPIntegrityMonitor;
+import org.openecomp.policy.drools.core.FeatureAPI;
+import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
+import org.openecomp.policy.drools.core.PolicyContainer;
+import org.openecomp.policy.drools.core.PolicySession;
+import org.openecomp.policy.drools.im.PMStandbyStateChangeNotifier;
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+import bitronix.tm.Configuration;
+import bitronix.tm.TransactionManagerServices;
+import bitronix.tm.resource.jdbc.PoolingDataSource;
+
+/**
+ * If this feature is supported, there is a single instance of it.
+ * It adds persistence to Drools sessions, but it is also intertwined with
+ * active/standby state management and IntegrityMonitor. For now, they are
+ * all treated as a single feature, but it would be nice to separate them.
+ *
+ * The bulk of the code here was once in other classes, such as
+ * 'PolicyContainer' and 'Main'. It was moved here as part of making this
+ * a separate optional feature.
+ */
+public class PersistenceFeature implements FeatureAPI
+{
+  // get an instance of logger
+  private static Logger logger =
+       FlexLogger.getLogger(PersistenceFeature.class);
+
+  // 'KieServices' singleton
+  static private KieServices kieServices = KieServices.Factory.get();
+
+  private static DroolsPdp myPdp;
+  private static Object myPdpSync = new Object();
+  private static DroolsPdpsElectionHandler electionHandler;
+
+  // indicates whether persistence has been disabled
+  private static boolean persistenceDisabled = false;
+
+  /*
+   * Used by JUnit testing to verify whether or not audit is running.
+   */
+  private static IntegrityAudit integrityAudit = null;
+
+  /**
+   * Lookup the adjunct for this feature that is associated with the
+   * specified PolicyContainer. If not found, create one.
+   *
+   * @param policyContainer the container whose adjunct we are looking up,
+   *   and possibly creating
+   * @return the associated 'ContainerAdjunct' instance, which may be new
+   */
+  private ContainerAdjunct getContainerAdjunct(PolicyContainer policyContainer)
+  {
+       Object rval = policyContainer.getAdjunct(this);
+       if (rval == null || ! (rval instanceof ContainerAdjunct))
+         {
+               // adjunct does not exist, or has the wrong type (should never happen)
+               rval = new ContainerAdjunct(policyContainer);
+               policyContainer.setAdjunct(this, rval);
+         }
+       return((ContainerAdjunct)rval);
+  }
+
+  /**************************/
+  /* 'FeatureAPI' interface */
+  /**************************/
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public int getSequenceNumber()
+  {
+       return(1);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void globalInit(String args[], String configDir)
+  {
+       // Initialization code associated with 'PolicyContainer'
+       DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor = null;
+       try
+         {
+               droolsPdpIntegrityMonitor = DroolsPDPIntegrityMonitor.init(configDir);
+         }
+       catch (Exception e)
+         {
+               logger.error(MessageCodes.EXCEPTION_ERROR, e,
+                                        "main", "DroolsPDPIntegrityMonitor.init()");
+         }
+
+       initializePersistence(configDir, droolsPdpIntegrityMonitor);
+
+       // 1. Start Integrity Monitor (unless it was specifically disabled in the CORE layer
+               
+               
+       if (persistenceDisabled) {
+         System.out.println("WARNING: Starting Engine with Persistance disabled");
+         logger.warn("Starting Engine with Persistance disabled");
+       } else {
+         DroolsPDPIntegrityMonitor im = null;
+         //At this point the DroolsPDPIntegrityMonitor instance must exist
+         try {
+               im = DroolsPDPIntegrityMonitor.getInstance();
+         } catch (Exception e1) {
+               String msg = "policy-core startup failed to get DroolsPDPIntegrityMonitor instance:  \n" + e1;
+               System.out.println(msg);
+               e1.printStackTrace();
+         }
+         //Now get the StateManagement instance so we can register our observer
+         StateManagement sm = im.getStateManager();
+                       
+         //Create an instance of the Observer
+         PMStandbyStateChangeNotifier pmNotifier = new PMStandbyStateChangeNotifier();
+                       
+         //Register the PMStandbyStateChangeNotifier Observer
+         sm.addObserver(pmNotifier);
+       }
+  }
+
+  /**
+   * This is a hook to create a new persistent KieSession.
+   *
+   * {@inheritDoc}
+   */
+  @Override
+       public KieSession activatePolicySession
+       (PolicyContainer policyContainer, String name, String kieBaseName)
+  {
+       return(getContainerAdjunct(policyContainer)
+                  .newPersistentKieSession(name, kieBaseName));
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void disposeKieSession(PolicySession policySession)
+  {
+       // TODO: There should be one data source per session
+       getContainerAdjunct(policySession.getPolicyContainer())
+         .disposeKieSession();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void destroyKieSession(PolicySession policySession)
+  {
+       // TODO: There should be one data source per session
+       getContainerAdjunct(policySession.getPolicyContainer())
+         .destroyKieSession();
+  }
+  
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void beforeStartEngine() 
+   {
+        return;
+   }
+  
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+   public void afterStartEngine() 
+  {
+       PolicyEngine.manager.lock();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void beforeShutdownEngine() 
+  {
+         return;
+  }
+  
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void beforeCreateController(String name, Properties properties) 
+  {
+         return;
+  }
+  
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public void afterCreateController(String name) 
+  {
+         return;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+   public void afterShutdownEngine() 
+  {
+       return;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+   public void beforeStartController(String name) 
+  {
+         return;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+   public void afterStartController(String name) 
+  {
+         return;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+       public boolean isPersistenceEnabled()
+  {
+       return(!persistenceDisabled);
+  }
+
+  /**************************/
+
+  /**
+   * @return 'true' if Drools persistence is disabled, and 'false' if not
+   */
+  static public boolean getPersistenceDisabled()
+  {
+       return(persistenceDisabled);
+  }
+
+  /**
+   * Read in the persistence properties, determine whether persistence is
+   * enabled or disabled, and initialize persistence if enabled.
+   */
+  private static void initializePersistence(String configDir, DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor)
+  {
+         
+               try {
+                       Properties pDrools = PropertyUtil.getProperties(configDir
+                                       + "/droolsPersistence.properties");
+                       DroolsPersistenceProperties.initProperties(pDrools);
+                       Properties pXacml = PropertyUtil.getProperties(configDir
+                                       + "/xacmlPersistence.properties");
+                       XacmlPersistenceProperties.initProperties(pXacml);
+                       if ("true".equals(pDrools.getProperty("persistenceDisabled"))) {
+                               // 'persistenceDisabled' only relates to the 'drools'
+                               // database. The fact that integrityMonitor/xacml depends upon
+                               // persistence is an implementation detail there (which can't
+                               // currently be disabled), and doesn't directly affect
+                               // 'policy-core'.
+                               persistenceDisabled = true;
+                       } 
+               } catch (IOException e1) {
+                       logger.error(MessageCodes.MISS_PROPERTY_ERROR, e1,
+                                       "initializePersistence");
+               }
+                 
+           /*
+            * Might as well handle the Integrity Monitor properties here, too.
+            */
+           try {
+                 Properties pIm =
+                   PropertyUtil.getProperties(configDir + "/IntegrityMonitor.properties");
+                 IntegrityMonitorProperties.initProperties(pIm);
+                 logger.info("initializePersistence: resourceName=" + IntegrityMonitorProperties.getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID));
+           } catch (IOException e1) {
+                 logger.error(MessageCodes.MISS_PROPERTY_ERROR, e1, "initializePersistence");
+           }
+         
+
+               if (persistenceDisabled) {
+                       // The persistence design is tied to 'DroolsPdpsElectionHandler',
+                       // so we should bypass that as well. This also means that we
+                       // won't get active/standby notifications, so we need to go
+                       // into the 'active' state in order to have any 'PolicySession'
+                       // instances.
+                       return;
+               }
+
+           DroolsPdpsConnector conn = getDroolsPdpsConnector("ncompPU");
+               String uniquePdpId = IntegrityMonitorProperties.getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+               if(uniquePdpId == null){
+                       throw new NullPointerException();
+               }
+               
+               /*
+                * In a JUnit test environment, one or more PDPs may already have been
+                * inserted in the DB, so we need to check for this.
+                */
+               DroolsPdp existingPdp = conn.getPdp(uniquePdpId);
+               if (existingPdp != null) {
+                       System.out.println("Found existing PDP record, pdpId="
+                                       + existingPdp.getPdpId() + ", isDesignated="
+                                       + existingPdp.isDesignated() + ", updatedDate="
+                                       + existingPdp.getUpdatedDate());
+                       myPdp = existingPdp;
+               }
+               
+           /*
+            * Kick off integrity audit for Drools DB.
+            */
+           startIntegrityAudit(configDir);
+                               
+               synchronized(myPdpSync){
+                       if(myPdp == null){
+
+                               myPdp = new DroolsPdpImpl(uniquePdpId,false,4,new Date());      
+                       }
+                       if(myPdp != null){
+                               String site_name = "";
+                               site_name = IntegrityMonitorProperties.getProperty(IntegrityMonitorProperties.SITE_NAME);
+                               if (site_name == null) {
+                                       site_name = "";
+                               }else{
+                                       site_name = site_name.trim();
+                               }
+                               myPdp.setSiteName(site_name);
+                       }
+                       if(electionHandler == null){
+               electionHandler = new DroolsPdpsElectionHandler(conn,myPdp,droolsPdpIntegrityMonitor);
+                       }
+               }
+               Configuration bitronixConfiguration = TransactionManagerServices.getConfiguration();
+               bitronixConfiguration.setJournal(null);
+               bitronixConfiguration.setServerId(uniquePdpId);
+               System.out.println("\n\nThis controller is a standby, waiting to be chosen as primary...\n\n");
+               logger.info("\n\nThis controller is a standby, waiting to be chosen as primary...\n\n");
+  }
+
+       private static void startIntegrityAudit(String configDir) {
+
+               logger.info("startIntegrityAudit: Entering, configDir='" + configDir
+                               + "'");
+
+               /*
+                * Initialize Integrity Audit properties. file.
+                */
+               try {
+
+                       String resourceName = IntegrityMonitorProperties
+                                       .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+                       /*
+                        * Load properties for auditing of Drools DB.
+                        */
+                       Properties droolsPia = PropertyUtil.getProperties(configDir
+                                       + "/IntegrityMonitor.properties");
+
+                       /*
+                        * Supplement properties specific to the IntegrityMonitor (e.g.
+                        * site_name, node_type, resource.name) with properties specific to
+                        * persisting Drools DB entities (see
+                        * ../policy-core/src/main/resources/persistence.xml)
+                        * 
+                        * Note: integrity_audit_period_seconds is defined in
+                        * IntegrityMonitor.properties, rather than creating a whole new
+                        * "IntegrityAudit.properties" file for just one property.
+                        */
+                       droolsPia
+                                       .setProperty(
+                                                       IntegrityAuditProperties.DB_DRIVER,
+                                                       DroolsPersistenceProperties
+                                                                       .getProperty(DroolsPersistenceProperties.DB_DRIVER));
+                       droolsPia.setProperty(IntegrityAuditProperties.DB_PWD,
+                                       DroolsPersistenceProperties
+                                                       .getProperty(DroolsPersistenceProperties.DB_PWD));
+                       droolsPia.setProperty(IntegrityAuditProperties.DB_URL,
+                                       DroolsPersistenceProperties
+                                                       .getProperty(DroolsPersistenceProperties.DB_URL));
+                       droolsPia.setProperty(IntegrityAuditProperties.DB_USER,
+                                       DroolsPersistenceProperties
+                                                       .getProperty(DroolsPersistenceProperties.DB_USER));
+
+                       /*
+                        * Start audit for Drools DB.
+                        */
+                       integrityAudit = new IntegrityAudit(
+                                       resourceName, "ncompPU", droolsPia);
+                       integrityAudit.startAuditThread();
+
+               } catch (IOException e1) {
+                       logger.error(
+                                       MessageCodes.MISS_PROPERTY_ERROR,
+                                       e1,
+                                       "initializePersistence: IntegrityAuditProperties: "
+                                                       + e1.getMessage());
+               } catch (Exception e2) {
+                       logger.error(
+                                       MessageCodes.EXCEPTION_ERROR,
+                                       e2,
+                                       "initializePersistence: IntegrityAuditProperties: "
+                                                       + e2.getMessage());
+               }
+
+               logger.debug("startIntegrityAudit: Exiting");
+
+       }
+  
+       /*
+        * Moved code to instantiate a JpaDroolsPdpsConnector object from main() to
+        * this method, so it can also be accessed from StandbyStateChangeNotifier
+        * class.
+        */
+       public static DroolsPdpsConnector getDroolsPdpsConnector(String pu) {
+
+               Map<String, Object> propMap = new HashMap<String, Object>();
+               propMap.put("javax.persistence.jdbc.driver", DroolsPersistenceProperties
+                               .getProperty(DroolsPersistenceProperties.DB_DRIVER));
+               propMap.put("javax.persistence.jdbc.url",
+                               DroolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_URL));
+               propMap.put("javax.persistence.jdbc.user", DroolsPersistenceProperties
+                               .getProperty(DroolsPersistenceProperties.DB_USER));
+               propMap.put("javax.persistence.jdbc.password",
+                               DroolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_PWD));
+
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+                               pu, propMap);
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emf);
+
+               return conn;
+       }
+
+       /*
+        * IntegrityAudit instance is needed by JUnit testing to ascertain whether
+        * or not audit is running.
+        */
+       public static IntegrityAudit getIntegrityAudit() {
+
+               return integrityAudit;
+
+       }
+
+  /* ============================================================ */
+
+  /**
+   * Each instance of this class is a logical extension of a 'PolicyContainer'
+   * instance. It's reference is stored in the 'adjuncts' table within the
+   * 'PolicyContainer', and will be garbage-collected with the container.
+   */
+  class ContainerAdjunct
+  {
+       // this is the 'PolicyContainer' instance that this adjunct is extending
+       private PolicyContainer policyContainer;
+       private PoolingDataSource ds = null;
+
+       /**
+        * Constructor - initialize a new 'ContainerAdjunct'
+        *
+        * @param policyContainer the 'PolicyContainer' instance this adjunct
+        *              is extending
+        */
+       ContainerAdjunct(PolicyContainer policyContainer)
+       {
+         this.policyContainer = policyContainer;
+       }
+
+       /**
+        * Create a new persistent KieSession. If there is already a corresponding
+        * entry in the database, it is used to initialize the KieSession. If not,
+        * a completely new session is created.
+        *
+        * @param name the name of the KieSession (which is also the name of
+        *      the associated PolicySession)
+        * @param kieBaseName the name of the 'KieBase' instance containing
+        *      this session
+        * @return a new KieSession with persistence enabled (if persistence is
+        *      disabled, 'null' is returned
+        */
+       private KieSession newPersistentKieSession(String name, String kieBaseName)
+       {
+         if (persistenceDisabled)
+               {
+                 return(null);
+               }
+         long desiredSessionId = -1;
+         synchronized (myPdpSync) {
+               
+       
+       
+               for(DroolsSession droolsSession : electionHandler.getSessions()){
+                 if(droolsSession.getSessionName().equals(name)){
+                       desiredSessionId = droolsSession.getSessionId();
+                 }
+               }
+         }
+         System.out.println("\n\nThis controller is primary... coming up with session "+desiredSessionId+"\n\n");
+         logger.info("\n\nThis controller is primary... coming up with session "+desiredSessionId+"\n\n");
+         Map<String, Object> props = new HashMap<String, Object>();
+         props.put("URL", DroolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_URL));
+         props.put("user", DroolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_USER));
+         props.put("password", DroolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_PWD));
+         props.put("dataSource",DroolsPersistenceProperties.getProperty(DroolsPersistenceProperties.DB_DATA_SOURCE));
+         logger.info("getPolicySession:session does not exist -- attempt to create one with name " + name);
+         // session does not exist -- attempt to create one
+         System.getProperties().put("java.naming.factory.initial","bitronix.tm.jndi.BitronixInitialContextFactory");
+         Environment env = kieServices.newEnvironment();
+         //kContainer.newKieBase(null);
+         ds = new PoolingDataSource();                 
+         ds.setUniqueName("jdbc/BitronixJTADataSource"+name);
+         ds.setClassName( (String)props.remove("dataSource"));
+         //ds.setClassName( "org.h2.Driver" );
+         ds.setMaxPoolSize( 3 );
+         ds.setIsolationLevel("SERIALIZABLE");
+         ds.setAllowLocalTransactions( true );
+         //ds.getDriverProperties().put( "user", "sa" );
+         //ds.getDriverProperties().put( "password", "" );
+         //ds.getDriverProperties().put( "URL", "jdbc:h2:tcp://localhost/drools" );
+         ds.getDriverProperties().putAll(props);
+         ds.init();    
+         Properties emfProperties = new Properties();
+         emfProperties.setProperty(PersistenceUnitProperties.JTA_DATASOURCE, "jdbc/BitronixJTADataSource"+name);
+         env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, Persistence.createEntityManagerFactory("ncompsessionsPU",emfProperties));
+         env.set(EnvironmentName.TRANSACTION_MANAGER,TransactionManagerServices.getTransactionManager());
+         KieSessionConfiguration kConf = KieServices.Factory.get().newKieSessionConfiguration();
+         KieSession kieSession;
+         try{
+               kieSession = kieServices.getStoreServices().loadKieSession(desiredSessionId, policyContainer.getKieContainer().getKieBase(kieBaseName), kConf, env);
+               System.out.println("LOADING We can load session "+desiredSessionId+", going to create a new one");
+               logger.info("LOADING We can load session "+desiredSessionId+", going to create a new one");
+         }catch(Exception e){
+               System.out.println("LOADING We cannot load session "+desiredSessionId+", going to create a new one");
+
+               logger.info("LOADING We cannot load session "+desiredSessionId+", going to create a new one");
+               kieSession = kieServices.getStoreServices().newKieSession(policyContainer.getKieContainer().getKieBase(kieBaseName), null, env);
+               System.out.println("LOADING CREATED "+kieSession.getIdentifier());
+               logger.info("LOADING CREATED "+kieSession.getIdentifier());
+         }
+         synchronized (myPdpSync) {
+               myPdp.setSessionId(name,kieSession.getIdentifier());
+               electionHandler.updateMyPdp();
+         }
+         return(kieSession);
+       }
+
+       private void disposeKieSession()
+       {
+       if (ds != null)
+         {
+               ds.close();
+               ds = null;
+         }
+       }
+
+       private void destroyKieSession()
+       {
+         // does the same thing as 'dispose'
+         disposeKieSession();
+       }
+  }
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/ThreadRunningChecker.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/ThreadRunningChecker.java
new file mode 100644 (file)
index 0000000..ccec824
--- /dev/null
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+public interface ThreadRunningChecker {
+       public void checkThreadStatus();
+
+}
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/XacmlPersistenceProperties.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/XacmlPersistenceProperties.java
new file mode 100644 (file)
index 0000000..7e2388e
--- /dev/null
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.persistence;
+
+import java.util.Properties;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+
+public class XacmlPersistenceProperties {
+       // get an instance of logger 
+       private static Logger  logger = FlexLogger.getLogger(XacmlPersistenceProperties.class); 
+       /*
+        * xacmlPersistence.properties parameter key values
+        */
+       public static final String DB_DRIVER = "javax.persistence.jdbc.driver";
+       public static final String DB_DATA_SOURCE  = "hibernate.dataSource";
+       public static final String DB_URL = "javax.persistence.jdbc.url";
+       public static final String DB_USER = "javax.persistence.jdbc.user";
+       public static final String DB_PWD = "javax.persistence.jdbc.password";
+               
+       private static Properties properties = null;
+       /*
+        * Initialize the parameter values from the droolsPersitence.properties file values
+        * 
+        * This is designed so that the Properties object is obtained from the xacmlPersistence.properties
+        * file and then is passed to this method to initialize the value of the parameters.
+        * This allows the flexibility of JUnit tests using getProperties(filename) to get the
+        * properties while runtime methods can use getPropertiesFromClassPath(filename).
+        * 
+        */
+       public static void initProperties (Properties prop){
+               logger.info("XacmlPersistenceProperties.initProperties(Properties): entry");
+               logger.info("\n\nXacmlPersistenceProperties.initProperties: Properties = \n" + prop + "\n\n");
+               
+               properties = prop;
+       }
+
+       public static String getProperty(String key){
+               return properties.getProperty(key);
+       }
+       
+       public static Properties getProperties() {
+               return properties;
+       }
+}
diff --git a/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI b/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI
new file mode 100644 (file)
index 0000000..540a4bd
--- /dev/null
@@ -0,0 +1 @@
+org.openecomp.policy.drools.persistence.PersistenceFeature
diff --git a/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/IntegrityAuditIntegrationTest.java b/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/IntegrityAuditIntegrationTest.java
new file mode 100644 (file)
index 0000000..6b65473
--- /dev/null
@@ -0,0 +1,279 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.controller.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.im.AdministrativeStateException;
+import org.openecomp.policy.common.im.IntegrityMonitor;
+import org.openecomp.policy.common.im.StandbyStatusException;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.drools.core.DroolsPDPIntegrityMonitor;
+import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
+import org.openecomp.policy.drools.core.PolicyContainer;
+import org.openecomp.policy.drools.im.PMStandbyStateChangeNotifier;
+import org.openecomp.policy.drools.persistence.DroolsPdpEntity;
+import org.openecomp.policy.drools.persistence.DroolsPdpImpl;
+import org.openecomp.policy.drools.persistence.DroolsPdpsConnector;
+import org.openecomp.policy.drools.persistence.JpaDroolsPdpsConnector;
+import org.openecomp.policy.drools.persistence.DroolsPersistenceProperties;
+import org.openecomp.policy.drools.persistence.PersistenceFeature;
+import org.openecomp.policy.drools.persistence.XacmlPersistenceProperties;
+import org.openecomp.policy.drools.system.Main;
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+/*
+ * Cloned from StandbyStateManagement.java in support of US673632.
+ * See MultiSite_v1-10.ppt, slide 38
+ */
+public class IntegrityAuditIntegrationTest {
+               
+       
+       public static final String INTEGRITY_MONITOR_PROPERTIES_FILE="src/test/server/config/IntegrityMonitor.properties";
+
+       /*
+        * Currently, the DroolsPdpsElectionHandler.DesignationWaiter is invoked every ten seconds, starting 
+        * at ten seconds after the minute boundary (e.g. 13:05:10). So, an 80 second sleep should be 
+        * sufficient to ensure that we wait for the DesignationWaiter to do its job, before 
+        * checking the results. 
+        */
+       private long sleepTime = 80000;
+               
+       /*
+        * Sleep 5 seconds after each test to allow interrupt (shutdown) recovery.
+        */
+       private long interruptRecoveryTime = 5000;
+       
+       /*
+        * See the IntegrityMonitor.getJmxUrl() method for the rationale behind this jmx related processing.
+        */
+       @BeforeClass
+       public static void setUpClass() throws Exception {
+               
+               PolicyLogger.info("setUpClass: Entering");
+
+               String userDir = System.getProperty("user.dir");
+               PolicyLogger.debug("setUpClass: userDir=" + userDir);
+               System.setProperty("com.sun.management.jmxremote.port", "9980");
+               System.setProperty("com.sun.management.jmxremote.authenticate","false");
+                               
+               // Make sure path to config directory is set correctly in PolicyContainer.main
+               // Also make sure we ignore HTTP server failures resulting from port conflicts.
+               PolicyContainer.isUnitTesting = true;
+               
+               /*
+                * Setting isUnitTesting to true ensures
+                * 
+                * 1) That we load test version of properties files
+                * 
+                * and
+                * 
+                * 2) that we use dbAuditSimulate() method, because all we care about
+                * for this JUnit testing is that the audits are executed.
+                */
+               IntegrityAudit.isUnitTesting = true;
+               
+               initializeDb();
+               
+               PolicyLogger.info("setUpClass: Exiting");
+               
+       }
+
+       @AfterClass
+       public static void tearDownClass() throws Exception {
+                               
+       }
+
+       @Before
+       public void setUp() throws Exception {
+               
+       }
+
+       @After
+       public void tearDown() throws Exception {
+               
+       }
+
+       
+       /*
+        * Verifies that audit thread starts successfully.
+        */
+       //@Ignore
+       @Test
+       public void testAuditInit() throws Exception {
+               
+               PolicyLogger.debug("\n\ntestAuditInit: Entering\n\n");
+
+               PolicyLogger.debug("testAuditInit: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               INTEGRITY_MONITOR_PROPERTIES_FILE)));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+               
+               PolicyLogger.debug("testAuditInit: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testAuditInit: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testAuditInit: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testAuditInit: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testAuditInit: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+               
+               /*
+                * Insert this PDP as designated.  Initial standby state will be 
+                * either null or cold standby.   
+                */
+               PolicyLogger.debug("testAuditInit: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, true, 4, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testAuditInit: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               PolicyLogger.debug("testAuditInit: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+                               
+               PolicyLogger.debug("testAuditInit: Running policy-management.Main class, designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testAuditInit: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting PDP="
+                               + thisPdpId);
+               Thread.sleep(interruptRecoveryTime);
+               
+               IntegrityAudit integrityAudit = PersistenceFeature.getIntegrityAudit();
+               PolicyLogger.debug("testAuditInit: isThreadInitialized=" + integrityAudit.isThreadInitialized());
+               assertTrue("AuditThread not initialized!?",integrityAudit.isThreadInitialized());
+                               
+               PolicyLogger.debug("testAuditInit: Stopping auditThread");
+               integrityAudit.stopAuditThread();
+               Thread.sleep(1000);
+               //This will interrupt thread.  However, the thread will not die.  It keeps on ticking and trying to
+               //run the audit.
+               assertTrue("AuditThread not still running after stopAuditThread invoked!?",integrityAudit.isThreadInitialized());
+
+               PolicyLogger.debug("testAuditInit: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();
+               
+               PolicyLogger.debug("\n\ntestAuditInit: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }       
+       
+    /*
+     * This method initializes and cleans the DB so that PDP-D will be able to 
+     * store IntegrityAuditEntity in the DB.
+     */
+       public static void initializeDb(){
+               
+               PolicyLogger.debug("initializeDb: Entering");
+               
+       Properties cleanProperties = new Properties();
+       cleanProperties.put(DroolsPersistenceProperties.DB_DRIVER,"org.h2.Driver");
+       cleanProperties.put(DroolsPersistenceProperties.DB_URL, "jdbc:h2:file:./sql/drools");
+       cleanProperties.put(DroolsPersistenceProperties.DB_USER, "sa");
+       cleanProperties.put(DroolsPersistenceProperties.DB_PWD, "");
+       //EntityManagerFactory emf = Persistence.createEntityManagerFactory("schemaPU", cleanProperties);
+       EntityManagerFactory emf = Persistence.createEntityManagerFactory("junitDroolsPU", cleanProperties);
+               
+               EntityManager em = emf.createEntityManager();
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               et.begin();
+
+               // Clean up the DB
+               em.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
+
+               // commit transaction
+               et.commit();
+               em.close();
+               
+               PolicyLogger.debug("initializeDb: Exiting");
+       }       
+       
+       private class PolicyManagementRunner extends Thread {
+
+               public void run() {
+                       PolicyLogger.info("PolicyManagementRunner.run: Entering");
+                       String args[] = { "src/main/server/config" };
+                       try {
+                               Main.main(args);
+                       } catch (Exception e) {
+                               PolicyLogger
+                                               .info("PolicyManagementRunner.run: Exception thrown from Main.main(), message="
+                                                               + e.getMessage());
+                       }
+                       PolicyLogger.info("PolicyManagementRunner.run: Exiting");
+               }
+               
+               public void stopRunner() {
+                       PolicyEngine.manager.shutdown();
+               }
+
+       }
+       
+}
diff --git a/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/ResiliencyTestCases.java b/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/ResiliencyTestCases.java
new file mode 100644 (file)
index 0000000..f58d304
--- /dev/null
@@ -0,0 +1,1267 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.controller.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.im.AdministrativeStateException;
+import org.openecomp.policy.common.im.IntegrityMonitor;
+import org.openecomp.policy.common.im.StandbyStatusException;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.drools.core.DroolsPDPIntegrityMonitor;
+import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
+import org.openecomp.policy.drools.core.PolicyContainer;
+import org.openecomp.policy.drools.im.PMStandbyStateChangeNotifier;
+import org.openecomp.policy.drools.persistence.DroolsPdp;
+import org.openecomp.policy.drools.persistence.DroolsPdpEntity;
+import org.openecomp.policy.drools.persistence.DroolsPdpImpl;
+import org.openecomp.policy.drools.persistence.DroolsPdpsConnector;
+import org.openecomp.policy.drools.persistence.JpaDroolsPdpsConnector;
+import org.openecomp.policy.drools.persistence.DroolsPersistenceProperties;
+import org.openecomp.policy.drools.persistence.XacmlPersistenceProperties;
+import org.openecomp.policy.drools.system.Main;
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+import org.apache.commons.lang3.time.DateUtils;
+
+/*
+ * Cloned from StandbyStateManagement.java in support of US673632.
+ * See MultiSite_v1-10.ppt, slide 38
+ */
+public class ResiliencyTestCases {
+                       
+       /*
+        * Currently, the DroolsPdpsElectionHandler.DesignationWaiter is invoked every ten seconds, starting 
+        * at ten seconds after the minute boundary (e.g. 13:05:10). So, an 80 second sleep should be 
+        * sufficient to ensure that we wait for the DesignationWaiter to do its job, before 
+        * checking the results. 
+        */
+       long sleepTime = 80000;
+       
+       /*
+        * DroolsPdpsElectionHandler runs every ten seconds, so a 15 second sleep should be 
+        * plenty to ensure it has time to re-promote this PDP.
+        */
+       long electionWaitSleepTime = 15000;
+       
+       /*
+        * Sleep 5 seconds after each test to allow interrupt (shutdown) recovery.
+        */
+       long interruptRecoveryTime = 5000;
+
+       /*
+        * See the IntegrityMonitor.getJmxUrl() method for the rationale behind this jmx related processing.
+        */
+       @BeforeClass
+       public static void setUpClass() throws Exception {
+               
+               String userDir = System.getProperty("user.dir");
+               PolicyLogger.debug("setUpClass: userDir=" + userDir);
+               System.setProperty("com.sun.management.jmxremote.port", "9980");
+               System.setProperty("com.sun.management.jmxremote.authenticate","false");
+                               
+               // Make sure path to config directory is set correctly in PolicyContainer.main
+               // Also make sure we ignore HTTP server failures resulting from port conflicts.
+               PolicyContainer.isUnitTesting = true;
+               
+       }
+
+       @AfterClass
+       public static void tearDownClass() throws Exception {
+       }
+
+       @Before
+       public void setUp() throws Exception {
+       }
+
+       @After
+       public void tearDown() throws Exception {
+                               
+       }
+       
+       public void cleanDroolsDB() throws Exception{
+               PolicyLogger.debug("\n\ncleanDroolsDB: Entering\n\n");
+
+               PolicyLogger.debug("cleanDroolsDB: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+
+               PolicyLogger.debug("cleanDroolsDB: Creating emfDrools");
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               PolicyLogger.debug("cleanDroolsDB: Cleaning up tables");
+               
+               EntityManager em = emf.createEntityManager();
+               EntityTransaction et = em.getTransaction();
+               et.begin();
+               
+               // Make sure the DB is clean
+               PolicyLogger.debug("cleanDroolsDB: clean DroolsPdpEntity");
+               em.createQuery("DELETE FROM DroolsPdpEntity").executeUpdate();
+               PolicyLogger.debug("cleanDroolsDB: clean DroolsSessionEntity");
+               em.createQuery("DELETE FROM DroolsSessionEntity").executeUpdate();
+               
+               em.flush(); 
+               PolicyLogger.debug("cleanDroolsDB: after flush");
+
+               et.commit(); 
+               
+               PolicyLogger.debug("\n\ncleanDroolsDB: Exiting\n\n");
+       }
+       
+       public void cleanXacmlDB() throws Exception {
+               PolicyLogger.debug("\n\ncleanXacmlDB: Entering\n\n");
+
+               PolicyLogger.debug("cleanXacmlDB: Reading IntegrityMonitorProperties");
+
+               PolicyLogger.debug("cleanXacmlDB: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               
+               PolicyLogger.debug("cleanXacmlDB: Creating emf");
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               EntityManager em = emf.createEntityManager();
+               EntityTransaction et = em.getTransaction();
+               et.begin();
+               
+               // Make sure the DB is clean
+               PolicyLogger.debug("cleanXacmlDB: clean StateManagementEntity");
+               em.createQuery("DELETE FROM StateManagementEntity").executeUpdate();
+               PolicyLogger.debug("cleanXacmlDB: clean ResourceRegistrationEntity");
+               em.createQuery("DELETE FROM ResourceRegistrationEntity").executeUpdate();
+               PolicyLogger.debug("cleanXacmlDB: clean ForwardProgressEntity");
+               em.createQuery("DELETE FROM ForwardProgressEntity").executeUpdate();
+               
+               em.flush(); 
+               PolicyLogger.debug("cleandXacmlDB: after flush");
+
+               et.commit(); 
+               
+               PolicyLogger.debug("\n\ncleanXacmlDB: Exiting\n\n");
+               
+       }
+       
+       @Ignore
+       @Test
+       public void singleNodeTests() throws Exception{
+               //snNewInstall();
+               snNewInstallBadDepData();
+               /*snRecoveryFromBadDepData();
+               snLock();
+               snLockRestart();
+               snUnlock();
+               snUnlockRestart();*/
+       }
+       
+       @Ignore
+       @Test
+       public void twoNodeTests() throws Exception{
+               tnNewInstall();
+               tnLockActive();
+               tnUnlockColdStandby();
+               tnFailActive();
+               tnRecoverFailed();
+       }
+       
+       @Ignore
+       @Test
+       public void twoSitesTwoNodesPerSiteTests() throws Exception{
+               tstnNewInstall();
+               tstnLock1Site1();
+               tstnLock2Site1();
+               tstnFailActiveSite2();
+               tstnRecoverFailedSite2();
+               tstnUnlockSite1();
+               tstnFailSite2();
+       }
+       
+
+       /*
+        * Single Node Tests
+        */
+       public void snNewInstall() throws Exception{
+               PolicyLogger.debug("\n\nsnNewInstall: Entry\n\n");
+               cleanDroolsDB();
+               cleanXacmlDB();
+               
+               //*******************************************
+               
+               PolicyLogger.debug("snNewInstall: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("snNewInstall: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("snNewInstall: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("snNewInstall: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("snNewInstall: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+       
+               PolicyLogger.debug("snNewInstall: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdp pdp = new DroolsPdpImpl(thisPdpId, true, 4, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("snNewInstall: After insertion, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+
+               /*
+                * When the Standby Status changes (from providingservice) to hotstandby
+                * or coldstandby,the Active/Standby selection algorithm must stand down
+                * if thePDP-D is currently the lead/active node and allow another PDP-D
+                * to take over.
+                * 
+                * It must also call lock on all engines in the engine management.
+                * 
+                */
+               PolicyLogger.debug("snNewInstall: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+               
+               // Artificially putting a PDP into service is really a two step process, 1)
+               // inserting it as designated and 2) promoting it so that its standbyStatus
+               // is providing service.
+               
+               PolicyLogger.debug("snNewInstall: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("snNewInstall: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting PDP="
+                               + thisPdpId);
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("snNewInstall: Promoting PDP=" + thisPdpId);
+               sm.promote();           
+               
+               String standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("snNewInstall: Before locking, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               PolicyLogger.debug("snNewInstall: Locking sm");
+               sm.lock();
+               
+               Thread.sleep(interruptRecoveryTime);
+               /*
+                * Verify that the PDP is no longer designated.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("snNewInstall: After lock sm.lock() invoked, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("snNewInstall: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();
+       
+               PolicyLogger.debug("\n\nsnNewInstall: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+               
+               //********************************************
+
+               PolicyLogger.debug("\n\nsnNewInstall: Exit\n\n");
+       }
+       
+       public void snNewInstallBadDepData() throws Exception{
+               PolicyLogger.debug("\n\nsnNewInstallBadDepData: Entry\n\n");
+               cleanDroolsDB();
+               cleanXacmlDB();
+               
+               //*******************************************
+               
+               PolicyLogger.debug("snNewInstallBadDepData: Reading IntegrityMonitor_BadDependencyData.properties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor_BadDependencyData.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("snNewInstallBadDepData: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("snNewInstallBadDepData: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("snNewInstallBadDepData: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("snNewInstallBadDepData: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+       
+               PolicyLogger.debug("snNewInstallBadDepData: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdp pdp = new DroolsPdpImpl(thisPdpId, true, 4, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               //PolicyLogger.debug
+               System.out.println
+               ("\n\nsnNewInstallBadDepData: After insertion, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId + "\n\n********************");
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               /*
+                * When the Standby Status changes (from providingservice) to hotstandby
+                * or coldstandby,the Active/Standby selection algorithm must stand down
+                * if thePDP-D is currently the lead/active node and allow another PDP-D
+                * to take over.
+                */
+               PolicyLogger.debug("snNewInstall: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+               
+               // Artificially putting a PDP into service is really a two step process, 1)
+               // inserting it as designated and 2) promoting it so that its standbyStatus
+               // is providing service.
+               
+               PolicyLogger.debug("snNewInstall: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("snNewInstall: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting PDP="
+                               + thisPdpId);
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("snNewInstall: Promoting PDP=" + thisPdpId);
+               sm.promote();           
+               
+               String standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("snNewInstall: Before locking, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               /*
+                * Verify that the PDP is no longer designated.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("snNewInstall: After lock sm.lock() invoked, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("snNewInstall: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();
+       
+               PolicyLogger.debug("\n\nsnNewInstall: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+               
+               //********************************************
+
+               PolicyLogger.debug("\n\nsnNewInstallBadDepData: Exit\n\n");
+       }
+       
+       public void snRecoveryFromBadDepData() throws Exception{
+               
+       }
+       
+       public void snLock() throws Exception {
+               
+       }
+       
+       public void snLockRestart() throws Exception {
+               
+       }
+       
+       public void snUnlock() throws Exception {
+               
+       }
+       
+       public void snUnlockRestart() throws Exception {
+               
+       }
+       
+       /*
+        * Two Nodes tests
+        */
+       public void tnNewInstall() throws Exception {
+               
+       }
+       
+       public void tnLockActive() throws Exception {
+               
+       }
+       
+       public void tnUnlockColdStandby() throws Exception {
+               
+       }
+       
+       public void tnFailActive() throws Exception {
+               
+       }
+       
+       public void tnRecoverFailed() throws Exception {
+               
+       }
+       
+       /*
+        * Two Sites, Two Nodes Each Site tests
+        */
+       
+       public void tstnNewInstall() throws Exception {
+               
+       }
+       
+       public void tstnLock1Site1() throws Exception {
+               
+       }
+       
+       public void tstnLock2Site1() throws Exception {
+               
+       }
+       
+       public void tstnFailActiveSite2() throws Exception {
+               
+       }
+       
+       public void tstnRecoverFailedSite2() throws Exception {
+               
+       }
+       
+       public void tstnUnlockSite1() throws Exception {
+               
+       }
+       
+       public void tstnFailSite2() throws Exception {
+               
+       }
+       
+       
+       @Ignore
+       @Test
+       public void testColdStandby() throws Exception {
+
+               PolicyLogger.debug("\n\ntestColdStandby: Entering\n\n");
+
+               PolicyLogger.debug("testColdStandby: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("testColdStandby: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testColdStandby: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testColdStandby: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testColdStandby: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testColdStandby: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+       
+               PolicyLogger.debug("testColdStandby: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdp pdp = new DroolsPdpImpl(thisPdpId, true, 4, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testColdStandby: After insertion, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+
+               /*
+                * When the Standby Status changes (from providingservice) to hotstandby
+                * or coldstandby,the Active/Standby selection algorithm must stand down
+                * if thePDP-D is currently the lead/active node and allow another PDP-D
+                * to take over.
+                * 
+                * It must also call lock on all engines in the engine management.
+                * 
+                * Yes, this is kludgy, but we have a chicken and egg problem here: we
+                * need a StateManagement object to invoke the
+                * deleteAllStateManagementEntities method.
+                */
+               PolicyLogger.debug("testColdStandby: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+               
+               // Artificially putting a PDP into service is really a two step process, 1)
+               // inserting it as designated and 2) promoting it so that its standbyStatus
+               // is providing service.
+               
+               PolicyLogger.debug("testColdStandby: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testColdStandby: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting PDP="
+                               + thisPdpId);
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("testColdStandby: Promoting PDP=" + thisPdpId);
+               sm.promote();           
+               
+               String standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("testColdStandby: Before locking, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               PolicyLogger.debug("testColdStandby: Locking sm");
+               sm.lock();
+               
+               Thread.sleep(interruptRecoveryTime);
+               /*
+                * Verify that the PDP is no longer designated.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testColdStandby: After lock sm.lock() invoked, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("testColdStandby: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();
+       
+               PolicyLogger.debug("\n\ntestColdStandby: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       /*
+        * Tests hot standby when there is only one PDP.
+        */
+       @Ignore
+       @Test
+       public void testHotStandby1() throws Exception {
+       
+               PolicyLogger.debug("\n\ntestHotStandby1: Entering\n\n");
+               
+               PolicyLogger.debug("testHotStandby1: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+               
+               PolicyLogger.debug("testHotStandby1: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testHotStandby1: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testHotStandby1: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testHotStandby1: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testHotStandby1: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+                                       
+               /*
+                * Insert this PDP as not designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               PolicyLogger.debug("testHotStandby1: Inserting PDP=" + thisPdpId + " as not designated");
+               Date yesterday = DateUtils.addDays(new Date(), -1);
+               DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, false, 4, yesterday);
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testHotStandby1: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("testHotStandby1: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+
+               PolicyLogger.debug("testHotStandby1: Demoting PDP=" + thisPdpId);
+               // demoting should cause state to transit to hotstandby
+               sm.demote();
+               
+               PolicyLogger.debug("testHotStandby1: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+                               
+               PolicyLogger.debug("testHotStandby1: Sleeping "
+                               + sleepTime
+                               + "ms, to allow JpaDroolsPdpsConnector time to check droolspdpentity table");
+               Thread.sleep(sleepTime);
+               
+               /*
+                * Verify that this formerly un-designated PDP in HOT_STANDBY is now designated and providing service.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testHotStandby1: After sm.demote() invoked, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               String standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("testHotStandby1: After demotion, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               assertTrue(standbyStatus != null  &&  standbyStatus.equals(StateManagement.PROVIDING_SERVICE));
+                               
+               PolicyLogger.debug("testHotStandby1: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+       
+               PolicyLogger.debug("\n\ntestHotStandby1: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+
+       /*
+        * Tests hot standby when two PDPs are involved.
+        */
+       @Ignore
+       @Test
+       public void testHotStandby2() throws Exception {
+
+               PolicyLogger.debug("\n\ntestHotStandby2: Entering\n\n");
+               
+               PolicyLogger.debug("testHotStandby2: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+               
+               PolicyLogger.debug("testHotStandby2: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testHotStandby2: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testHotStandby2: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testHotStandby2: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testHotStandby2: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+               
+               /*
+                * Insert a PDP that's designated but not current.
+                */
+               String activePdpId = "pdp2";
+               PolicyLogger.debug("testHotStandby2: Inserting PDP=" + activePdpId + " as stale, designated PDP");
+               Date yesterday = DateUtils.addDays(new Date(), -1);
+               DroolsPdp pdp = new DroolsPdpImpl(activePdpId, true, 4, yesterday);
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(activePdpId);
+               PolicyLogger.debug("testHotStandby2: After insertion, PDP=" + activePdpId + ", which is not current, has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               /*
+                * Promote the designated PDP.
+                * 
+                * We have a chicken and egg problem here: we need a StateManagement
+                * object to invoke the deleteAllStateManagementEntities method.
+                */
+               PolicyLogger.debug("testHotStandy2: Promoting PDP=" + activePdpId);
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, activePdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+               
+               // Artificially putting a PDP into service is really a two step process, 1)
+               // inserting it as designated and 2) promoting it so that its standbyStatus
+               // is providing service.
+                               
+               /*
+                * Insert this PDP as not designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               PolicyLogger.debug("testHotStandby2: Inserting PDP=" + thisPdpId + " as not designated");
+               pdp = new DroolsPdpImpl(thisPdpId, false, 4, yesterday);
+               conn.insertPdp(pdp);
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testHotStandby2: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("testHotStandby2: Demoting PDP=" + thisPdpId);
+               StateManagement sm2 = new StateManagement(emfXacml, thisPdpId);
+               sm2.addObserver(pmStandbyStateChangeNotifier);
+               
+               PolicyLogger.debug("testHotStandby2: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testHotStandby2: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting/demoting");
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("testHotStandby2: Runner started; promoting PDP=" + activePdpId);
+               sm.promote();
+               String standbyStatus = sm.getStandbyStatus(activePdpId);
+               PolicyLogger.debug("testHotStandby2: After promoting, PDP=" + activePdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               // demoting PDP should ensure that state transits to hotstandby
+               PolicyLogger.debug("testHotStandby2: Runner started; demoting PDP=" + thisPdpId);
+               sm2.demote();
+               standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("testHotStandby2: After demoting, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               PolicyLogger.debug("testHotStandby2: Sleeping "
+                               + sleepTime
+                               + "ms, to allow JpaDroolsPdpsConnector time to check droolspdpentity table");
+               Thread.sleep(sleepTime);
+               
+               /*
+                * Verify that this PDP, demoted to HOT_STANDBY, is now
+                * re-designated and providing service.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testHotStandby2: After demoting PDP=" + activePdpId
+                               + ", DESIGNATED=" + droolsPdpEntity.isDesignated()
+                               + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               standbyStatus = sm2.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("testHotStandby2: After demoting PDP=" + activePdpId
+                               + ", PDP=" + thisPdpId + " has standbyStatus=" + standbyStatus);
+               assertTrue(standbyStatus != null
+                               && standbyStatus.equals(StateManagement.PROVIDING_SERVICE));
+                               
+               PolicyLogger.debug("testHotStandby2: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+
+               PolicyLogger.debug("\n\ntestHotStandby2: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       /*
+        * 1) Inserts and designates this PDP, then verifies that startTransaction
+        * is successful.
+        * 
+        * 2) Demotes PDP, and verifies that because there is only one PDP, it will
+        * be immediately re-promoted, thus allowing startTransaction to be
+        * successful.
+        * 
+        * 3) Locks PDP and verifies that startTransaction results in
+        * AdministrativeStateException.
+        * 
+        * 4) Unlocks PDP and verifies that startTransaction results in
+        * StandbyStatusException.
+        * 
+        * 5) Promotes PDP and verifies that startTransaction is once again
+        * successful.
+        */
+       @Ignore
+       @Test
+       public void testLocking1() throws Exception {
+                               
+               PolicyLogger.debug("testLocking1: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("testLocking1: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking1: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking1: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testLocking1: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testLocking1: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+               
+               /*
+                * Insert this PDP as designated.  Initial standby state will be 
+                * either null or cold standby.   
+                */
+               PolicyLogger.debug("testLocking1: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, true, 4, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testLocking1: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               PolicyLogger.debug("testLocking1: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+                               
+               PolicyLogger.debug("testLocking1: Running policy-management.Main class, designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testLocking1: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting PDP="
+                               + thisPdpId);
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("testLocking1: Promoting PDP=" + thisPdpId);
+               sm.promote();
+
+               PolicyLogger.debug("testLocking1: Sleeping "
+                               + sleepTime
+                               + "ms, to allow time for policy-management.Main class to come up, designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               Thread.sleep(sleepTime);
+               
+               PolicyLogger.debug("testLocking1: Waking up and invoking startTransaction on active PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor = (DroolsPDPIntegrityMonitor) IntegrityMonitor
+                               .getInstance();
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking1: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               // demoting should cause state to transit to hotstandby, followed by re-promotion,
+               // since there is only one PDP.
+               PolicyLogger.debug("testLocking1: demoting PDP=" + thisPdpId);
+               sm = droolsPdpIntegrityMonitor.getStateManager();
+               sm.demote();
+               
+               PolicyLogger.debug("testLocking1: sleeping" + electionWaitSleepTime
+                               + " to allow election handler to re-promote PDP=" + thisPdpId);
+               Thread.sleep(electionWaitSleepTime);
+                                                               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on re-promoted PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking1: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               // locking should cause state to transit to cold standby
+               PolicyLogger.debug("testLocking1: locking PDP=" + thisPdpId);
+               sm.lock();
+               
+               // Just to avoid any race conditions, sleep a little after locking
+               PolicyLogger.debug("testLocking1: Sleeping a few millis after locking, to avoid race condition");
+               Thread.sleep(100);
+               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on locked PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       PolicyLogger.error("testLocking1: startTransaction unexpectedly successful");
+                       assertTrue(false);
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.debug("testLocking1: As expected, caught AdministrativeStateException, message=" + e.getMessage());
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               } finally {
+                       droolsPdpIntegrityMonitor.endTransaction();
+               }               
+               
+               // unlocking should cause state to transit to hot standby
+               PolicyLogger.debug("testLocking1: unlocking PDP=" + thisPdpId);
+               sm.unlock();
+               
+               // Just to avoid any race conditions, sleep a little after locking
+               PolicyLogger.debug("testLocking1: Sleeping a few millis after unlocking, to avoid race condition");
+               Thread.sleep(100);
+               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on unlocked PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       PolicyLogger.error("testLocking1: startTransaction unexpectedly successful");
+                       assertTrue(false);
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.debug("testLocking1: As expected, caught StandbyStatusException, message=" + e.getMessage());
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               } finally {
+                       droolsPdpIntegrityMonitor.endTransaction();
+               }
+               
+               // promoting should cause state to transit to providing service
+               PolicyLogger.debug("testLocking1: promoting PDP=" + thisPdpId);
+               sm.promote();
+               
+               // Just to avoid any race conditions, sleep a little after promoting
+               PolicyLogger.debug("testLocking1: Sleeping a few millis after promoting, to avoid race condition");
+               Thread.sleep(100);
+               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on promoted PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking1: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               PolicyLogger.debug("testLocking1: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+
+               PolicyLogger.debug("\n\ntestLocking1: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       /*
+        * 1) Inserts and designates this PDP, then verifies that startTransaction
+        * is successful.
+        * 
+        * 2) Inserts another PDP in hotstandby.
+        * 
+        * 3) Demotes this PDP, and verifies 1) that other PDP is not promoted (because one
+        * PDP cannot promote another PDP) and 2) that this PDP is re-promoted.
+        */
+       @Ignore
+       @Test
+       public void testLocking2() throws Exception {
+
+               PolicyLogger.debug("\n\ntestLocking2: Entering\n\n");
+               
+               PolicyLogger.debug("testLocking2: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("testLocking2: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking2: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking2: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testLocking2: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testLocking2: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+               
+               /*
+                * Insert this PDP as designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               PolicyLogger.debug("testLocking2: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, true, 3, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testLocking2: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               PolicyLogger.debug("testLocking2: Instantiating stateManagement object and promoting PDP=" + thisPdpId);
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+                               
+               /*
+                * Insert another PDP as not designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               String standbyPdpId = "pdp2";
+               PolicyLogger.debug("testLocking2: Inserting PDP=" + standbyPdpId + " as not designated");
+               Date yesterday = DateUtils.addDays(new Date(), -1);
+               pdp = new DroolsPdpImpl(standbyPdpId, false, 4, yesterday);
+               conn.insertPdp(pdp);
+               droolsPdpEntity = conn.getPdp(standbyPdpId);
+               PolicyLogger.debug("testLocking2: After insertion, PDP=" + standbyPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("testLocking2: Demoting PDP=" + standbyPdpId);
+               StateManagement sm2 = new StateManagement(emfXacml, standbyPdpId);
+               sm2.addObserver(pmStandbyStateChangeNotifier);
+                               
+               PolicyLogger.debug("testLocking2: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testLocking2: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting/demoting");
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("testLocking2: Promoting PDP=" + thisPdpId);
+               sm.promote();
+
+               // demoting PDP should ensure that state transits to hotstandby
+               PolicyLogger.debug("testLocking2: Demoting PDP=" + standbyPdpId);
+               sm2.demote();
+               
+               PolicyLogger.debug("testLocking2: Sleeping "
+                               + sleepTime
+                               + "ms, to allow time for policy-management.Main class to come up");
+               Thread.sleep(sleepTime);
+               
+               PolicyLogger.debug("testLocking2: Waking up and invoking startTransaction on active PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor = (DroolsPDPIntegrityMonitor) IntegrityMonitor
+                               .getInstance();
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking2: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               // demoting should cause state to transit to hotstandby followed by re-promotion.
+               PolicyLogger.debug("testLocking2: demoting PDP=" + thisPdpId);
+               sm = droolsPdpIntegrityMonitor.getStateManager();
+               sm.demote();
+               
+               PolicyLogger.debug("testLocking2: sleeping" + electionWaitSleepTime
+                               + " to allow election handler to re-promote PDP=" + thisPdpId);
+               Thread.sleep(electionWaitSleepTime);
+               
+               PolicyLogger.debug("testLocking2: Waking up and invoking startTransaction on re-promoted PDP="
+                               + thisPdpId + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking2: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               PolicyLogger.debug("testLocking2: Verifying designated status for PDP="
+                               + standbyPdpId);
+               boolean standbyPdpDesignated = conn.getPdp(standbyPdpId).isDesignated();
+               assertTrue(standbyPdpDesignated == false);
+               
+               PolicyLogger.debug("testLocking2: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+
+               PolicyLogger.debug("\n\ntestLocking2: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       private class PolicyManagementRunner extends Thread {
+
+               public void run() {
+                       PolicyLogger.debug("PolicyManagementRunner.run: Entering");
+                       String args[] = { "src/main/server/config" };
+                       try {
+                               Main.main(args);
+                       } catch (Exception e) {
+                               PolicyLogger
+                                               .debug("PolicyManagementRunner.run: Exception thrown from Main.main(), message="
+                                                               + e.getMessage());
+                       }
+                       PolicyLogger.debug("PolicyManagementRunner.run: Exiting");
+               }
+               
+               public void stopRunner() {
+                       PolicyEngine.manager.shutdown();
+               }
+
+       }
+       
+}
diff --git a/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/StandbyStateManagementTest.java b/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/StandbyStateManagementTest.java
new file mode 100644 (file)
index 0000000..af64986
--- /dev/null
@@ -0,0 +1,887 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-persistence
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.controller.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.im.AdministrativeStateException;
+import org.openecomp.policy.common.im.IntegrityMonitor;
+import org.openecomp.policy.common.im.StandbyStatusException;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.drools.core.DroolsPDPIntegrityMonitor;
+import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
+import org.openecomp.policy.drools.core.PolicyContainer;
+import org.openecomp.policy.drools.im.PMStandbyStateChangeNotifier;
+import org.openecomp.policy.drools.persistence.DroolsPdp;
+import org.openecomp.policy.drools.persistence.DroolsPdpEntity;
+import org.openecomp.policy.drools.persistence.DroolsPdpImpl;
+import org.openecomp.policy.drools.persistence.DroolsPdpsConnector;
+import org.openecomp.policy.drools.persistence.JpaDroolsPdpsConnector;
+import org.openecomp.policy.drools.persistence.DroolsPersistenceProperties;
+import org.openecomp.policy.drools.persistence.XacmlPersistenceProperties;
+import org.openecomp.policy.drools.system.Main;
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+import org.apache.commons.lang3.time.DateUtils;
+
+/*
+ * Cloned from StandbyStateManagement.java in support of US673632.
+ * See MultiSite_v1-10.ppt, slide 38
+ */
+public class StandbyStateManagementTest {
+                       
+       /*
+        * Currently, the DroolsPdpsElectionHandler.DesignationWaiter is invoked every ten seconds, starting 
+        * at ten seconds after the minute boundary (e.g. 13:05:10). So, an 80 second sleep should be 
+        * sufficient to ensure that we wait for the DesignationWaiter to do its job, before 
+        * checking the results. 
+        */
+       long sleepTime = 80000;
+       
+       /*
+        * DroolsPdpsElectionHandler runs every ten seconds, so a 15 second sleep should be 
+        * plenty to ensure it has time to re-promote this PDP.
+        */
+       long electionWaitSleepTime = 15000;
+       
+       /*
+        * Sleep 5 seconds after each test to allow interrupt (shutdown) recovery.
+        */
+       long interruptRecoveryTime = 5000;
+
+       /*
+        * See the IntegrityMonitor.getJmxUrl() method for the rationale behind this jmx related processing.
+        */
+       @BeforeClass
+       public static void setUpClass() throws Exception {
+               
+               String userDir = System.getProperty("user.dir");
+               PolicyLogger.debug("setUpClass: userDir=" + userDir);
+               System.setProperty("com.sun.management.jmxremote.port", "9980");
+               System.setProperty("com.sun.management.jmxremote.authenticate","false");
+                               
+               // Make sure path to config directory is set correctly in PolicyContainer.main
+               // Also make sure we ignore HTTP server failures resulting from port conflicts.
+               PolicyContainer.isUnitTesting = true;
+               
+       }
+
+       @AfterClass
+       public static void tearDownClass() throws Exception {
+       }
+
+       @Before
+       public void setUp() throws Exception {
+       }
+
+       @After
+       public void tearDown() throws Exception {
+                               
+       }
+
+       @Ignore
+       @Test
+       public void testColdStandby() throws Exception {
+
+               PolicyLogger.debug("\n\ntestColdStandby: Entering\n\n");
+
+               PolicyLogger.debug("testColdStandby: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("testColdStandby: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testColdStandby: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testColdStandby: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testColdStandby: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testColdStandby: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+       
+               PolicyLogger.debug("testColdStandby: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdp pdp = new DroolsPdpImpl(thisPdpId, true, 4, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testColdStandby: After insertion, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+
+               /*
+                * When the Standby Status changes (from providingservice) to hotstandby
+                * or coldstandby,the Active/Standby selection algorithm must stand down
+                * if thePDP-D is currently the lead/active node and allow another PDP-D
+                * to take over.
+                * 
+                * It must also call lock on all engines in the engine management.
+                * 
+                * Yes, this is kludgy, but we have a chicken and egg problem here: we
+                * need a StateManagement object to invoke the
+                * deleteAllStateManagementEntities method.
+                */
+               PolicyLogger.debug("testColdStandby: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+               
+               // Artificially putting a PDP into service is really a two step process, 1)
+               // inserting it as designated and 2) promoting it so that its standbyStatus
+               // is providing service.
+               
+               PolicyLogger.debug("testColdStandby: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testColdStandby: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting PDP="
+                               + thisPdpId);
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("testColdStandby: Promoting PDP=" + thisPdpId);
+               sm.promote();           
+               
+               String standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("testColdStandby: Before locking, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               PolicyLogger.debug("testColdStandby: Locking sm");
+               sm.lock();
+               
+               Thread.sleep(interruptRecoveryTime);
+               /*
+                * Verify that the PDP is no longer designated.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testColdStandby: After lock sm.lock() invoked, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("testColdStandby: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();
+       
+               PolicyLogger.debug("\n\ntestColdStandby: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       /*
+        * Tests hot standby when there is only one PDP.
+        */
+       @Ignore
+       @Test
+       public void testHotStandby1() throws Exception {
+       
+               PolicyLogger.debug("\n\ntestHotStandby1: Entering\n\n");
+               
+               PolicyLogger.debug("testHotStandby1: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+               
+               PolicyLogger.debug("testHotStandby1: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testHotStandby1: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testHotStandby1: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testHotStandby1: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testHotStandby1: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+                                       
+               /*
+                * Insert this PDP as not designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               PolicyLogger.debug("testHotStandby1: Inserting PDP=" + thisPdpId + " as not designated");
+               Date yesterday = DateUtils.addDays(new Date(), -1);
+               DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, false, 4, yesterday);
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testHotStandby1: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("testHotStandby1: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+
+               PolicyLogger.debug("testHotStandby1: Demoting PDP=" + thisPdpId);
+               // demoting should cause state to transit to hotstandby
+               sm.demote();
+               
+               PolicyLogger.debug("testHotStandby1: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+                               
+               PolicyLogger.debug("testHotStandby1: Sleeping "
+                               + sleepTime
+                               + "ms, to allow JpaDroolsPdpsConnector time to check droolspdpentity table");
+               Thread.sleep(sleepTime);
+               
+               /*
+                * Verify that this formerly un-designated PDP in HOT_STANDBY is now designated and providing service.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testHotStandby1: After sm.demote() invoked, DESIGNATED="
+                               + droolsPdpEntity.isDesignated() + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               String standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.debug("testHotStandby1: After demotion, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               assertTrue(standbyStatus != null  &&  standbyStatus.equals(StateManagement.PROVIDING_SERVICE));
+                               
+               PolicyLogger.debug("testHotStandby1: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+       
+               PolicyLogger.debug("\n\ntestHotStandby1: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+
+       /*
+        * Tests hot standby when two PDPs are involved.
+        */
+       @Ignore
+       @Test
+       public void testHotStandby2() throws Exception {
+
+               PolicyLogger.info("\n\ntestHotStandby2: Entering\n\n");
+               
+               PolicyLogger.info("testHotStandby2: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+               
+               PolicyLogger.info("testHotStandby2: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.info("testHotStandby2: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.info("testHotStandby2: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.info("testHotStandby2: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.info("testHotStandby2: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+               
+               /*
+                * Insert a PDP that's designated but not current.
+                */
+               String activePdpId = "pdp2";
+               PolicyLogger.info("testHotStandby2: Inserting PDP=" + activePdpId + " as stale, designated PDP");
+               Date yesterday = DateUtils.addDays(new Date(), -1);
+               DroolsPdp pdp = new DroolsPdpImpl(activePdpId, true, 4, yesterday);
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(activePdpId);
+               PolicyLogger.info("testHotStandby2: After insertion, PDP=" + activePdpId + ", which is not current, has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               /*
+                * Promote the designated PDP.
+                * 
+                * We have a chicken and egg problem here: we need a StateManagement
+                * object to invoke the deleteAllStateManagementEntities method.
+                */
+               PolicyLogger.info("testHotStandy2: Promoting PDP=" + activePdpId);
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, activePdpId);//pdp2
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+               
+               // Artificially putting a PDP into service is really a two step process, 1)
+               // inserting it as designated and 2) promoting it so that its standbyStatus
+               // is providing service.
+                               
+               /*
+                * Insert this PDP as not designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               PolicyLogger.info("testHotStandby2: Inserting PDP=" + thisPdpId + " as not designated");
+               pdp = new DroolsPdpImpl(thisPdpId, false, 4, yesterday);
+               conn.insertPdp(pdp);
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.info("testHotStandby2: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.info("testHotStandby2: Demoting PDP=" + thisPdpId);//pdp1
+               StateManagement sm2 = new StateManagement(emfXacml, thisPdpId);
+               sm2.addObserver(pmStandbyStateChangeNotifier);
+               
+               PolicyLogger.info("testHotStandby2: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner(); //pdp1
+               policyManagementRunner.start();
+               
+               PolicyLogger.info("testHotStandby2: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting/demoting");
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.info("testHotStandby2: Runner started; promoting PDP=" + activePdpId);//pdpd2xs
+               //at this point, the newly created pdp will have set the state to disabled/failed/cold standby
+               //because it is stale. So, it cannot be promoted.  We need to call sm.enableNotFailed() so we
+               //can promote it and demote the other pdp - else the other pdp will just spring back to providingservice
+               sm.enableNotFailed();//pdp1
+               sm.promote();
+               String standbyStatus = sm.getStandbyStatus(activePdpId);
+               PolicyLogger.info("testHotStandby2: After promoting, PDP=" + activePdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               // demoting PDP should ensure that state transits to hotstandby
+               PolicyLogger.info("testHotStandby2: Runner started; demoting PDP=" + thisPdpId);
+               sm2.demote();//pdp1
+               standbyStatus = sm.getStandbyStatus(thisPdpId);
+               PolicyLogger.info("testHotStandby2: After demoting, PDP=" + thisPdpId + " has standbyStatus="
+                               + standbyStatus);
+               
+               PolicyLogger.info("testHotStandby2: Sleeping "
+                               + sleepTime
+                               + "ms, to allow JpaDroolsPdpsConnector time to check droolspdpentity table");
+               Thread.sleep(sleepTime);
+               
+               /*
+                * Verify that this PDP, demoted to HOT_STANDBY, is now
+                * re-designated and providing service.
+                */
+               droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.info("testHotStandby2: After demoting PDP=" + activePdpId
+                               + ", DESIGNATED=" + droolsPdpEntity.isDesignated()
+                               + " for PDP=" + thisPdpId);
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               standbyStatus = sm2.getStandbyStatus(thisPdpId);
+               PolicyLogger.info("testHotStandby2: After demoting PDP=" + activePdpId
+                               + ", PDP=" + thisPdpId + " has standbyStatus=" + standbyStatus);
+               assertTrue(standbyStatus != null
+                               && standbyStatus.equals(StateManagement.PROVIDING_SERVICE));
+                               
+               PolicyLogger.info("testHotStandby2: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+
+               PolicyLogger.info("\n\ntestHotStandby2: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       /*
+        * 1) Inserts and designates this PDP, then verifies that startTransaction
+        * is successful.
+        * 
+        * 2) Demotes PDP, and verifies that because there is only one PDP, it will
+        * be immediately re-promoted, thus allowing startTransaction to be
+        * successful.
+        * 
+        * 3) Locks PDP and verifies that startTransaction results in
+        * AdministrativeStateException.
+        * 
+        * 4) Unlocks PDP and verifies that startTransaction results in
+        * StandbyStatusException.
+        * 
+        * 5) Promotes PDP and verifies that startTransaction is once again
+        * successful.
+        */
+       @Ignore
+       @Test
+       public void testLocking1() throws Exception {
+                               
+               PolicyLogger.debug("testLocking1: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("testLocking1: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking1: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking1: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testLocking1: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testLocking1: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+               
+               /*
+                * Insert this PDP as designated.  Initial standby state will be 
+                * either null or cold standby.   
+                */
+               PolicyLogger.debug("testLocking1: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, true, 4, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testLocking1: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               PolicyLogger.debug("testLocking1: Instantiating stateManagement object");
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+                               
+               PolicyLogger.debug("testLocking1: Running policy-management.Main class, designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testLocking1: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting PDP="
+                               + thisPdpId);
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("testLocking1: Promoting PDP=" + thisPdpId);
+               sm.promote();
+
+               PolicyLogger.debug("testLocking1: Sleeping "
+                               + sleepTime
+                               + "ms, to allow time for policy-management.Main class to come up, designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               Thread.sleep(sleepTime);
+               
+               PolicyLogger.debug("testLocking1: Waking up and invoking startTransaction on active PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor = (DroolsPDPIntegrityMonitor) IntegrityMonitor
+                               .getInstance();
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking1: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               // demoting should cause state to transit to hotstandby, followed by re-promotion,
+               // since there is only one PDP.
+               PolicyLogger.debug("testLocking1: demoting PDP=" + thisPdpId);
+               sm = droolsPdpIntegrityMonitor.getStateManager();
+               sm.demote();
+               
+               PolicyLogger.debug("testLocking1: sleeping" + electionWaitSleepTime
+                               + " to allow election handler to re-promote PDP=" + thisPdpId);
+               Thread.sleep(electionWaitSleepTime);
+                                                               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on re-promoted PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking1: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               // locking should cause state to transit to cold standby
+               PolicyLogger.debug("testLocking1: locking PDP=" + thisPdpId);
+               sm.lock();
+               
+               // Just to avoid any race conditions, sleep a little after locking
+               PolicyLogger.debug("testLocking1: Sleeping a few millis after locking, to avoid race condition");
+               Thread.sleep(100);
+               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on locked PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       PolicyLogger.error("testLocking1: startTransaction unexpectedly successful");
+                       assertTrue(false);
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.debug("testLocking1: As expected, caught AdministrativeStateException, message=" + e.getMessage());
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               } finally {
+                       droolsPdpIntegrityMonitor.endTransaction();
+               }               
+               
+               // unlocking should cause state to transit to hot standby
+               PolicyLogger.debug("testLocking1: unlocking PDP=" + thisPdpId);
+               sm.unlock();
+               
+               // Just to avoid any race conditions, sleep a little after locking
+               PolicyLogger.debug("testLocking1: Sleeping a few millis after unlocking, to avoid race condition");
+               Thread.sleep(100);
+               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on unlocked PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       PolicyLogger.error("testLocking1: startTransaction unexpectedly successful");
+                       assertTrue(false);
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.debug("testLocking1: As expected, caught StandbyStatusException, message=" + e.getMessage());
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               } finally {
+                       droolsPdpIntegrityMonitor.endTransaction();
+               }
+               
+               // promoting should cause state to transit to providing service
+               PolicyLogger.debug("testLocking1: promoting PDP=" + thisPdpId);
+               sm.promote();
+               
+               // Just to avoid any race conditions, sleep a little after promoting
+               PolicyLogger.debug("testLocking1: Sleeping a few millis after promoting, to avoid race condition");
+               Thread.sleep(100);
+               
+               PolicyLogger.debug("testLocking1: Invoking startTransaction on promoted PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking1: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking1: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               PolicyLogger.debug("testLocking1: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+
+               PolicyLogger.debug("\n\ntestLocking1: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       /*
+        * 1) Inserts and designates this PDP, then verifies that startTransaction
+        * is successful.
+        * 
+        * 2) Inserts another PDP in hotstandby.
+        * 
+        * 3) Demotes this PDP, and verifies 1) that other PDP is not promoted (because one
+        * PDP cannot promote another PDP) and 2) that this PDP is re-promoted.
+        */
+       @Ignore
+       @Test
+       public void testLocking2() throws Exception {
+
+               PolicyLogger.debug("\n\ntestLocking2: Entering\n\n");
+               
+               PolicyLogger.debug("testLocking2: Reading IntegrityMonitorProperties");
+               Properties integrityMonitorProperties = new Properties();
+               integrityMonitorProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/IntegrityMonitor.properties")));
+               IntegrityMonitorProperties.initProperties(integrityMonitorProperties);
+               String thisPdpId = IntegrityMonitorProperties
+                               .getProperty(IntegrityMonitorProperties.PDP_INSTANCE_ID);
+
+               PolicyLogger.debug("testLocking2: Reading xacmlPersistenceProperties");
+               Properties xacmlPersistenceProperties = new Properties();
+               xacmlPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/xacmlPersistence.properties")));
+               XacmlPersistenceProperties.initProperties(xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking2: Creating emfXacml");
+               EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
+                               "junitXacmlPU", xacmlPersistenceProperties);
+               
+               PolicyLogger.debug("testLocking2: Reading droolsPersistenceProperties");
+               Properties droolsPersistenceProperties = new Properties();
+               droolsPersistenceProperties.load(new FileInputStream(new File(
+                               "src/test/server/config/droolsPersistence.properties")));
+               DroolsPersistenceProperties.initProperties(droolsPersistenceProperties);
+
+               PolicyLogger.debug("testLocking2: Creating emfDrools");
+               EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
+                               "junitDroolsPU", droolsPersistenceProperties);
+               
+               DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
+               
+               PolicyLogger.debug("testLocking2: Cleaning up tables");
+               conn.deleteAllSessions();
+               conn.deleteAllPdps();
+               
+               /*
+                * Insert this PDP as designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               PolicyLogger.debug("testLocking2: Inserting PDP=" + thisPdpId + " as designated");
+               DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, true, 3, new Date());
+               conn.insertPdp(pdp);
+               DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
+               PolicyLogger.debug("testLocking2: After insertion, PDP=" + thisPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == true);
+               
+               PolicyLogger.debug("testLocking2: Instantiating stateManagement object and promoting PDP=" + thisPdpId);
+               StateManagement sm = new StateManagement(emfXacml, "dummy");
+               sm.deleteAllStateManagementEntities();
+               sm = new StateManagement(emfXacml, thisPdpId);
+               PMStandbyStateChangeNotifier pmStandbyStateChangeNotifier = new PMStandbyStateChangeNotifier();
+               sm.addObserver(pmStandbyStateChangeNotifier);
+                               
+               /*
+                * Insert another PDP as not designated.  Initial standby state will be 
+                * either null or cold standby.   Demoting should transit state to
+                * hot standby.
+                */
+               String standbyPdpId = "pdp2";
+               PolicyLogger.debug("testLocking2: Inserting PDP=" + standbyPdpId + " as not designated");
+               Date yesterday = DateUtils.addDays(new Date(), -1);
+               pdp = new DroolsPdpImpl(standbyPdpId, false, 4, yesterday);
+               conn.insertPdp(pdp);
+               droolsPdpEntity = conn.getPdp(standbyPdpId);
+               PolicyLogger.debug("testLocking2: After insertion, PDP=" + standbyPdpId + " has DESIGNATED="
+                               + droolsPdpEntity.isDesignated());
+               assertTrue(droolsPdpEntity.isDesignated() == false);
+               
+               PolicyLogger.debug("testLocking2: Demoting PDP=" + standbyPdpId);
+               StateManagement sm2 = new StateManagement(emfXacml, standbyPdpId);
+               sm2.addObserver(pmStandbyStateChangeNotifier);
+                               
+               PolicyLogger.debug("testLocking2: Running policy-management.Main class");
+               PolicyManagementRunner policyManagementRunner = new PolicyManagementRunner();
+               policyManagementRunner.start();
+               
+               PolicyLogger.debug("testLocking2: Runner started; Sleeping "
+                               + interruptRecoveryTime + "ms before promoting/demoting");
+               Thread.sleep(interruptRecoveryTime);
+
+               PolicyLogger.debug("testLocking2: Promoting PDP=" + thisPdpId);
+               sm.promote();
+
+               // demoting PDP should ensure that state transits to hotstandby
+               PolicyLogger.debug("testLocking2: Demoting PDP=" + standbyPdpId);
+               sm2.demote();
+               
+               PolicyLogger.debug("testLocking2: Sleeping "
+                               + sleepTime
+                               + "ms, to allow time for policy-management.Main class to come up");
+               Thread.sleep(sleepTime);
+               
+               PolicyLogger.debug("testLocking2: Waking up and invoking startTransaction on active PDP="
+                               + thisPdpId
+                               + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor = (DroolsPDPIntegrityMonitor) IntegrityMonitor
+                               .getInstance();
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking2: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               // demoting should cause state to transit to hotstandby followed by re-promotion.
+               PolicyLogger.debug("testLocking2: demoting PDP=" + thisPdpId);
+               sm = droolsPdpIntegrityMonitor.getStateManager();
+               sm.demote();
+               
+               PolicyLogger.debug("testLocking2: sleeping" + electionWaitSleepTime
+                               + " to allow election handler to re-promote PDP=" + thisPdpId);
+               Thread.sleep(electionWaitSleepTime);
+               
+               PolicyLogger.debug("testLocking2: Waking up and invoking startTransaction on re-promoted PDP="
+                               + thisPdpId + ", designated="
+                               + conn.getPdp(thisPdpId).isDesignated());
+               try {
+                       droolsPdpIntegrityMonitor.startTransaction();
+                       droolsPdpIntegrityMonitor.endTransaction();
+                       PolicyLogger.debug("testLocking2: As expected, transaction successful");
+               } catch (AdministrativeStateException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught AdministrativeStateException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (StandbyStatusException e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught StandbyStatusException, message=" + e.getMessage());
+                       assertTrue(false);
+               } catch (Exception e) {
+                       PolicyLogger.error("testLocking2: Unexpectedly caught Exception, message=" + e.getMessage());
+                       assertTrue(false);
+               }
+               
+               PolicyLogger.debug("testLocking2: Verifying designated status for PDP="
+                               + standbyPdpId);
+               boolean standbyPdpDesignated = conn.getPdp(standbyPdpId).isDesignated();
+               assertTrue(standbyPdpDesignated == false);
+               
+               PolicyLogger.debug("testLocking2: Stopping policyManagementRunner");
+               policyManagementRunner.stopRunner();            
+
+               PolicyLogger.debug("\n\ntestLocking2: Exiting\n\n");
+               Thread.sleep(interruptRecoveryTime);
+
+       }
+       
+       private class PolicyManagementRunner extends Thread {
+
+               public void run() {
+                       PolicyLogger.info("PolicyManagementRunner.run: Entering");
+                       String args[] = { "src/main/server/config" };
+                       try {
+                               Main.main(args);
+                       } catch (Exception e) {
+                               PolicyLogger
+                                               .info("PolicyManagementRunner.run: Exception thrown from Main.main(), message="
+                                                               + e.getMessage());
+                       }
+                       PolicyLogger.info("PolicyManagementRunner.run: Exiting");
+               }
+               
+               public void stopRunner() {
+                       PolicyEngine.manager.shutdown();
+               }
+
+       }
+       
+}
diff --git a/policy-persistence/src/test/resources/IntegrityMonitor.properties b/policy-persistence/src/test/resources/IntegrityMonitor.properties
new file mode 100644 (file)
index 0000000..0ab3628
--- /dev/null
@@ -0,0 +1,67 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+#hostPort = ${{host_port}}
+hostPort = 0.0.0.0:9981
+
+# The following were added as part of US673632
+#
+# Forward Progress Monitor update interval seconds
+fp_monitor_interval = 30
+# Failed counter threshold before failover 
+failed_counter_threshold = 3
+# Interval between test transactions when no traffic seconds
+test_trans_interval = 10
+# Interval between writes of the FPC to the DB seconds 
+write_fpc_interval = 5
+# Name of the site in which this node is hosted 
+site_name = pdp_1
+# Node type
+# Note: Make sure you don't leave any trailing spaces, or you'll get an 'invalid node type' error! 
+node_type = pdp_drools
+# Dependency groups are groups of resources upon which a node operational state is dependent upon. 
+# Each group is a comma-separated list of resource names and groups are separated by a semicolon.  For example:
+#dependency_groups=site_1.astra_1,site_1.astra_2;site_1.brms_1,site_1.brms_2;site_1.logparser_1;site_1.pypdp_1
+#dependency_groups=${{dependency_groups}}
+dependency_groups=""
+# When set to true, dependent health checks are performed by using JMX to invoke test() on the dependent.
+# The default false is to use state checks for health.
+#test_via_jmx=${{test_via_jmx}}
+# This is the max number of seconds beyond which a non incrementing FPC is considered a failure
+#max_fpc_update_interval=${{max_fpc_update_interval}}
+
+# Needed by DroolsPdpsElectionHandler
+pdp.checkInterval=1500
+pdp.updateInterval=1000
+#pdp.timeout=3000
+# Need long timeout, because testTransaction is only run every 10 seconds.
+pdp.timeout=15000
+#how long do we wait for the pdp table to populate on initial startup
+pdp.initialWait=20000
+
+# Known as the PDPID in the droolpdpentity table.
+resource.name=pdp1
+#resource.name=${{resource_name}}
+
+
+
+
+
+
diff --git a/policy-persistence/src/test/resources/META-INF/persistence.xml b/policy-persistence/src/test/resources/META-INF/persistence.xml
new file mode 100644 (file)
index 0000000..51ec161
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  policy-persistence
+  ================================================================================
+  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=========================================================
+  -->
+
+<persistence version="2.1"
+       xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+
+       <persistence-unit name="junitDroolsPU" transaction-type="RESOURCE_LOCAL">
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.openecomp.policy.drools.persistence.DroolsPdpEntity</class>
+               <class>org.openecomp.policy.drools.persistence.DroolsSessionEntity</class>
+               <class>org.openecomp.policy.drools.persistence.LastSiteEntity</class>
+               <class>org.drools.persistence.info.SessionInfo</class>
+               <class>org.drools.persistence.info.WorkItemInfo</class>
+               <class>org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity</class>
+               <properties>
+                       <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
+                       <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/> 
+            <property name="javax.persistence.schema-generation.scripts.create-target" value="./sql/generatedCreateDrools.ddl"/>
+            <property name="javax.persistence.schema-generation.scripts.drop-target" value="./sql/generatedDropDrools.ddl"/>
+        </properties>
+       </persistence-unit>
+       
+       <persistence-unit name="junitXacmlPU" transaction-type="RESOURCE_LOCAL">
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.openecomp.policy.common.im.jpa.StateManagementEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.ForwardProgressEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.ResourceRegistrationEntity</class>
+               <class>org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity</class>
+               <properties>
+                       <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
+                       <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/> 
+            <property name="javax.persistence.schema-generation.scripts.create-target" value="./sql/generatedCreateXacml.ddl"/>
+            <property name="javax.persistence.schema-generation.scripts.drop-target" value="./sql/generatedDropXacml.ddl"/>
+        </properties>
+       </persistence-unit>
+
+</persistence>
diff --git a/policy-persistence/src/test/resources/droolsPersistence.properties b/policy-persistence/src/test/resources/droolsPersistence.properties
new file mode 100644 (file)
index 0000000..544e1c2
--- /dev/null
@@ -0,0 +1,51 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+javax.persistence.jdbc.driver = org.h2.Driver
+javax.persistence.jdbc.url  = jdbc:h2:file:./sql/drools
+javax.persistence.jdbc.user = sa
+javax.persistence.jdbc.password =
+
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://localhost:3306/drools
+#javax.persistence.jdbc.user=root
+#javax.persistence.jdbc.password=policy
+
+#javax.persistence.jdbc.driver = ${{JDBC_DRIVER}}
+#javax.persistence.jdbc.url  = ${{JDBC_DROOLS_URL}}
+#javax.persistence.jdbc.user = ${{JDBC_USER}}
+#javax.persistence.jdbc.password = ${{JDBC_PASSWORD}}
+
+# Needed?
+#javax.persistence.jdbc.driver = org.h2.Driver
+#javax.persistence.jdbc.url  = jdbc:h2:file:./sql/ncomp
+#javax.persistence.jdbc.user = sa
+#javax.persistence.jdbc.password =
+#persistenceDisabled=false
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://192.168.56.30:3306/drools
+#javax.persistence.jdbc.user=patb
+#javax.persistence.jdbc.password=policy
+
+hibernate.dataSource=org.mariadb.jdbc.MySQLDataSource
+
+# For testing purposes, it may be convenient to disable persistence
+persistenceDisabled=false
+
diff --git a/policy-persistence/src/test/resources/log4j.properties b/policy-persistence/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..746d59a
--- /dev/null
@@ -0,0 +1,31 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+log4j.rootLogger=DEBUG, out
+log4j.logger.com.att=DEBUG
+log4j.logger.org.openecomp.policy.drools.system=DEBUG
+log4j.logger.org.openecomp.policy.drools.im=DEBUG
+log4j.logger.org.openecomp.policy.common.im=DEBUG
+log4j.logger.org.openecomp.policy.drools.event.comm=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d %-5p %-30.30c{1} %4L - %m%n
diff --git a/policy-persistence/src/test/resources/logback.xml b/policy-persistence/src/test/resources/logback.xml
new file mode 100644 (file)
index 0000000..9fd83e8
--- /dev/null
@@ -0,0 +1,209 @@
+<!--
+  ============LICENSE_START=======================================================
+  policy-persistence
+  ================================================================================
+  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=========================================================
+  -->
+
+<!-- Controls the output of logs for JUnit tests -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  <property name="logDir" value="testingLogs" />
+  
+  <!-- directory path for debugging type logs -->
+  <property name="debugDir" value="testingLogs" />
+  
+  <!--  specify the component name 
+    <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="drools-pdp"></property>
+  <property name="subComponentName" value="policy-management"></property>
+  
+  <!--  log file names -->
+  <property name="errorLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  
+   <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{server}|%X{clientIpAddress}|%c||%msg%n" />
+   <!--  <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}||%X{Timer}|%msg%n" />  -->
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+   <!--
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+  -->
+  <!-- example from old log4j.properties:  ${catalina.base}/logs/pdp-rest.log  -->  
+
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+
+  <!-- The EELFAppender is used to record events to the general application 
+    log -->
+    
+    
+
+  
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+    related logging events. The audit logger and appender are specializations 
+    of the EELF application root logger and appender. This can be used to segregate 
+    Policy engine events from other components, or it can be eliminated to record 
+    these events as part of the application root log. -->
+    
+  <appender name="EELFAudit"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+         <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+
+<appender name="EELFMetrics"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+        %msg%n"</pattern> -->
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+   
+  <appender name="EELFError"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${errorLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>ERROR</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFError"/>
+  </appender>
+  
+   <appender name="EELFDebug"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${debugLogDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <!-- <level>INFO</level> -->
+     <level>DEBUG</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>true</includeCallerData>
+  </appender>
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+    <logger name="com.att.eelf.error" level="error" additivity="false">
+  <appender-ref ref="asyncEELFError" />
+  </logger>
+  
+   <!-- <logger name="com.att.eelf.debug" level="info" additivity="false"> -->
+   <logger name="com.att.eelf.debug" level="debug" additivity="false">
+        <appender-ref ref="asyncEELFDebug" />
+  </logger>
+  
+  <!-- <root level="INFO"> -->
+  <root level="DEBUG">
+        <appender-ref ref="asyncEELFDebug" />
+        <appender-ref ref="asyncEELFError" />
+  </root>
+
+</configuration>
diff --git a/policy-persistence/src/test/resources/xacmlPersistence.properties b/policy-persistence/src/test/resources/xacmlPersistence.properties
new file mode 100644 (file)
index 0000000..284e87d
--- /dev/null
@@ -0,0 +1,43 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+javax.persistence.jdbc.driver = org.h2.Driver
+javax.persistence.jdbc.url  = jdbc:h2:file:./sql/xacml
+javax.persistence.jdbc.user = sa
+javax.persistence.jdbc.password =
+
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://127.0.0.1:3306/xacml
+#javax.persistence.jdbc.user=root
+#javax.persistence.jdbc.password=policy
+
+#javax.persistence.jdbc.driver = ${{JDBC_DRIVER}}
+#javax.persistence.jdbc.url  = ${{JDBC_URL}}
+#javax.persistence.jdbc.user = ${{JDBC_USER}}
+#javax.persistence.jdbc.password = ${{JDBC_PASSWORD}}
+
+# Needed?
+hibernate.dataSource=org.mariadb.jdbc.MySQLDataSource
+
+# For testing purposes, it may be convenient to disable persistence
+persistenceDisabled=false
+
+
diff --git a/policy-persistence/src/test/server/config/IntegrityMonitor.properties b/policy-persistence/src/test/server/config/IntegrityMonitor.properties
new file mode 100644 (file)
index 0000000..b16beda
--- /dev/null
@@ -0,0 +1,62 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+# port 9981 fails on Jenkins, so try another.
+hostPort = 0.0.0.0:57692
+
+# The following were added as part of US673632
+#
+# Forward Progress Monitor update interval seconds
+fp_monitor_interval = 30
+# Failed counter threshold before failover 
+failed_counter_threshold = 3
+# Interval between test transactions when no traffic seconds
+test_trans_interval = 10
+# Interval between writes of the FPC to the DB seconds 
+write_fpc_interval = 5
+# Name of the site in which this node is hosted 
+site_name = pdp_1
+# Node type. Can take values of: pdp-xacml, pdp-drools, pap, pap-admin, logparser, brms-gateway, 
+# astra-gateway, elk-server and pypdpNode type
+# Note: Make sure you don't leave any trailing spaces, or you'll get an 'invalid node type' error! 
+node_type = pdp_drools
+# Dependency groups are groups of resources upon which a node operational state is dependent upon. 
+# Each group is a comma-separated list of resource names and groups are separated by a semicolon.  For example:
+#For JUnit testing this must be empty since none of the other components exist 
+#dependency_groups=site_1.astra_1,site_1.astra_2;site_1.brms_1,site_1.brms_2;site_1.logparser_1;site_1.pypdp_1
+dependency_groups=
+
+# Needed by DroolsPdpsElectionHandler
+pdp.checkInterval=1500
+pdp.updateInterval=1000
+#pdp.timeout=3000
+# Need long timeout, because testTransaction is only run every 10 seconds.
+pdp.timeout=15000
+#how long do we wait for the pdp table to populate on initial startup
+pdp.initialWait=20000
+
+# Known as the PDPID in the droolpdpentity table.
+resource.name=pdp1
+
+# The amount of this a resource (entity) should sleep between audit executions.
+# If not specified, defaults to five seconds.
+# -1 turns off audit
+# zero forces audit to run continuously
+integrity_audit_period_seconds=60
diff --git a/policy-persistence/src/test/server/config/droolsPersistence.properties b/policy-persistence/src/test/server/config/droolsPersistence.properties
new file mode 100644 (file)
index 0000000..8cdaf6a
--- /dev/null
@@ -0,0 +1,35 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+javax.persistence.jdbc.driver = org.h2.Driver
+javax.persistence.jdbc.url  = jdbc:h2:file:./sql/drools
+javax.persistence.jdbc.user = sa
+javax.persistence.jdbc.password =
+
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://localhost:3306/drools
+#javax.persistence.jdbc.user=root
+#javax.persistence.jdbc.password=policy
+
+# Needed?
+hibernate.dataSource=org.mariadb.jdbc.MySQLDataSource
+
+# For testing purposes, it may be convenient to disable persistence
+persistenceDisabled=false
diff --git a/policy-persistence/src/test/server/config/policyLogger.properties b/policy-persistence/src/test/server/config/policyLogger.properties
new file mode 100644 (file)
index 0000000..6ee66fd
--- /dev/null
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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 
+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
diff --git a/policy-persistence/src/test/server/config/xacmlPersistence.properties b/policy-persistence/src/test/server/config/xacmlPersistence.properties
new file mode 100644 (file)
index 0000000..149aa55
--- /dev/null
@@ -0,0 +1,38 @@
+###
+# ============LICENSE_START=======================================================
+# policy-persistence
+# ================================================================================
+# 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=========================================================
+###
+
+javax.persistence.jdbc.driver = org.h2.Driver
+javax.persistence.jdbc.url  = jdbc:h2:file:./sql/xacml
+javax.persistence.jdbc.user = sa
+javax.persistence.jdbc.password =
+
+#javax.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://127.0.0.1:3306/xacml
+#javax.persistence.jdbc.user=root
+#javax.persistence.jdbc.password=policy
+
+# Needed?
+hibernate.dataSource=org.mariadb.jdbc.MySQLDataSource
+
+# For testing purposes, it may be convenient to disable persistence
+persistenceDisabled=false
+
+
diff --git a/policy-utils/pom.xml b/policy-utils/pom.xml
new file mode 100644 (file)
index 0000000..b7ac7fb
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>policy-utils</artifactId>
+
+  <parent>
+    <groupId>org.openecomp.policy.drools-pdp</groupId>
+    <artifactId>drools-pdp</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+
+       <dependencies>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.11</version>
+               </dependency>
+        <dependency>
+                <groupId>log4j</groupId>
+                <artifactId>log4j</artifactId>
+                <version>1.2.17</version>
+                       <scope>provided</scope>
+        </dependency>          
+        <dependency>
+                       <groupId>com.att.eelf</groupId>
+                       <artifactId>eelf-core</artifactId>
+                       <version>0.0.1</version>
+               </dependency>                   
+               <dependency>
+                       <groupId>ch.qos.logback</groupId>
+                       <artifactId>logback-classic</artifactId>
+                       <version>1.1.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>ch.qos.logback</groupId>
+                       <artifactId>logback-core</artifactId>
+                       <version>1.1.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-api</artifactId>
+                       <version>1.7.6</version>
+               </dependency>       
+               <dependency>
+                       <groupId>org.openecomp.policy.common</groupId>
+                       <artifactId>ECOMP-Logging</artifactId>
+                       <version>${common-modules.version}</version>
+               </dependency>   
+       </dependencies>
+
+    
+</project>
diff --git a/policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedService.java b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedService.java
new file mode 100644 (file)
index 0000000..b50e6e8
--- /dev/null
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.utils;
+
+/**
+ * This is a base interface that is used to control the order of a list
+ * of services (features) discovered via 'ServiceLoader'. See
+ * 'OrderedServiceImpl' for more details.
+ */
+public interface OrderedService
+{
+  /**
+   * @return an integer sequence number, which determines the order of a list
+   *   of objects implementing this interface
+   */
+  public int getSequenceNumber();
+}
diff --git a/policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedServiceImpl.java b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedServiceImpl.java
new file mode 100644 (file)
index 0000000..2747e85
--- /dev/null
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.utils;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ServiceLoader;
+
+/**
+ * This class is a template for building a sorted list of service instances,
+ * which are discovered and created using 'ServiceLoader'. 
+ */
+public class OrderedServiceImpl<T extends OrderedService>
+{
+  // sorted list of instances implementing the service
+  private List<T> implementers = null;
+
+  // 'ServiceLoader' that is used to discover and create the services
+  private ServiceLoader<T> serviceLoader = null; //ServiceLoader.load(T.class);
+
+  /**
+   * Constructor - create the 'ServiceLoader' instance
+   *
+   * @param clazz the class object associated with 'T' (I supposed it could
+   *   be a subclass, but I'm not sure this is useful)
+   */
+  public OrderedServiceImpl(Class clazz)
+  {
+       // This constructor wouldn't be needed if 'T.class' was legal
+       serviceLoader = ServiceLoader.load(clazz);
+  }
+
+  /**
+   * @return the sorted list of services implementing interface 'T' discovered
+   *   by 'ServiceLoader'.
+   */
+  public synchronized List<T> getList()
+  {
+       if (implementers == null)
+         {
+               rebuildList();
+         }
+       return(implementers);
+  }
+
+  /**
+   * This method is called by 'getList', but could also be called directly if
+   * we were running with a 'ClassLoader' that supported the dynamic addition
+   * of JAR files. In this case, it could be invoked in order to discover any
+   * new services implementing interface 'T'. This is probably a relatively
+   * expensive operation in terms of CPU and elapsed time, so it is best if it
+   * isn't invoked too frequently.
+   *
+   * @return the sorted list of services implementing interface 'T' discovered
+   *   by 'ServiceLoader'.
+   */
+  public synchronized List<T> rebuildList()
+  {
+       // build a list of all of the current implementors
+       List<T> tmp = new LinkedList<T>();
+       for (T service : serviceLoader)
+         {
+               tmp.add(service);
+         }
+
+       // Sort the list according to sequence number, and then alphabetically
+       // according to full class name.
+       Collections.sort(tmp, new Comparator<T>()
+                                        {
+                                          public int compare(T o1, T o2)
+                                                {
+                                                  int s1 = o1.getSequenceNumber();
+                                                  int s2 = o2.getSequenceNumber();
+                                                  int rval;
+                                                  if (s1 < s2)
+                                                        {
+                                                          rval = -1;
+                                                        }
+                                                  else if (s1 > s2)
+                                                        {
+                                                          rval = 1;
+                                                        }
+                                                  else
+                                                        {
+                                                          rval = o1.getClass().getName().compareTo
+                                                                (o2.getClass().getName());
+                                                        }
+                                                  return(rval);
+                                                }
+                                        });
+
+       // create an unmodifiable version of this list
+       implementers = Collections.unmodifiableList(tmp);
+       System.out.println("***** OrderedServiceImpl implementers:\n" + implementers);
+       return(implementers);
+  }
+}
diff --git a/policy-utils/src/main/java/org/openecomp/policy/drools/utils/Pair.java b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/Pair.java
new file mode 100644 (file)
index 0000000..a5e3469
--- /dev/null
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.utils;
+
+public class Pair<F,S> {
+       
+    protected F first;
+    protected S second;
+    
+       public Pair(F first, S second){
+        this.first = first;
+        this.second = second;
+    }
+       
+    public F first() {return this.first;}
+    
+    public S second() {return this.second;}
+    
+    public F getFirst() {return this.first;}
+
+       public S getSecond() {return this.second;}
+    
+    public void first(F first) {this.first = first;}
+    
+    public void second(S second) {this.second = second;}
+    
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("Pair [first=").append(first).append(", second=").append(second).append("]");
+               return builder.toString();
+       }
+}
diff --git a/policy-utils/src/main/java/org/openecomp/policy/drools/utils/PropertyUtil.java b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/PropertyUtil.java
new file mode 100644 (file)
index 0000000..34ddcc1
--- /dev/null
@@ -0,0 +1,403 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * This class provides utilities to read properties from a properties
+ * file, and optionally get notifications of future changes
+ */
+public class PropertyUtil
+{
+  /**
+   * Read in a properties file
+   * @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.
+   */
+  static public Properties getProperties(File file) throws IOException
+  {
+       // create an InputStream (may throw a FileNotFoundException)
+       FileInputStream fis = new FileInputStream(file);
+       try
+         {
+               // create the properties instance
+               Properties rval = new Properties();
+
+               // load properties (may throw an IOException)
+               rval.load(fis);
+               return(rval);
+         }
+       finally
+         {
+               // close input stream
+               fis.close();
+         }
+  }
+
+  /**
+   * Read in a properties file
+   * @param fileName 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.
+   */
+  static public Properties getProperties(String fileName) throws IOException
+  {
+       return(getProperties(new File(fileName)));
+  }
+
+  /* ============================================================ */
+
+  // timer thread used for polling for property file changes
+  private static Timer timer = null;
+
+  /**
+   * This is the callback interface, used for sending notifications of
+   * changes in the properties file.
+   */
+  public interface Listener
+  {
+       /**
+        * Notification of a properties file change
+        * @param properties the new properties
+        * @param the set of property names that have changed, including
+        *              additions and removals
+        */
+       void propertiesChanged(Properties properties, Set<String> changedKeys);
+  }
+
+  // this table maps canonical file into a 'ListenerRegistration' instance
+  static private HashMap<File, ListenerRegistration> registrations =
+       new HashMap<File, ListenerRegistration>();
+
+  /**
+   * This is an internal class - one instance of this exists for each
+   * property file that is being monitored. Note that multiple listeners
+   * can be registered for the same file.
+   */
+  private static class ListenerRegistration
+  {
+       // the canonical path of the file being monitored
+       File file;
+
+       // the most recent value of 'file.lastModified()'
+       long lastModified;
+
+       // the most recent set of properties
+       Properties properties;
+
+       // the set of listeners monitoring this file
+       LinkedList<Listener> listeners;
+
+       // the 'TimerTask' instance, used for periodic polling
+       TimerTask timerTask;
+
+       /**
+        * Constructor - create a 'ListenerRegistration' instance for this
+        * file, but with no listeners
+        */
+       ListenerRegistration(File file) throws IOException
+       {
+         this.file = file;
+
+         // The initial value of 'lastModified' is set to 0 to ensure that we
+         // correctly handle the case where the file is modified within the
+         // same second that polling begins.
+         lastModified = 0;
+
+         // fetch current properties
+         properties = getProperties(file);
+
+         // no listeners yet
+         listeners = new LinkedList<Listener>();
+
+         // add to static table, so this instance can be shared
+         registrations.put(file, this);
+
+         if (timer == null)
+               {
+                 // still need to create a timer thread
+                 synchronized(PropertyUtil.class)
+                       {
+                         // an additional check is added inside the 'synchronized' block,
+                         // just in case someone beat us to it
+                         if (timer == null)
+                               {
+                                 timer = new Timer("PropertyUtil-Timer", true);
+                               }
+                       }
+               }
+
+         // create and schedule the timer task, so this is periodically polled
+         timerTask = new TimerTask()
+               {
+                 public void run()
+                 {
+                       try
+                         {
+                               poll();
+                         }
+                       catch (Exception e)
+                         {
+                               System.err.println(e);
+                         }
+                 }
+               };
+         timer.schedule(timerTask, 10000L, 10000L);
+       }
+
+       /**
+        * Add a listener to the notification list
+        * @param listener this is the listener to add to the list
+        * @return the properties at the moment the listener was added to the list
+        */
+       synchronized Properties addListener(Listener listener)
+       {
+         listeners.add(listener);
+         return((Properties)properties.clone());
+       }
+
+       /**
+        * Remove a listener from the notification list
+        * @param listener this is the listener to remove
+        */
+       synchronized void removeListener(Listener listener)
+       {
+         listeners.remove(listener);
+
+         // See if we need to remove this 'ListenerRegistration' instance
+         // from the table. The 'synchronized' block is needed in case
+         // another listener is being added at about the same time that this
+         // one is being removed.
+         synchronized(registrations)
+               {
+                 if (listeners.size() == 0)
+                       {
+                         timerTask.cancel();
+                         registrations.remove(file);
+                       }
+               }
+       }
+
+       /**
+        * This method is periodically called to check for property list updates
+        * @throws IOException if there is an error in reading the properties file
+        */
+       synchronized void poll() throws IOException
+       {
+         long timestamp = file.lastModified();
+         if (timestamp != lastModified)
+               {
+                 // update the record, and send out the notifications
+                 lastModified = timestamp;
+
+                 // Save old set, and initial set of changed properties.
+                 Properties oldProperties = properties;
+                 HashSet<String> changedProperties =
+                       new HashSet<String>(oldProperties.stringPropertyNames());
+
+                 // Fetch the list of listeners that we will potentially notify,
+                 // and the new properties. Note that this is in a 'synchronized'
+                 // block to ensure that all listeners receiving notifications
+                 // actually have a newer list of properties than the one
+                 // returned on the initial 'getProperties' call.
+                 properties = getProperties(file);
+                 
+                 Set<String> newPropertyNames = properties.stringPropertyNames();
+                 changedProperties.addAll(newPropertyNames);
+
+                 // At this point, 'changedProperties' is the union of all properties
+                 // in both the old and new properties files. Iterate through all
+                 // of the entries in the new properties file - if the entry
+                 // matches the one in the old file, remove it from
+                 // 'changedProperties'.
+                 for (String name : newPropertyNames)
+                       {
+                         if (properties.getProperty(name).equals
+                                 (oldProperties.getProperty(name)))
+                               {
+                                 // Apparently, any property that exists must be of type
+                                 // 'String', and can't be null. For this reason, we don't
+                                 // need to worry about the case where
+                                 // 'properties.getProperty(name)' returns 'null'. Note that
+                                 // 'oldProperties.getProperty(name)' may be 'null' if the
+                                 // old property does not exist.
+                                 changedProperties.remove(name);
+                               }
+                       }
+
+                 // 'changedProperties' should be correct at this point
+                 if (changedProperties.size() != 0)
+                       {
+                         // there were changes - notify everyone in 'listeners'
+                         for (final Listener notify : listeners)
+                               {
+                                 // Copy 'properties' and 'changedProperties', so it doesn't
+                                 // cause problems if the recipient makes changes.
+                                 final Properties tmpProperties =
+                                       (Properties)(properties.clone());
+                                 final HashSet<String> tmpChangedProperties =
+                                       new HashSet<String>(changedProperties);
+
+                                 // Do the notification in a separate thread, so blocking
+                                 // won't cause any problems.
+                                 new Thread()
+                                 {
+                                       public void run()
+                                       {
+                                         notify.propertiesChanged
+                                               (tmpProperties, tmpChangedProperties);
+                                       }
+                                 }.start();
+                               }
+                       }
+               }
+       }
+  }
+
+  /**
+   * Read in a properties file, and register for update notifications.
+   * NOTE: it is possible that the first callback will occur while this
+   * method is still in progress. To avoid this problem, use 'synchronized'
+   * blocks around this invocation and in the callback -- that will ensure
+   * that the processing of the initial properties complete before any
+   * updates are processed.
+   *
+   * @param file the properties file
+   * @param notify if not null, this is a callback interface that is used for
+   *   notifications of changes
+   * @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.
+   */
+  static public Properties getProperties(File file, Listener listener)
+       throws IOException
+  {
+       if (listener == null)
+         {
+               // no listener specified -- just fetch the properties
+               return(getProperties(file));
+         }
+
+       // Convert the file to a canonical form in order to avoid the situation
+       // where different names refer to the same file.
+       file = file.getCanonicalFile();
+
+       // See if there is an existing registration. The 'synchronized' block
+       // is needed to handle the case where a new listener is added at about
+       // the same time that another one is being removed.
+       synchronized(registrations)
+         {
+               ListenerRegistration reg = registrations.get(file);
+               if (reg == null)
+                 {
+                       // a new registration is needed
+                       reg = new ListenerRegistration(file);
+                 }
+               return(reg.addListener(listener));
+         }
+  }
+
+  /**
+   * Read in a properties file, and register for update notifications.
+   * NOTE: it is possible that the first callback will occur while this
+   * method is still in progress. To avoid this problem, use 'synchronized'
+   * blocks around this invocation and in the callback -- that will ensure
+   * that the processing of the initial properties complete before any
+   * updates are processed.
+   *
+   * @param fileName the properties file
+   * @param notify if not null, this is a callback interface that is used for
+   *   notifications of changes
+   * @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.
+   */
+  static public Properties getProperties(String fileName, Listener listener)
+       throws IOException
+  {
+       return(getProperties(new File(fileName), listener));
+  }
+
+  /**
+   * Stop listenening for updates
+   * @param file the properties file
+   * @param notify if not null, this is a callback interface that was used for
+   *   notifications of changes
+   */
+  static public void stopListening(File file, Listener listener)
+  {
+       if (listener != null)
+         {
+               ListenerRegistration reg = registrations.get(file);
+               if (reg != null)
+                 {
+                       reg.removeListener(listener);
+                 }
+         }
+  }
+
+  /**
+   * Stop listenening for updates
+   * @param fileName the properties file
+   * @param notify if not null, this is a callback interface that was used for
+   *   notifications of changes
+   */
+  static public void stopListening(String fileName, Listener listener)
+  {
+       stopListening(new File(fileName), listener);
+  }
+
+  /* ============================================================ */
+
+  // TEMPORARY - used to test callback interface
+  static public class Test implements Listener
+  {
+       String name;
+
+       public Test(String name)
+         {
+               this.name = name;
+         }
+
+       public void propertiesChanged(Properties properties, Set<String> changedKeys)
+         {
+               System.out.println("Test(" + name + ")\nproperties = " + properties
+                                                  + "\nchangedKeys = " + changedKeys);
+         }
+  }
+}
diff --git a/policy-utils/src/main/java/org/openecomp/policy/drools/utils/ReflectionUtil.java b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/ReflectionUtil.java
new file mode 100644 (file)
index 0000000..0b86c2a
--- /dev/null
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * 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=========================================================
+ */
+
+/**
+ * 
+ */
+package org.openecomp.policy.drools.utils;
+
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+/**
+ * Reflection utilities
+ *
+ */
+public class ReflectionUtil {
+       
+       /**
+        * returns (if exists) a class fetched from a given classloader
+        * 
+        * @param classLoader the class loader
+        * @param classname the class name
+        * @return the PolicyEvent class
+        * @throws IllegalArgumentException if an invalid parameter has been passed in
+        */
+       public static Class<?> fetchClass(ClassLoader classLoader, 
+                                                 String classname) 
+               throws IllegalArgumentException {
+               
+               PolicyLogger.info("FETCH-CLASS: " +  classname + " FROM " + classLoader);
+               
+               if (classLoader == null)
+                       throw new IllegalArgumentException("A class loader must be provided");
+               
+               if (classname == null)
+                       throw new IllegalArgumentException("A class name to be fetched in class loader " +
+                                                      classLoader + " must be provided");
+               
+               try {
+                       Class<?> aClass = Class.forName(classname, 
+                                                               true, 
+                                                               classLoader);
+                       return aClass;
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       PolicyLogger.error("FETCH-CLASS: " + classname + " IN " + classLoader + " does NOT exist");
+               }
+               
+               return null;
+       }
+       
+       /**
+        * 
+        * @param classLoader target class loader
+        * @param classname class name to fetch
+        * @return true if exists
+        * @throws IllegalArgumentException if an invalid parameter has been passed in
+        */
+       public static boolean isClass(ClassLoader classLoader, String classname) 
+           throws IllegalArgumentException {
+               return fetchClass(classLoader, classname) != null;
+       }
+       
+       /**
+        * is a subclass?
+        * @param parent superclass
+        * @param presumedSubclass subclass
+        * @return
+        */
+       public static boolean isSubclass(Class<?> parent, Class<?> presumedSubclass) {          
+               PolicyLogger.debug("IS-SUBCLASS: superclass: " +  parent.getCanonicalName() + 
+                                         " subclass: " + presumedSubclass.getCanonicalName());
+               return (parent.isAssignableFrom(presumedSubclass));
+       }
+
+}
diff --git a/policy-utils/src/main/java/org/openecomp/policy/drools/utils/Triple.java b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/Triple.java
new file mode 100644 (file)
index 0000000..214d949
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.utils;
+
+public class Triple<F,S,T> {
+       
+    private F first;
+    private S second;
+    private T third;
+    
+    public Triple(F first, S second, T third){
+        this.first = first;
+        this.second = second;
+        this.third = third;
+    }
+    public F first(){ return this.first; }
+    
+    public S second(){ return this.second; }
+    
+    public T third(){ return this.third; }
+    
+    public void first(F first){ this.first = first; }
+    
+    public void second(S second){ this.second = second; }
+    
+    public void third(T third){ this.third = third; }
+}
diff --git a/policy-utils/src/test/java/org/openecomp/policy/drools/utils/PropertyUtilTest.java b/policy-utils/src/test/java/org/openecomp/policy/drools/utils/PropertyUtilTest.java
new file mode 100644 (file)
index 0000000..5509171
--- /dev/null
@@ -0,0 +1,204 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.drools.utils;
+
+import static org.junit.Assert.*;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+public class PropertyUtilTest
+{
+ // private static final Logger PolicyLogger =
+//     Logger.getLogger(PropertyUtilTest.class.getName());
+
+  private static File directory = null;
+
+  /**
+   * Test Setup -- Create a directory for temporary files
+   */
+  @BeforeClass
+       static public void setup()
+  {
+       PolicyLogger.info("setup: creating a temporary directory");
+
+       // create a directory for temporary files
+       directory = new File(UUID.randomUUID().toString());
+       directory.mkdir();
+  }
+
+  /**
+   * Test Cleanup -- Remove temporary files
+   */
+  @AfterClass
+       static public void teardown()
+  {
+       PolicyLogger.info("teardown: remove the temporary directory");
+
+       // the assumption is that we only have one level of temporary files
+       for (File file : directory.listFiles())
+         {
+               file.delete();
+         }
+       directory.delete();
+  }
+
+  /**
+   * Utility method to write a properties file
+   *
+   * @param name the file name, relative to the temporary directory
+   * @param the properties to store in the file
+   * @return a File instance associated with the newly-created file
+   * @throws IOException if the file can't be created for some reason
+   */
+  File createFile(String name, Properties p) throws IOException
+  {
+       File file = new File(directory, name);
+       FileOutputStream fos = new FileOutputStream(file);
+       try
+         {
+               p.store(fos, "Property file '" + name + "'");
+         }
+       finally
+         {
+               fos.close();
+         }
+       return(file);
+  }
+
+  /**
+   * Create a 'PropertyUtil.Listener' subclass, which receives property
+   * file updates. It stores the latest values in an array, and notifies
+   * any thread waiting on this array.
+   *
+   * @param returns this is an array of length 2 -- the first entry will
+   *   contain the 'properties' value, and the second will contain
+   *   'changedKeys'. It is also used to signal any waiting thread
+   *   using 'returns.notifyAll()'.
+   */
+  PropertyUtil.Listener createListenerThread(final Object[] returns)
+  {
+       return(new PropertyUtil.Listener()
+         {
+               public void propertiesChanged
+                 (Properties properties, Set<String> changedKeys)
+               {
+                 // When a notification is received, store the values in the
+                 // 'returns' array, and signal using the same array.
+                 PolicyLogger.info("Listener invoked: properties=" + properties
+                                         + ", changedKeys=" + changedKeys);
+                 returns[0] = properties;
+                 returns[1] = changedKeys;
+                 synchronized(returns)
+                       {
+                         returns.notifyAll();
+                       }
+               }
+         });
+  }
+
+  /**
+   * Test the basic properties file interface.
+   */
+  @Test
+       public void testGetProperties() throws Exception
+  {
+       PolicyLogger.info("testGetProperties: test the basic properties file interface");
+
+       // copy system properties
+       PolicyLogger.info("Copy system properties to a file");
+       Properties prop1 = System.getProperties();
+       File file1 = createFile("createAndReadPropertyFile-1", prop1);
+
+       // read in properties, and compare
+       PolicyLogger.info("Read in properties from new file");
+       Properties prop2 = PropertyUtil.getProperties(file1);
+
+       // they should match
+       assertEquals(prop1, prop2);
+  }
+
+  /**
+   * This tests the 'PropertyUtil.Listener' interface.
+   */
+  @Test
+       public void testListenerInterface() throws Exception
+  {
+       PolicyLogger.info("testListenerInterface: test receipt of dynamic updates");
+
+       // create initial property file
+       Properties prop1 = new Properties();
+       prop1.setProperty("p1", "p1 value");
+       prop1.setProperty("p2", "p2 value");
+       prop1.setProperty("p3", "p3 value");
+       PolicyLogger.info("Create initial properties file: " + prop1);
+       File file1 = createFile("createAndReadPropertyFile-2", prop1);
+
+       // create a listener for the notification interface
+       Object[] returns = new Object[2];
+       PropertyUtil.Listener listener = createListenerThread(returns);
+
+       // read it in, and do a comparison
+       Properties prop2 = PropertyUtil.getProperties(file1, listener);
+       PolicyLogger.info("Read in properties: " + prop2);
+       assertEquals(prop1, prop2);
+       assertEquals(prop2.getProperty("p1"), "p1 value");
+       assertEquals(prop2.getProperty("p2"), "p2 value");
+       assertEquals(prop2.getProperty("p3"), "p3 value");
+
+       // make some changes, and update the file (p3 is left unchanged)
+       prop2.remove("p1");             // remove one property
+       prop2.setProperty("p2", "new p2 value");        // change one property
+       prop2.setProperty("p4", "p4 value");            // add a new property
+       PolicyLogger.info("Modified properties: " + prop2);
+
+       // now, update the file, and wait for notification
+       synchronized(returns)
+         {
+               createFile("createAndReadPropertyFile-2", prop2);
+
+               // wait up to 60 seconds, although we should receive notification
+               // in 10 seconds or less (if things are working)
+               returns.wait(60000L);
+         }
+
+       // verify we have the updates
+       assertEquals(prop2, returns[0]);
+
+       // verify that we have the expected set of keys
+       assertEquals(new TreeSet(Arrays.asList(new String[]{"p1", "p2", "p4"})),
+                                returns[1]);
+  }
+}
diff --git a/policy-utils/src/test/resources/log4j.properties b/policy-utils/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..0063f10
--- /dev/null
@@ -0,0 +1,26 @@
+###
+# ============LICENSE_START=======================================================
+# policy-utils
+# ================================================================================
+# 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=========================================================
+###
+
+log4j.rootLogger=INFO, out
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d %-5p %-30.30c{1} %4L - %m%n
diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..0400209
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,194 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>org.openecomp.policy.drools-pdp</groupId>
+       <artifactId>drools-pdp</artifactId>
+       <version>1.0.0-SNAPSHOT</version>
+       <packaging>pom</packaging>
+       <name>ECOMP Policy Engine - Drools PDP</name>
+
+       <description>The ECOMP Policy Engine drools-based PDP Project</description>
+
+       <properties>
+               <maven.compiler.source>1.8</maven.compiler.source>
+               <maven.compiler.target>1.8</maven.compiler.target>
+
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <project.source.version>1.8</project.source.version>
+               <project.target.version>1.8</project.target.version>
+               <!-- <common-modules.version>[1.0.0-SNAPSHOT]</common-modules.version> -->
+               <common-modules.version>1.0.0-SNAPSHOT</common-modules.version>
+  
+               <sonar.language>java</sonar.language>
+               <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+               <sonar.surefire.reportsPath>${project.build.directory}/surefire-reports</sonar.surefire.reportsPath>
+               <sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco.exec</sonar.jacoco.reportPath>
+               <sonar.jacoco.itReportPath>/opt/app/jacoco-it.exec</sonar.jacoco.itReportPath>
+               <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero>
+       </properties>
+
+       <modules>
+               <module>policy-utils</module>
+               <module>policy-core</module>
+               <module>policy-endpoints</module>
+               <module>policy-management</module>
+               <module>policy-persistence</module>
+               <module>policy-healthcheck</module>
+               <module>packages</module>
+       </modules>
+
+       <repositories>
+               <repository>
+                       <id>central</id>
+                       <name>Maven 2 repository</name>
+                       <url>http://repo2.maven.org/maven2/</url>
+               </repository>
+
+               <repository>
+                 <id>eclipse</id>
+                 <url>https://repo.eclipse.org/content/repositories/releases</url>
+                 <releases>
+                   <enabled>true</enabled>
+                   <updatePolicy>daily</updatePolicy>
+                 </releases>
+                 <snapshots>
+                   <enabled>false</enabled>
+                 </snapshots>
+               </repository>
+
+               <repository>
+                       <id>soapUI</id>
+                       <url>http://www.soapui.org/repository/maven2/</url>
+                       <name>SoapUI plugin</name>
+               </repository>
+       </repositories>
+
+       <dependencies>
+
+       </dependencies>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-deploy-plugin</artifactId>
+                               <version>2.8</version> <!-- This version supports the "deployAtEnd" parameter -->
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>3.0</version>
+                               <configuration>
+                                       <encoding>${project.encoding}</encoding>
+                                       <source>${project.source.version}</source>
+                                       <target>${project.target.version}</target>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>2.6</version>
+                               <configuration>
+                                       <encoding>${project.encoding}</encoding>
+                               </configuration>
+                       </plugin>
+                       <!-- 
+                               license plugin
+                            Run 
+                               mvn clean 
+                            before running from the command line
+                               mvn license:update-file-header
+                       -->
+                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                               <artifactId>license-maven-plugin</artifactId>
+                               <version>1.9</version>
+                               <configuration>
+                                       <extraExtensions>
+                                               <!-- Used to add or change the header style <fileTypeYouAreMapping> 
+                                                       fileTypeMappedInto </fileTypeYouAreMapping> -->
+                                               <drl>java</drl>
+                                               <ccf>properties</ccf>
+
+                                               <!-- Because the typical sql comment type confuses the update algorithm -->
+                                               <sql>java</sql>
+                                       </extraExtensions>
+                                       <licenseName>apache_v2</licenseName>
+
+                                       <inceptionYear>2017</inceptionYear>
+                                       <organizationName>AT&amp;T Intellectual Property. All rights reserved.</organizationName>
+
+                                       <!-- Once you have established the tags and delimiter, they cannot be 
+                                               changed -->
+                                       <processStartTag>============LICENSE_START=======================================================</processStartTag>
+                                       <processEndTag>============LICENSE_END=========================================================</processEndTag>
+                                       <sectionDelimiter>================================================================================</sectionDelimiter>
+                                       <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
+                                       <canUpdateCopyright>true</canUpdateCopyright>
+                                       <canUpdateDescription>true</canUpdateDescription>
+                                       <canUpdateLicense>true</canUpdateLicense>
+                                       <emptyLineAfterHeader>true</emptyLineAfterHeader>
+                                       <roots>
+                                               <!-- Default is src, target/generated-sources, target/processed-sources -->
+
+                                               <!-- Everything except the files in the excludes section -->
+                                               <root>/</root>
+                                       </roots>
+                                       <excludes>
+                                               <!-- Files which are to be excluded. The pom.xml is excluded because 
+                                                       the start/end tags and the delimiters are in the body of the file. This confuses 
+                                                       the algorithm. So, this file must be manually updated with a license header. -->
+                                               <exclude>pom.xml</exclude>
+                                       </excludes>
+                               </configuration>
+                       </plugin>
+               </plugins>
+               <pluginManagement>
+                       <plugins>
+                               <plugin>
+                                       <groupId>org.jacoco</groupId>
+                                       <artifactId>jacoco-maven-plugin</artifactId>
+                                       <version>0.7.5.201505241946</version>
+                                       <configuration>
+                                               <dumpOnExit>true</dumpOnExit>
+                                               <includes>
+                                                       <include>org.openecomp.*</include>
+                                               </includes>
+                                       </configuration>
+                                       <executions>
+                                               <execution>
+                                                       <id>jacoco-initialize-unit-tests</id>
+                                                       <goals>
+                                                               <goal>prepare-agent</goal>
+                                                       </goals>
+                                                       <configuration>
+                                                               <destFile>${project.build.directory}/coverage-reports/jacoco.exec</destFile>
+                                                       </configuration>
+                                               </execution>
+                                       </executions>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+       </build>
+</project>
diff --git a/project-configs/maven/conf/settings.xml b/project-configs/maven/conf/settings.xml
new file mode 100644 (file)
index 0000000..55687cd
--- /dev/null
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+       license agreements. See the NOTICE file distributed with this work for additional 
+       information regarding copyright ownership. The ASF licenses this file to 
+       you 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. -->
+
+
+
+<!-- | This is the configuration file for Maven. It can be specified at two 
+       levels: | | 1. User Level. This settings.xml file provides configuration 
+       for a single user, | and is normally provided in ${user.home}/.m2/settings.xml. 
+       | | NOTE: This location can be overridden with the CLI option: | | -s /path/to/user/settings.xml 
+       | | 2. Global Level. This settings.xml file provides configuration for all 
+       Maven | users on a machine (assuming they're all using the same Maven | installation). 
+       It's normally provided in | ${maven.home}/conf/settings.xml. | | NOTE: This 
+       location can be overridden with the CLI option: | | -gs /path/to/global/settings.xml 
+       | | The sections in this sample file are intended to give you a running start 
+       at | getting the most out of your Maven installation. Where appropriate, 
+       the default | values (values used when the setting is not specified) are 
+       provided. | | -->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+       <!-- localRepository | The path to the local repository maven will use to 
+               store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> -->
+       <localRepository>${user.home}/.m2/repository</localRepository>
+       <!-- interactiveMode | This will determine whether maven prompts you when 
+               it needs input. If set to false, | maven will use a sensible default value, 
+               perhaps based on some other setting, for | the parameter in question. | | 
+               Default: true <interactiveMode>true</interactiveMode> -->
+
+       <!-- offline | Determines whether maven should attempt to connect to the 
+               network when executing a build. | This will have an effect on artifact downloads, 
+               artifact deployment, and others. | | Default: false <offline>false</offline> -->
+
+       <!-- pluginGroups | This is a list of additional group identifiers that 
+               will be searched when resolving plugins by their prefix, i.e. | when invoking 
+               a command line like "mvn prefix:goal". Maven will automatically add the group 
+               identifiers | "org.apache.maven.plugins" and "org.codehaus.mojo" if these 
+               are not already contained in the list. | -->
+       <pluginGroups>
+               <!-- pluginGroup | Specifies a further group identifier to use for plugin 
+                       lookup. <pluginGroup>com.your.plugins</pluginGroup> -->
+       </pluginGroups>
+
+       <!-- proxies | This is a list of proxies which can be used on this machine 
+               to connect to the network. | Unless otherwise specified (by system property 
+               or command-line switch), the first proxy | specification in this list marked 
+               as active will be used. | -->
+       <proxies>
+       </proxies>
+
+       <!-- servers | This is a list of authentication profiles, keyed by the server-id 
+               used within the system. | Authentication profiles can be used whenever maven 
+               must make a connection to a remote server. | -->
+       <servers>
+               <!-- server | Specifies the authentication information to use when connecting 
+                       to a particular server, identified by | a unique name within the system (referred 
+                       to by the 'id' attribute below). | | NOTE: You should either specify username/password 
+                       OR privateKey/passphrase, since these pairings are | used together. | <server> 
+                       <id>deploymentRepo</id> <username>repouser</username> <password>repopwd</password> 
+                       </server> -->
+
+               <!-- Another sample, using keys to authenticate. <server> <id>siteServer</id> 
+                       <privateKey>/path/to/private/key</privateKey> <passphrase>optional; leave 
+                       empty if not used.</passphrase> </server> -->
+       </servers>
+
+       <!-- mirrors | This is a list of mirrors to be used in downloading artifacts 
+               from remote repositories. | | It works like this: a POM may declare a repository 
+               to use in resolving certain artifacts. | However, this repository may have 
+               problems with heavy traffic at times, so people have mirrored | it to several 
+               places. | | That repository definition will have a unique id, so we can create 
+               a mirror reference for that | repository, to be used as an alternate download 
+               site. The mirror site will be the preferred | server for that repository. 
+               | -->
+       <mirrors>
+               <!-- mirror | Specifies a repository mirror site to use instead of a given 
+                       repository. The repository that | this mirror serves has an ID that matches 
+                       the mirrorOf element of this mirror. IDs are used | for inheritance and direct 
+                       lookup purposes, and must be unique across the set of mirrors. | -->
+       </mirrors>
+
+       <!-- profiles | This is a list of profiles which can be activated in a variety 
+               of ways, and which can modify | the build process. Profiles provided in the 
+               settings.xml are intended to provide local machine- | specific paths and 
+               repository locations which allow the build to work in the local environment. 
+               | | For example, if you have an integration testing plugin - like cactus 
+               - that needs to know where | your Tomcat instance is installed, you can provide 
+               a variable here such that the variable is | dereferenced during the build 
+               process to configure the cactus plugin. | | As noted above, profiles can 
+               be activated in a variety of ways. One way - the activeProfiles | section 
+               of this document (settings.xml) - will be discussed later. Another way essentially 
+               | relies on the detection of a system property, either matching a particular 
+               value for the property, | or merely testing its existence. Profiles can also 
+               be activated by JDK version prefix, where a | value of '1.4' might activate 
+               a profile when the build is executed on a JDK version of '1.4.2_07'. | Finally, 
+               the list of active profiles can be specified directly from the command line. 
+               | | NOTE: For profiles defined in the settings.xml, you are restricted to 
+               specifying only artifact | repositories, plugin repositories, and free-form 
+               properties to be used as configuration | variables for plugins in the POM. 
+               | | -->
+       <profiles>
+               <!-- profile | Specifies a set of introductions to the build process, to 
+                       be activated using one or more of the | mechanisms described above. For inheritance 
+                       purposes, and to activate profiles via <activatedProfiles/> | or the command 
+                       line, profiles have to have an ID that is unique. | | An encouraged best 
+                       practice for profile identification is to use a consistent naming convention 
+                       | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 
+                       'user-brett', etc. | This will make it more intuitive to understand what 
+                       the set of introduced profiles is attempting | to accomplish, particularly 
+                       when you only have a list of profile id's for debug. | | This profile example 
+                       uses the JDK version to trigger activation, and provides a JDK-specific repo. 
+                       <profile> <id>jdk-1.4</id> <activation> <jdk>1.4</jdk> </activation> <repositories> 
+                       <repository> <id>jdk14</id> <name>Repository for JDK 1.4 builds</name> <url>http://www.myhost.com/maven/jdk14</url> 
+                       <layout>default</layout> <snapshotPolicy>always</snapshotPolicy> </repository> 
+                       </repositories> </profile> -->
+
+               <!-- | Here is another profile, activated by the system property 'target-env' 
+                       with a value of 'dev', | which provides a specific path to the Tomcat instance. 
+                       To use this, your plugin configuration | might hypothetically look like: 
+                       | | ... | <plugin> | <groupId>org.myco.myplugins</groupId> | <artifactId>myplugin</artifactId> 
+                       | | <configuration> | <tomcatLocation>${tomcatPath}</tomcatLocation> | </configuration> 
+                       | </plugin> | ... | | NOTE: If you just wanted to inject this configuration 
+                       whenever someone set 'target-env' to | anything, you could just leave off 
+                       the <value/> inside the activation-property. | <profile> <id>env-dev</id> 
+                       <activation> <property> <name>target-env</name> <value>dev</value> </property> 
+                       </activation> <properties> <tomcatPath>/path/to/tomcat/instance</tomcatPath> 
+                       </properties> </profile> -->
+       </profiles>
+
+       <!-- activeProfiles | List of profiles that are active for all builds. | 
+               <activeProfiles> <activeProfile>alwaysActiveProfile</activeProfile> <activeProfile>anotherAlwaysActiveProfile</activeProfile> 
+               </activeProfiles> -->
+</settings>
diff --git a/version.properties b/version.properties
new file mode 100644 (file)
index 0000000..56ab0af
--- /dev/null
@@ -0,0 +1,35 @@
+###
+# ============LICENSE_START=======================================================
+# ECOMP Policy Engine - Drools PDP
+# ================================================================================
+# 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=========================================================
+###
+
+###########################################################
+# Versioning variables
+# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... )
+# because they are used in Jenkins, whose plug-in doesn't support
+release_name=1
+sprint_number=0
+feature_revision=0
+swm_revision=1
+
+base_version=${release_name}.${sprint_number}.${feature_revision}
+
+# Release must be completed with svn revision # in Jenkins
+release_version=${base_version}-${swm_revision}
+snapshot_version=${base_version}-SNAPSHOT