summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPamela Dragosh <pdragosh@research.att.com>2017-02-14 19:45:48 -0500
committerPamela Dragosh <pdragosh@research.att.com>2017-02-14 19:46:03 -0500
commit0e16acf4d8579fd82349d6cd24e236275735a818 (patch)
tree2c397f9d025dacfb3318d75e8fef9a750f71f76b
parentec6b0922de2f7e9e68ba9586efc9ed2ad75768f8 (diff)
Initial OpenECOMP policy/drools-pdp commit
Change-Id: I0072ccab6f40ed32da39667f9f8523b6d6dad2e2 Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
-rw-r--r--.gitignore7
-rw-r--r--.gitreview4
-rw-r--r--LICENSE.txt16
-rw-r--r--README.md3
-rw-r--r--packages/base/.gitignore1
-rw-r--r--packages/base/pom.xml95
-rw-r--r--packages/base/src/assembly/zip.xml42
-rw-r--r--packages/base/src/files/bin/db_upgrade_droolspdp.sh154
-rw-r--r--packages/base/src/files/bin/db_upgrade_droolspdp_remote.sh151
-rw-r--r--packages/base/src/files/bin/monitor.sh148
-rw-r--r--packages/base/src/files/bin/policy.sh154
-rw-r--r--packages/base/src/files/data/mysql/160400_droolspdp_downgrade_script.sql23
-rw-r--r--packages/base/src/files/data/mysql/160400_droolspdp_upgrade_script.sql57
-rw-r--r--packages/base/src/files/data/mysql/160401_droolspdp_downgrade_script.sql30
-rw-r--r--packages/base/src/files/data/mysql/160401_droolspdp_upgrade_script.sql30
-rw-r--r--packages/base/src/files/data/mysql/160700_droolspdp_downgrade_script.sql25
-rw-r--r--packages/base/src/files/data/mysql/160700_droolspdp_upgrade_script.sql68
-rw-r--r--packages/base/src/files/data/mysql/161000_droolspdp_downgrade_script.sql47
-rw-r--r--packages/base/src/files/data/mysql/161000_droolspdp_upgrade_script.sql54
-rw-r--r--packages/base/src/files/data/mysql/161001_droolspdp_downgrade_script.sql56
-rw-r--r--packages/base/src/files/data/mysql/161001_droolspdp_upgrade_script.sql52
-rw-r--r--packages/base/src/files/data/mysql/161002_droolspdp_downgrade_script.sql21
-rw-r--r--packages/base/src/files/data/mysql/161002_droolspdp_upgrade_script.sql41
-rw-r--r--packages/base/src/files/data/mysql/161003_droolspdp_downgrade_script.sql22
-rw-r--r--packages/base/src/files/data/mysql/161003_droolspdp_upgrade_script.sql29
-rw-r--r--packages/base/src/files/data/mysql/161004_droolspdp_downgrade_script.sql2
-rw-r--r--packages/base/src/files/data/mysql/161004_droolspdp_upgrade_script.sql5
-rw-r--r--packages/base/src/files/data/mysql/170200_droolspdp_downgrade_script.sql21
-rw-r--r--packages/base/src/files/data/mysql/170200_droolspdp_upgrade_script.sql21
-rwxr-xr-xpackages/base/src/files/etc/cron.d/monitor.cron1
-rw-r--r--packages/base/src/files/etc/monitor/monitor.cfg6
-rw-r--r--packages/base/src/files/etc/profile.d/env.sh35
-rw-r--r--packages/base/src/files/etc/profile.d/su.cfg1
-rw-r--r--packages/base/src/files/install/mysql/data/151000_downgrade_script.sql75
-rw-r--r--packages/base/src/files/install/mysql/data/151000_upgrade_script.sql1563
-rw-r--r--packages/base/src/files/install/mysql/data/151001_downgrade_script.sql248
-rw-r--r--packages/base/src/files/install/mysql/data/151001_upgrade_script.sql246
-rw-r--r--packages/base/src/files/install/mysql/data/151002_downgrade_script.sql21
-rw-r--r--packages/base/src/files/install/mysql/data/151002_upgrade_script.sql21
-rw-r--r--packages/base/src/files/install/mysql/data/151200_downgrade_script.sql43
-rw-r--r--packages/base/src/files/install/mysql/data/151200_upgrade_script.sql226
-rw-r--r--packages/base/src/files/install/mysql/data/160200_downgrade_script.sql39
-rw-r--r--packages/base/src/files/install/mysql/data/160200_upgrade_script.sql127
-rw-r--r--packages/base/src/files/install/mysql/data/160201_downgrade_script.sql43
-rw-r--r--packages/base/src/files/install/mysql/data/160201_upgrade_script.sql44
-rw-r--r--packages/base/src/files/install/mysql/data/160400_downgrade_script.sql33
-rw-r--r--packages/base/src/files/install/mysql/data/160400_upgrade_script.sql124
-rwxr-xr-xpackages/base/src/files/m2/settings.xml83
-rwxr-xr-xpackages/base/src/files/m2/standalone-settings.xml57
-rw-r--r--packages/install/.gitignore1
-rw-r--r--packages/install/pom.xml94
-rw-r--r--packages/install/src/assembly/zip.xml39
-rw-r--r--packages/install/src/files/base.conf68
-rw-r--r--packages/install/src/files/policy-management.conf5
-rw-r--r--packages/pom.xml43
-rw-r--r--policy-core/pom.xml235
-rw-r--r--policy-core/src/assembly/assemble_zip.xml85
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/core/FeatureAPI.java153
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/core/PolicyContainer.java828
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/core/PolicySession.java349
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmx.java47
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxListener.java64
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxMBean.java27
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/properties/Lockable.java45
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java96
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/properties/Startable.java65
-rw-r--r--policy-core/src/main/resources/META-INF/jndi.properties21
-rw-r--r--policy-core/src/main/resources/META-INF/persistence.xml70
-rw-r--r--policy-endpoints/pom.xml157
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/Topic.java76
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicEndpoint.java692
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicListener.java42
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicRegisterable.java42
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSink.java42
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSource.java40
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopic.java26
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSink.java47
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSource.java83
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSink.java30
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSinkFactory.java308
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSource.java29
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSourceFactory.java380
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSink.java32
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSinkFactory.java292
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSource.java34
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSourceFactory.java362
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusConsumer.java204
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusPublisher.java231
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusTopicBase.java112
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineBusTopicSink.java284
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineDmaapTopicSink.java84
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineUebTopicSink.java91
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedBusTopicSource.java477
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedDmaapTopicSource.java120
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedUebTopicSource.java89
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClient.java48
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClientFactory.java185
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/internal/JerseyClient.java242
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java81
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java206
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java130
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyServletServer.java353
-rw-r--r--policy-endpoints/src/main/resources/schema/pdpd-configuration.jsonschema61
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java230
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java181
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java19
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEndpoints.java25
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestMockHealthCheck.java28
-rw-r--r--policy-healthcheck/pom.xml157
-rw-r--r--policy-healthcheck/src/assembly/assemble_zip.xml85
-rw-r--r--policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheck.java178
-rw-r--r--policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheckFeature.java92
-rw-r--r--policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java27
-rw-r--r--policy-healthcheck/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI1
-rw-r--r--policy-management/config/policy-engine.properties26
-rw-r--r--policy-management/config/policyLogger.properties44
-rw-r--r--policy-management/pom.xml259
-rw-r--r--policy-management/src/assembly/assemble_zip.xml85
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java170
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsControllerFactory.java540
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java718
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java219
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/persistence/SystemPersistence.java255
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java1451
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/JsonProtocolFilter.java304
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/ProtocolCoderToolset.java668
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java309
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/ControllerConfiguration.java280
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/DroolsConfiguration.java278
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/PdpdConfiguration.java283
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java1181
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/system/Main.java131
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyController.java110
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyControllerFactory.java464
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java1182
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/system/internal/AggregatedPolicyController.java462
-rw-r--r--policy-management/src/main/server-gen/bin/add-secured-participant.sh122
-rw-r--r--policy-management/src/main/server-gen/bin/create-api-key.sh76
-rw-r--r--policy-management/src/main/server-gen/bin/create-secured-topic.sh130
-rw-r--r--policy-management/src/main/server-gen/bin/options125
-rw-r--r--policy-management/src/main/server-gen/bin/pdpd-configuration.sh200
-rw-r--r--policy-management/src/main/server-gen/bin/policy-management-controller191
-rw-r--r--policy-management/src/main/server-gen/bin/rest-add-controller.sh37
-rw-r--r--policy-management/src/main/server-gen/bin/rest-delete-controller.sh43
-rw-r--r--policy-management/src/main/server/config/IntegrityMonitor.properties81
-rw-r--r--policy-management/src/main/server/config/controller.properties.README153
-rw-r--r--policy-management/src/main/server/config/droolsPersistence.properties51
-rw-r--r--policy-management/src/main/server/config/log4j.properties48
-rw-r--r--policy-management/src/main/server/config/logback.xml211
-rw-r--r--policy-management/src/main/server/config/makefile9
-rw-r--r--policy-management/src/main/server/config/policy-engine.properties46
-rw-r--r--policy-management/src/main/server/config/policy-healthcheck.properties23
-rw-r--r--policy-management/src/main/server/config/policyLogger.properties49
-rw-r--r--policy-management/src/main/server/config/system.properties31
-rw-r--r--policy-management/src/main/server/config/xacmlPersistence.properties43
-rw-r--r--policy-persistence/config/policy-engine.properties33
-rw-r--r--policy-persistence/config/policyLogger.properties44
-rw-r--r--policy-persistence/pom.xml154
-rw-r--r--policy-persistence/src/assembly/assemble_zip.xml85
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/core/DbAudit.java205
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java485
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorProperties.java68
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java524
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/im/PMStandbyStateChangeNotifier.java280
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdp.java45
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpEntity.java171
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpImpl.java115
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpObject.java97
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsConnector.java67
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java948
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPersistenceProperties.java64
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSession.java31
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSessionEntity.java90
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java688
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java614
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/ThreadRunningChecker.java26
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/XacmlPersistenceProperties.java65
-rw-r--r--policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI1
-rw-r--r--policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/IntegrityAuditIntegrationTest.java279
-rw-r--r--policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/ResiliencyTestCases.java1267
-rw-r--r--policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/StandbyStateManagementTest.java887
-rw-r--r--policy-persistence/src/test/resources/IntegrityMonitor.properties67
-rw-r--r--policy-persistence/src/test/resources/META-INF/persistence.xml56
-rw-r--r--policy-persistence/src/test/resources/droolsPersistence.properties51
-rw-r--r--policy-persistence/src/test/resources/log4j.properties31
-rw-r--r--policy-persistence/src/test/resources/logback.xml209
-rw-r--r--policy-persistence/src/test/resources/xacmlPersistence.properties43
-rw-r--r--policy-persistence/src/test/server/config/IntegrityMonitor.properties62
-rw-r--r--policy-persistence/src/test/server/config/droolsPersistence.properties35
-rw-r--r--policy-persistence/src/test/server/config/policyLogger.properties44
-rw-r--r--policy-persistence/src/test/server/config/xacmlPersistence.properties38
-rw-r--r--policy-utils/pom.xml75
-rw-r--r--policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedService.java35
-rw-r--r--policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedServiceImpl.java117
-rw-r--r--policy-utils/src/main/java/org/openecomp/policy/drools/utils/Pair.java51
-rw-r--r--policy-utils/src/main/java/org/openecomp/policy/drools/utils/PropertyUtil.java403
-rw-r--r--policy-utils/src/main/java/org/openecomp/policy/drools/utils/ReflectionUtil.java92
-rw-r--r--policy-utils/src/main/java/org/openecomp/policy/drools/utils/Triple.java45
-rw-r--r--policy-utils/src/test/java/org/openecomp/policy/drools/utils/PropertyUtilTest.java204
-rw-r--r--policy-utils/src/test/resources/log4j.properties26
-rw-r--r--pom.xml194
-rw-r--r--project-configs/maven/conf/settings.xml162
-rw-r--r--version.properties35
203 files changed, 33981 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..37cd4d1e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+.project
+.settings
+.classpath
+.jupiter
+.pydevproject
+target
+.metadata/
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 00000000..6a107fd8
--- /dev/null
+++ b/.gitreview
@@ -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
index 00000000..dde205e9
--- /dev/null
+++ b/LICENSE.txt
@@ -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
index 00000000..6614ee66
--- /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
index 00000000..b83d2226
--- /dev/null
+++ b/packages/base/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/packages/base/pom.xml b/packages/base/pom.xml
new file mode 100644
index 00000000..80ba20b6
--- /dev/null
+++ b/packages/base/pom.xml
@@ -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
index 00000000..1f3b206f
--- /dev/null
+++ b/packages/base/src/assembly/zip.xml
@@ -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
index 00000000..738317de
--- /dev/null
+++ b/packages/base/src/files/bin/db_upgrade_droolspdp.sh
@@ -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
index 00000000..96cfda1c
--- /dev/null
+++ b/packages/base/src/files/bin/db_upgrade_droolspdp_remote.sh
@@ -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
index 00000000..f4fad486
--- /dev/null
+++ b/packages/base/src/files/bin/monitor.sh
@@ -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
index 00000000..67f56caf
--- /dev/null
+++ b/packages/base/src/files/bin/policy.sh
@@ -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
index 00000000..44f49198
--- /dev/null
+++ b/packages/base/src/files/data/mysql/160400_droolspdp_downgrade_script.sql
@@ -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
index 00000000..03e96521
--- /dev/null
+++ b/packages/base/src/files/data/mysql/160400_droolspdp_upgrade_script.sql
@@ -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
index 00000000..c8bbe035
--- /dev/null
+++ b/packages/base/src/files/data/mysql/160401_droolspdp_downgrade_script.sql
@@ -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
index 00000000..e7d92216
--- /dev/null
+++ b/packages/base/src/files/data/mysql/160401_droolspdp_upgrade_script.sql
@@ -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
index 00000000..c8613bb7
--- /dev/null
+++ b/packages/base/src/files/data/mysql/160700_droolspdp_downgrade_script.sql
@@ -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
index 00000000..3350859e
--- /dev/null
+++ b/packages/base/src/files/data/mysql/160700_droolspdp_upgrade_script.sql
@@ -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
index 00000000..b1ab793c
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161000_droolspdp_downgrade_script.sql
@@ -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
index 00000000..9ef24426
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161000_droolspdp_upgrade_script.sql
@@ -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
index 00000000..983a9f3c
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161001_droolspdp_downgrade_script.sql
@@ -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
index 00000000..2731e1bd
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161001_droolspdp_upgrade_script.sql
@@ -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
index 00000000..90ed6457
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161002_droolspdp_downgrade_script.sql
@@ -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
index 00000000..ff99d36a
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161002_droolspdp_upgrade_script.sql
@@ -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
index 00000000..ba9ac573
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161003_droolspdp_downgrade_script.sql
@@ -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
index 00000000..7f8c17ca
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161003_droolspdp_upgrade_script.sql
@@ -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
index 00000000..0f756585
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161004_droolspdp_downgrade_script.sql
@@ -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
index 00000000..f3a6cdda
--- /dev/null
+++ b/packages/base/src/files/data/mysql/161004_droolspdp_upgrade_script.sql
@@ -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
index 00000000..928a584e
--- /dev/null
+++ b/packages/base/src/files/data/mysql/170200_droolspdp_downgrade_script.sql
@@ -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
index 00000000..93bb69e3
--- /dev/null
+++ b/packages/base/src/files/data/mysql/170200_droolspdp_upgrade_script.sql
@@ -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
index 00000000..b7321720
--- /dev/null
+++ b/packages/base/src/files/etc/cron.d/monitor.cron
@@ -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
index 00000000..afc6c714
--- /dev/null
+++ b/packages/base/src/files/etc/monitor/monitor.cfg
@@ -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
index 00000000..be8e7471
--- /dev/null
+++ b/packages/base/src/files/etc/profile.d/env.sh
@@ -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
index 00000000..9cacea38
--- /dev/null
+++ b/packages/base/src/files/etc/profile.d/su.cfg
@@ -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
index 00000000..d336c5c0
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151000_downgrade_script.sql
@@ -0,0 +1,75 @@
+/*-
+ * ============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 xacml;
+
+DROP TABLE IF EXISTS XACML.SYSTEMLOGDB;
+DROP TABLE IF EXISTS XACML.SEQUENCE;
+DROP TABLE IF EXISTS XACML.RULEALGORITHMS;
+DROP TABLE IF EXISTS XACML.ROLES;
+DROP TABLE IF EXISTS XACML.POLICYALGORITHMS;
+DROP TABLE IF EXISTS XACML.POLICY_MANANGEMENT;
+DROP TABLE IF EXISTS XACML.PIPRESOLVERPARAMS;
+DROP TABLE IF EXISTS XACML.PIPRESOLVER;
+DROP TABLE IF EXISTS XACML.PIPCONFIGPARAMS;
+DROP TABLE IF EXISTS XACML.PIPCONFIGURATION;
+DROP TABLE IF EXISTS XACML.PIPTYPE;
+DROP TABLE IF EXISTS XACML.OBADVICEEXPRESSIONS;
+DROP TABLE IF EXISTS XACML.GLOBALROLESETTINGS;
+DROP TABLE IF EXISTS XACML.FUNCTIONARGUMENTS;
+DROP TABLE IF EXISTS XACML.FUNCTIONDEFINITION;
+DROP TABLE IF EXISTS XACML.ECOMPNAME;
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;
+DROP TABLE IF EXISTS XACML.ATTRIBUTEASSIGNMENT;
+DROP TABLE IF EXISTS XACML.CONSTRAINTVALUES;
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;
+DROP TABLE IF EXISTS XACML.OBADVICE;
+DROP TABLE IF EXISTS XACML.CONSTRAINTTYPE;
+DROP TABLE IF EXISTS XACML.CATEGORY;
+DROP TABLE IF EXISTS XACML.DATATYPE;
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;
+DROP TABLE IF EXISTS XACML.SERVICEGROUP;
+DROP TABLE IF EXISTS XACML.SECURITYZONE;
+DROP TABLE IF EXISTS XACML.POLICYENTITY;
+DROP TABLE IF EXISTS XACML.CONFIGURATIONDATAENTITY;
+DROP TABLE IF EXISTS XACML.POLICYDBDAOENTITY;
+
+DROP TABLE IF EXISTS XACML.POLICYSCORE;
+DROP TABLE IF EXISTS XACML.ACTIONLIST;
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;
+DROP TABLE IF EXISTS XACML.TERM;
+DROP TABLE IF EXISTS XACML.PREFIXLIST;
+DROP TABLE IF EXISTS XACML.SCOPE;
+DROP TABLE IF EXISTS XACML.ENFORCINGTYPE;
+DROP TABLE IF EXISTS XACML.PORTLIST;
+DROP TABLE IF EXISTS XACML.GROUPSERVICELIST;
+DROP TABLE IF EXISTS XACML.VSCLACTION;
+DROP TABLE IF EXISTS XACML.VNFTYPE;
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;
+
+-- DROP SEQUENCE IF EXISTS XACML.SEQCONFIG;
+-- DROP SEQUENCE IF EXISTS XACML.SEQPOLICY;
+
+DROP TABLE IF EXISTS LOG.SEQUENCE;
+DROP TABLE IF EXISTS LOG.SYSTEMLOGDB;
+
+DROP VIEW IF EXISTS xacml.match_functions;
+DROP VIEW IF EXISTS xacml.xacml.function_flattener;
+DROP VIEW IF EXISTS xacml.xacml.higherorder_bag_functions;
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
index 00000000..065d705f
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151000_upgrade_script.sql
@@ -0,0 +1,1563 @@
+/*-
+ * ============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 xacml;
+
+DROP TABLE IF EXISTS XACML.SYSTEMLOGDB;
+DROP TABLE IF EXISTS XACML.SEQUENCE;
+DROP TABLE IF EXISTS XACML.RULEALGORITHMS;
+DROP TABLE IF EXISTS XACML.ROLES;
+DROP TABLE IF EXISTS XACML.POLICYALGORITHMS;
+DROP TABLE IF EXISTS XACML.POLICY_MANANGEMENT;
+DROP TABLE IF EXISTS XACML.PIPRESOLVERPARAMS;
+DROP TABLE IF EXISTS XACML.PIPRESOLVER;
+DROP TABLE IF EXISTS XACML.PIPCONFIGPARAMS;
+DROP TABLE IF EXISTS XACML.PIPCONFIGURATION;
+DROP TABLE IF EXISTS XACML.PIPTYPE;
+DROP TABLE IF EXISTS XACML.OBADVICEEXPRESSIONS;
+DROP TABLE IF EXISTS XACML.GLOBALROLESETTINGS;
+DROP TABLE IF EXISTS XACML.FUNCTIONARGUMENTS;
+DROP TABLE IF EXISTS XACML.FUNCTIONDEFINITION;
+DROP TABLE IF EXISTS XACML.ECOMPNAME;
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;
+DROP TABLE IF EXISTS XACML.ATTRIBUTEASSIGNMENT;
+DROP TABLE IF EXISTS XACML.CONSTRAINTVALUES;
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;
+DROP TABLE IF EXISTS XACML.OBADVICE;
+DROP TABLE IF EXISTS XACML.CONSTRAINTTYPE;
+DROP TABLE IF EXISTS XACML.CATEGORY;
+DROP TABLE IF EXISTS XACML.DATATYPE;
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;
+DROP TABLE IF EXISTS XACML.SERVICEGROUP;
+DROP TABLE IF EXISTS XACML.SECURITYZONE;
+DROP TABLE IF EXISTS XACML.VSCLACTION;
+DROP TABLE IF EXISTS XACML.VNFTYPE;
+DROP TABLE IF EXISTS XACML.POLICYENTITY;
+DROP TABLE IF EXISTS XACML.CONFIGURATIONDATAENTITY;
+DROP TABLE IF EXISTS XACML.PolicyDBDaoEntity;
+
+DROP TABLE IF EXISTS XACML.POLICYSCORE;
+DROP TABLE IF EXISTS XACML.ACTIONLIST;
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;
+DROP TABLE IF EXISTS XACML.TERM;
+DROP TABLE IF EXISTS XACML.PREFIXLIST;
+DROP TABLE IF EXISTS XACML.SCOPE;
+DROP TABLE IF EXISTS XACML.GROUPSERVICELIST;
+DROP TABLE IF EXISTS XACML.ENFORCINGTYPE;
+DROP TABLE IF EXISTS XACML.PORTLIST;
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;
+
+-- DROP SEQUENCE IF EXISTS XACML.SEQCONFIG;
+-- DROP SEQUENCE IF EXISTS XACML.SEQPOLICY;
+DROP TABLE IF EXISTS LOG.SEQUENCE;
+DROP TABLE IF EXISTS LOG.SYSTEMLOGDB;
+
+DROP VIEW IF EXISTS xacml.match_functions;
+DROP VIEW IF EXISTS xacml.function_flattener;
+DROP VIEW IF EXISTS xacml.higherorder_bag_functions;
+
+DROP TABLE IF EXISTS XACML.GroupServiceList;
+
+CREATE TABLE XACML.GroupServiceList
+(
+id INTEGER NOT NULL,
+name varchar(32),
+serviceList varchar(255),
+PRIMARY KEY (id)
+)
+;
+CREATE INDEX IDX_GROUPSERVICELIST ON XACML.GROUPSERVICELIst(ID);
+
+DROP TABLE IF EXISTS XACML.PolicyAlgorithms;
+
+CREATE TABLE XACML.PolicyAlgorithms
+(
+id INTEGER NOT NULL,
+ is_standard CHAR NOT NULL,
+ short_name VARCHAR(64) NOT NULL,
+ xacml_id VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.AttributeAssignment;
+
+CREATE TABLE XACML.AttributeAssignment
+(
+id INTEGER NOT NULL,
+ attribute_id INTEGER,
+ expression VARCHAR(5000) NOT NULL,
+ OBADVICE_id INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.roles;
+CREATE TABLE XACML.roles
+(
+id INTEGER NOT NULL,
+ attuid VARCHAR(45) NOT NULL,
+ role VARCHAR(45) NOT NULL,
+ scope VARCHAR(45),
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.POLICYSCORE;
+CREATE TABLE XACML.POLICYSCORE
+(
+POLICY_NAME VARCHAR(200) NOT NULL,
+ POLICY_SCORE VARCHAR(100),
+ PRIMARY KEY (POLICY_NAME)
+)
+;
+
+DROP TABLE IF EXISTS XACML.GlobalRoleSettings;
+CREATE TABLE XACML.GlobalRoleSettings
+(
+role VARCHAR(45) NOT NULL,
+ lockdown BOOLEAN,
+ PRIMARY KEY (role)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PIPResolverParams;
+CREATE TABLE XACML.PIPResolverParams
+(
+id INTEGER NOT NULL,
+ PARAM_DEFAULT VARCHAR(2048),
+ PARAM_NAME VARCHAR(1024) NOT NULL,
+ PARAM_VALUE VARCHAR(2048) NOT NULL,
+ REQUIRED CHAR NOT NULL,
+ ID_RESOLVER INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.Attribute;
+CREATE TABLE XACML.Attribute
+(
+id INTEGER NOT NULL,
+ ATTRIBUTE_VALUE VARCHAR(255),
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048),
+ is_designator CHAR NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ PRIORITY VARCHAR(45),
+ selector_path VARCHAR(2048),
+ xacml_id VARCHAR(100) NOT NULL UNIQUE,
+ category INTEGER,
+ constraint_type INTEGER,
+ datatype INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.FunctionArguments;
+CREATE TABLE XACML.FunctionArguments
+(
+id INTEGER NOT NULL,
+ arg_index INTEGER NOT NULL,
+ is_bag INTEGER NOT NULL,
+ datatype_id INTEGER,
+ function_id INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.actionlist;
+CREATE TABLE XACML.actionlist
+(
+id INTEGER NOT NULL,
+ actionname VARCHAR(45) NOT NULL,
+ description VARCHAR(64),
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.Obadvice;
+CREATE TABLE XACML.Obadvice
+(
+id INTEGER NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP NOT NULL,
+ description VARCHAR(2048),
+ fulfill_on VARCHAR(32),
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ type VARCHAR(100) NOT NULL,
+ xacml_id VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.ObadviceExpressions;
+CREATE TABLE XACML.ObadviceExpressions
+(
+id INTEGER NOT NULL,
+ type VARCHAR(100) NOT NULL,
+ obadvice_id INTEGER,
+ attribute_id INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.RuleAlgorithms;
+CREATE TABLE XACML.RuleAlgorithms
+(
+id INTEGER NOT NULL,
+ is_standard CHAR NOT NULL,
+ short_name VARCHAR(64) NOT NULL,
+ xacml_id VARCHAR(255) NOT NULL UNIQUE,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.ConstraintValues;
+CREATE TABLE XACML.ConstraintValues
+(
+id INTEGER NOT NULL,
+ property VARCHAR(1000),
+ value VARCHAR(1000),
+ attribute_id INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.DecisionSettings;
+CREATE TABLE XACML.DecisionSettings
+(
+id INTEGER NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048),
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ PRIORITY VARCHAR(45),
+ xacml_id VARCHAR(45) NOT NULL UNIQUE,
+ datatype INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.policy_manangement;
+CREATE TABLE XACML.policy_manangement
+(
+id INTEGER NOT NULL,
+ CONFIG_NAME VARCHAR(45) NOT NULL,
+ CREATE_DATE_TIME TIMESTAMP NOT NULL,
+ CREATED_BY VARCHAR(45) NOT NULL,
+ ECOMP_NAME VARCHAR(45) NOT NULL,
+ POLICY_NAME VARCHAR(45) NOT NULL,
+ scope VARCHAR(45) NOT NULL,
+ UPDATE_DATE_TIME TIMESTAMP NOT NULL,
+ UPDATED_BY VARCHAR(45) NOT NULL,
+ XML text NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PIPConfiguration;
+CREATE TABLE XACML.PIPConfiguration
+(
+id INTEGER NOT NULL,
+ CLASSNAME VARCHAR(2048) NOT NULL,
+ CREATED_BY VARCHAR(255) NOT NULL,
+ CREATED_DATE TIMESTAMP NOT NULL,
+ DESCRIPTION VARCHAR(2048),
+ ISSUER VARCHAR(1024),
+ MODIFIED_BY VARCHAR(255) NOT NULL,
+ MODIFIED_DATE TIMESTAMP NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ READ_ONLY CHAR NOT NULL,
+ REQUIRES_RESOLVER CHAR NOT NULL,
+ TYPE INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.protocollist;
+CREATE TABLE XACML.protocollist
+(
+id INTEGER NOT NULL,
+ description VARCHAR(64),
+ protocolname VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+
+DROP TABLE IF EXISTS XACML.FunctionDefinition;
+CREATE TABLE XACML.FunctionDefinition
+(
+id INTEGER NOT NULL,
+ arg_lb INTEGER NOT NULL,
+ arg_ub INTEGER NOT NULL,
+ ho_arg_lb INTEGER,
+ ho_arg_ub INTEGER,
+ ho_primitive CHAR,
+ is_bag_return INTEGER NOT NULL,
+ is_higher_order INTEGER NOT NULL,
+ short_name VARCHAR(64) NOT NULL,
+ xacml_id VARCHAR(255) NOT NULL,
+ return_datatype INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PIPResolver;
+CREATE TABLE XACML.PIPResolver
+(
+id INTEGER NOT NULL,
+ CLASSNAME VARCHAR(2048) NOT NULL,
+ CREATED_BY VARCHAR(255) NOT NULL,
+ CREATED_DATE TIMESTAMP NOT NULL,
+ DESCRIPTION VARCHAR(2048),
+ ISSUER VARCHAR(1024),
+ MODIFIED_BY VARCHAR(255) NOT NULL,
+ MODIFIED_DATE TIMESTAMP NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ READ_ONLY CHAR NOT NULL,
+ PIP_ID INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.TERM;
+CREATE TABLE XACML.TERM
+(
+id INTEGER NOT NULL,
+ description VARCHAR(100),
+ action VARCHAR(100),
+ destIPList VARCHAR(100),
+ destPortList VARCHAR(100),
+ portList VARCHAR(100),
+ protocolList VARCHAR(100),
+ srcIPList VARCHAR(100),
+ srcPortList VARCHAR(100),
+ termName VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PREFIXLIST;
+CREATE TABLE XACML.PREFIXLIST
+(
+id INTEGER NOT NULL,
+ pl_name VARCHAR(45) NOT NULL,
+ pl_value VARCHAR(64) NOT NULL,
+ description VARCHAR(255),
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.Datatype;
+CREATE TABLE XACML.Datatype
+(
+id INTEGER NOT NULL,
+ is_standard CHAR NOT NULL,
+ short_name VARCHAR(64) NOT NULL,
+ xacml_id VARCHAR(255) NOT NULL UNIQUE,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PIPType;
+CREATE TABLE XACML.PIPType
+(
+id INTEGER NOT NULL,
+ type VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.ActionPolicyDict;
+CREATE TABLE XACML.ActionPolicyDict
+(
+id INTEGER NOT NULL,
+ ATTRIBUTE_NAME VARCHAR(45) NOT NULL,
+ Body VARCHAR(4096),
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048),
+ Headers VARCHAR(1024),
+ Method VARCHAR(45) NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ Type VARCHAR(45) NOT NULL,
+ URL VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.Category;
+CREATE TABLE XACML.Category
+(
+id INTEGER NOT NULL,
+ grouping VARCHAR(64) NOT NULL,
+ is_standard CHAR NOT NULL,
+ short_name VARCHAR(64) NOT NULL,
+ xacml_id VARCHAR(255) NOT NULL UNIQUE,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.Scope;
+CREATE TABLE XACML.Scope
+(
+scopeId BIGINT NOT NULL,
+ parentScope BIGINT,
+ scopeName VARCHAR(255) NOT NULL,
+ PRIMARY KEY (scopeId)
+)
+;
+CREATE INDEX parentScope ON Scope (parentScope);
+
+DROP TABLE IF EXISTS XACML.EcompName;
+CREATE TABLE XACML.EcompName
+(
+id INTEGER NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048),
+ ecomp_Name VARCHAR(100) NOT NULL UNIQUE,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.ConstraintType;
+CREATE TABLE XACML.ConstraintType
+(
+id INTEGER NOT NULL,
+ constraint_type VARCHAR(64) NOT NULL,
+ description VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.EnforcingType;
+CREATE TABLE XACML.EnforcingType
+(
+id INTEGER NOT NULL,
+ connectionQuery VARCHAR(255) NOT NULL,
+ enforcingType VARCHAR(255) NOT NULL UNIQUE,
+ script VARCHAR(255) NOT NULL,
+ valueQuery VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PIPConfigParams;
+CREATE TABLE XACML.PIPConfigParams
+(
+id INTEGER NOT NULL,
+ PARAM_DEFAULT VARCHAR(2048),
+ PARAM_NAME VARCHAR(1024) NOT NULL,
+ PARAM_VALUE VARCHAR(2048) NOT NULL,
+ REQUIRED CHAR NOT NULL,
+ PIP_ID INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.portlist;
+CREATE TABLE XACML.portlist
+(
+id INTEGER NOT NULL,
+ description VARCHAR(64),
+ portname VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.SEQUENCE;
+CREATE TABLE XACML.SEQUENCE
+(
+SEQ_NAME VARCHAR(50) NOT NULL,
+ SEQ_COUNT NUMERIC(38),
+ PRIMARY KEY (SEQ_NAME)
+)
+;
+-- INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0);
+-- CREATE SEQUENCE seq START WITH 1;
+
+DROP TABLE IF EXISTS XACML.SYSTEMLOGDB;
+CREATE TABLE XACML.SYSTEMLOGDB
+(
+ id INTEGER NOT NULL AUTO_INCREMENT,
+ system VARCHAR(255) NOT NULL,
+ description VARCHAR(2048),
+ remote VARCHAR(255) NOT NULL,
+ type VARCHAR(10) NOT NULL,
+ date TIMESTAMP NOT NULL,
+ logtype VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+)
+
+;
+
+DROP TABLE IF EXISTS LOG.SEQUENCE;
+CREATE TABLE LOG.SEQUENCE
+(
+SEQ_NAME VARCHAR(50) NOT NULL,
+ SEQ_COUNT NUMERIC(38),
+ PRIMARY KEY (SEQ_NAME)
+)
+;
+
+DROP TABLE IF EXISTS LOG.SYSTEMLOGDB;
+CREATE TABLE LOG.SYSTEMLOGDB
+(
+ id INTEGER NOT NULL AUTO_INCREMENT,
+ system VARCHAR(255) NOT NULL,
+ description VARCHAR(2048),
+ remote VARCHAR(255) NOT NULL,
+ type VARCHAR(10) NOT NULL,
+ date TIMESTAMP NOT NULL,
+ logtype VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+drop table if exists SUPPORT.DB_VERSION;
+create table SUPPORT.DB_VERSION
+(
+ the_key varchar(20) primary key not null,
+ version varchar(20)
+)
+;
+
+DROP TABLE IF EXISTS XACML.SERVICEGROUP;
+CREATE TABLE XACML.SERVICEGROUP
+(
+id integer NOT NULL,
+name varchar(32),
+type varchar(16),
+transportprotocol varchar(255),
+appprotocol varchar(255),
+ports varchar(255),
+`desc` varchar(255),
+primary key(id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.SECURITYZONE;
+CREATE TABLE XACML.SECURITYZONE
+(
+id integer NOT NULL,
+name varchar(32),
+value varchar(64),
+primary key(id)
+)
+;
+
+CREATE TABLE XACML.VSCLACTION
+(
+ID INTEGER NOT NULL,
+VSCL_ACTION VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+CREATE TABLE XACML.VNFTYPE
+(
+ID INTEGER NOT NULL,
+VNF_TYPE VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+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.POLICYENTITY;
+CREATE TABLE XACML.PolicyEntity
+(
+policyId BIGINT NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ deleted BOOLEAN NOT NULL,
+ description VARCHAR(2048) NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ policyData TEXT,
+ policyName VARCHAR(255) NOT NULL,
+ scope VARCHAR(255) NOT NULL,
+ version INTEGER,
+ configurationDataId BIGINT,
+ PRIMARY KEY (policyId))
+;
+CREATE INDEX scope ON XACML.PolicyEntity (scope);
+CREATE INDEX policyName ON XACML.PolicyEntity (policyName);
+
+DROP TABLE IF EXISTS XACML.ConfigurationDataEntity;
+CREATE TABLE XACML.ConfigurationDataEntity
+(
+configurationDataId BIGINT NOT NULL,
+ configBody TEXT,
+ configType VARCHAR(255) NOT NULL,
+ configurationName VARCHAR(255) NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ deleted BOOLEAN NOT NULL,
+ description VARCHAR(2048) NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ version INTEGER,
+ PRIMARY KEY (configurationDataId))
+;
+
+DROP TABLE IF EXISTS XACML.PolicyDBDaoEntity;
+CREATE TABLE XACML.PolicyDBDaoEntity
+(
+ policyDBDaoUrl VARCHAR(500) NOT NULL UNIQUE,
+ created_date TIMESTAMP,
+ description VARCHAR(2048) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ PRIMARY KEY (policyDBDaoUrl))
+;
+
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;
+CREATE TABLE ADDRESSGROUP
+(
+ id INTEGER NOT NULL,
+ name varchar(32),
+ description VARCHAR(64),
+ prefixlist varchar(255)
+);
+
+create index idx_addressgroup on ADDRESSGROUP(ID);
+
+
+
+create or replace view xacml.match_functions
+as select d.id as id, d.short_name as shortname, d.xacml_id as xacmlid,
+d.return_datatype as return_datatype, d.is_bag_return as is_bag_return,
+d.arg_lb as arg_lb, d.arg_ub as arg_ub, a1.is_bag as arg1_isbag,
+a1.datatype_id as arg1_datatype, a2.is_bag as arg2_isbag,
+a2.datatype_id as arg2_datatype
+from (xacml.functiondefinition d
+left join xacml.functionarguments a1 on (a1.function_id = d.id and a1.arg_index = 1)
+left join xacml.functionarguments a2 on (a2.function_id = d.id and a2.arg_index = 2))
+where (d.arg_lb = 2 and d.arg_ub = 2 and d.return_datatype = 18 and a1.is_bag = 0)
+order by d.short_name;
+
+create or replace view xacml.function_flattener
+as select d.id as id, d.short_name as shortname,
+d.return_datatype as return_datatype, d.is_bag_return as is_bag_return,
+d.is_higher_order as is_higher_order, d.arg_lb as arg_lb, d.arg_ub as arg_ub,
+a1.is_bag as arg1_isbag, a1.datatype_id as arg1_datatype, a2.is_bag as arg2_isbag,
+a2.datatype_id as arg2_datatype, a3.is_bag as arg3_isbag,
+a3.datatype_id as arg3_datatype
+from (xacml.functiondefinition d left join xacml.functionarguments a1
+on (a1.function_id = d.id and a1.arg_index = 1)
+left join xacml.functionarguments a2 on (a2.function_id = d.id and a2.arg_index = 2)
+left join xacml.functionarguments a3 on (a3.function_id = d.id and a3.arg_index = 3))
+order by d.id;
+
+create or replace view xacml.higherorder_bag_functions
+as select * from xacml.function_flattener
+where is_higher_order = 1 and is_bag_return = 1 and return_datatype=18
+and arg_lb=2 and arg_ub=2 and arg1_isbag = 1 and (arg2_isbag = 1 or arg2_isbag is null);
+
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.SYSTEMLOGDB TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.SEQUENCE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.RULEALGORITHMS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ROLES TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICYALGORITHMS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICY_MANANGEMENT TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPRESOLVERPARAMS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPRESOLVER TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPCONFIGPARAMS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPCONFIGURATION TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PIPTYPE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.OBADVICEEXPRESSIONS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.GLOBALROLESETTINGS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.FUNCTIONARGUMENTS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.FUNCTIONDEFINITION TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ECOMPNAME TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.DECISIONSETTINGS TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ATTRIBUTEASSIGNMENT TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CONSTRAINTVALUES TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ATTRIBUTE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.OBADVICE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CONSTRAINTTYPE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CATEGORY TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.DATATYPE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ACTIONPOLICYDICT TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICYENTITY TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.CONFIGURATIONDATAENTITY TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PolicyDBDaoEntity TO policy_user;
+
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.POLICYSCORE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ACTIONLIST TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PROTOCOLLIST TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.TERM TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PREFIXLIST TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.SCOPE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ENFORCINGTYPE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.PORTLIST TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.GROUPSERVICELIST TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.VSCLACTION TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.VNFTYPE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON XACML.ADDRESSGROUP TO policy_user;
+
+GRANT SELECT, INSERT, UPDATE, DELETE ON LOG.SEQUENCE TO policy_user;
+GRANT SELECT, INSERT, UPDATE, DELETE ON LOG.SYSTEMLOGDB TO policy_user;
+
+grant insert, update, delete, select on support.db_version to policy_user;
+grant select on xacml.match_functions to policy_user;
+grant select on xacml.function_flattener to policy_user;
+grant select on xacml.higherorder_bag_functions to policy_user;
+
+
+
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+
+
+
+
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+
+
+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.');
+INSERT INTO XACML.CONSTRAINTTYPE (ID,CONSTRAINT_TYPE,DESCRIPTION) VALUES (2,'Regular Expression','Define a regular expression the attribute must match against during policy creation.');
+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.');
+
+
+
+
+
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (12,'S','integer','http://www.w3.org/2001/XMLSchema#integer');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (13,'S','base64Binary','http://www.w3.org/2001/XMLSchema#base64Binary');
+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');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (15,'S','dayTimeDuration','http://www.w3.org/2001/XMLSchema#dayTimeDuration');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (16,'S','time','http://www.w3.org/2001/XMLSchema#time');
+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');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (18,'S','boolean','http://www.w3.org/2001/XMLSchema#boolean');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (19,'S','dateTime','http://www.w3.org/2001/XMLSchema#dateTime');
+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');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (21,'S','date','http://www.w3.org/2001/XMLSchema#date');
+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');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (23,'S','yearMonthDuration','http://www.w3.org/2001/XMLSchema#yearMonthDuration');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (24,'S','hexBinary','http://www.w3.org/2001/XMLSchema#hexBinary');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (25,'S','double','http://www.w3.org/2001/XMLSchema#double');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (26,'S','string','http://www.w3.org/2001/XMLSchema#string');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (27,'S','anyURI','http://www.w3.org/2001/XMLSchema#anyURI');
+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');
+INSERT INTO XACML.DATATYPE (ID,IS_STANDARD,SHORT_NAME,XACML_ID) VALUES (29,'S','user','');
+
+
+
+
+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'));
+
+
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (1,1,0,12,1);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (2,2,0,12,1);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (3,1,0,12,2);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (4,2,0,12,2);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (5,1,0,25,3);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (6,1,1,12,4);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (7,1,1,25,5);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (8,1,0,26,6);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (9,2,0,26,6);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (10,1,0,26,7);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (11,2,0,26,7);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (12,1,0,26,8);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (13,2,0,26,8);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (14,1,0,26,9);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (15,2,0,26,9);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (16,1,0,26,10);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (17,1,0,26,11);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (18,1,0,18,12);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (19,1,0,26,13);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (20,1,0,12,14);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (21,1,0,26,15);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (22,1,0,25,16);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (23,1,0,26,17);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (24,1,0,16,18);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (25,1,0,26,19);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (26,1,0,21,20);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (27,1,0,26,21);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (28,1,0,19,22);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (29,1,0,26,23);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (30,1,0,27,24);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (31,1,0,26,25);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (32,1,0,15,26);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (33,1,0,26,27);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (34,1,0,23,28);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (35,1,0,26,29);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (36,1,0,14,30);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (37,1,0,26,31);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (38,1,0,20,32);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (39,1,0,26,33);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (40,1,0,22,34);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (41,1,0,26,35);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (42,1,0,17,36);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (43,2,0,27,37);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (44,1,0,26,37);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (45,1,0,26,38);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (46,2,0,27,38);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (47,1,0,26,39);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (48,2,0,26,39);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (49,1,0,26,40);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (50,2,0,27,40);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (51,1,0,26,41);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (52,2,0,12,41);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (53,3,0,12,41);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (54,1,0,27,42);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (55,2,0,12,42);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (56,3,0,12,42);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (57,1,0,18,43);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (58,2,0,18,43);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (59,1,0,12,44);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (60,2,0,12,44);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (61,1,0,25,45);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (62,2,0,25,45);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (63,1,0,21,46);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (64,2,0,21,46);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (65,1,0,16,47);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (66,2,0,16,47);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (67,1,0,19,48);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (68,2,0,19,48);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (69,1,0,15,49);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (70,2,0,15,49);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (71,1,0,23,50);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (72,2,0,23,50);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (73,1,0,27,51);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (74,2,0,27,51);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (75,1,0,14,52);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (76,2,0,14,52);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (77,1,0,20,53);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (78,2,0,20,53);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (79,1,0,24,54);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (80,2,0,24,54);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (81,1,0,13,55);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (82,2,0,13,55);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (83,1,0,12,56);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (84,2,0,12,56);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (85,1,0,25,57);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (86,2,0,25,57);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (89,1,0,25,58);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (90,2,0,25,58);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (91,1,0,12,59);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (92,2,0,12,59);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (93,1,0,25,60);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (94,2,0,25,60);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (95,1,0,12,61);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (96,2,0,12,61);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (97,1,0,25,62);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (98,2,0,25,62);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (99,1,0,12,63);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (100,2,0,12,63);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (101,1,0,12,64);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (102,1,0,25,65);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (103,1,0,25,66);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (104,1,0,25,67);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (125,1,0,26,68);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (126,1,0,26,69);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (128,1,0,12,70);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (129,1,0,12,71);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (130,2,0,12,71);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (131,1,0,12,72);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (132,2,0,12,72);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (133,1,0,12,73);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (134,2,0,12,73);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (135,1,0,25,74);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (136,2,0,25,74);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (137,1,0,25,75);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (138,2,0,25,75);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (139,1,0,25,76);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (140,2,0,25,76);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (141,1,0,25,77);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (142,2,0,25,77);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (143,1,0,19,78);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (144,2,0,15,78);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (145,1,0,19,79);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (146,2,0,23,79);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (147,1,0,19,80);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (148,2,0,15,80);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (149,1,0,19,81);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (150,2,0,23,81);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (151,1,0,21,82);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (152,2,0,23,82);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (153,1,0,21,83);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (154,2,0,23,83);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (155,1,0,26,84);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (156,2,0,26,84);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (157,1,0,26,85);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (158,2,0,26,85);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (159,1,0,26,86);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (160,2,0,26,86);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (161,1,0,26,87);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (162,2,0,26,87);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (163,1,0,16,88);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (164,2,0,16,88);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (165,1,0,16,89);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (166,2,0,16,89);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (167,1,0,16,90);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (168,2,0,16,90);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (169,1,0,16,91);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (170,2,0,16,91);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (171,1,0,16,92);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (172,2,0,16,92);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (173,1,0,19,93);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (174,2,0,19,93);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (175,1,0,19,94);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (176,2,0,19,94);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (177,1,0,19,95);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (178,2,0,19,95);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (179,1,0,19,96);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (180,2,0,19,96);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (181,1,0,21,97);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (182,2,0,21,97);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (183,1,0,21,98);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (184,2,0,21,98);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (185,2,0,21,99);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (186,1,0,21,99);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (187,2,0,21,100);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (188,1,0,21,100);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (189,1,1,26,101);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (190,1,1,26,102);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (191,1,0,26,103);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (192,2,1,26,103);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (193,1,0,26,104);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (194,1,1,12,105);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (195,1,0,12,106);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (196,2,1,12,106);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (197,1,0,12,107);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (198,1,1,25,108);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (199,1,0,25,109);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (200,2,1,25,109);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (201,1,0,25,110);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (202,1,1,18,111);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (203,1,1,18,112);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (204,1,0,18,113);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (205,2,1,18,113);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (206,1,0,18,114);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (207,1,1,16,115);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (208,1,1,16,116);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (209,1,0,16,117);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (210,2,1,16,117);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (211,1,0,16,118);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (212,1,1,21,119);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (213,1,1,21,120);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (214,1,0,21,121);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (215,2,1,21,121);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (216,1,0,21,122);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (217,1,1,19,123);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (218,1,1,19,124);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (219,1,0,19,125);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (220,2,1,19,125);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (221,1,0,19,126);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (222,1,1,27,127);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (223,1,1,27,128);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (224,1,0,27,129);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (225,2,1,27,129);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (226,1,0,27,130);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (227,1,1,24,131);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (228,1,1,24,132);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (229,1,0,24,133);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (230,2,1,24,133);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (231,1,0,24,134);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (232,1,1,13,135);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (233,1,1,13,136);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (234,1,0,13,137);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (235,2,1,13,137);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (236,1,0,13,138);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (237,1,1,15,139);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (238,1,1,15,140);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (239,1,0,15,141);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (240,2,1,15,141);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (241,1,0,15,142);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (242,1,1,23,143);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (243,1,1,23,144);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (244,2,1,23,145);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (245,1,0,23,145);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (246,1,0,23,146);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (247,1,1,14,147);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (248,1,1,14,148);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (249,1,0,14,149);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (250,2,1,14,149);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (251,1,0,14,150);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (252,1,1,20,151);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (253,1,1,20,152);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (254,1,0,20,153);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (255,2,1,20,153);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (256,1,0,20,154);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (257,1,1,22,155);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (258,1,1,22,156);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (259,1,0,22,157);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (260,2,1,22,157);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (261,1,0,22,158);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (262,1,1,17,159);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (263,1,1,17,160);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (264,1,0,17,161);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (265,2,1,17,161);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (266,1,0,17,162);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (267,1,0,26,163);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (268,2,0,26,163);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (269,1,0,26,164);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (270,2,0,27,164);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (271,1,0,26,165);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (272,2,0,22,165);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (273,1,0,26,166);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (274,2,0,17,166);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (275,1,0,26,167);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (276,2,0,20,167);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (277,1,0,26,168);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (278,2,0,14,168);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (279,1,1,26,169);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (280,2,1,26,169);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (281,1,1,26,170);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (282,2,1,26,170);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (283,1,1,26,171);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (284,1,1,26,172);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (285,2,1,26,172);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (286,1,1,26,173);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (287,2,1,26,173);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (288,2,1,12,174);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (289,1,1,12,174);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (290,1,1,12,175);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (292,2,1,12,176);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (293,1,1,12,176);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (294,2,1,12,177);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (295,1,1,12,177);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (296,1,1,25,178);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (297,2,1,25,178);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (298,1,1,25,179);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (299,1,1,25,180);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (300,2,1,25,180);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (301,1,1,25,181);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (302,2,1,25,181);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (303,1,1,18,182);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (304,2,1,18,182);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (305,1,1,18,183);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (306,2,1,18,183);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (307,1,1,18,184);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (308,1,1,18,185);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (309,2,1,18,185);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (310,1,1,18,186);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (311,2,1,18,186);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (312,2,1,16,187);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (313,1,1,16,187);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (314,1,1,16,188);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (315,2,1,16,188);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (316,1,1,16,189);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (317,1,1,16,190);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (318,2,1,16,190);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (319,1,1,16,191);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (320,2,1,16,191);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (321,1,1,21,192);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (322,2,1,21,192);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (323,1,1,21,193);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (324,2,1,21,193);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (325,1,1,21,194);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (326,1,1,21,195);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (327,2,1,21,195);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (328,1,1,21,196);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (329,2,1,21,196);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (330,1,1,19,197);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (331,2,1,19,197);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (332,1,1,19,198);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (333,2,1,19,198);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (334,1,1,19,199);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (335,1,1,19,200);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (336,2,1,19,200);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (337,1,1,19,201);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (338,2,1,19,201);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (339,1,1,27,202);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (340,2,1,27,202);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (341,1,1,27,203);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (342,2,1,27,203);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (343,1,1,27,204);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (344,1,1,27,205);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (345,2,1,27,205);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (346,1,1,27,206);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (347,2,1,27,206);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (348,1,1,24,207);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (349,2,1,24,207);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (350,1,1,24,208);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (351,2,1,24,208);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (352,1,1,24,209);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (353,1,1,24,210);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (354,2,1,24,210);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (355,1,1,24,211);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (356,2,1,24,211);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (357,1,1,13,212);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (358,2,1,13,212);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (359,1,1,13,213);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (360,2,1,13,213);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (361,1,1,13,214);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (362,1,1,13,215);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (363,2,1,13,215);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (364,1,1,13,216);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (365,2,1,13,216);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (366,1,1,15,217);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (367,2,1,15,217);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (368,1,1,15,218);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (369,2,1,15,218);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (370,1,1,15,219);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (371,1,1,15,220);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (372,2,1,15,220);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (373,1,1,15,221);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (374,2,1,15,221);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (375,1,1,23,222);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (376,2,1,23,222);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (377,1,1,23,223);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (378,2,1,23,223);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (380,1,1,23,224);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (381,1,1,23,225);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (382,2,1,23,225);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (383,2,1,23,226);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (384,1,1,23,226);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (385,1,1,14,227);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (386,2,1,14,227);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (387,1,1,14,228);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (388,2,1,14,228);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (389,1,1,14,229);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (390,1,1,14,230);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (391,2,1,14,230);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (392,1,1,14,231);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (393,2,1,14,231);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (394,1,1,20,232);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (395,2,1,20,232);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (396,1,1,20,233);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (397,2,1,20,233);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (398,1,1,20,234);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (399,1,1,20,235);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (400,2,1,20,235);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (401,1,1,20,236);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (402,2,1,20,236);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (403,1,0,14,237);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (404,2,0,14,237);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (405,1,0,26,238);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (406,2,0,20,238);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (407,1,1,12,239);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (408,2,1,12,239);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (409,1,1,25,240);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (410,2,1,25,240);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (411,1,0,18,241);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (412,1,0,18,242);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (413,1,0,12,243);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (414,2,0,18,243);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (415,1,0,18,244);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (416,1,0,18,245);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (417,2,0,null,245);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (418,3,1,null,245);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (419,1,0,18,246);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (420,2,0,null,246);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (421,3,1,null,246);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (422,1,0,18,247);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (423,2,1,null,247);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (424,3,1,null,247);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (433,1,0,18,248);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (434,2,1,null,248);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (435,3,1,null,248);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (436,1,0,18,249);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (437,2,1,null,249);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (438,3,1,null,249);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (439,1,0,18,250);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (440,2,1,null,250);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (441,3,1,null,250);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (442,1,0,null,251);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (447,2,1,null,251);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (448,1,0,28,252);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (449,1,0,28,253);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (450,2,0,28,253);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (451,1,0,28,254);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (452,2,0,28,254);
+INSERT INTO XACML.FUNCTIONARGUMENTS (ID,ARG_INDEX,IS_BAG,DATATYPE_ID,FUNCTION_ID) VALUES (453,3,0,16,92);
+
+
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+
+
+INSERT INTO XACML.GLOBALROLESETTINGS (ROLE,LOCKDOWN) VALUES ('super-admin',0);
+
+
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1711,null,'type','jdbc','0',1709);
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1712,null,'jdbc.url','jdbc:h2:file:/','0',1709);
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1713,null,'jdbc.driver','org.h2.Driver','0',1709);
+INSERT INTO XACML.PIPCONFIGPARAMS (ID,PARAM_DEFAULT,PARAM_NAME,PARAM_VALUE,REQUIRED,PIP_ID) VALUES (1714,null,'jdbc.conn.password','smil3yfc','0',1709);
+
+
+
+
+
+
+
+
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (500,'SQL');
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (501,'LDAP');
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (502,'CSV');
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (503,'Hyper-CSV');
+INSERT INTO XACML.PIPTYPE (ID,TYPE) VALUES (504,'Custom');
+
+
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+
+
+
+
+
+
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+
+
+INSERT INTO XACML.SEQUENCE (SEQ_NAME,SEQ_COUNT) VALUES ('SEQ_GEN',3050);
+
+
+
+ALTER TABLE XACML.AttributeAssignment ADD CONSTRAINT FK_AttributeAssignment_OBADVICE_id
+FOREIGN KEY (OBADVICE_id) REFERENCES XACML.Obadvice (id);
+ALTER TABLE XACML.PIPResolverParams ADD CONSTRAINT FK_PIPResolverParams_ID_RESOLVER
+FOREIGN KEY (ID_RESOLVER) REFERENCES XACML.PIPResolver (id);
+ALTER TABLE XACML.Attribute ADD CONSTRAINT FK_Attribute_category
+FOREIGN KEY (category) REFERENCES XACML.Category (id);
+ALTER TABLE XACML.Attribute ADD CONSTRAINT FK_Attribute_constraint_type
+FOREIGN KEY (constraint_type) REFERENCES XACML.ConstraintType (id);
+ALTER TABLE XACML.Attribute ADD CONSTRAINT FK_Attribute_datatype
+FOREIGN KEY (datatype) REFERENCES XACML.Datatype (id);
+ALTER TABLE XACML.FunctionArguments ADD CONSTRAINT FK_FunctionArguments_function_id
+FOREIGN KEY (function_id) REFERENCES XACML.FunctionDefinition (id);
+ALTER TABLE XACML.FunctionArguments ADD CONSTRAINT FK_FunctionArguments_datatype_id
+FOREIGN KEY (datatype_id) REFERENCES XACML.Datatype (id);
+ALTER TABLE XACML.ObadviceExpressions ADD CONSTRAINT FK_ObadviceExpressions_obadvice_id
+FOREIGN KEY (obadvice_id) REFERENCES XACML.Obadvice (id);
+ALTER TABLE XACML.ObadviceExpressions ADD CONSTRAINT FK_ObadviceExpressions_attribute_id
+FOREIGN KEY (attribute_id) REFERENCES XACML.Attribute (id);
+ALTER TABLE XACML.ConstraintValues ADD CONSTRAINT FK_ConstraintValues_attribute_id
+FOREIGN KEY (attribute_id) REFERENCES XACML.Attribute (id);
+ALTER TABLE XACML.DecisionSettings ADD CONSTRAINT FK_DecisionSettings_datatype
+FOREIGN KEY (datatype) REFERENCES XACML.Datatype (id);
+ALTER TABLE XACML.PIPConfiguration ADD CONSTRAINT FK_PIPConfiguration_TYPE
+FOREIGN KEY (TYPE) REFERENCES XACML.PIPType (id);
+
+ALTER TABLE FunctionDefinition ADD CONSTRAINT FK_FunctionDefinition_return_datatype
+FOREIGN KEY (return_datatype) REFERENCES XACML.Datatype (id);
+ALTER TABLE PIPResolver ADD CONSTRAINT FK_PIPResolver_PIP_ID
+FOREIGN KEY (PIP_ID) REFERENCES XACML.PIPConfiguration (id);
+ALTER TABLE PIPConfigParams ADD CONSTRAINT FK_PIPConfigParams_PIP_ID
+FOREIGN KEY (PIP_ID) REFERENCES XACML.PIPConfiguration (id);
+
+ALTER TABLE XACML.PolicyEntity ADD CONSTRAINT UNQ_PolicyEntity_0 UNIQUE (policyName, scope, deleted);
+ALTER TABLE XACML.PolicyEntity ADD CONSTRAINT FK_PolicyEntity_configurationDataId FOREIGN KEY (configurationDataId)
+ REFERENCES XACML.ConfigurationDataEntity (configurationDataId);
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
index 00000000..06cf389a
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151001_downgrade_script.sql
@@ -0,0 +1,248 @@
+/*-
+ * ============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 XACML.ENFORCINGTYPE;
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;
+DROP TABLE IF EXISTS XACML.TERM;
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;
+DROP TABLE IF EXISTS XACML.PORTLIST;
+DROP TABLE IF EXISTS XACML.PREFIXLIST;
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;
+DROP TABLE IF EXISTS XACML.POLICYSCORE;
+DROP TABLE IF EXISTS XACML.VSCLACTION;
+DROP TABLE IF EXISTS XACML.VNFTYPE;
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;
+DROP TABLE IF EXISTS XACML.POLICY_MANAGEMENT;
+DROP TABLE IF EXISTS XACML.SCOPES;
+
+DROP TABLE IF EXISTS XACML.SERVICEGROUP;
+CREATE TABLE XACML.SERVICEGROUP
+(
+id integer NOT NULL,
+name varchar(32),
+type varchar(16),
+transportprotocol varchar(255),
+appprotocol varchar(255),
+ports varchar(255),
+`desc` varchar(255),
+primary key(id)
+)
+;
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SERVICEGROUP TO POLICY_USER;
+
+
+DROP TABLE IF EXISTS XACML.EnforcingType;
+CREATE TABLE XACML.EnforcingType
+(
+id INTEGER NOT NULL,
+ connectionQuery VARCHAR(255) NOT NULL,
+ enforcingType VARCHAR(255) NOT NULL UNIQUE,
+ script VARCHAR(255) NOT NULL,
+ valueQuery VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.ActionPolicyDict;
+CREATE TABLE XACML.ActionPolicyDict
+(
+id INTEGER NOT NULL,
+ ATTRIBUTE_NAME VARCHAR(45) NOT NULL,
+ Body VARCHAR(4096),
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048),
+ Headers VARCHAR(1024),
+ Method VARCHAR(45) NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ Type VARCHAR(45) NOT NULL,
+ URL VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.TERM;
+CREATE TABLE XACML.TERM
+(
+id INTEGER NOT NULL,
+ description VARCHAR(100),
+ action VARCHAR(100),
+ destIPList VARCHAR(100),
+ destPortList VARCHAR(100),
+ portList VARCHAR(100),
+ protocolList VARCHAR(100),
+ srcIPList VARCHAR(100),
+ srcPortList VARCHAR(100),
+ termName VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;
+CREATE TABLE XACML.PROTOCOLLIST
+(
+id INTEGER NOT NULL,
+ description VARCHAR(64),
+ protocolname VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PORTLIST;
+CREATE TABLE XACML.PORTLIST
+(
+id INTEGER NOT NULL,
+ description VARCHAR(64),
+ portname VARCHAR(45) NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.PREFIXLIST;
+CREATE TABLE XACML.PREFIXLIST
+(
+id INTEGER NOT NULL,
+ pl_name VARCHAR(45) NOT NULL,
+ pl_value VARCHAR(64) NOT NULL,
+ description VARCHAR(255),
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;
+CREATE TABLE ADDRESSGROUP
+(
+ id INTEGER NOT NULL,
+ name varchar(32),
+ description VARCHAR(64),
+ prefixlist varchar(255)
+);
+
+CREATE INDEX idx_addressgroup on XACML.ADDRESSGROUP(ID);
+
+DROP TABLE IF EXISTS XACML.POLICYSCORE;
+CREATE TABLE XACML.POLICYSCORE
+(
+POLICY_NAME VARCHAR(200) NOT NULL,
+ POLICY_SCORE VARCHAR(100),
+ PRIMARY KEY (POLICY_NAME)
+)
+;
+
+CREATE TABLE XACML.VSCLACTION
+(
+ID INTEGER NOT NULL,
+VSCL_ACTION VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+CREATE TABLE XACML.VNFTYPE
+(
+ID INTEGER NOT NULL,
+VNF_TYPE VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+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.ATTRIBUTE;
+CREATE TABLE XACML.ATTRIBUTE
+(
+id INTEGER NOT NULL,
+ ATTRIBUTE_VALUE VARCHAR(255),
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048),
+ is_designator CHAR NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ PRIORITY VARCHAR(45),
+ selector_path VARCHAR(2048),
+ xacml_id VARCHAR(100) NOT NULL UNIQUE,
+ category INTEGER,
+ constraint_type INTEGER,
+ datatype INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;
+CREATE TABLE XACML.DECISIONSETTINGS
+(
+id INTEGER NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048),
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ PRIORITY VARCHAR(45),
+ xacml_id VARCHAR(45) NOT NULL UNIQUE,
+ datatype INTEGER,
+ PRIMARY KEY (id)
+)
+;
+
+DROP TABLE IF EXISTS XACML.POLICY_MANANGEMENT;
+CREATE TABLE XACML.POLICY_MANANGEMENT
+(
+id INTEGER NOT NULL,
+ CONFIG_NAME VARCHAR(45) NOT NULL,
+ CREATE_DATE_TIME TIMESTAMP NOT NULL,
+ CREATED_BY VARCHAR(45) NOT NULL,
+ ECOMP_NAME VARCHAR(45) NOT NULL,
+ POLICY_NAME VARCHAR(45) NOT NULL,
+ scope VARCHAR(45) NOT NULL,
+ UPDATE_DATE_TIME TIMESTAMP NOT NULL,
+ UPDATED_BY VARCHAR(45) NOT NULL,
+ XML text NOT NULL,
+ PRIMARY KEY (id)
+)
+;
+
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ENFORCINGTYPE;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ACTIONPOLICYDICT;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.TERM;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.PROTOCOLLIST;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.PORTLIST;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.PREFIXLIST;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ADDRESSGROUP;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.POLICYSCORE;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.VSCLACTION;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.VNFTYPE;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.ATTRIBUTE;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.DECISIONSETTINGS;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.POLICY_MANAGEMENT;
+GRANT INSERT, UPDATE, DELETE, SELECT XACML.SCOPES;
+
+
+set foreign_key_checks=1;
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
index 00000000..9708fd42
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151001_upgrade_script.sql
@@ -0,0 +1,246 @@
+/*-
+ * ============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 XACML.SERVICEGROUP;
+CREATE TABLE XACML.SERVICEGROUP
+(
+id integer NOT NULL,
+name varchar(32),
+type varchar(16),
+transportprotocol varchar(255),
+appprotocol varchar(255),
+ports varchar(255),
+description varchar(255),
+primary key(id)
+)
+;
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SERVICEGROUP TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.ENFORCINGTYPE;
+CREATE TABLE XACML.ENFORCINGTYPE
+(
+ID INTEGER NOT NULL,
+ENFORCINGTYPE VARCHAR(255) NOT NULL,
+SCRIPT VARCHAR(5000) NOT NULL,
+CONNECTIONQUERY VARCHAR(1000) NOT NULL,
+VALUEQUERY VARCHAR(1000) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ENFORCINGTYPE TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.ACTIONPOLICYDICT;
+CREATE TABLE XACML.ACTIONPOLICYDICT
+(
+ID INTEGER NOT NULL,
+TYPE VARCHAR(45) NOT NULL,
+URL VARCHAR(45) NOT NULL,
+METHOD VARCHAR(45) NOT NULL,
+HEADERS VARCHAR(1024) NOT NULL,
+BODY VARCHAR(4096) NOT NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+ATTRIBUTE_NAME VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(1024),
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ACTIONPOLICYDICT TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.TERM;
+CREATE TABLE XACML.TERM
+(
+ID INTEGER NOT NULL,
+TERMNAME VARCHAR(45) NOT NULL,
+SRCIPLIST VARCHAR(100),
+DESTIPLIST VARCHAR(100),
+PROTOCOLLIST VARCHAR(100),
+PORTLIST VARCHAR(100),
+SRCPORTLIST VARCHAR(100),
+DESTPORTLIST VARCHAR(100),
+ACTION VARCHAR(100),
+DESCRIPTION VARCHAR(100),
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.TERM TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.PROTOCOLLIST;
+CREATE TABLE XACML.PROTOCOLLIST
+(
+ID INTEGER NOT NULL,
+PROTOCOLNAME VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(64),
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.PROTOCOLLIST TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.PORTLIST;
+CREATE TABLE XACML.PORTLIST
+(
+ID INTEGER NOT NULL,
+PORTNAME VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(64),
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.PORTLIST TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.PREFIXLIST;
+CREATE TABLE XACML.PREFIXLIST
+(
+ID INTEGER NOT NULL,
+PL_NAME VARCHAR(45) NOT NULL,
+PL_VALUE VARCHAR(64),
+DESCRIPTION VARCHAR(255) NULL,
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.PREFIXLIST TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.ADDRESSGROUP;
+CREATE TABLE XACML.ADDRESSGROUP
+(
+ ID INTEGER NOT NULL,
+ NAME VARCHAR(32),
+ DESCRIPTION VARCHAR(64),
+ PREFIXLIST VARCHAR(255),
+ PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ADDRESSGROUP TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.POLICYSCORE;
+CREATE TABLE XACML.POLICYSCORE
+(
+POLICY_NAME VARCHAR(100) NOT NULL,
+POLICY_SCORE VARCHAR(100),
+PRIMARY KEY(POLICY_NAME)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.POLICYSCORE TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.VSCLACTION;
+CREATE TABLE XACML.VSCLACTION
+(
+ID INTEGER NOT NULL,
+VSCL_ACTION VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.VSCLACTION TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.VNFTYPE;
+CREATE TABLE XACML.VNFTYPE
+(
+ID INTEGER NOT NULL,
+VNF_TYPE VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.VNFTYPE TO POLICY_USER;
+
+SET FOREIGN_KEY_CHECKS=0;
+
+DROP TABLE IF EXISTS XACML.ATTRIBUTE;
+CREATE TABLE XACML.ATTRIBUTE
+(
+ID INTEGER NOT NULL,
+CREATED_BY VARCHAR(255) NOT NULL,
+CREATED_DATE TIMESTAMP,
+DESCRIPTION VARCHAR(2048),
+IS_DESIGNATOR CHAR(1) NOT NULL,
+MODIFIED_BY VARCHAR(255) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+SELECTOR_PATH VARCHAR(2048),
+XACML_ID VARCHAR(500) NOT NULL,
+CATEGORY INTEGER,
+CONSTRAINT_TYPE INTEGER,
+DATATYPE INTEGER,
+PRIORITY VARCHAR(45),
+ATTRIBUTE_VALUE VARCHAR(45),
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ATTRIBUTE TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.DECISIONSETTINGS;
+CREATE TABLE XACML.DECISIONSETTINGS
+(
+ ID INTEGER NOT NULL,
+ XACML_ID VARCHAR(45) NOT NULL,
+ DESCRIPTION VARCHAR(45),
+ DATATYPE VARCHAR(45) NOT NULL,
+ CREATED_BY VARCHAR(45) NOT NULL,
+ MODIFIED_DATE TIMESTAMP NOT NULL,
+ MODIFIED_BY VARCHAR(45) NOT NULL,
+ PRIORITY VARCHAR(45),
+ CREATED_DATE TIMESTAMP NOT NULL,
+ PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.DECISIONSETTINGS TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.POLICY_MANAGEMENT;
+CREATE TABLE XACML.POLICY_MANAGEMENT
+(
+ ID INTEGER NOT NULL,
+ CONFIG_NAME VARCHAR(45) NOT NULL,
+ CREATE_DATE_TIME TIMESTAMP,
+ CREATED_BY VARCHAR(45) NOT NULL,
+ ECOMP_NAME VARCHAR(45) NOT NULL,
+ POLICY_NAME VARCHAR(45) NOT NULL,
+ SCOPE VARCHAR(45) NOT NULL,
+ UPDATE_DATE_TIME TIMESTAMP NOT NULL,
+ UPDATED_BY VARCHAR(45) NOT NULL,
+ XML TEXT NOT NULL,
+ PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.POLICY_MANAGEMENT TO POLICY_USER;
+
+DROP TABLE IF EXISTS XACML.SCOPES;
+CREATE TABLE XACML.SCOPES
+(
+ ID INTEGER NOT NULL,
+ SCOPE VARCHAR(45) NOT NULL,
+ PARENT_SCOPE INTEGER,
+ PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SCOPES TO POLICY_USER;
+
+
+set foreign_key_checks=1;
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
index 00000000..66cdf302
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151002_downgrade_script.sql
@@ -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=========================================================
+ */
+
+REVOKE INSERT, UPDATE, DELETE, SELECT ON XACML.SECURITYZONE from policy_user;
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
index 00000000..3b4d27e4
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151002_upgrade_script.sql
@@ -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=========================================================
+ */
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.SECURITYZONE TO policy_user;
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
index 00000000..a3147223
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151200_downgrade_script.sql
@@ -0,0 +1,43 @@
+/*-
+ * ============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 xacml.PolicyEntity;
+DROP TABLE IF EXISTS xacml.ConfigurationDataEntity;
+DROP TABLE IF EXISTS xacml.PolicyDBDaoEntity;
+DROP TABLE IF EXISTS xacml.GroupEntity;
+DROP TABLE IF EXISTS xacml.PdpEntity;
+DROP TABLE IF EXISTS xacml.ActionBodyEntity;
+DROP TABLE IF EXISTS xacml.DatabaseLockEntity;
+DROP TABLE IF EXISTS xacml.PolicyGroupEntity;
+
+ALTER TABLE XACML.TERM DROP COLUMN FROMZONE;
+ALTER TABLE XACML.TERM DROP COLUMN TOZONE;
+
+ALTER TABLE XACML.ACTIONPOLICYDICT DROP INDEX ACTIONPOLICYDICT_UNIQUE;
+
+DROP TABLE IF EXISTS XACML.ZONE;
+
+DROP TABLE IF EXISTS XACML.POLICYVERSION;
+
+ALTER TABLE XACML.VSCLACTION DROP INDEX VSCLACTION_VSCL_ACTION_UNIQUE;
+
+set foreign_key_checks=1;
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
index 00000000..ecb23da0
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/151200_upgrade_script.sql
@@ -0,0 +1,226 @@
+/*-
+ * ============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 xacml.PolicyEntity;
+CREATE TABLE xacml.PolicyEntity
+(
+policyId BIGINT NOT NULL AUTO_INCREMENT,
+created_by VARCHAR(255) NOT NULL,
+created_date TIMESTAMP,
+deleted BOOLEAN NOT NULL,
+description VARCHAR(2048) NOT NULL,
+modified_by VARCHAR(255) NOT NULL,
+modified_date TIMESTAMP NOT NULL,
+policyData TEXT,
+policyName VARCHAR(255) NOT NULL,
+policyVersion INTEGER,
+scope VARCHAR(255) NOT NULL,
+version INTEGER,
+actionBodyId BIGINT,
+configurationDataId BIGINT,
+PRIMARY KEY (policyId)
+);
+
+CREATE INDEX scope ON xacml.PolicyEntity (scope);
+CREATE INDEX policyName ON xacml.PolicyEntity (policyName);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PolicyEntity to policy_user;
+
+DROP TABLE IF EXISTS xacml.ConfigurationDataEntity;
+CREATE TABLE xacml.ConfigurationDataEntity
+(
+ configurationDataId BIGINT NOT NULL AUTO_INCREMENT,
+ configBody TEXT,
+ configType VARCHAR(255) NOT NULL,
+ configurationName VARCHAR(255) NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ deleted BOOLEAN NOT NULL,
+ description VARCHAR(2048) NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ version INTEGER,
+ PRIMARY KEY (configurationDataId)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.ConfigurationDataEntity to policy_user;
+
+DROP TABLE IF EXISTS xacml.PolicyDBDaoEntity;
+CREATE TABLE xacml.PolicyDBDaoEntity
+(
+ policyDBDaoUrl VARCHAR(500) NOT NULL,
+ created_date TIMESTAMP,
+ description VARCHAR(2048) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ password VARCHAR(100),
+ username VARCHAR(100),
+ PRIMARY KEY (policyDBDaoUrl)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PolicyDBDaoEntity to policy_user;
+
+DROP TABLE IF EXISTS xacml.GroupEntity;
+CREATE TABLE xacml.GroupEntity
+(
+groupKey BIGINT NOT NULL AUTO_INCREMENT,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ defaultGroup BOOLEAN NOT NULL,
+ deleted BOOLEAN NOT NULL,
+ description VARCHAR(2048) NOT NULL,
+ groupId VARCHAR(100) NOT NULL,
+ groupName VARCHAR(255) NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ version INTEGER,
+ PRIMARY KEY (groupKey)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.GroupEntity to policy_user;
+
+DROP TABLE IF EXISTS xacml.PdpEntity;
+CREATE TABLE xacml.PdpEntity
+(
+pdpKey BIGINT NOT NULL AUTO_INCREMENT,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ deleted BOOLEAN NOT NULL,
+ description VARCHAR(2048) NOT NULL,
+ jmxPort INTEGER NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ pdpId VARCHAR(255) NOT NULL,
+ pdpName VARCHAR(255) NOT NULL,
+ groupKey BIGINT,
+ PRIMARY KEY (pdpKey)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PdpEntity to policy_user;
+
+DROP TABLE IF EXISTS xacml.ActionBodyEntity;
+CREATE TABLE xacml.ActionBodyEntity
+(
+actionBodyId BIGINT NOT NULL AUTO_INCREMENT,
+ actionBody TEXT,
+ actionBodyName VARCHAR(255) NOT NULL,
+ created_by VARCHAR(255) NOT NULL,
+ created_date TIMESTAMP,
+ deleted BOOLEAN NOT NULL,
+ modified_by VARCHAR(255) NOT NULL,
+ modified_date TIMESTAMP NOT NULL,
+ version INTEGER,
+ PRIMARY KEY (actionBodyId)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.ActionBodyEntity to policy_user;
+
+DROP TABLE IF EXISTS xacml.DatabaseLockEntity;
+CREATE TABLE xacml.DatabaseLockEntity
+(
+ lock_key INTEGER NOT NULL,
+ PRIMARY KEY (lock_key)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.DatabaseLockEntity to policy_user;
+
+DROP TABLE IF EXISTS xacml.PolicyGroupEntity;
+CREATE TABLE xacml.PolicyGroupEntity
+(
+groupKey BIGINT NOT NULL AUTO_INCREMENT,
+ policyId BIGINT NOT NULL,
+ PRIMARY KEY (groupKey,policyId)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT on xacml.PolicyGroupEntity to policy_user;
+
+ALTER TABLE xacml.PolicyEntity ADD CONSTRAINT UNQ_PolicyEntity_0 UNIQUE (policyName, scope);
+ALTER TABLE xacml.PolicyEntity ADD CONSTRAINT FK_PolicyEntity_configurationDataId FOREIGN KEY (configurationDataId)
+REFERENCES xacml.ConfigurationDataEntity (configurationDataId);
+ALTER TABLE xacml.PolicyEntity ADD CONSTRAINT FK_PolicyEntity_actionBodyId FOREIGN KEY (actionBodyId)
+REFERENCES xacml.ActionBodyEntity (actionBodyId);
+ALTER TABLE xacml.PdpEntity ADD CONSTRAINT FK_PdpEntity_groupKey FOREIGN KEY (groupKey)
+REFERENCES xacml.GroupEntity (groupKey);
+
+ALTER TABLE xacml.PolicyGroupEntity ADD CONSTRAINT FK_PolicyGroupEntity_policyId FOREIGN KEY (policyId)
+REFERENCES xacml.PolicyEntity (policyId);
+
+ALTER TABLE xacml.PolicyGroupEntity ADD CONSTRAINT FK_PolicyGroupEntity_groupKey FOREIGN KEY (groupKey)
+REFERENCES xacml.GroupEntity (groupKey);
+
+-- CREATE SEQUENCE xacml.seqActBody START WITH 1;
+-- CREATE SEQUENCE xacml.seqGroup INCREMENT BY 50 START WITH 50;
+-- CREATE SEQUENCE xacml.seqConfig START WITH 1;
+-- CREATE SEQUENCE xacml.seqPolicy START WITH 1;
+-- CREATE SEQUENCE xacml.seqPdp INCREMENT BY 50 START WITH 50;
+
+DROP TABLE IF EXISTS XACML.TERM;
+CREATE TABLE XACML.TERM
+(
+ ID int NOT NULL,
+ termName VARCHAR(45) NOT NULL,
+ fromzone VARCHAR(100),
+ tozone VARCHAR(100),
+ srcIPList VARCHAR(100),
+ destIPList VARCHAR(100) ,
+ protocolList VARCHAR(100) ,
+ portList VARCHAR(100) ,
+ srcPortList VARCHAR(100) ,
+ destPortList VARCHAR(100) ,
+ action VARCHAR(100),
+ DESCRIPTION VARCHAR(100),
+ PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.TERM TO policy_user;
+
+ALTER TABLE XACML.ACTIONPOLICYDICT add constraint ACTIONPOLICYDICT_UNIQUE UNIQUE(ATTRIBUTE_NAME);
+
+DROP TABLE IF EXISTS XACML.ZONE;
+CREATE TABLE XACML.ZONE
+(
+ ID INTEGER NOT NULL,
+ zonename VARCHAR(45) NOT NULL,
+ zonevalue VARCHAR(64)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.ZONE TO policy_user;
+
+DROP TABLE IF EXISTS XACML.POLICYVERSION;
+
+CREATE TABLE XACML.POLICYVERSION
+(
+ID INTEGER NOT NULL,
+POLICY_NAME VARCHAR(255) NOT NULL,
+ACTIVE_VERSION INTEGER NULL,
+HIGHEST_VERSION INTEGER NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+CREATED_BY VARCHAR(45) NOT NULL,
+MODIFIED_DATE TIMESTAMP NOT NULL,
+MODIFIED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+GRANT INSERT, UPDATE, DELETE, SELECT ON XACML.POLICYVERSION to policy_user;
+
+ALTER TABLE XACML.VSCLACTION ADD CONSTRAINT VSCLACTION_VSCL_ACTION_UNIQUE UNIQUE(VSCL_ACTION);
+
+set foreign_key_checks=1;
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
index 00000000..41baaa92
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/160200_downgrade_script.sql
@@ -0,0 +1,39 @@
+/*-
+ * ============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.DCAEuuid;
+drop table if exists xacml.MicroServiceLocation;
+drop table if exists xacml.DCAEUsers;
+drop table if exists xacml.microserviceconfigname;
+drop table if exists xacml.vmType;
+
+alter table xacml.term drop column created_by;
+alter table xacml.term drop column created_date;
+alter table xacml.term drop column modified_by;
+alter table xacml.term drop column modified_date;
+
+drop table if exists xacml.pepoptions;
+drop table if exists xacml.VarbindDictionary;
+drop table if exists xacml.GocEventAlarm;
+drop table if exists xacml.GocTraversal;
+drop table if exists xacml.BRMSParamTemplate;
+
+alter table xacml.roles drop column name;
+
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
index 00000000..46629a94
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/160200_upgrade_script.sql
@@ -0,0 +1,127 @@
+/*-
+ * ============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.DCAEuuid;
+CREATE TABLE xacml.DCAEuuid (
+ ID int NOT NULL,
+ name VARCHAR(45) NOT NULL,
+ description VARCHAR(64)
+ );
+
+drop table if exists xacml.MicroServiceLocation;
+CREATE TABLE xacml.MicroServiceLocation (
+ ID int NOT NULL,
+ name VARCHAR(45) NOT NULL,
+ description VARCHAR(64)
+ );
+
+drop table if exists xacml.DCAEUsers;
+CREATE TABLE xacml.DCAEUsers (
+ ID int NOT NULL,
+ name VARCHAR(45) NOT NULL,
+ description VARCHAR(64)
+ );
+
+drop table if exists xacml.microserviceconfigname;
+CREATE TABLE xacml.microserviceconfigname (
+ ID int NOT NULL,
+ name VARCHAR(45) NOT NULL,
+ description VARCHAR(64)
+ );
+
+drop table if exists xacml.vmType;
+CREATE TABLE xacml.vmType (
+ ID int NOT NULL,
+ name VARCHAR(45) NOT NULL,
+ description VARCHAR(64)
+ );
+
+alter table xacml.term add created_by varchar(100);
+alter table xacml.term add created_date date;
+alter table xacml.term add modified_by varchar(100);
+alter table xacml.term add modified_date date;
+
+drop table if exists xacml.pepoptions;
+CREATE TABLE xacml.PEPOPTIONS (
+ID INT NOT NULL,
+PEP_NAME VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(1024),
+Actions VARCHAR(1024) NOT NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+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.VarbindDictionary;
+CREATE TABLE xacml.VarbindDictionary (
+Id INT NOT NULL,
+created_by VARCHAR(255) NOT NULL,
+created_date TIMESTAMP,
+modified_by VARCHAR(255) NOT NULL,
+modified_date TIMESTAMP NOT NULL,
+varbind_Description VARCHAR(2048),
+varbind_Name VARCHAR(45) NOT NULL UNIQUE,
+varbind_oid VARCHAR(45) NOT NULL,
+PRIMARY KEY (Id)
+);
+
+drop table if exists xacml.GocEventAlarm;
+CREATE TABLE xacml.GocEventAlarm(
+Id INT NOT NULL,
+Event VARCHAR(45) NOT NULL,
+description VARCHAR(1024),
+Alarm VARCHAR(1024) NOT NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+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.GocTraversal;
+CREATE TABLE xacml.GocTraversal(
+ID INT NOT NULL,
+TRAVERSAL VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45) NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+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.BRMSParamTemplate;
+CREATE TABLE xacml.BRMSParamTemplate(
+ID INT NOT NULL,
+param_template_name VARCHAR(45) NOT NULL,
+DESCRIPTION VARCHAR(45),
+rule LONGTEXT NOT NULL,
+CREATED_DATE TIMESTAMP NOT NULL,
+CREATED_BY VARCHAR(45) NOT NULL,
+PRIMARY KEY(ID)
+);
+
+alter table xacml.roles add name varchar(45);
+
+
+
+
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
index 00000000..5f6381af
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/160201_downgrade_script.sql
@@ -0,0 +1,43 @@
+/*-
+ * ============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 xacml.attribute modify created_date timestamp;
+alter table xacml.obadvice modify created_date timestamp;
+alter table xacml.decisionsettings modify created_date timestamp;
+alter table xacml.actionpolicydict modify created_date timestamp;
+alter table xacml.ecompname modify created_date timestamp;
+alter table xacml.policyentity modify created_date timestamp;
+alter table xacml.configurationdataentity modify created_date timestamp;
+alter table xacml.policydbdaoentity modify created_date timestamp;
+
+alter table xacml.actionpolicydict modify created_date timestamp;
+alter table xacml.vsclaction modify created_date timestamp;
+alter table xacml.vnftype modify created_date timestamp;
+
+alter table xacml.groupentity modify created_date timestamp;
+alter table xacml.pdpentity modify created_date timestamp;
+alter table xacml.actionbodyentity modify created_date timestamp;
+
+alter table xacml.term modify created_date timestamp;
+alter table xacml.varbinddictionary modify created_date timestamp;
+alter table xacml.pepoptions modify created_date timestamp;
+alter table xacml.goceventalarm modify created_date timestamp;
+alter table xacml.goctraversal modify created_date timestamp;
+alter table xacml.brmsparamtemplate modify created_date timestamp;
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
index 00000000..70ddf791
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/160201_upgrade_script.sql
@@ -0,0 +1,44 @@
+/*-
+ * ============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 xacml.attribute modify created_date timestamp default current_timestamp;
+alter table xacml.obadvice modify created_date timestamp default current_timestamp;
+alter table xacml.decisionsettings modify created_date timestamp default current_timestamp;
+alter table xacml.actionpolicydict modify created_date timestamp default current_timestamp;
+alter table xacml.ecompname modify created_date timestamp default current_timestamp;
+alter table xacml.policyentity modify created_date timestamp default current_timestamp;
+alter table xacml.configurationdataentity modify created_date timestamp default current_timestamp;
+alter table xacml.policydbdaoentity modify created_date timestamp default current_timestamp;
+
+alter table xacml.actionpolicydict modify created_date timestamp default current_timestamp;
+alter table xacml.vsclaction modify created_date timestamp default current_timestamp;
+alter table xacml.vnftype modify created_date timestamp default current_timestamp;
+
+alter table xacml.groupentity modify created_date timestamp default current_timestamp;
+alter table xacml.pdpentity modify created_date timestamp default current_timestamp;
+alter table xacml.actionbodyentity modify created_date timestamp default current_timestamp;
+
+alter table xacml.term modify created_date timestamp default current_timestamp;
+alter table xacml.term modify modified_date timestamp not null;
+alter table xacml.varbinddictionary modify created_date timestamp default current_timestamp;
+alter table xacml.pepoptions modify created_date timestamp default current_timestamp;
+alter table xacml.goceventalarm modify created_date timestamp default current_timestamp;
+alter table xacml.goctraversal modify created_date timestamp default current_timestamp;
+alter table xacml.brmsparamtemplate modify created_date timestamp default current_timestamp;
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
index 00000000..d5a990fc
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/160400_downgrade_script.sql
@@ -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
index 00000000..745b4715
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/160400_upgrade_script.sql
@@ -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
index 00000000..f7b3c9e5
--- /dev/null
+++ b/packages/base/src/files/m2/settings.xml
@@ -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
index 00000000..277113c2
--- /dev/null
+++ b/packages/base/src/files/m2/standalone-settings.xml
@@ -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
index 00000000..b83d2226
--- /dev/null
+++ b/packages/install/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/packages/install/pom.xml b/packages/install/pom.xml
new file mode 100644
index 00000000..2ed29546
--- /dev/null
+++ b/packages/install/pom.xml
@@ -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
index 00000000..48b82d40
--- /dev/null
+++ b/packages/install/src/assembly/zip.xml
@@ -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
index 00000000..90128e91
--- /dev/null
+++ b/packages/install/src/files/base.conf
@@ -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
index 00000000..609aa868
--- /dev/null
+++ b/packages/install/src/files/policy-management.conf
@@ -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
index 00000000..3cde69cd
--- /dev/null
+++ b/packages/pom.xml
@@ -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
index 00000000..3e4bc681
--- /dev/null
+++ b/policy-core/pom.xml
@@ -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
index 00000000..447a5271
--- /dev/null
+++ b/policy-core/src/assembly/assemble_zip.xml
@@ -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
index 00000000..a14c6547
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/core/FeatureAPI.java
@@ -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
index 00000000..ae7cd622
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/core/PolicyContainer.java
@@ -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
index 00000000..89341d6b
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/core/PolicySession.java
@@ -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
index 00000000..7fa0dd0a
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmx.java
@@ -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
index 00000000..4b48da07
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxListener.java
@@ -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
index 00000000..a947e82b
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/core/jmx/PdpJmxMBean.java
@@ -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
index 00000000..fd8681c3
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/properties/Lockable.java
@@ -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
index 00000000..13580219
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java
@@ -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
index 00000000..bb6334a2
--- /dev/null
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/properties/Startable.java
@@ -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
index 00000000..033a08aa
--- /dev/null
+++ b/policy-core/src/main/resources/META-INF/jndi.properties
@@ -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
index 00000000..34685b0e
--- /dev/null
+++ b/policy-core/src/main/resources/META-INF/persistence.xml
@@ -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
index 00000000..e62853c5
--- /dev/null
+++ b/policy-endpoints/pom.xml
@@ -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
index 00000000..d38bab5a
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/Topic.java
@@ -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
index 00000000..b3f236f7
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicEndpoint.java
@@ -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
index 00000000..7a2e9711
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicListener.java
@@ -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
index 00000000..2ce8e9e7
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicRegisterable.java
@@ -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
index 00000000..2250b1ea
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSink.java
@@ -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
index 00000000..0dfbe1c4
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/TopicSource.java
@@ -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
index 00000000..c38f627e
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopic.java
@@ -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
index 00000000..30978c27
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSink.java
@@ -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
index 00000000..e6a46d2f
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/BusTopicSource.java
@@ -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
index 00000000..3c55c9f3
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSink.java
@@ -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
index 00000000..5b4cfd42
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSinkFactory.java
@@ -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
index 00000000..8da7906a
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSource.java
@@ -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
index 00000000..f8d85eb7
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/DmaapTopicSourceFactory.java
@@ -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
index 00000000..efa4dc5e
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSink.java
@@ -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
index 00000000..85b98838
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSinkFactory.java
@@ -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
index 00000000..4da01302
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSource.java
@@ -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
index 00000000..bf2a4038
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/UebTopicSourceFactory.java
@@ -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
index 00000000..6fee5ce0
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusConsumer.java
@@ -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
index 00000000..798bf989
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusPublisher.java
@@ -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
index 00000000..e36e3afc
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/BusTopicBase.java
@@ -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
index 00000000..bd88818b
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineBusTopicSink.java
@@ -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
index 00000000..417c6d47
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineDmaapTopicSink.java
@@ -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
index 00000000..2d4b1552
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/InlineUebTopicSink.java
@@ -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
index 00000000..f37c349e
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedBusTopicSource.java
@@ -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
index 00000000..e65d44a7
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedDmaapTopicSource.java
@@ -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
index 00000000..edb55c75
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/event/comm/bus/internal/SingleThreadedUebTopicSource.java
@@ -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
index 00000000..2e81b2c8
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClient.java
@@ -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
index 00000000..53a8c2b2
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/HttpClientFactory.java
@@ -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
index 00000000..4fa59dc8
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/client/internal/JerseyClient.java
@@ -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
index 00000000..5f5dd787
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java
@@ -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
index 00000000..bd5ae242
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java
@@ -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
index 00000000..4914a4cb
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java
@@ -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
index 00000000..74360e80
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyServletServer.java
@@ -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
index 00000000..34ee199a
--- /dev/null
+++ b/policy-endpoints/src/main/resources/schema/pdpd-configuration.jsonschema
@@ -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
index 00000000..ced3dcf4
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java
@@ -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
index 00000000..94f29804
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java
@@ -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
index 00000000..a0320a09
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java
@@ -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
index 00000000..a00f2ffd
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEndpoints.java
@@ -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
index 00000000..ff1b4980
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestMockHealthCheck.java
@@ -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
index 00000000..c279cd1d
--- /dev/null
+++ b/policy-healthcheck/pom.xml
@@ -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
index 00000000..266e1d0a
--- /dev/null
+++ b/policy-healthcheck/src/assembly/assemble_zip.xml
@@ -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
index 00000000..2ed2e075
--- /dev/null
+++ b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheck.java
@@ -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
index 00000000..ce1dd90b
--- /dev/null
+++ b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/HealthCheckFeature.java
@@ -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
index 00000000..e37e758a
--- /dev/null
+++ b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java
@@ -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
index 00000000..7e307d08
--- /dev/null
+++ b/policy-healthcheck/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI
@@ -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
index 00000000..41456c27
--- /dev/null
+++ b/policy-management/config/policy-engine.properties
@@ -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
index 00000000..f8f31d8f
--- /dev/null
+++ b/policy-management/config/policyLogger.properties
@@ -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
index 00000000..2983f1f4
--- /dev/null
+++ b/policy-management/pom.xml
@@ -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
index 00000000..85a1dbfa
--- /dev/null
+++ b/policy-management/src/assembly/assemble_zip.xml
@@ -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
index 00000000..72f8e0b2
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java
@@ -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
index 00000000..d94e773c
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsControllerFactory.java
@@ -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
index 00000000..2c5708d3
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java
@@ -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
index 00000000..f0c0f474
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java
@@ -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
index 00000000..6bb1185d
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/persistence/SystemPersistence.java
@@ -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
index 00000000..8f8a4ba7
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java
@@ -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
index 00000000..a2ce3123
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/JsonProtocolFilter.java
@@ -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
index 00000000..9e079ff5
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/ProtocolCoderToolset.java
@@ -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
index 00000000..3c112573
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java
@@ -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
index 00000000..98af02ee
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/ControllerConfiguration.java
@@ -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
index 00000000..87cf2348
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/DroolsConfiguration.java
@@ -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
index 00000000..65de6656
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/configuration/PdpdConfiguration.java
@@ -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
index 00000000..48e6313a
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java
@@ -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
index 00000000..108600b2
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/system/Main.java
@@ -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
index 00000000..543fd0e3
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyController.java
@@ -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
index 00000000..e105bbb9
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyControllerFactory.java
@@ -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
index 00000000..33f2a098
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java
@@ -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
index 00000000..96f9e5bf
--- /dev/null
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/system/internal/AggregatedPolicyController.java
@@ -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
index 00000000..d6843fee
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/add-secured-participant.sh
@@ -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
index 00000000..ea0ec7ad
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/create-api-key.sh
@@ -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
index 00000000..b0d4d6f2
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/create-secured-topic.sh
@@ -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
index 00000000..a9ae7125
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/options
@@ -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
index 00000000..8c553927
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/pdpd-configuration.sh
@@ -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
index 00000000..4d28d941
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/policy-management-controller
@@ -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
index 00000000..187b2916
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/rest-add-controller.sh
@@ -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
index 00000000..de1d601c
--- /dev/null
+++ b/policy-management/src/main/server-gen/bin/rest-delete-controller.sh
@@ -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
index 00000000..1201a9da
--- /dev/null
+++ b/policy-management/src/main/server/config/IntegrityMonitor.properties
@@ -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
index 00000000..8421cf40
--- /dev/null
+++ b/policy-management/src/main/server/config/controller.properties.README
@@ -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
index 00000000..60793cdc
--- /dev/null
+++ b/policy-management/src/main/server/config/droolsPersistence.properties
@@ -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
index 00000000..6ad25643
--- /dev/null
+++ b/policy-management/src/main/server/config/log4j.properties
@@ -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
index 00000000..545b6f48
--- /dev/null
+++ b/policy-management/src/main/server/config/logback.xml
@@ -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
index 00000000..5a96c541
--- /dev/null
+++ b/policy-management/src/main/server/config/makefile
@@ -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
index 00000000..647f7367
--- /dev/null
+++ b/policy-management/src/main/server/config/policy-engine.properties
@@ -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
index 00000000..51da7ece
--- /dev/null
+++ b/policy-management/src/main/server/config/policy-healthcheck.properties
@@ -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
index 00000000..4a977992
--- /dev/null
+++ b/policy-management/src/main/server/config/policyLogger.properties
@@ -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
index 00000000..feffbd00
--- /dev/null
+++ b/policy-management/src/main/server/config/system.properties
@@ -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
index 00000000..e88d8aaf
--- /dev/null
+++ b/policy-management/src/main/server/config/xacmlPersistence.properties
@@ -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
index 00000000..2c50ba9a
--- /dev/null
+++ b/policy-persistence/config/policy-engine.properties
@@ -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
index 00000000..6ee66fd6
--- /dev/null
+++ b/policy-persistence/config/policyLogger.properties
@@ -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
index 00000000..074a9d44
--- /dev/null
+++ b/policy-persistence/pom.xml
@@ -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
index 00000000..e0e22f5b
--- /dev/null
+++ b/policy-persistence/src/assembly/assemble_zip.xml
@@ -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
index 00000000..51e92aa9
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DbAudit.java
@@ -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
index 00000000..2b6058fd
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java
@@ -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
index 00000000..d1b1ad6d
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorProperties.java
@@ -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
index 00000000..86c672e2
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java
@@ -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
index 00000000..46e5a5e6
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/im/PMStandbyStateChangeNotifier.java
@@ -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
index 00000000..11cc8788
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdp.java
@@ -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
index 00000000..87b58723
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpEntity.java
@@ -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
index 00000000..e0f5d816
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpImpl.java
@@ -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
index 00000000..7a219148
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpObject.java
@@ -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
index 00000000..fa75c2e7
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsConnector.java
@@ -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
index 00000000..82ee5d1d
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java
@@ -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
index 00000000..63af53cb
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPersistenceProperties.java
@@ -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
index 00000000..21a480d9
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSession.java
@@ -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
index 00000000..89e310f0
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsSessionEntity.java
@@ -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
index 00000000..ac9255a2
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java
@@ -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
index 00000000..e2c7f402
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java
@@ -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
index 00000000..ccec824c
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/ThreadRunningChecker.java
@@ -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
index 00000000..7e2388e5
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/XacmlPersistenceProperties.java
@@ -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
index 00000000..540a4bd4
--- /dev/null
+++ b/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI
@@ -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
index 00000000..6b654732
--- /dev/null
+++ b/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/IntegrityAuditIntegrationTest.java
@@ -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
index 00000000..f58d304e
--- /dev/null
+++ b/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/ResiliencyTestCases.java
@@ -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
index 00000000..af649866
--- /dev/null
+++ b/policy-persistence/src/test/java/org/openecomp/policy/drools/controller/test/StandbyStateManagementTest.java
@@ -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
index 00000000..0ab36286
--- /dev/null
+++ b/policy-persistence/src/test/resources/IntegrityMonitor.properties
@@ -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
index 00000000..51ec1613
--- /dev/null
+++ b/policy-persistence/src/test/resources/META-INF/persistence.xml
@@ -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
index 00000000..544e1c23
--- /dev/null
+++ b/policy-persistence/src/test/resources/droolsPersistence.properties
@@ -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
index 00000000..746d59a0
--- /dev/null
+++ b/policy-persistence/src/test/resources/log4j.properties
@@ -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
index 00000000..9fd83e8d
--- /dev/null
+++ b/policy-persistence/src/test/resources/logback.xml
@@ -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
index 00000000..284e87d7
--- /dev/null
+++ b/policy-persistence/src/test/resources/xacmlPersistence.properties
@@ -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
index 00000000..b16beda9
--- /dev/null
+++ b/policy-persistence/src/test/server/config/IntegrityMonitor.properties
@@ -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
index 00000000..8cdaf6ab
--- /dev/null
+++ b/policy-persistence/src/test/server/config/droolsPersistence.properties
@@ -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
index 00000000..6ee66fd6
--- /dev/null
+++ b/policy-persistence/src/test/server/config/policyLogger.properties
@@ -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
index 00000000..149aa557
--- /dev/null
+++ b/policy-persistence/src/test/server/config/xacmlPersistence.properties
@@ -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
index 00000000..b7ac7fb2
--- /dev/null
+++ b/policy-utils/pom.xml
@@ -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
index 00000000..b50e6e85
--- /dev/null
+++ b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedService.java
@@ -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
index 00000000..2747e85e
--- /dev/null
+++ b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/OrderedServiceImpl.java
@@ -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
index 00000000..a5e34695
--- /dev/null
+++ b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/Pair.java
@@ -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
index 00000000..34ddcc1c
--- /dev/null
+++ b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/PropertyUtil.java
@@ -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
index 00000000..0b86c2aa
--- /dev/null
+++ b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/ReflectionUtil.java
@@ -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
index 00000000..214d949e
--- /dev/null
+++ b/policy-utils/src/main/java/org/openecomp/policy/drools/utils/Triple.java
@@ -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
index 00000000..55091718
--- /dev/null
+++ b/policy-utils/src/test/java/org/openecomp/policy/drools/utils/PropertyUtilTest.java
@@ -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
index 00000000..0063f104
--- /dev/null
+++ b/policy-utils/src/test/resources/log4j.properties
@@ -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
index 00000000..04002099
--- /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
index 00000000..55687cde
--- /dev/null
+++ b/project-configs/maven/conf/settings.xml
@@ -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
index 00000000..56ab0aff
--- /dev/null
+++ b/version.properties
@@ -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