DR AAF CADI integration 14/82814/6
authorefiacor <fiachra.corcoran@est.tech>
Tue, 26 Mar 2019 14:29:01 +0000 (14:29 +0000)
committerefiacor <fiachra.corcoran@est.tech>
Tue, 26 Mar 2019 14:29:01 +0000 (14:29 +0000)
Change-Id: I01548882f813e4029dddf7ddee2af12472163761
Issue-ID: DMAAP-1016
Signed-off-by: efiacor <fiachra.corcoran@est.tech>
54 files changed:
datarouter-docker-compose/src/main/resources/database/sql_init_01.sql
datarouter-docker-compose/src/main/resources/docker-compose.yml
datarouter-docker-compose/src/main/resources/node_data/aaf_certs/org.onap.dmaap-dr.keyfile [new file with mode: 0755]
datarouter-docker-compose/src/main/resources/node_data/node.properties
datarouter-docker-compose/src/main/resources/prov_data/aaf_certs/org.onap.dmaap-dr.keyfile [new file with mode: 0755]
datarouter-docker-compose/src/main/resources/prov_data/addSubscriber.txt
datarouter-docker-compose/src/main/resources/prov_data/provserver.properties
datarouter-node/aaf_certs/org.onap.dmaap-dr.keyfile [new file with mode: 0755]
datarouter-node/pom.xml
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/DRNodeCadiFilter.java [new file with mode: 0644]
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/DeliveryTask.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/DestInfo.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/IsFrom.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/LogManager.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/NodeConfig.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/NodeConfigManager.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/NodeMain.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/NodeServlet.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/PathUtil.java [new file with mode: 0644]
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/ProvData.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/SubnetMatcher.java
datarouter-node/src/main/resources/drNodeCadi.properties [new file with mode: 0644]
datarouter-node/src/main/resources/node.properties
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/DRNodeCadiFilterTest.java [new file with mode: 0644]
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/DeliveryQueueTest.java
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/DeliveryTest.java
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeConfigTest.java
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeServletTest.java
datarouter-prov/aaf_certs/org.onap.dmaap-dr.keyfile [new file with mode: 0755]
datarouter-prov/pom.xml
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/BaseServlet.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/DRFeedsServlet.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/FeedServlet.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/Main.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/SubscribeServlet.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/SubscriptionServlet.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/beans/Feed.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/beans/Subscription.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DB.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DRProvCadiFilter.java [new file with mode: 0644]
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/LogfileLoader.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/PasswordProcessor.java [new file with mode: 0644]
datarouter-prov/src/main/resources/drProvCadi.properties [new file with mode: 0644]
datarouter-prov/src/main/resources/misc/sql_init_01.sql
datarouter-prov/src/main/resources/provserver.properties
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DRFeedsServletTest.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DrServletTestBase.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/FeedServletTest.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscribeServletTest.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscriptionServletTest.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/utils/DRProvCadiFilterTest.java [new file with mode: 0644]
datarouter-prov/src/test/resources/create.sql
datarouter-prov/src/test/resources/h2Database.properties
pom.xml

index 14c59a6..83dfd0b 100644 (file)
@@ -4,7 +4,7 @@ CREATE TABLE FEEDS (
     FEEDID         INT UNSIGNED NOT NULL PRIMARY KEY,
     GROUPID        INT(10) UNSIGNED NOT NULL DEFAULT 0,
     NAME           VARCHAR(255) NOT NULL,
     FEEDID         INT UNSIGNED NOT NULL PRIMARY KEY,
     GROUPID        INT(10) UNSIGNED NOT NULL DEFAULT 0,
     NAME           VARCHAR(255) NOT NULL,
-    VERSION        VARCHAR(20) NOT NULL,
+    VERSION        VARCHAR(20) NULL,
     DESCRIPTION    VARCHAR(1000),
     BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL,
     AUTH_CLASS     VARCHAR(32) NOT NULL,
     DESCRIPTION    VARCHAR(1000),
     BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL,
     AUTH_CLASS     VARCHAR(32) NOT NULL,
@@ -16,13 +16,14 @@ CREATE TABLE FEEDS (
     DELETED        BOOLEAN DEFAULT FALSE,
     LAST_MOD       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED      BOOLEAN DEFAULT FALSE,
     DELETED        BOOLEAN DEFAULT FALSE,
     LAST_MOD       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED      BOOLEAN DEFAULT FALSE,
-    CREATED_DATE   TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+    CREATED_DATE   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    AAF_INSTANCE   VARCHAR(256)
 );
 
 CREATE TABLE FEED_ENDPOINT_IDS (
     FEEDID        INT UNSIGNED NOT NULL,
 );
 
 CREATE TABLE FEED_ENDPOINT_IDS (
     FEEDID        INT UNSIGNED NOT NULL,
-    USERID        VARCHAR(20) NOT NULL,
-    PASSWORD      VARCHAR(32) NOT NULL
+    USERID        VARCHAR(60) NOT NULL,
+    PASSWORD      VARCHAR(100) NOT NULL
 );
 
 CREATE TABLE FEED_ENDPOINT_ADDRS (
 );
 
 CREATE TABLE FEED_ENDPOINT_ADDRS (
@@ -35,8 +36,9 @@ CREATE TABLE SUBSCRIPTIONS (
     FEEDID                      INT UNSIGNED NOT NULL,
     GROUPID                     INT(10) UNSIGNED NOT NULL DEFAULT 0,
     DELIVERY_URL                VARCHAR(256),
     FEEDID                      INT UNSIGNED NOT NULL,
     GROUPID                     INT(10) UNSIGNED NOT NULL DEFAULT 0,
     DELIVERY_URL                VARCHAR(256),
-    DELIVERY_USER               VARCHAR(20),
-    DELIVERY_PASSWORD           VARCHAR(32),
+    FOLLOW_REDIRECTS            TINYINT(1) NOT NULL DEFAULT 0,
+    DELIVERY_USER               VARCHAR(60),
+    DELIVERY_PASSWORD           VARCHAR(100),
     DELIVERY_USE100             BOOLEAN DEFAULT FALSE,
     METADATA_ONLY               BOOLEAN DEFAULT FALSE,
     SUBSCRIBER                  VARCHAR(8) NOT NULL,
     DELIVERY_USE100             BOOLEAN DEFAULT FALSE,
     METADATA_ONLY               BOOLEAN DEFAULT FALSE,
     SUBSCRIBER                  VARCHAR(8) NOT NULL,
@@ -45,8 +47,9 @@ CREATE TABLE SUBSCRIPTIONS (
     LAST_MOD                    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED                   BOOLEAN DEFAULT FALSE,
     PRIVILEGED_SUBSCRIBER       BOOLEAN DEFAULT FALSE,
     LAST_MOD                    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED                   BOOLEAN DEFAULT FALSE,
     PRIVILEGED_SUBSCRIBER       BOOLEAN DEFAULT FALSE,
+    CREATED_DATE                TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     DECOMPRESS                  BOOLEAN DEFAULT FALSE,
     DECOMPRESS                  BOOLEAN DEFAULT FALSE,
-    CREATED_DATE                TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+    AAF_INSTANCE                VARCHAR(256)
 
 );
 
 
 );
 
@@ -89,7 +92,7 @@ CREATE TABLE LOG_RECORDS (
 CREATE TABLE INGRESS_ROUTES (
     SEQUENCE  INT UNSIGNED NOT NULL,
     FEEDID    INT UNSIGNED NOT NULL,
 CREATE TABLE INGRESS_ROUTES (
     SEQUENCE  INT UNSIGNED NOT NULL,
     FEEDID    INT UNSIGNED NOT NULL,
-    USERID    VARCHAR(20),
+    USERID    VARCHAR(50),
     SUBNET    VARCHAR(44),
     NODESET   INT UNSIGNED NOT NULL
 );
     SUBNET    VARCHAR(44),
     NODESET   INT UNSIGNED NOT NULL
 );
@@ -144,6 +147,6 @@ INSERT INTO PARAMETERS VALUES
     ('PROV_MAXFEED_COUNT',  '10000'),
     ('PROV_MAXSUB_COUNT',   '100000'),
     ('PROV_REQUIRE_CERT', 'false'),
     ('PROV_MAXFEED_COUNT',  '10000'),
     ('PROV_MAXSUB_COUNT',   '100000'),
     ('PROV_REQUIRE_CERT', 'false'),
-    ('PROV_REQUIRE_SECURE', 'false'),
+    ('PROV_REQUIRE_SECURE', 'true'),
     ('_INT_VALUES', 'LOGROLL_INTERVAL|PROV_MAXFEED_COUNT|PROV_MAXSUB_COUNT|DELIVERY_INIT_RETRY_INTERVAL|DELIVERY_MAX_RETRY_INTERVAL|DELIVERY_RETRY_RATIO|DELIVERY_MAX_AGE|DELIVERY_FILE_PROCESS_INTERVAL')
     ;
     ('_INT_VALUES', 'LOGROLL_INTERVAL|PROV_MAXFEED_COUNT|PROV_MAXSUB_COUNT|DELIVERY_INIT_RETRY_INTERVAL|DELIVERY_MAX_RETRY_INTERVAL|DELIVERY_RETRY_RATIO|DELIVERY_MAX_AGE|DELIVERY_FILE_PROCESS_INTERVAL')
     ;
index 8784ee6..bd4726a 100644 (file)
@@ -68,7 +68,7 @@ services:
   datarouter-subscriber:
     image: nexus3.onap.org:10001/onap/dmaap/datarouter-subscriber
     container_name: subscriber-node
   datarouter-subscriber:
     image: nexus3.onap.org:10001/onap/dmaap/datarouter-subscriber
     container_name: subscriber-node
-    hostname: subscriber.com
+    hostname: dmaap-dr-subscriber
     ports:
     - "7070:7070"
     volumes:
     ports:
     - "7070:7070"
     volumes:
@@ -76,7 +76,7 @@ services:
     networks:
       testing_net:
         aliases:
     networks:
       testing_net:
         aliases:
-        - subscriber.com
+        - dmaap-dr-subscriber
 
   mariadb_container:
     image: mariadb:10.2.14
 
   mariadb_container:
     image: mariadb:10.2.14
diff --git a/datarouter-docker-compose/src/main/resources/node_data/aaf_certs/org.onap.dmaap-dr.keyfile b/datarouter-docker-compose/src/main/resources/node_data/aaf_certs/org.onap.dmaap-dr.keyfile
new file mode 100755 (executable)
index 0000000..85bfa61
--- /dev/null
@@ -0,0 +1,27 @@
+j4IkjDmzOE_ZdHuN_cePYmySXrhmqM4WuGp86_RTiBlJ1TTvUaP_SOSZOqH0fxjk32gRvxJ01_iO
+mLtbQ-wZKk-fwCK_o6xrXJcN0G_Y8VGK2OMeqypm98ji25CSMvTdFLaohdPJwiRNMdmwwyF5q1Od
+pKviCISBlQ49ytwy3Mv0x7aV3kjkDWSgpx9TiMbWoAKlddcdQMUTEMh0CT0nLGv9uhwmRQ4I8UuE
+IzvR1Rit9HayMlXFND6n0IWggYqtAeRV-8wDrI2rAXGOrfLF0RC5-c0Wd0N000BWXvsT_nCYBCM6
+ffA5eAKCJmOVjJFzQTRXJq7Zhwij0CtEPgqqaipKUQhHaft9xeKXW3SPhREIn75F2u2uCcU1sNmd
+ytAk7yBPwdEcCQD-KVE9ZB3_57H0WIEr45SpU5ZePJkt2YV85H2Tlc_hGK18gTAcvGqDO3qELmV5
+SBHX5X_ZNL93mOkt37R0SGRdMZVIPJXNTgl4fGAsapvU7Y7sGMYrf2Ea0D-3hctk-aOKuuPEI1Ug
+0lqKjghJdvHYRFbm4C_7H-ai7UcBuixBd54Mp-hyBX-gjnFZuMHazFX2toKNe9RgDXIavHzTfF-l
+8fjdQpTplc2ECLINf-X6gs7w0zPYv04kLKixwlFff4ZocoxelGDEBlYYGNNxQBZvQtUX_dZetXF1
+VPNnwTB7Sp0fqaXR2aVaZNFSZYeL7VdxkiT0becNRa9QE9s2gU7oO_KTE8JyAiJyO-ojAvSUi-p_
+rq2Ivmab_L4t6GwMpv-EmRcntUQ_PM4s_XvJL2RmmSPWoNvbgCS0IilpYi2CPnEEgxqX37-Unx8m
+tYoNkiN-j9rA3Hr4EjEhrbOLf2wAh6RUeULerBpLKnf0Ans6UhjT7XVDaNvzxtAE-GrUCKHQ0ml2
+P_vzDBlGKobaRo-WQzQA-mZKGo1W4Q-qwFdusUflgfJ7iTrvw62jn30f4xGZcaP5Oa-9JvdZJggW
+1UvAM-85LdjGTxuI9KXbqRLWZk46B-UF7mDOce6dbRXjY48bZWIHEXcpzPQg6QA02cO10TN5K89V
+qXeCnz03ePf0u6YhMAOt5xiUvJpd1y_WI0jh4SH2dT26SegcuRTVLnEG0aL6ClypObwj3FLB1Pek
+UESqziiG4mQf_rzBAdPqcjbP8oeM2-mz09VYNyUOQ-7gk6bMAMWVqBx0uDxgIwUzr2UMbahB2Kg6
+9V7yE7obAKZa8x5oMiDGnvgjL9QeHwhUsNbwhhgqTDnB10vj4gh8RkNK8OsxQ53Nofj2PQZfY0GJ
+a6It7DCmnAgQ9N51RvCeodmmK9Zh3n_zoxt8gA-eV8zbidXZYQwYWx6ai7ooP7yol2bE_TLDDY9l
+_oYO_db73wSmqgTvoAdmrQGO4NI_g2iYN-Gd4XK4V_xgYPKyY5tHNSd4OKr_UuYiSioyNxE4IK1t
+zWyJ3tUXAyeq_ZjUDjabsnGnxmgujShRfK-rBh_1AapY3Oh99-aehETtcXihUmFX4lohowniWTA3
+MF1MMlRM5N1phF7xFgkAaZJfkQ-inqgWYvQ9XuW0LfumN4QeO8KnfknukSSgZ86PYTrgJKDIOKWn
+UYsxSoE_U02WxQThW8ayrFtKRLGR2x9bMaKzaON0tfltwyQO7ttsKlSyORIWVrGO48CyEDxpDs8U
+RDvN_SgFq1gWarCKLL0HDUdLGMfimZP7sPfVEKkprMlDp_gpx7kD7SaB1m7xuNjhBd-6I3gqSR7g
+lizTgKmuGalPRGorxX72vlTEYqLtgNWok6e9qjMGhEYCf02li6Ksoxp4ZejN_9S1-FGlcuq3SE9f
+Pm0HckGtPJ8u3u2mmLpT1QzzS0RG3XJU5kNJvZcSEG0GOsU7OnWTXoZnleFJvEoQrOuQeZJLyuxn
+mnmd49xrTirtxkLB83L8HQdAHvY5Phx8LbR9NJYvkH1MIEbBrrfUUx-x_llROOAYdPxvtpYcMkSt
+ApZwRgyvaBiwUirWbnlpmf8QV1MYMlZeBbbqPZIC4eaqcxOSmZa8ox4aR3XQg9zjCxm_jXdE
\ No newline at end of file
index 98b7137..62b0f82 100644 (file)
@@ -3,7 +3,6 @@
 # * org.onap.dmaap
 # * ===========================================================================
 # * Copyright ï¿½ 2017 AT&T Intellectual Property. All rights reserved.
 # * org.onap.dmaap
 # * ===========================================================================
 # * Copyright ï¿½ 2017 AT&T Intellectual Property. All rights reserved.
-# * Modifications Copyright (C) 2018 Nokia. All rights reserved.
 # * ===========================================================================
 # * Licensed under the Apache License, Version 2.0 (the "License");
 # * you may not use this file except in compliance with the License.
 # * ===========================================================================
 # * Licensed under the Apache License, Version 2.0 (the "License");
 # * you may not use this file except in compliance with the License.
 # *
 #-------------------------------------------------------------------------------
 #
 # *
 #-------------------------------------------------------------------------------
 #
-#    Configuration parameters fixed at startup for the DataRouter node
+#    Configuration parameters set at startup for the DataRouter node
 #
 #    URL to retrieve dynamic configuration
 #
 #    URL to retrieve dynamic configuration
-#
-#ProvisioningURL:    ${DRTR_PROV_INTURL}
-ProvisioningURL=https://dmaap-dr-prov:8443/internal/prov
-
+ProvisioningURL = https://dmaap-dr-prov:8443/internal/prov
 #
 #    URL to upload PUB/DEL/EXP logs
 #
 #    URL to upload PUB/DEL/EXP logs
-#
-#LogUploadURL:    ${DRTR_LOG_URL}
-LogUploadURL=https://dmaap-dr-prov:8443/internal/logs
-
+LogUploadURL = https://dmaap-dr-prov:8443/internal/logs
 #
 #    The port number for http as seen within the server
 #
 #    The port number for http as seen within the server
-#
-#IntHttpPort:    ${DRTR_NODE_INTHTTPPORT:-8080}
-IntHttpPort=8080
+IntHttpPort = 8080
 #
 #    The port number for https as seen within the server
 #
 #    The port number for https as seen within the server
-#
-IntHttpsPort=8443
+IntHttpsPort = 8443
 #
 #    The external port number for https taking port mapping into account
 #
 #    The external port number for https taking port mapping into account
+ExtHttpsPort = 443
 #
 #
-ExtHttpsPort=443
-#
-#    The minimum interval between fetches of the dynamic configuration
-#    from the provisioning server
-#
-MinProvFetchInterval=10000
+#    The minimum interval between fetches of the dynamic configuration from the provisioning server
+MinProvFetchInterval = 10000
 #
 #    The minimum interval between saves of the redirection data file
 #
 #    The minimum interval between saves of the redirection data file
-#
-MinRedirSaveInterval=10000
+MinRedirSaveInterval = 10000
 #
 #    The path to the directory where log files are stored
 #
 #    The path to the directory where log files are stored
-#
-LogDir=/opt/app/datartr/logs
+LogDir = /opt/app/datartr/logs
 #
 #    The retention interval (in days) for log files
 #
 #    The retention interval (in days) for log files
-#
-LogRetention=30
+LogRetention = 30
 #
 #    The path to the directories where data and meta data files are stored
 #
 #    The path to the directories where data and meta data files are stored
-#
-SpoolDir=/opt/app/datartr/spool
+SpoolDir = /opt/app/datartr/spool
 #
 #    The path to the redirection data file
 #
 #    The path to the redirection data file
-#
-#RedirectionFile:    etc/redirections.dat
+RedirectionFile = etc/redirections.dat
 #
 #    The type of keystore for https
 #
 #    The type of keystore for https
-KeyStoreType:    jks
+KeyStoreType = jks
 #
 #    The path to the keystore for https
 #
 #    The path to the keystore for https
-#
-KeyStoreFile:/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.jks
+KeyStoreFile = /opt/app/datartr/aaf_certs/org.onap.dmaap-dr.jks
 #
 #    The password for the https keystore
 #
 #    The password for the https keystore
-#
 KeyStorePassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The password for the private key in the https keystore
 KeyStorePassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The password for the private key in the https keystore
-#
 KeyPassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The type of truststore for https
 KeyPassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The type of truststore for https
-#
-TrustStoreType=jks
+TrustStoreType = jks
 #
 #    The path to the truststore for https
 #
 #    The path to the truststore for https
-#
-TrustStoreFile=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.trust.jks
+TrustStoreFile = /opt/app/datartr/aaf_certs/org.onap.dmaap-dr.trust.jks
 #
 #    The password for the https truststore
 #
 #    The password for the https truststore
-#
 TrustStorePassword=(Rd,&{]%ePdp}4JZjqoJ2G+g
 #
 #    The path to the file used to trigger an orderly shutdown
 TrustStorePassword=(Rd,&{]%ePdp}4JZjqoJ2G+g
 #
 #    The path to the file used to trigger an orderly shutdown
-#
-QuiesceFile=etc/SHUTDOWN
+QuiesceFile = etc/SHUTDOWN
 #
 #    The key used to generate passwords for node to node transfers
 #
 #    The key used to generate passwords for node to node transfers
+NodeAuthKey = Node123!
+#
+#    DR_NODE DEFAULT ENABLED TLS PROTOCOLS
+NodeHttpsProtocols = TLSv1.1|TLSv1.2
+#
+#    AAF type to generate permission string
+AAFType = org.onap.dmaap-dr.feed
+#
+#    AAF default instance to generate permission string - default should be legacy
+AAFInstance = legacy
+#
+#    AAF action to generate permission string - default should be publish
+AAFAction = publish
+#
+#    AAF URL to connect to AAF server
+AafUrl = https://aaf-onap-test.osaaf.org:8095
 #
 #
-NodeAuthKey=Node123!
+#    AAF CADI enabled flag
+CadiEnabled = false
 
 
diff --git a/datarouter-docker-compose/src/main/resources/prov_data/aaf_certs/org.onap.dmaap-dr.keyfile b/datarouter-docker-compose/src/main/resources/prov_data/aaf_certs/org.onap.dmaap-dr.keyfile
new file mode 100755 (executable)
index 0000000..a586a72
--- /dev/null
@@ -0,0 +1,27 @@
+VDu7g5rP2-JMemc6RwP0HqM4ILJnuja8R_bzdCG1u0_Z2EQJN_7ZNPDb28V6JCDF-59sX10_i9vT
+-nw77ViAuwJO7ffSut8ipVhESeQxTokZsErzMFpeJZDhMM16W5LLtxwUs_tgh_EQIJSc-WcFUNYS
+NagugzjmNE5-hUosLgnt7mZ1nX4zFER9Nq1ce0EQS--kAB9rxcRmoywPlBlHvPmP_caiwpa1SzJp
+gbFF6smyLEWhjDhJkgvM_4FwaQCbJBVGcy2a3Lc9orHsz9S1RJTZ9CExhasM0qEp3kk0fMEFE9k6
+TomOpUBGizLfHPpg18KtXyM8zErj8qdS0KMwaCKtwGzCWw08MF5rVZrMYWLKDMOs8U2ESU7x28nV
+KSrAsR11QD7vX4PTVTfjEpcHSGe-9nPD7TckY8_O-9l67v_OUW1Fw4MSESCN0RtT7ZlNYwDV0syA
+X94rv1Y45N41tfX76jz8PDB9G-PF36BtkICJWK24zwuQDgpkURhCLPYzvBhPmCPyQil810X9s_bX
+icmV2cSN3oYQRz5dNSjUYH1CDt9edAJt4p2PQhM3A2xXyw1FVvbAIYA7iF-3qYG9csroBzsCcS5C
+hX8929jZHQWU5pygtpedEWhX__tnSrd-xIpxPnhOxrb-lNLva5JGKauU2DrGoLd_7RTwbuRdCiQo
+uGFtYOtjLciPz81oEEpXQTReeSnvGyGiZNxRrKWMEmq-biyQd4DuRVmTDuLAG4rd92QWS6qUz0uf
+9TtJiYlN3mNkxz3ahEGWLKR79rH9juJ3xqpcF-Rb7Y1bmiCDBv3DVVFiYIpwQuto1iSIYabL34Ql
+QqX65E1c3uvPksN6Nl1nvAVxSKM94wAFsMiA9Rp8AN9pDSxtj7D3kZCG8I0YaIxF_s-OeJtr1RPx
+ifv8vrwN23GUQCmpGBbyNXNe6zz-hz_HJdAsBr6WjLny9LQkeYszHGF-OL5ps6K5gHBRV0Ui1C7H
+Gj7egsjnV_Lu5MpBxhTrquDrZKK3t38kf0zrV-zfSGzJlGbLS91h8bR-7FAZiNEzgXPWYi26w81i
+W3Csx4oqsfKswp0pO80rggkFf9LL9pjCkSUTTVyF-toa9kY2h7JsVtqntP4Mjagp4Tnj01988kne
+Mj8SLm2mJySTLdH5Hi4arKW943iCqYjEaZ7wXFNJSZ6vvBm3KC1XX6C0DjRrgQoKIHw_4JcGhvOU
+P5LdpBT1AOcE8lIKrGGq8hyfJKLVUMec-NkzAT2aIl0YJoUcJv4fs-lKccGL4FDrq5y_yvD3xQ6v
+xt7KTanFxntqLYmM72Y2eFwJGlDEHhm0SejAV64-odksA_zMLLuYwkq_KSj0If9AVpRXz7KzIj9P
+9y-WMfAWKFfIyqGWXt5sYdMTQPG4qKCcFQBx3T0E6kiQMBuOZz0dR032eFPMexrymEowjosr2jt3
+ib8rFxmPMyyUWoV1iBafFMLf5PN2oapTq76gqeQQGGwpmYJB8cWlS1Eq_ZbzZpK2PSwX-fC6NSf3
+KtOV_r2VI3e_V6csnWTY8nxCJj9FlQCvLOzp964DNsBeUwDpsD7T_pgQy0THgAnq32ZtDvQfgeUE
+TUJC7oQeOEY7QBWjbZkumds51j7oTlsp2dPForlHwBk_2Nd5VCwVRNa1QMS8WcghLYbUCX5zeplc
+u2bopHn9GD614gt7f7wysDgTGegOCAuMoL7wA9TXN4BSfAF9mwpdtRFE4lT3N1xmfhKt9rM6Lu8T
+RGvBOmTOTT5IwJrrE5mpvmESw05sHUcCZ9ENv-VhoeC3Ffk9uXqrDggQgaDs9XcXqzEPBp9wDPTt
+UJpbtBGECSSTuXAZyUh3I0WFz96kVuHmQpDYVTpy1sxPjmgjgKyhu_6jLGSsYpVBH063n7KSKVdF
+ROKojZN4-FsBlPhoOhNEd7x1OBfgCG79HKGk33jhESObZkPIrcTc17jiE-ud2D1B1_Fl-OJNR7Vh
+GIk4WMZrH9NeVwDuIgBxF74plqg6tSl0Cdd4m7e3Drsq-wRfsU2gNTo5oL-2SgbsO5n3ubQf
\ No newline at end of file
index 45e1273..ccb55f6 100644 (file)
 # *
 #-------------------------------------------------------------------------------
 {
 # *
 #-------------------------------------------------------------------------------
 {
-                "delivery" :
-
-                {
-                                "url" : "http://172.100.0.3:7070/",
-                                "user" : "datarouter",
-                                "password" : "datarouter",
-                                "use100" : true
-                },
-                "metadataOnly" : false,
-                "suspend" : false,
-                "groupid" : 29,
-                "subscriber" : "sg481n"
+"delivery" :
+    {
+        "url" : "http://172.100.0.3:7070/",
+        "user" : "datarouter",
+        "password" : "datarouter",
+        "use100" : true
+    },
+"metadataOnly" : false,
+"suspend" : false,
+"groupid" : 29,
+"subscriber" : "sg481n"
 }
 }
index 7e38f28..21b9bc4 100755 (executable)
@@ -43,8 +43,27 @@ org.onap.dmaap.datarouter.provserver.logretention        = 30
 # relaxation to accommodate OOM kubernetes deploy
 org.onap.dmaap.datarouter.provserver.isaddressauthenabled = false
 
 # relaxation to accommodate OOM kubernetes deploy
 org.onap.dmaap.datarouter.provserver.isaddressauthenabled = false
 
+#Localhost address config
+org.onap.dmaap.datarouter.provserver.localhost = 127.0.0.1
+
 # Database access
 org.onap.dmaap.datarouter.db.driver   = org.mariadb.jdbc.Driver
 org.onap.dmaap.datarouter.db.url      = jdbc:mariadb://datarouter-mariadb:3306/datarouter
 org.onap.dmaap.datarouter.db.login    = datarouter
 org.onap.dmaap.datarouter.db.password = datarouter
 # Database access
 org.onap.dmaap.datarouter.db.driver   = org.mariadb.jdbc.Driver
 org.onap.dmaap.datarouter.db.url      = jdbc:mariadb://datarouter-mariadb:3306/datarouter
 org.onap.dmaap.datarouter.db.login    = datarouter
 org.onap.dmaap.datarouter.db.password = datarouter
+
+# PROV - DEFAULT ENABLED TLS PROTOCOLS
+org.onap.dmaap.datarouter.provserver.https.include.protocols = TLSv1.1|TLSv1.2
+
+# AAF config
+org.onap.dmaap.datarouter.provserver.cadi.enabled = false
+
+org.onap.dmaap.datarouter.provserver.passwordencryption   = PasswordEncryptionKey#@$%^&1234#
+org.onap.dmaap.datarouter.provserver.aaf.feed.type        = org.onap.dmaap-dr.feed
+org.onap.dmaap.datarouter.provserver.aaf.sub.type         = org.onap.dmaap-dr.sub
+org.onap.dmaap.datarouter.provserver.aaf.instance         = legacy
+org.onap.dmaap.datarouter.provserver.aaf.action.publish   = publish
+org.onap.dmaap.datarouter.provserver.aaf.action.subscribe = subscribe
+
+# AAF URL to connect to AAF server
+org.onap.dmaap.datarouter.provserver.cadi.aaf.url = https://aaf-onap-test.osaaf.org:8095
\ No newline at end of file
diff --git a/datarouter-node/aaf_certs/org.onap.dmaap-dr.keyfile b/datarouter-node/aaf_certs/org.onap.dmaap-dr.keyfile
new file mode 100755 (executable)
index 0000000..85bfa61
--- /dev/null
@@ -0,0 +1,27 @@
+j4IkjDmzOE_ZdHuN_cePYmySXrhmqM4WuGp86_RTiBlJ1TTvUaP_SOSZOqH0fxjk32gRvxJ01_iO
+mLtbQ-wZKk-fwCK_o6xrXJcN0G_Y8VGK2OMeqypm98ji25CSMvTdFLaohdPJwiRNMdmwwyF5q1Od
+pKviCISBlQ49ytwy3Mv0x7aV3kjkDWSgpx9TiMbWoAKlddcdQMUTEMh0CT0nLGv9uhwmRQ4I8UuE
+IzvR1Rit9HayMlXFND6n0IWggYqtAeRV-8wDrI2rAXGOrfLF0RC5-c0Wd0N000BWXvsT_nCYBCM6
+ffA5eAKCJmOVjJFzQTRXJq7Zhwij0CtEPgqqaipKUQhHaft9xeKXW3SPhREIn75F2u2uCcU1sNmd
+ytAk7yBPwdEcCQD-KVE9ZB3_57H0WIEr45SpU5ZePJkt2YV85H2Tlc_hGK18gTAcvGqDO3qELmV5
+SBHX5X_ZNL93mOkt37R0SGRdMZVIPJXNTgl4fGAsapvU7Y7sGMYrf2Ea0D-3hctk-aOKuuPEI1Ug
+0lqKjghJdvHYRFbm4C_7H-ai7UcBuixBd54Mp-hyBX-gjnFZuMHazFX2toKNe9RgDXIavHzTfF-l
+8fjdQpTplc2ECLINf-X6gs7w0zPYv04kLKixwlFff4ZocoxelGDEBlYYGNNxQBZvQtUX_dZetXF1
+VPNnwTB7Sp0fqaXR2aVaZNFSZYeL7VdxkiT0becNRa9QE9s2gU7oO_KTE8JyAiJyO-ojAvSUi-p_
+rq2Ivmab_L4t6GwMpv-EmRcntUQ_PM4s_XvJL2RmmSPWoNvbgCS0IilpYi2CPnEEgxqX37-Unx8m
+tYoNkiN-j9rA3Hr4EjEhrbOLf2wAh6RUeULerBpLKnf0Ans6UhjT7XVDaNvzxtAE-GrUCKHQ0ml2
+P_vzDBlGKobaRo-WQzQA-mZKGo1W4Q-qwFdusUflgfJ7iTrvw62jn30f4xGZcaP5Oa-9JvdZJggW
+1UvAM-85LdjGTxuI9KXbqRLWZk46B-UF7mDOce6dbRXjY48bZWIHEXcpzPQg6QA02cO10TN5K89V
+qXeCnz03ePf0u6YhMAOt5xiUvJpd1y_WI0jh4SH2dT26SegcuRTVLnEG0aL6ClypObwj3FLB1Pek
+UESqziiG4mQf_rzBAdPqcjbP8oeM2-mz09VYNyUOQ-7gk6bMAMWVqBx0uDxgIwUzr2UMbahB2Kg6
+9V7yE7obAKZa8x5oMiDGnvgjL9QeHwhUsNbwhhgqTDnB10vj4gh8RkNK8OsxQ53Nofj2PQZfY0GJ
+a6It7DCmnAgQ9N51RvCeodmmK9Zh3n_zoxt8gA-eV8zbidXZYQwYWx6ai7ooP7yol2bE_TLDDY9l
+_oYO_db73wSmqgTvoAdmrQGO4NI_g2iYN-Gd4XK4V_xgYPKyY5tHNSd4OKr_UuYiSioyNxE4IK1t
+zWyJ3tUXAyeq_ZjUDjabsnGnxmgujShRfK-rBh_1AapY3Oh99-aehETtcXihUmFX4lohowniWTA3
+MF1MMlRM5N1phF7xFgkAaZJfkQ-inqgWYvQ9XuW0LfumN4QeO8KnfknukSSgZ86PYTrgJKDIOKWn
+UYsxSoE_U02WxQThW8ayrFtKRLGR2x9bMaKzaON0tfltwyQO7ttsKlSyORIWVrGO48CyEDxpDs8U
+RDvN_SgFq1gWarCKLL0HDUdLGMfimZP7sPfVEKkprMlDp_gpx7kD7SaB1m7xuNjhBd-6I3gqSR7g
+lizTgKmuGalPRGorxX72vlTEYqLtgNWok6e9qjMGhEYCf02li6Ksoxp4ZejN_9S1-FGlcuq3SE9f
+Pm0HckGtPJ8u3u2mmLpT1QzzS0RG3XJU5kNJvZcSEG0GOsU7OnWTXoZnleFJvEoQrOuQeZJLyuxn
+mnmd49xrTirtxkLB83L8HQdAHvY5Phx8LbR9NJYvkH1MIEbBrrfUUx-x_llROOAYdPxvtpYcMkSt
+ApZwRgyvaBiwUirWbnlpmf8QV1MYMlZeBbbqPZIC4eaqcxOSmZa8ox4aR3XQg9zjCxm_jXdE
\ No newline at end of file
index 3e75e88..9c82ff3 100755 (executable)
             <artifactId>commons-lang3</artifactId>
             <version>3.0</version>
         </dependency>
             <artifactId>commons-lang3</artifactId>
             <version>3.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.onap.aaf.authz</groupId>
+            <artifactId>aaf-cadi-aaf</artifactId>
+            <version>${aaf-cadi-aaf.version}</version>
+        </dependency>
     </dependencies>
     <profiles>
         <profile>
     </dependencies>
     <profiles>
         <profile>
diff --git a/datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/DRNodeCadiFilter.java b/datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/DRNodeCadiFilter.java
new file mode 100644 (file)
index 0000000..b012259
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.datarouter.node;
+
+import org.apache.log4j.Logger;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.filter.CadiFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+public class DRNodeCadiFilter extends CadiFilter {
+    private static Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.node.NodeServlet");
+
+    DRNodeCadiFilter(boolean init, PropAccess access) throws ServletException {
+        super(init, access);
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+        String path = httpRequest.getPathInfo();
+        if (!(path.startsWith("/internal"))) {
+            if (!(httpRequest.getMethod().equalsIgnoreCase("POST"))) {
+                if (httpRequest.getMethod().equalsIgnoreCase("DELETE") && path.startsWith("/delete")) {
+                    chain.doFilter(request, response);
+                } else {
+                    String feedId = getFeedId(request, response);
+                    String aafDbInstance = NodeConfigManager.getInstance().getAafInstance(feedId);
+                    if (aafDbInstance != null && !aafDbInstance.equals("") && !aafDbInstance.equalsIgnoreCase("legacy")) {
+                        logger.info("DRNodeCadiFilter - doFilter: FeedId - " + feedId + ":" + "AAF Instance -" + aafDbInstance);
+                        super.doFilter(request, response, chain);
+                    } else {
+                        logger.info("DRNodeCadiFilter - doFilter: FeedId - " + feedId + ":" + "Legacy Feed");
+                        chain.doFilter(request, response);
+                    }
+                }
+            }
+        } else {
+            chain.doFilter(request, response);
+        }
+    }
+
+    private String getFeedId(ServletRequest request, ServletResponse response) {
+        HttpServletRequest req = (HttpServletRequest) request;
+        HttpServletResponse resp = (HttpServletResponse) response;
+        String fileid = req.getPathInfo();
+        if (fileid == null) {
+            logger.info("NODE0105 Rejecting bad URI for PUT " + req.getPathInfo() + " from " + req.getRemoteAddr());
+            try {
+                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Invalid request URI.  Expecting <feed-publishing-url>/<fileid>.");
+            } catch (IOException e) {
+                logger.error("NODE0541 DRNodeCadiFilter.getFeedId: ", e);
+            }
+            return null;
+        }
+        String feedid = "";
+
+        if (fileid.startsWith("/publish/")) {
+            fileid = fileid.substring(9);
+            int i = fileid.indexOf('/');
+            if (i == -1 || i == fileid.length() - 1) {
+                logger.info("NODE0105 Rejecting bad URI for PUT (publish) of " + req.getPathInfo() + " from " + req.getRemoteAddr());
+                try {
+                    resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Invalid request URI.  Expecting <feed-publishing-url>/<fileid>.  Possible missing fileid.");
+                } catch (IOException e) {
+                    logger.error("NODE0542 DRNodeCadiFilter.getFeedId: ", e);
+                }
+                return null;
+            }
+            feedid = fileid.substring(0, i);
+        }
+        return feedid;
+    }
+
+}
index a3af88f..b64396b 100644 (file)
@@ -64,6 +64,7 @@ public class DeliveryTask implements Runnable, Comparable<DeliveryTask> {
     private String feedid;
     private String subid;
     private int attempts;
     private String feedid;
     private String subid;
     private int attempts;
+    private boolean followRedirects;
     private String[][] hdrs;
     private String newInvocationId;
 
     private String[][] hdrs;
     private String newInvocationId;
 
@@ -81,6 +82,7 @@ public class DeliveryTask implements Runnable, Comparable<DeliveryTask> {
         this.pubid = pubid;
         destInfo = deliveryTaskHelper.getDestinationInfo();
         subid = destInfo.getSubId();
         this.pubid = pubid;
         destInfo = deliveryTaskHelper.getDestinationInfo();
         subid = destInfo.getSubId();
+        this.followRedirects = destInfo.isFollowRedirects();
         feedid = destInfo.getLogData();
         spool = destInfo.getSpool();
         String dfn = spool + "/" + pubid;
         feedid = destInfo.getLogData();
         spool = destInfo.getSpool();
         String dfn = spool + "/" + pubid;
@@ -125,7 +127,7 @@ public class DeliveryTask implements Runnable, Comparable<DeliveryTask> {
                 hdrv.add(new String[]{h, v});
             }
         } catch (Exception e) {
                 hdrv.add(new String[]{h, v});
             }
         } catch (Exception e) {
-            loggerDeliveryTask.error("Exception "+e.getStackTrace(),e);
+            loggerDeliveryTask.error("Exception "+ Arrays.toString(e.getStackTrace()), e);
         }
         hdrs = hdrv.toArray(new String[hdrv.size()][]);
         url = deliveryTaskHelper.getDestURL(fileid);
         }
         hdrs = hdrv.toArray(new String[hdrv.size()][]);
         url = deliveryTaskHelper.getDestURL(fileid);
@@ -245,7 +247,7 @@ public class DeliveryTask implements Runnable, Comparable<DeliveryTask> {
             }
             deliveryTaskHelper.reportStatus(this, rc, xpubid, rmsg);
         } catch (Exception e) {
             }
             deliveryTaskHelper.reportStatus(this, rc, xpubid, rmsg);
         } catch (Exception e) {
-            loggerDeliveryTask.error("Exception " + e.getStackTrace(), e);
+            loggerDeliveryTask.error("Exception " + Arrays.toString(e.getStackTrace()), e);
             deliveryTaskHelper.reportException(this, e);
         }
     }
             deliveryTaskHelper.reportException(this, e);
         }
     }
@@ -324,7 +326,7 @@ public class DeliveryTask implements Runnable, Comparable<DeliveryTask> {
         } catch (ProtocolException pe) {
             deliveryTaskHelper.reportDeliveryExtra(this, -1L);
             // Rcvd error instead of 100-continue
         } catch (ProtocolException pe) {
             deliveryTaskHelper.reportDeliveryExtra(this, -1L);
             // Rcvd error instead of 100-continue
-            loggerDeliveryTask.error("Exception " + pe.getStackTrace(), pe);
+            loggerDeliveryTask.error("Exception " + Arrays.toString(pe.getStackTrace()), pe);
         }
         return outputStream;
     }
         }
         return outputStream;
     }
@@ -409,4 +411,11 @@ public class DeliveryTask implements Runnable, Comparable<DeliveryTask> {
     public String getFeedId() {
         return (feedid);
     }
     public String getFeedId() {
         return (feedid);
     }
+
+    /**
+     * Get the followRedirects for this delivery task
+     */
+    public boolean getFollowRedirects() {
+        return(followRedirects);
+    }
 }
 }
index 7375352..8aa339f 100644 (file)
@@ -39,7 +39,8 @@ public class DestInfo {
     private boolean use100;
     private boolean privilegedSubscriber;
     private boolean decompress;
     private boolean use100;
     private boolean privilegedSubscriber;
     private boolean decompress;
-
+    private boolean followRedirects;
+    private String aafInstance;
     /**
      * Create a destination information object.
      *
     /**
      * Create a destination information object.
      *
@@ -53,9 +54,10 @@ public class DestInfo {
      * @param    metaonly    Is this a metadata only delivery?
      * @param    use100    Should I use expect 100-continue?
      * @param    privilegedSubscriber   Can we wait to receive a file processed acknowledgement before deleting file
      * @param    metaonly    Is this a metadata only delivery?
      * @param    use100    Should I use expect 100-continue?
      * @param    privilegedSubscriber   Can we wait to receive a file processed acknowledgement before deleting file
+     * @param    followRedirects Is follow redirect of destination enabled?
      * @param    decompress     To see if the they want there information compressed or decompressed
      */
      * @param    decompress     To see if the they want there information compressed or decompressed
      */
-    public DestInfo(String name, String spool, String subid, String logdata, String url, String authuser, String authentication, boolean metaonly, boolean use100, boolean privilegedSubscriber, boolean decompress) {
+    public DestInfo(String name, String spool, String subid, String logdata, String url, String authuser, String authentication, boolean metaonly, boolean use100, boolean privilegedSubscriber, boolean followRedirects, boolean decompress) {
         this.name = name;
         this.spool = spool;
         this.subid = subid;
         this.name = name;
         this.spool = spool;
         this.subid = subid;
@@ -66,6 +68,7 @@ public class DestInfo {
         this.metaonly = metaonly;
         this.use100 = use100;
         this.privilegedSubscriber = privilegedSubscriber;
         this.metaonly = metaonly;
         this.use100 = use100;
         this.privilegedSubscriber = privilegedSubscriber;
+        this.followRedirects = followRedirects;
         this.decompress = decompress;
     }
 
         this.decompress = decompress;
     }
 
@@ -87,6 +90,7 @@ public class DestInfo {
         this.metaonly = subscription.isMetaDataOnly();
         this.use100 = subscription.isUsing100();
         this.privilegedSubscriber = subscription.isPrivilegedSubscriber();
         this.metaonly = subscription.isMetaDataOnly();
         this.use100 = subscription.isUsing100();
         this.privilegedSubscriber = subscription.isPrivilegedSubscriber();
+        this.followRedirects = subscription.getFollowRedirect();
         this.decompress = subscription.isDecompress();
     }
 
         this.decompress = subscription.isDecompress();
     }
 
@@ -185,6 +189,15 @@ public class DestInfo {
         return (privilegedSubscriber);
     }
 
         return (privilegedSubscriber);
     }
 
+    /**
+    * Should I follow redirects?
+    *
+    * @return True if I should.
+    */
+    public boolean isFollowRedirects() {
+        return (followRedirects);
+    }
+
     /**
      * Should i decompress the file before sending it on
      *
     /**
      * Should i decompress the file before sending it on
      *
index 35ba095..b8db030 100644 (file)
@@ -26,6 +26,7 @@ package org.onap.dmaap.datarouter.node;
 
 import org.apache.log4j.Logger;
 
 
 import org.apache.log4j.Logger;
 
+import java.io.IOException;
 import java.util.*;
 import java.net.*;
 
 import java.util.*;
 import java.net.*;
 
@@ -62,24 +63,37 @@ public class IsFrom {
         long now = System.currentTimeMillis();
         if (now > nextcheck) {
             nextcheck = now + 10000;
         long now = System.currentTimeMillis();
         if (now > nextcheck) {
             nextcheck = now + 10000;
-            Vector<String> v = new Vector<>();
+            ArrayList<String> hostAddrArray = new ArrayList<>();
             try {
                 InetAddress[] addrs = InetAddress.getAllByName(fqdn);
             try {
                 InetAddress[] addrs = InetAddress.getAllByName(fqdn);
-                for (InetAddress a : addrs) {
-                    v.add(a.getHostAddress());
+                for (InetAddress addr : addrs) {
+                    hostAddrArray.add(addr.getHostAddress());
                 }
             } catch (UnknownHostException e) {
                 logger.debug("IsFrom: UnknownHostEx: " + e.toString(), e);
             }
                 }
             } catch (UnknownHostException e) {
                 logger.debug("IsFrom: UnknownHostEx: " + e.toString(), e);
             }
-            ips = v.toArray(new String[v.size()]);
+            ips = hostAddrArray.toArray(new String[0]);
             logger.info("IsFrom: DNS ENTRIES FOR FQDN " + fqdn + " : " + Arrays.toString(ips));
         }
             logger.info("IsFrom: DNS ENTRIES FOR FQDN " + fqdn + " : " + Arrays.toString(ips));
         }
-        for (String s : ips) {
-            if (s.equals(ip) || s.equals(System.getenv("DMAAP_DR_PROV_SERVICE_HOST"))) {
-                return (true);
+        for (String ipAddr : ips) {
+            if (ipAddr.equals(ip)) {
+                return true;
             }
         }
             }
         }
-        return (false);
+        return false;
+    }
+
+    synchronized boolean isReachable(String ip) {
+        try {
+            if (InetAddress.getByName(ip).isReachable(1000)) {
+                return true;
+            }
+        } catch (UnknownHostException e) {
+            logger.debug("IsFrom: UnknownHostEx: " + e.toString(), e);
+        } catch (IOException e) {
+            logger.debug("IsFrom: Failed to parse IP : " + ip + " : " + e.toString(), e);
+        }
+        return false;
     }
 
     /**
     }
 
     /**
index 032c6ce..3fa5dc2 100644 (file)
@@ -104,8 +104,7 @@ public class LogManager extends TimerTask {
 
         public Uploader() {
             dq = new DeliveryQueue(this,
 
         public Uploader() {
             dq = new DeliveryQueue(this,
-                new DestInfo("LogUpload", uploaddir, null, null, null, config.getMyName(), config.getMyAuth(), false,
-                    false, false, false));
+                new DestInfo("LogUpload", uploaddir, null, null, null, config.getMyName(), config.getMyAuth(), false, false, false, false, false));
             setDaemon(true);
             setName("Log Uploader");
             start();
             setDaemon(true);
             setName("Log Uploader");
             start();
index 5577e52..791eee1 100644 (file)
 package org.onap.dmaap.datarouter.node;
 
 import java.io.File;
 package org.onap.dmaap.datarouter.node;
 
 import java.io.File;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Vector;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Vector;
+import org.apache.log4j.Logger;
 
 /**
  * Processed configuration for this node.
 
 /**
  * Processed configuration for this node.
@@ -37,7 +39,7 @@ import java.util.Vector;
  * discarded.
  */
 public class NodeConfig {
  * discarded.
  */
 public class NodeConfig {
-
+    private static Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.node.NodeConfig");
     /**
      * Raw configuration entry for a data router node
      */
     /**
      * Raw configuration entry for a data router node
      */
@@ -104,6 +106,12 @@ public class NodeConfig {
         private String id;
         private String logdata;
         private String status;
         private String id;
         private String logdata;
         private String status;
+        private String createdDate;
+        /*
+         * AAF changes: TDP EPIC US# 307413
+         * Passing aafInstance from to identify legacy/AAF feeds
+         */
+        private String aafInstance;
 
         /**
          * Construct a feed configuration entry.
 
         /**
          * Construct a feed configuration entry.
@@ -113,10 +121,27 @@ public class NodeConfig {
          * @param status The reason why this feed cannot be used (Feed has been deleted, Feed has been suspended) or
          * null if it is valid.
          */
          * @param status The reason why this feed cannot be used (Feed has been deleted, Feed has been suspended) or
          * null if it is valid.
          */
-        public ProvFeed(String id, String logdata, String status) {
+        public ProvFeed(String id, String logdata, String status, String createdDate, String aafInstance) {
             this.id = id;
             this.logdata = logdata;
             this.status = status;
             this.id = id;
             this.logdata = logdata;
             this.status = status;
+            this.createdDate = createdDate;
+            this.aafInstance = aafInstance;
+        }
+
+        /**
+         * Get the created date of the data feed.
+         */
+        public String getCreatedDate()
+        {
+            return(createdDate);
+        }
+
+        /**
+         * Get the aafInstance of the data feed.
+         */
+        public String getAafInstance() {
+            return aafInstance;
         }
 
         /**
         }
 
         /**
@@ -232,6 +257,7 @@ public class NodeConfig {
         private boolean metaonly;
         private boolean use100;
         private boolean privilegedSubscriber;
         private boolean metaonly;
         private boolean use100;
         private boolean privilegedSubscriber;
+        private boolean followRedirect;
         private boolean decompress;
 
         /**
         private boolean decompress;
 
         /**
@@ -246,10 +272,10 @@ public class NodeConfig {
          * @param metaonly Is this a meta data only subscription?
          * @param use100 Should we send Expect: 100-continue?
          * @param privilegedSubscriber Can we wait to receive a delete file call before deleting file
          * @param metaonly Is this a meta data only subscription?
          * @param use100 Should we send Expect: 100-continue?
          * @param privilegedSubscriber Can we wait to receive a delete file call before deleting file
+         * @param followRedirect Is follow redirect of destination enabled?
          * @param decompress To see if they want their information compressed or decompressed
          */
          * @param decompress To see if they want their information compressed or decompressed
          */
-        public ProvSubscription(String subid, String feedid, String url, String authuser, String credentials,
-                boolean metaonly, boolean use100, boolean privilegedSubscriber, boolean decompress) {
+        public ProvSubscription(String subid, String feedid, String url, String authuser, String credentials, boolean metaonly, boolean use100, boolean privilegedSubscriber, boolean followRedirect, boolean decompress) {
             this.subid = subid;
             this.feedid = feedid;
             this.url = url;
             this.subid = subid;
             this.feedid = feedid;
             this.url = url;
@@ -258,6 +284,7 @@ public class NodeConfig {
             this.metaonly = metaonly;
             this.use100 = use100;
             this.privilegedSubscriber = privilegedSubscriber;
             this.metaonly = metaonly;
             this.use100 = use100;
             this.privilegedSubscriber = privilegedSubscriber;
+            this.followRedirect = followRedirect;
             this.decompress = decompress;
         }
 
             this.decompress = decompress;
         }
 
@@ -319,10 +346,18 @@ public class NodeConfig {
 
         /**
          * Should i decompress the file before sending it on
 
         /**
          * Should i decompress the file before sending it on
-         */
+        */
         public boolean isDecompress() {
             return (decompress);
         }
         public boolean isDecompress() {
             return (decompress);
         }
+
+        /**
+         *  New field is added - FOLLOW_REDIRECTS feature iTrack:DATARTR-17 - 1706
+         *     Get the followRedirect of this destination
+         */
+        boolean getFollowRedirect() {
+            return(followRedirect);
+        }
     }
 
     /**
     }
 
     /**
@@ -348,7 +383,12 @@ public class NodeConfig {
             this.feedid = feedid;
             this.subnet = subnet;
             this.user = user;
             this.feedid = feedid;
             this.subnet = subnet;
             this.user = user;
-            this.nodes = nodes;
+            //Sonar fix
+            if(nodes == null) {
+                this.nodes = new String[0];
+            } else {
+                this.nodes = Arrays.copyOf(nodes, nodes.length);
+            }
         }
 
         /**
         }
 
         /**
@@ -480,6 +520,8 @@ public class NodeConfig {
         Hashtable<String, String> authusers = new Hashtable<String, String>();
         Redirection[] redirections;
         Target[] targets;
         Hashtable<String, String> authusers = new Hashtable<String, String>();
         Redirection[] redirections;
         Target[] targets;
+        String createdDate;
+        String aafInstance;
     }
 
     private Hashtable<String, String> params = new Hashtable<>();
     }
 
     private Hashtable<String, String> params = new Hashtable<>();
@@ -510,24 +552,24 @@ public class NodeConfig {
         Vector<DestInfo> destInfos = new Vector<>();
         myauth = NodeUtils.getNodeAuthHdr(myname, nodeauthkey);
         for (ProvNode pn : pd.getNodes()) {
         Vector<DestInfo> destInfos = new Vector<>();
         myauth = NodeUtils.getNodeAuthHdr(myname, nodeauthkey);
         for (ProvNode pn : pd.getNodes()) {
-            String cn = pn.getCName();
-            if (nodeinfo.get(cn) != null) {
+            String cName = pn.getCName();
+            if (nodeinfo.get(cName) != null) {
                 continue;
             }
                 continue;
             }
-            String auth = NodeUtils.getNodeAuthHdr(cn, nodeauthkey);
-            DestInfo di = new DestInfo("n:" + cn, spooldir + "/n/" + cn, null, "n2n-" + cn,
-                    "https://" + cn + ":" + port + "/internal/publish", cn, myauth, false, true, false, false);
+            String auth = NodeUtils.getNodeAuthHdr(cName, nodeauthkey);
+            DestInfo di = new DestInfo("n:" + cName, spooldir + "/n/" + cName, null, "n2n-" + cName,
+                    "https://" + cName + ":" + port + "/internal/publish", cName, myauth, false, true, false, false, false);
             (new File(di.getSpool())).mkdirs();
             destInfos.add(di);
             (new File(di.getSpool())).mkdirs();
             destInfos.add(di);
-            nodeinfo.put(cn, di);
-            nodes.put(auth, new IsFrom(cn));
+            nodeinfo.put(cName, di);
+            nodes.put(auth, new IsFrom(cName));
         }
         }
-        PathFinder pf = new PathFinder(myname, nodeinfo.keySet().toArray(new String[nodeinfo.size()]), pd.getHops());
-        Hashtable<String, Vector<Redirection>> rdtab = new Hashtable<String, Vector<Redirection>>();
+        PathFinder pf = new PathFinder(myname, nodeinfo.keySet().toArray(new String[0]), pd.getHops());
+        Hashtable<String, Vector<Redirection>> rdtab = new Hashtable<>();
         for (ProvForceIngress pfi : pd.getForceIngress()) {
             Vector<Redirection> v = rdtab.get(pfi.getFeedId());
             if (v == null) {
         for (ProvForceIngress pfi : pd.getForceIngress()) {
             Vector<Redirection> v = rdtab.get(pfi.getFeedId());
             if (v == null) {
-                v = new Vector<Redirection>();
+                v = new Vector<>();
                 rdtab.put(pfi.getFeedId(), v);
             }
             Redirection r = new Redirection();
                 rdtab.put(pfi.getFeedId(), v);
             }
             Redirection r = new Redirection();
@@ -538,16 +580,16 @@ public class NodeConfig {
             r.nodes = pfi.getNodes();
             v.add(r);
         }
             r.nodes = pfi.getNodes();
             v.add(r);
         }
-        Hashtable<String, Hashtable<String, String>> pfutab = new Hashtable<String, Hashtable<String, String>>();
+        Hashtable<String, Hashtable<String, String>> pfutab = new Hashtable<>();
         for (ProvFeedUser pfu : pd.getFeedUsers()) {
             Hashtable<String, String> t = pfutab.get(pfu.getFeedId());
             if (t == null) {
         for (ProvFeedUser pfu : pd.getFeedUsers()) {
             Hashtable<String, String> t = pfutab.get(pfu.getFeedId());
             if (t == null) {
-                t = new Hashtable<String, String>();
+                t = new Hashtable<>();
                 pfutab.put(pfu.getFeedId(), t);
             }
             t.put(pfu.getCredentials(), pfu.getUser());
         }
                 pfutab.put(pfu.getFeedId(), t);
             }
             t.put(pfu.getCredentials(), pfu.getUser());
         }
-        Hashtable<String, String> egrtab = new Hashtable<String, String>();
+        Hashtable<String, String> egrtab = new Hashtable<>();
         for (ProvForceEgress pfe : pd.getForceEgress()) {
             if (pfe.getNode().equals(myname) || nodeinfo.get(pfe.getNode()) == null) {
                 continue;
         for (ProvForceEgress pfe : pd.getForceEgress()) {
             if (pfe.getNode().equals(myname) || nodeinfo.get(pfe.getNode()) == null) {
                 continue;
@@ -558,7 +600,7 @@ public class NodeConfig {
         for (ProvFeedSubnet pfs : pd.getFeedSubnets()) {
             Vector<SubnetMatcher> v = pfstab.get(pfs.getFeedId());
             if (v == null) {
         for (ProvFeedSubnet pfs : pd.getFeedSubnets()) {
             Vector<SubnetMatcher> v = pfstab.get(pfs.getFeedId());
             if (v == null) {
-                v = new Vector<SubnetMatcher>();
+                v = new Vector<>();
                 pfstab.put(pfs.getFeedId(), v);
             }
             v.add(new SubnetMatcher(pfs.getCidr()));
                 pfstab.put(pfs.getFeedId(), v);
             }
             v.add(new SubnetMatcher(pfs.getCidr()));
@@ -584,6 +626,7 @@ public class NodeConfig {
                 sididx = Integer.parseInt(subId);
                 sididx -= sididx % 100;
             } catch (Exception e) {
                 sididx = Integer.parseInt(subId);
                 sididx -= sididx % 100;
             } catch (Exception e) {
+                logger.error("NODE0517 Exception NodeConfig: "+e);
             }
             String subscriptionDirectory = sididx + "/" + subId;
             DestInfo destinationInfo = new DestInfo("s:" + subId,
             }
             String subscriptionDirectory = sididx + "/" + subId;
             DestInfo destinationInfo = new DestInfo("s:" + subId,
@@ -603,7 +646,7 @@ public class NodeConfig {
             }
             sb.append(' ').append(subId);
         }
             }
             sb.append(' ').append(subId);
         }
-        alldests = destInfos.toArray(new DestInfo[destInfos.size()]);
+        alldests = destInfos.toArray(new DestInfo[0]);
         for (ProvFeed pfx : pd.getFeeds()) {
             String fid = pfx.getId();
             Feed f = feeds.get(fid);
         for (ProvFeed pfx : pd.getFeeds()) {
             String fid = pfx.getId();
             Feed f = feeds.get(fid);
@@ -612,13 +655,19 @@ public class NodeConfig {
             }
             f = new Feed();
             feeds.put(fid, f);
             }
             f = new Feed();
             feeds.put(fid, f);
+            f.createdDate = pfx.getCreatedDate();
             f.loginfo = pfx.getLogData();
             f.status = pfx.getStatus();
             f.loginfo = pfx.getLogData();
             f.status = pfx.getStatus();
+            /*
+             * AAF changes: TDP EPIC US# 307413
+             * Passing aafInstance from ProvFeed to identify legacy/AAF feeds
+             */
+            f.aafInstance = pfx.getAafInstance();
             Vector<SubnetMatcher> v1 = pfstab.get(fid);
             if (v1 == null) {
                 f.subnets = new SubnetMatcher[0];
             } else {
             Vector<SubnetMatcher> v1 = pfstab.get(fid);
             if (v1 == null) {
                 f.subnets = new SubnetMatcher[0];
             } else {
-                f.subnets = v1.toArray(new SubnetMatcher[v1.size()]);
+                f.subnets = v1.toArray(new SubnetMatcher[0]);
             }
             Hashtable<String, String> h1 = pfutab.get(fid);
             if (h1 == null) {
             }
             Hashtable<String, String> h1 = pfutab.get(fid);
             if (h1 == null) {
@@ -629,7 +678,7 @@ public class NodeConfig {
             if (v2 == null) {
                 f.redirections = new Redirection[0];
             } else {
             if (v2 == null) {
                 f.redirections = new Redirection[0];
             } else {
-                f.redirections = v2.toArray(new Redirection[v2.size()]);
+                f.redirections = v2.toArray(new Redirection[0]);
             }
             StringBuffer sb = feedTargets.get(fid);
             if (sb == null) {
             }
             StringBuffer sb = feedTargets.get(fid);
             if (sb == null) {
@@ -687,7 +736,7 @@ public class NodeConfig {
                 }
             }
         }
                 }
             }
         }
-        return (tv.toArray(new Target[tv.size()]));
+        return (tv.toArray(new Target[0]));
     }
 
     /**
     }
 
     /**
@@ -743,6 +792,32 @@ public class NodeConfig {
         return provSubscription.isPrivilegedSubscriber();
     }
 
         return provSubscription.isPrivilegedSubscriber();
     }
 
+    /**
+     * Check whether publication is allowed for AAF Feed.
+     * @param feedid The ID of the feed being requested.
+     * @param ip The requesting IP address
+     */
+    public String isPublishPermitted(String feedid, String ip) {
+        Feed f = feeds.get(feedid);
+        String nf = "Feed does not exist";
+        if (f != null) {
+            nf = f.status;
+        }
+        if (nf != null) {
+            return(nf);
+        }
+        if (f.subnets.length == 0) {
+            return(null);
+        }
+        byte[] addr = NodeUtils.getInetAddress(ip);
+        for (SubnetMatcher snm: f.subnets) {
+            if (snm.matches(addr)) {
+                return(null);
+            }
+        }
+        return("Publisher not permitted for this feed");
+    }
+
     /**
      * Get authenticated user
      */
     /**
      * Get authenticated user
      */
@@ -750,6 +825,16 @@ public class NodeConfig {
         return (feeds.get(feedid).authusers.get(credentials));
     }
 
         return (feeds.get(feedid).authusers.get(credentials));
     }
 
+    /**
+     * AAF changes: TDP EPIC US# 307413
+     * Check AAF_instance for feed ID
+     * @param feedid   The ID of the feed specified
+     */
+    public String getAafInstance(String feedid) {
+        Feed f = feeds.get(feedid);
+        return f.aafInstance;
+    }
+
     /**
      * Check if the request should be redirected to a different ingress node
      */
     /**
      * Check if the request should be redirected to a different ingress node
      */
@@ -810,6 +895,16 @@ public class NodeConfig {
         return (f.targets);
     }
 
         return (f.targets);
     }
 
+    /**
+     * Get the creation date for a feed
+     * @param feedid The feed ID
+     * @return the timestamp of creation date of feed id passed
+     */
+    public String getCreatedDate(String feedid) {
+        Feed f = feeds.get(feedid);
+        return(f.createdDate);
+    }
+
     /**
      * Get the feed ID for a subscription
      *
     /**
      * Get the feed ID for a subscription
      *
index d98c47a..8011c63 100644 (file)
@@ -26,6 +26,10 @@ package org.onap.dmaap.datarouter.node;
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
+import org.apache.log4j.Logger;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.dmaap.datarouter.node.eelf.EelfMsgs;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
@@ -33,8 +37,6 @@ import java.io.Reader;
 import java.net.URL;
 import java.util.Properties;
 import java.util.Timer;
 import java.net.URL;
 import java.util.Properties;
 import java.util.Timer;
-import org.apache.log4j.Logger;
-import org.onap.dmaap.datarouter.node.eelf.EelfMsgs;
 
 
 /**
 
 
 /**
@@ -95,32 +97,54 @@ public class NodeConfigManager implements DeliveryQueueHelper {
     private String eventlogsuffix;
     private String eventloginterval;
     private boolean followredirects;
     private String eventlogsuffix;
     private String eventloginterval;
     private boolean followredirects;
+    private String [] enabledprotocols;
+    private String aafType;
+    private String aafInstance;
+    private String aafAction;
+    private String aafURL;
+    private boolean cadiEnabled;
 
 
     /**
      * Get the default node configuration manager
      */
     public static NodeConfigManager getInstance() {
 
 
     /**
      * Get the default node configuration manager
      */
     public static NodeConfigManager getInstance() {
-        return (base);
+        return base;
     }
 
     /**
      * Initialize the configuration of a Data Router node
      */
     private NodeConfigManager() {
     }
 
     /**
      * Initialize the configuration of a Data Router node
      */
     private NodeConfigManager() {
-        Properties p = new Properties();
+
+        Properties drNodeProperties = new Properties();
         try {
         try {
-            p.load(new FileInputStream(System
+            logger.info("NODE0301 Loading local config file node.properties");
+            drNodeProperties.load(new FileInputStream(System
                     .getProperty("org.onap.dmaap.datarouter.node.properties", "/opt/app/datartr/etc/node.properties")));
         } catch (Exception e) {
                     .getProperty("org.onap.dmaap.datarouter.node.properties", "/opt/app/datartr/etc/node.properties")));
         } catch (Exception e) {
-
             NodeUtils.setIpAndFqdnForEelf("NodeConfigManager");
             eelflogger.error(EelfMsgs.MESSAGE_PROPERTIES_LOAD_ERROR);
             logger.error("NODE0301 Unable to load local configuration file " + System
             NodeUtils.setIpAndFqdnForEelf("NodeConfigManager");
             eelflogger.error(EelfMsgs.MESSAGE_PROPERTIES_LOAD_ERROR);
             logger.error("NODE0301 Unable to load local configuration file " + System
-                            .getProperty("org.onap.dmaap.datarouter.node.properties", "/opt/app/datartr/etc/node.properties"),
-                    e);
+                            .getProperty("org.onap.dmaap.datarouter.node.properties", "/opt/app/datartr/etc/node.properties"), e);
         }
         }
-        provurl = p.getProperty("ProvisioningURL", "https://feeds-drtr.web.att.com/internal/prov");
+        provurl = drNodeProperties.getProperty("ProvisioningURL", "https://dmaap-dr-prov:8443/internal/prov");
+        /*
+         * START - AAF changes: TDP EPIC US# 307413
+         * Pull AAF settings from node.properties
+         */
+        aafType = drNodeProperties.getProperty("AAFType", "org.onap.dmaap-dr.feed");
+        aafInstance = drNodeProperties.getProperty("AAFInstance", "legacy");
+        aafAction = drNodeProperties.getProperty("AAFAction", "publish");
+        aafURL = drNodeProperties.getProperty("AafUrl", "https://aaf-onap-test.osaaf.org:8095");
+        cadiEnabled = Boolean.parseBoolean(drNodeProperties.getProperty("CadiEnabled", "false"));
+        /*
+         * END - AAF changes: TDP EPIC US# 307413
+         * Pull AAF settings from node.properties
+         */
+        //Disable and enable protocols*/
+        enabledprotocols = ((drNodeProperties.getProperty("NodeHttpsProtocols")).trim()).split("\\|");
+
         try {
             provhost = (new URL(provurl)).getHost();
         } catch (Exception e) {
         try {
             provhost = (new URL(provurl)).getHost();
         } catch (Exception e) {
@@ -130,14 +154,14 @@ public class NodeConfigManager implements DeliveryQueueHelper {
             System.exit(1);
         }
         logger.info("NODE0303 Provisioning server is " + provhost);
             System.exit(1);
         }
         logger.info("NODE0303 Provisioning server is " + provhost);
-        eventlogurl = p.getProperty("LogUploadURL", "https://feeds-drtr.web.att.com/internal/logs");
+        eventlogurl = drNodeProperties.getProperty("LogUploadURL", "https://feeds-drtr.web.att.com/internal/logs");
         provcheck = new IsFrom(provhost);
         provcheck = new IsFrom(provhost);
-        gfport = Integer.parseInt(p.getProperty("IntHttpPort", "8080"));
-        svcport = Integer.parseInt(p.getProperty("IntHttpsPort", "8443"));
-        port = Integer.parseInt(p.getProperty("ExtHttpsPort", "443"));
-        long minpfinterval = Long.parseLong(p.getProperty("MinProvFetchInterval", "10000"));
-        long minrsinterval = Long.parseLong(p.getProperty("MinRedirSaveInterval", "10000"));
-        spooldir = p.getProperty("SpoolDir", "spool");
+        gfport = Integer.parseInt(drNodeProperties.getProperty("IntHttpPort", "8080"));
+        svcport = Integer.parseInt(drNodeProperties.getProperty("IntHttpsPort", "8443"));
+        port = Integer.parseInt(drNodeProperties.getProperty("ExtHttpsPort", "443"));
+        long minpfinterval = Long.parseLong(drNodeProperties.getProperty("MinProvFetchInterval", "10000"));
+        long minrsinterval = Long.parseLong(drNodeProperties.getProperty("MinRedirSaveInterval", "10000"));
+        spooldir = drNodeProperties.getProperty("SpoolDir", "spool");
         File fdir = new File(spooldir + "/f");
         fdir.mkdirs();
         for (File junk : fdir.listFiles()) {
         File fdir = new File(spooldir + "/f");
         fdir.mkdirs();
         for (File junk : fdir.listFiles()) {
@@ -145,26 +169,26 @@ public class NodeConfigManager implements DeliveryQueueHelper {
                 junk.delete();
             }
         }
                 junk.delete();
             }
         }
-        logdir = p.getProperty("LogDir", "logs");
+        logdir = drNodeProperties.getProperty("LogDir", "logs");
         (new File(logdir)).mkdirs();
         (new File(logdir)).mkdirs();
-        logretention = Long.parseLong(p.getProperty("LogRetention", "30")) * 86400000L;
+        logretention = Long.parseLong(drNodeProperties.getProperty("LogRetention", "30")) * 86400000L;
         eventlogprefix = logdir + "/events";
         eventlogsuffix = ".log";
         eventlogprefix = logdir + "/events";
         eventlogsuffix = ".log";
-        String redirfile = p.getProperty("RedirectionFile", "etc/redirections.dat");
-        kstype = p.getProperty("KeyStoreType", "jks");
-        ksfile = p.getProperty("KeyStoreFile", "etc/keystore");
-        kspass = p.getProperty("KeyStorePassword", "changeme");
-        kpass = p.getProperty("KeyPassword", "changeme");
-        tstype = p.getProperty("TrustStoreType", "jks");
-        tsfile = p.getProperty("TrustStoreFile");
-        tspass = p.getProperty("TrustStorePassword", "changeme");
+        String redirfile = drNodeProperties.getProperty("RedirectionFile", "etc/redirections.dat");
+        kstype = drNodeProperties.getProperty("KeyStoreType", "jks");
+        ksfile = drNodeProperties.getProperty("KeyStoreFile", "etc/keystore");
+        kspass = drNodeProperties.getProperty("KeyStorePassword", "changeme");
+        kpass = drNodeProperties.getProperty("KeyPassword", "changeme");
+        tstype = drNodeProperties.getProperty("TrustStoreType", "jks");
+        tsfile = drNodeProperties.getProperty("TrustStoreFile");
+        tspass = drNodeProperties.getProperty("TrustStorePassword", "changeme");
         if (tsfile != null && tsfile.length() > 0) {
             System.setProperty("javax.net.ssl.trustStoreType", tstype);
             System.setProperty("javax.net.ssl.trustStore", tsfile);
             System.setProperty("javax.net.ssl.trustStorePassword", tspass);
         }
         if (tsfile != null && tsfile.length() > 0) {
             System.setProperty("javax.net.ssl.trustStoreType", tstype);
             System.setProperty("javax.net.ssl.trustStore", tsfile);
             System.setProperty("javax.net.ssl.trustStorePassword", tspass);
         }
-        nak = p.getProperty("NodeAuthKey", "Node123!");
-        quiesce = new File(p.getProperty("QuiesceFile", "etc/SHUTDOWN"));
+        nak = drNodeProperties.getProperty("NodeAuthKey", "Node123!");
+        quiesce = new File(drNodeProperties.getProperty("QuiesceFile", "etc/SHUTDOWN"));
         myname = NodeUtils.getCanonicalName(kstype, ksfile, kspass);
         if (myname == null) {
             NodeUtils.setIpAndFqdnForEelf("NodeConfigManager");
         myname = NodeUtils.getCanonicalName(kstype, ksfile, kspass);
         if (myname == null) {
             NodeUtils.setIpAndFqdnForEelf("NodeConfigManager");
@@ -253,7 +277,7 @@ public class NodeConfigManager implements DeliveryQueueHelper {
 
     private void fetchconfig() {
         try {
 
     private void fetchconfig() {
         try {
-            System.out.println("provurl:: " + provurl);
+            logger.info("NodeConfigMan.fetchConfig: provurl:: " + provurl);
             Reader r = new InputStreamReader((new URL(provurl)).openStream());
             config = new NodeConfig(new ProvData(r), myname, spooldir, port, nak);
             localconfig();
             Reader r = new InputStreamReader((new URL(provurl)).openStream());
             config = new NodeConfig(new ProvData(r), myname, spooldir, port, nak);
             localconfig();
@@ -263,6 +287,7 @@ public class NodeConfigManager implements DeliveryQueueHelper {
                 try {
                     rr.run();
                 } catch (Exception e) {
                 try {
                     rr.run();
                 } catch (Exception e) {
+                    logger.error("NODE0518 Exception fetchconfig: " + e);
                 }
             }
         } catch (Exception e) {
                 }
             }
         } catch (Exception e) {
@@ -278,12 +303,12 @@ public class NodeConfigManager implements DeliveryQueueHelper {
      * fetch the provisioning data, ignore the request.  If the data has been fetched very recently (default 10
      * seconds), wait a while before fetching again.
      */
      * fetch the provisioning data, ignore the request.  If the data has been fetched very recently (default 10
      * seconds), wait a while before fetching again.
      */
-    public synchronized void gofetch(String remoteaddr) {
-        if (provcheck.isFrom(remoteaddr)) {
-            logger.info("NODE0307 Received configuration fetch request from provisioning server " + remoteaddr);
+    public synchronized void gofetch(String remoteAddr) {
+        if (provcheck.isReachable(remoteAddr)) {
+            logger.info("NODE0307 Received configuration fetch request from provisioning server " + remoteAddr);
             pfetcher.request();
         } else {
             pfetcher.request();
         } else {
-            logger.info("NODE0308 Received configuration fetch request from unexpected server " + remoteaddr);
+            logger.info("NODE0308 Received configuration fetch request from unexpected server " + remoteAddr);
         }
     }
 
         }
     }
 
@@ -344,6 +369,17 @@ public class NodeConfigManager implements DeliveryQueueHelper {
         return (config.isDeletePermitted(subId));
     }
 
         return (config.isDeletePermitted(subId));
     }
 
+    /**
+     * Check whether publication is allowed for AAF Feed.
+     *
+     * @param feedid The ID of the feed being requested
+     * @param ip The requesting IP address
+     * @return True if the IP and credentials are valid for the specified feed.
+     */
+    public String isPublishPermitted(String feedid, String ip) {
+        return(config.isPublishPermitted(feedid, ip));
+    }
+        
     /**
      * Check who the user is given the feed ID and the offered credentials.
      *
     /**
      * Check who the user is given the feed ID and the offered credentials.
      *
@@ -355,6 +391,15 @@ public class NodeConfigManager implements DeliveryQueueHelper {
         return (config.getAuthUser(feedid, credentials));
     }
 
         return (config.getAuthUser(feedid, credentials));
     }
 
+    /**
+     * AAF changes: TDP EPIC US# 307413
+     * Check AAF_instance for feed ID in NodeConfig
+     * @param feedid The ID of the feed specified
+     */
+    public String getAafInstance(String feedid) {
+        return(config.getAafInstance(feedid));
+    }
+
     /**
      * Check if the publish request should be sent to another node based on the feedid, user, and source IP address.
      *
     /**
      * Check if the publish request should be sent to another node based on the feedid, user, and source IP address.
      *
@@ -460,6 +505,23 @@ public class NodeConfigManager implements DeliveryQueueHelper {
         return (false);
     }
 
         return (false);
     }
 
+    /**
+     * Set up redirection on receipt of a 3XX from a target URL
+     */
+    public boolean handleRedirectionSubLevel(DeliveryTask task, DestInfo destinfo, String redirto, String fileid) {
+        fileid = "/" + fileid;
+        String subid = destinfo.getSubId();
+        String purl = destinfo.getURL();
+        if (task.getFollowRedirects() && subid != null && redirto.endsWith(fileid)) {
+            redirto = redirto.substring(0, redirto.length() - fileid.length());
+            if (!redirto.equals(purl)) {
+                rdmgr.redirect(subid, purl, redirto);
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Handle unreachable target URL
      */
     /**
      * Handle unreachable target URL
      */
@@ -529,6 +591,15 @@ public class NodeConfigManager implements DeliveryQueueHelper {
         return (config.getTargets(feedid));
     }
 
         return (config.getTargets(feedid));
     }
 
+    /**
+     * Get the creation date for a feed
+     * @param feedid The feed ID
+     * @return the timestamp of creation date of feed id passed
+     */
+    public String getCreatedDate(String feedid) {
+        return(config.getCreatedDate(feedid));
+    }
+
     /**
      * Get the spool directory for temporary files
      */
     /**
      * Get the spool directory for temporary files
      */
@@ -697,6 +768,16 @@ public class NodeConfigManager implements DeliveryQueueHelper {
         return (fdpstop);
     }
 
         return (fdpstop);
     }
 
+    /**
+     * Disable and enable protocols
+     * */
+    public String[] getEnabledprotocols() {
+        return enabledprotocols;
+    }
+    public void setEnabledprotocols(String[] enabledprotocols) {
+        this.enabledprotocols = enabledprotocols.clone();
+    }
+
     /**
      * Get the spool directory for a subscription
      */
     /**
      * Get the spool directory for a subscription
      */
@@ -716,4 +797,59 @@ public class NodeConfigManager implements DeliveryQueueHelper {
             return (null);
         }
     }
             return (null);
         }
     }
+
+    public String getAafType() {
+        return aafType;
+    }
+    public void setAafType(String aafType) {
+        this.aafType = aafType;
+    }
+    public String getAafInstance() {
+        return aafInstance;
+    }
+    public void setAafInstance(String aafInstance) {
+        this.aafInstance = aafInstance;
+    }
+    public String getAafAction() {
+        return aafAction;
+    }
+    public void setAafAction(String aafAction) {
+        this.aafAction = aafAction;
+    }
+    /*
+     * Get aafURL from SWM variable
+     * */
+    public String getAafURL() {
+        return aafURL;
+    }
+    public void setAafURL(String aafURL) {
+        this.aafURL = aafURL;
+    }
+
+    public boolean getCadiEnabeld() {
+        return cadiEnabled;
+    }
+    public void setCadiEnabled(boolean cadiEnabled) {
+        this.cadiEnabled = cadiEnabled;
+    }
+
+    /**
+     * Builds the permissions string to be verified
+     *
+     * @param aafInstance The aaf instance
+     * @return The permissions
+     */
+    protected String getPermission(String aafInstance) {
+        try {
+            String type = getAafType();
+            String action = getAafAction();
+            if (aafInstance == null || aafInstance.equals("")) {
+                aafInstance = getAafInstance();
+            }
+            return type + "|" + aafInstance + "|" + action;
+        } catch (Exception e) {
+            logger.error("NODE0543 NodeConfigManager.getPermission: ", e);
+        }
+        return null;
+    }
 }
 }
index d25531a..7ff33ff 100644 (file)
 
 package org.onap.dmaap.datarouter.node;
 
 
 package org.onap.dmaap.datarouter.node;
 
-import java.util.Arrays;
 import org.apache.log4j.Logger;
 import org.eclipse.jetty.http.HttpVersion;
 import org.apache.log4j.Logger;
 import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.SecureRequestCustomizer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.*;
+import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.onap.aaf.cadi.PropAccess;
+
+import javax.servlet.DispatcherType;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.EnumSet;
+import java.util.Properties;
 
 /**
  * The main starting point for the Data Router node
 
 /**
  * The main starting point for the Data Router node
@@ -47,6 +48,18 @@ public class NodeMain {
 
     private static Logger nodeMainLogger = Logger.getLogger("org.onap.dmaap.datarouter.node.NodeMain");
 
 
     private static Logger nodeMainLogger = Logger.getLogger("org.onap.dmaap.datarouter.node.NodeMain");
 
+    class Inner {
+        InputStream getCadiProps() {
+            InputStream in = null;
+            try {
+                in = getClass().getClassLoader().getResourceAsStream("drNodeCadi.properties");
+            } catch (Exception e) {
+                nodeMainLogger.error("Exception in Inner.getCadiProps() method " + e.getMessage());
+            }
+            return in;
+        }
+    }
+
     private static class WaitForConfig implements Runnable {
 
         private NodeConfigManager localNodeConfigManager;
     private static class WaitForConfig implements Runnable {
 
         private NodeConfigManager localNodeConfigManager;
@@ -67,8 +80,8 @@ public class NodeMain {
                     wait();
                 } catch (Exception exception) {
                     nodeMainLogger
                     wait();
                 } catch (Exception exception) {
                     nodeMainLogger
-                        .debug("NodeMain: waitForConfig exception. Exception Message:- " + exception.toString(),
-                            exception);
+                            .debug("NodeMain: waitForConfig exception. Exception Message:- " + exception.toString(),
+                                    exception);
                 }
             }
             localNodeConfigManager.deregisterConfigTask(this);
                 }
             }
             localNodeConfigManager.deregisterConfigTask(this);
@@ -89,8 +102,8 @@ public class NodeMain {
     /**
      * Start the data router.
      * <p>
     /**
      * Start the data router.
      * <p>
-     * The location of the node configuration file can be set using the org.onap.dmaap.datarouter.node.ConfigFile system
-     * property.  By default, it is "etc/node.properties".
+     * The location of the node configuration file can be set using the org.onap.dmaap.datarouter.node.properties system
+     * property.  By default, it is "/opt/app/datartr/etc/node.properties".
      */
     public static void main(String[] args) throws Exception {
         nodeMainLogger.info("NODE0001 Data Router Node Starting");
      */
     public static void main(String[] args) throws Exception {
         nodeMainLogger.info("NODE0001 Data Router Node Starting");
@@ -100,15 +113,15 @@ public class NodeMain {
         (new WaitForConfig(nodeConfigManager)).waitForConfig();
         delivery = new Delivery(nodeConfigManager);
         new LogManager(nodeConfigManager);
         (new WaitForConfig(nodeConfigManager)).waitForConfig();
         delivery = new Delivery(nodeConfigManager);
         new LogManager(nodeConfigManager);
+
         Server server = new Server();
         Server server = new Server();
+
         // HTTP configuration
         HttpConfiguration httpConfiguration = new HttpConfiguration();
         httpConfiguration.setRequestHeaderSize(2048);
 
         // HTTP connector
         // HTTP configuration
         HttpConfiguration httpConfiguration = new HttpConfiguration();
         httpConfiguration.setRequestHeaderSize(2048);
 
         // HTTP connector
-        ServletContextHandler ctxt;
-        try (ServerConnector httpServerConnector = new ServerConnector(server,
-            new HttpConnectionFactory(httpConfiguration))) {
+        try (ServerConnector httpServerConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration))) {
             httpServerConnector.setPort(nodeConfigManager.getHttpPort());
             httpServerConnector.setIdleTimeout(2000);
 
             httpServerConnector.setPort(nodeConfigManager.getHttpPort());
             httpServerConnector.setIdleTimeout(2000);
 
@@ -118,10 +131,23 @@ public class NodeMain {
             sslContextFactory.setKeyStorePath(nodeConfigManager.getKSFile());
             sslContextFactory.setKeyStorePassword(nodeConfigManager.getKSPass());
             sslContextFactory.setKeyManagerPassword(nodeConfigManager.getKPass());
             sslContextFactory.setKeyStorePath(nodeConfigManager.getKSFile());
             sslContextFactory.setKeyStorePassword(nodeConfigManager.getKSPass());
             sslContextFactory.setKeyManagerPassword(nodeConfigManager.getKPass());
-            /* Skip SSLv3 Fixes */
+
+            //SP-6 : Fixes for SDV scan to exclude/remove DES/3DES ciphers are taken care by upgrading jdk in descriptor.xml
+            sslContextFactory.setExcludeCipherSuites(
+                    "SSL_RSA_WITH_DES_CBC_SHA",
+                    "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+                    "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+                    "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+                    "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
+            );
+
             sslContextFactory.addExcludeProtocols("SSLv3");
             sslContextFactory.addExcludeProtocols("SSLv3");
-            nodeMainLogger.info("Excluded protocols node-" + Arrays.toString(sslContextFactory.getExcludeProtocols()));
-            /* End of SSLv3 Fixes */
+            sslContextFactory.setIncludeProtocols(nodeConfigManager.getEnabledprotocols());
+            nodeMainLogger.info("NODE00004 Unsupported protocols node server:-" + String.join(",", sslContextFactory.getExcludeProtocols()));
+            nodeMainLogger.info("NODE00004 Supported protocols node server:-" + String.join(",", sslContextFactory.getIncludeProtocols()));
+            nodeMainLogger.info("NODE00004 Unsupported ciphers node server:-" + String.join(",", sslContextFactory.getExcludeCipherSuites()));
 
             HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
             httpsConfiguration.setRequestHeaderSize(8192);
 
             HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
             httpsConfiguration.setRequestHeaderSize(8192);
@@ -133,21 +159,47 @@ public class NodeMain {
 
             // HTTPS connector
             try (ServerConnector httpsServerConnector = new ServerConnector(server,
 
             // HTTPS connector
             try (ServerConnector httpsServerConnector = new ServerConnector(server,
-                new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
-                new HttpConnectionFactory(httpsConfiguration))) {
+                    new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
+                    new HttpConnectionFactory(httpsConfiguration))) {
+
                 httpsServerConnector.setPort(nodeConfigManager.getHttpsPort());
                 httpsServerConnector.setPort(nodeConfigManager.getHttpsPort());
-                httpsServerConnector.setIdleTimeout(500000);
+                httpsServerConnector.setIdleTimeout(3600000);
                 httpsServerConnector.setAcceptQueueSize(2);
 
                 httpsServerConnector.setAcceptQueueSize(2);
 
+                //Context Handler
+                ServletContextHandler servletContextHandler = new ServletContextHandler(0);
+                servletContextHandler.setContextPath("/");
+                servletContextHandler.addServlet(new ServletHolder(new NodeServlet(delivery)), "/*");
+
+                //CADI Filter activation check
+                if (nodeConfigManager.getCadiEnabeld()) {
+                    Properties cadiProperties = new Properties();
+                    try {
+                        Inner obj = new NodeMain().new Inner();
+                        InputStream in = obj.getCadiProps();
+                        cadiProperties.load(in);
+                    } catch (IOException e1) {
+                        nodeMainLogger.error("NODE00005 Exception in NodeMain.Main() loading CADI properties " + e1.getMessage());
+                    }
+                    cadiProperties.setProperty("aaf_locate_url", nodeConfigManager.getAafURL());
+                    nodeMainLogger.info("NODE00005  aaf_url set to - " + cadiProperties.getProperty("aaf_url"));
+
+                    PropAccess access = new PropAccess(cadiProperties);
+                    servletContextHandler.addFilter(new FilterHolder(new DRNodeCadiFilter(true, access)), "/*", EnumSet.of(DispatcherType.REQUEST));
+                }
+
+                server.setHandler(servletContextHandler);
                 server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
             }
         }
                 server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
             }
         }
-        ctxt = new ServletContextHandler(0);
-        ctxt.setContextPath("/");
-        server.setHandler(ctxt);
-        ctxt.addServlet(new ServletHolder(new NodeServlet(delivery)), "/*");
-        nodeMainLogger.info("NODE0005 Data Router Node Activating Service");
-        server.start();
+
+        try {
+            server.start();
+            nodeMainLogger.info("NODE00006 Node Server started-" + server.getState());
+        } catch (Exception e) {
+            nodeMainLogger.info("NODE00006 Jetty failed to start. Reporting will we unavailable", e);
+        }
         server.join();
         server.join();
+        nodeMainLogger.info("NODE00007 Node Server joined - " + server.getState());
     }
 }
     }
 }
index 7988879..93e901f 100644 (file)
@@ -26,25 +26,24 @@ package org.onap.dmaap.datarouter.node;
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Writer;
+import org.apache.log4j.Logger;
+import org.onap.dmaap.datarouter.node.eelf.EelfMsgs;
+import org.slf4j.MDC;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Enumeration;
 import java.util.regex.Pattern;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Enumeration;
 import java.util.regex.Pattern;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.log4j.Logger;
+
+import static org.onap.dmaap.datarouter.node.NodeUtils.sendResponseError;
+
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Nullable;
-import org.onap.dmaap.datarouter.node.eelf.EelfMsgs;
-import org.slf4j.MDC;
 
 import static org.onap.dmaap.datarouter.node.NodeUtils.*;
 
 
 import static org.onap.dmaap.datarouter.node.NodeUtils.*;
 
@@ -64,9 +63,8 @@ public class NodeServlet extends HttpServlet {
     private static Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.node.NodeServlet");
     private static NodeConfigManager config;
     private static Pattern MetaDataPattern;
     private static Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.node.NodeServlet");
     private static NodeConfigManager config;
     private static Pattern MetaDataPattern;
-    //Adding EELF Logger Rally:US664892
-    private static EELFLogger eelflogger = EELFManager.getInstance()
-            .getLogger(NodeServlet.class);
+    private static EELFLogger eelflogger = EELFManager.getInstance().getLogger(NodeServlet.class);
+    private boolean isAAFFeed = false;
     private final Delivery delivery;
 
     static {
     private final Delivery delivery;
 
     static {
@@ -88,6 +86,7 @@ public class NodeServlet extends HttpServlet {
     /**
      * Get the NodeConfigurationManager
      */
     /**
      * Get the NodeConfigurationManager
      */
+    @Override
     public void init() {
         config = NodeConfigManager.getInstance();
         logger.info("NODE0101 Node Servlet Configured");
     public void init() {
         config = NodeConfigManager.getInstance();
         logger.info("NODE0101 Node Servlet Configured");
@@ -97,14 +96,15 @@ public class NodeServlet extends HttpServlet {
         if (config.isShutdown() || !config.isConfigured()) {
             sendResponseError(resp, HttpServletResponse.SC_SERVICE_UNAVAILABLE, logger);
             logger.info("NODE0102 Rejecting request: Service is being quiesced");
         if (config.isShutdown() || !config.isConfigured()) {
             sendResponseError(resp, HttpServletResponse.SC_SERVICE_UNAVAILABLE, logger);
             logger.info("NODE0102 Rejecting request: Service is being quiesced");
-            return (true);
+            return true;
         }
         }
-        return (false);
+        return false;
     }
 
     /**
      * Handle a GET for /internal/fetchProv
      */
     }
 
     /**
      * Handle a GET for /internal/fetchProv
      */
+    @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
         NodeUtils.setIpAndFqdnForEelf("doGet");
         NodeUtils.setRequestIdAndInvocationId(req);
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
         NodeUtils.setIpAndFqdnForEelf("doGet");
         NodeUtils.setRequestIdAndInvocationId(req);
@@ -149,12 +149,13 @@ public class NodeServlet extends HttpServlet {
     /**
      * Handle all PUT requests
      */
     /**
      * Handle all PUT requests
      */
+    @Override
     protected void doPut(HttpServletRequest req, HttpServletResponse resp) {
         NodeUtils.setIpAndFqdnForEelf("doPut");
         NodeUtils.setRequestIdAndInvocationId(req);
         eelflogger.info(EelfMsgs.ENTRY);
         eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader("X-DMAAP-DR-ON-BEHALF-OF"),
     protected void doPut(HttpServletRequest req, HttpServletResponse resp) {
         NodeUtils.setIpAndFqdnForEelf("doPut");
         NodeUtils.setRequestIdAndInvocationId(req);
         eelflogger.info(EelfMsgs.ENTRY);
         eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader("X-DMAAP-DR-ON-BEHALF-OF"),
-                    getIdFromPath(req) + "");
+                getIdFromPath(req) + "");
         try {
             common(req, resp, true);
         } catch (IOException ioe) {
         try {
             common(req, resp, true);
         } catch (IOException ioe) {
@@ -166,6 +167,7 @@ public class NodeServlet extends HttpServlet {
     /**
      * Handle all DELETE requests
      */
     /**
      * Handle all DELETE requests
      */
+    @Override
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) {
         NodeUtils.setIpAndFqdnForEelf("doDelete");
         NodeUtils.setRequestIdAndInvocationId(req);
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) {
         NodeUtils.setIpAndFqdnForEelf("doDelete");
         NodeUtils.setRequestIdAndInvocationId(req);
@@ -215,6 +217,27 @@ public class NodeServlet extends HttpServlet {
                 return;
             }
             feedid = fileid.substring(0, i);
                 return;
             }
             feedid = fileid.substring(0, i);
+
+            if (config.getCadiEnabeld()) {
+                String path = req.getPathInfo();
+                if (!path.startsWith("/internal") && feedid != null) {
+                    String aafInstance = config.getAafInstance(feedid);
+                    if (!(aafInstance.equalsIgnoreCase("legacy"))) {
+                        isAAFFeed = true;
+                        String permission = config.getPermission(aafInstance);
+                        logger.info("NodeServlet.common() permission string - " + permission);
+                        //Check in CADI Framework API if user has AAF permission or not
+                        if (!req.isUserInRole(permission)) {
+                            String message = "AAF disallows access to permission string - " + permission;
+                            logger.info("NODE0106 Rejecting unauthenticated PUT or DELETE of " + req.getPathInfo() + " from " + req.getRemoteAddr());
+                            resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+                            eelflogger.info(EelfMsgs.EXIT);
+                            return;
+                        }
+                    }
+                }
+            }
+
             fileid = fileid.substring(i + 1);
             pubid = config.getPublishId();
             xpubid = req.getHeader("X-DMAAP-DR-PUBLISH-ID");
             fileid = fileid.substring(i + 1);
             pubid = config.getPublishId();
             xpubid = req.getHeader("X-DMAAP-DR-PUBLISH-ID");
@@ -228,6 +251,7 @@ public class NodeServlet extends HttpServlet {
             }
             fileid = fileid.substring(18);
             pubid = req.getHeader("X-DMAAP-DR-PUBLISH-ID");
             }
             fileid = fileid.substring(18);
             pubid = req.getHeader("X-DMAAP-DR-PUBLISH-ID");
+            user = "datartr";   // SP6 : Added usr as datartr to avoid null entries for internal routing
             targets = config.parseRouting(req.getHeader("X-DMAAP-DR-ROUTING"));
         } else {
             logger.info("NODE0105 Rejecting bad URI for PUT or DELETE of " + req.getPathInfo() + " from " + req
             targets = config.parseRouting(req.getHeader("X-DMAAP-DR-ROUTING"));
         } else {
             logger.info("NODE0105 Rejecting bad URI for PUT or DELETE of " + req.getPathInfo() + " from " + req
@@ -257,17 +281,34 @@ public class NodeServlet extends HttpServlet {
         String logurl = "https://" + hp + "/internal/publish/" + fileid;
         if (feedid != null) {
             logurl = "https://" + hp + "/publish/" + feedid + "/" + fileid;
         String logurl = "https://" + hp + "/internal/publish/" + fileid;
         if (feedid != null) {
             logurl = "https://" + hp + "/publish/" + feedid + "/" + fileid;
-            String reason = config.isPublishPermitted(feedid, credentials, ip);
-            if (reason != null) {
-                logger.info(
-                        "NODE0111 Rejecting unauthorized publish attempt to feed " + feedid + " fileid " + fileid
-                                + " from "
-                                + ip + " reason " + reason);
-                resp.sendError(HttpServletResponse.SC_FORBIDDEN, reason);
-                eelflogger.info(EelfMsgs.EXIT);
-                return;
+            //Cadi code starts
+            if (!isAAFFeed) {
+                String reason = config.isPublishPermitted(feedid, credentials, ip);
+                if (reason != null) {
+                    logger.info("NODE0111 Rejecting unauthorized publish attempt to feed " + PathUtil.cleanString(feedid) + " fileid " + PathUtil.cleanString(fileid) + " from " + PathUtil.cleanString(ip) + " reason " + PathUtil.cleanString(reason));
+                    resp.sendError(HttpServletResponse.SC_FORBIDDEN, reason);
+                    eelflogger.info(EelfMsgs.EXIT);
+                    return;
+                }
+                user = config.getAuthUser(feedid, credentials);
+            } else {
+                String reason = config.isPublishPermitted(feedid, ip);
+                if (reason != null) {
+                    logger.info("NODE0111 Rejecting unauthorized publish attempt to feed " + PathUtil.cleanString(feedid) + " fileid " + PathUtil.cleanString(fileid) + " from " + PathUtil.cleanString(ip) + " reason   Invalid AAF user- " + PathUtil.cleanString(reason));
+                    String message = "Invalid AAF user- " + PathUtil.cleanString(reason);
+                    logger.info("NODE0106 Rejecting unauthenticated PUT or DELETE of " + PathUtil.cleanString(req.getPathInfo()) + " from " + PathUtil.cleanString(req.getRemoteAddr()));
+                    resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+                    return;
+                }
+                if ((req.getUserPrincipal() != null) && (req.getUserPrincipal().getName() != null)) {
+                    String userName = req.getUserPrincipal().getName();
+                    String[] attid = userName.split("@");
+                    user = attid[0];
+                } else {
+                    user = "AAFUser";
+                }
             }
             }
-            user = config.getAuthUser(feedid, credentials);
+            //Cadi code Ends
             String newnode = config.getIngressNode(feedid, user, ip);
             if (newnode != null) {
                 String port = "";
             String newnode = config.getIngressNode(feedid, user, ip);
             if (newnode != null) {
                 String port = "";
@@ -276,17 +317,17 @@ public class NodeServlet extends HttpServlet {
                     port = ":" + iport;
                 }
                 String redirto = "https://" + newnode + port + "/publish/" + feedid + "/" + fileid;
                     port = ":" + iport;
                 }
                 String redirto = "https://" + newnode + port + "/publish/" + feedid + "/" + fileid;
-                logger.info(
-                        "NODE0108 Redirecting publish attempt for feed " + feedid + " user " + user + " ip " + ip
-                                + " to "
-                                + redirto);
-                resp.sendRedirect(redirto);
+                logger.info("NODE0108 Redirecting publish attempt for feed " + PathUtil.cleanString(feedid) + " user " + PathUtil.cleanString(user) + " ip " + PathUtil.cleanString(ip) + " to " + PathUtil.cleanString(redirto));  //Fortify scan fixes - log forging
+                resp.sendRedirect(PathUtil.cleanString(redirto));         //Fortify scan fixes-open redirect - 2 issues
                 eelflogger.info(EelfMsgs.EXIT);
                 return;
             }
             resp.setHeader("X-DMAAP-DR-PUBLISH-ID", pubid);
         }
                 eelflogger.info(EelfMsgs.EXIT);
                 return;
             }
             resp.setHeader("X-DMAAP-DR-PUBLISH-ID", pubid);
         }
-        String fbase = config.getSpoolDir() + "/" + pubid;
+        if (req.getPathInfo().startsWith("/internal/publish/")) {
+            feedid = req.getHeader("X-DMAAP-DR-FEED-ID");
+        }
+        String fbase = PathUtil.cleanString(config.getSpoolDir() + "/" + pubid);  //Fortify scan fixes-Path manipulation
         File data = new File(fbase);
         File meta = new File(fbase + ".M");
         OutputStream dos = null;
         File data = new File(fbase);
         File meta = new File(fbase + ".M");
         OutputStream dos = null;
@@ -323,17 +364,13 @@ public class NodeServlet extends HttpServlet {
                         }
                         if ("x-dmaap-dr-meta".equals(hnlc)) {
                             if (hv.length() > 4096) {
                         }
                         if ("x-dmaap-dr-meta".equals(hnlc)) {
                             if (hv.length() > 4096) {
-                                logger.info(
-                                        "NODE0109 Rejecting publish attempt with metadata too long for feed " + feedid
-                                                + " user " + user + " ip " + ip);
+                                logger.info("NODE0109 Rejecting publish attempt with metadata too long for feed " + PathUtil.cleanString(feedid) + " user " + PathUtil.cleanString(user) + " ip " + PathUtil.cleanString(ip));  //Fortify scan fixes - log forging
                                 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Metadata too long");
                                 eelflogger.info(EelfMsgs.EXIT);
                                 return;
                             }
                             if (!MetaDataPattern.matcher(hv.replaceAll("\\\\.", "X")).matches()) {
                                 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Metadata too long");
                                 eelflogger.info(EelfMsgs.EXIT);
                                 return;
                             }
                             if (!MetaDataPattern.matcher(hv.replaceAll("\\\\.", "X")).matches()) {
-                                logger.info(
-                                        "NODE0109 Rejecting publish attempt with malformed metadata for feed " + feedid
-                                                + " user " + user + " ip " + ip);
+                                logger.info("NODE0109 Rejecting publish attempt with malformed metadata for feed " + PathUtil.cleanString(feedid) + " user " + PathUtil.cleanString(user) + " ip " + PathUtil.cleanString(ip));  //Fortify scan fixes - log forging
                                 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Malformed metadata");
                                 eelflogger.info(EelfMsgs.EXIT);
                                 return;
                                 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Malformed metadata");
                                 eelflogger.info(EelfMsgs.EXIT);
                                 return;
@@ -343,10 +380,10 @@ public class NodeServlet extends HttpServlet {
                     }
                 }
             }
                     }
                 }
             }
-            if(!hasRequestIdHeader){
+            if (!hasRequestIdHeader) {
                 mx.append("X-ONAP-RequestID\t").append(MDC.get("RequestId")).append('\n');
             }
                 mx.append("X-ONAP-RequestID\t").append(MDC.get("RequestId")).append('\n');
             }
-            if(!hasInvocationIdHeader){
+            if (!hasInvocationIdHeader) {
                 mx.append("X-InvocationID\t").append(MDC.get("InvocationId")).append('\n');
             }
             mx.append("X-DMAAP-DR-RECEIVED\t").append(rcvd).append('\n');
                 mx.append("X-InvocationID\t").append(MDC.get("InvocationId")).append('\n');
             }
             mx.append("X-DMAAP-DR-RECEIVED\t").append(rcvd).append('\n');
@@ -368,9 +405,9 @@ public class NodeServlet extends HttpServlet {
                 try {
                     exlen = Long.parseLong(req.getHeader("Content-Length"));
                 } catch (Exception e) {
                 try {
                     exlen = Long.parseLong(req.getHeader("Content-Length"));
                 } catch (Exception e) {
+                    logger.error("NODE0529 Exception common: " + e);
                 }
                 }
-                StatusLog.logPubFail(pubid, feedid, logurl, req.getMethod(), ctype, exlen, data.length(), ip, user,
-                        ioe.getMessage());
+                StatusLog.logPubFail(pubid, feedid, logurl, req.getMethod(), ctype, exlen, data.length(), ip, user, ioe.getMessage());
                 eelflogger.info(EelfMsgs.EXIT);
                 throw ioe;
             }
                 eelflogger.info(EelfMsgs.EXIT);
                 throw ioe;
             }
@@ -381,7 +418,7 @@ public class NodeServlet extends HttpServlet {
                     // TODO: unknown destination
                     continue;
                 }
                     // TODO: unknown destination
                     continue;
                 }
-                String dbase = di.getSpool() + "/" + pubid;
+                String dbase = PathUtil.cleanString(di.getSpool() + "/" + pubid);  //Fortify scan fixes-Path Manipulation
                 Files.createLink(Paths.get(dbase), dpath);
                 mw = new FileWriter(meta);
                 mw.write(metadata);
                 Files.createLink(Paths.get(dbase), dpath);
                 mw = new FileWriter(meta);
                 mw.write(metadata);
@@ -393,13 +430,25 @@ public class NodeServlet extends HttpServlet {
 
             }
             resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
 
             }
             resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
-            resp.getOutputStream().close();
-            StatusLog.logPub(pubid, feedid, logurl, req.getMethod(), ctype, data.length(), ip, user,
-                    HttpServletResponse.SC_NO_CONTENT);
+            try {
+                resp.getOutputStream().close();
+            } catch (IOException ioe) {
+                long exlen = -1;
+                try {
+                    exlen = Long.parseLong(req.getHeader("Content-Length"));
+                } catch (Exception e) {
+                    logger.debug("NODE00000 Exception common: " + e);
+                }
+                StatusLog.logPubFail(pubid, feedid, logurl, req.getMethod(), ctype, exlen, data.length(), ip, user, ioe.getMessage());
+                //Fortify scan fixes - log forging
+                logger.info("NODE0110 IO Exception while closing IO stream " + PathUtil.cleanString(feedid) + " user " + PathUtil.cleanString(user) + " ip " + PathUtil.cleanString(ip) + " " + ioe.toString(), ioe);
+
+                throw ioe;
+            }
+
+            StatusLog.logPub(pubid, feedid, logurl, req.getMethod(), ctype, data.length(), ip, user, HttpServletResponse.SC_NO_CONTENT);
         } catch (IOException ioe) {
         } catch (IOException ioe) {
-            logger.info(
-                    "NODE0110 IO Exception receiving publish attempt for feed " + feedid + " user " + user + " ip " + ip
-                            + " " + ioe.toString(), ioe);
+            logger.info("NODE0110 IO Exception receiving publish attempt for feed " + feedid + " user " + user + " ip " + ip + " " + ioe.toString(), ioe);
             eelflogger.info(EelfMsgs.EXIT);
             throw ioe;
         } finally {
             eelflogger.info(EelfMsgs.EXIT);
             throw ioe;
         } finally {
@@ -407,27 +456,32 @@ public class NodeServlet extends HttpServlet {
                 try {
                     is.close();
                 } catch (Exception e) {
                 try {
                     is.close();
                 } catch (Exception e) {
+                    logger.error("NODE0530 Exception common: " + e);
                 }
             }
             if (dos != null) {
                 try {
                     dos.close();
                 } catch (Exception e) {
                 }
             }
             if (dos != null) {
                 try {
                     dos.close();
                 } catch (Exception e) {
+                    logger.error("NODE0531 Exception common: " + e);
                 }
             }
             if (mw != null) {
                 try {
                     mw.close();
                 } catch (Exception e) {
                 }
             }
             if (mw != null) {
                 try {
                     mw.close();
                 } catch (Exception e) {
+                    logger.error("NODE0532 Exception common: " + e);
                 }
             }
             try {
                 data.delete();
             } catch (Exception e) {
                 }
             }
             try {
                 data.delete();
             } catch (Exception e) {
+                logger.error("NODE0533 Exception common: " + e);
             }
             try {
                 meta.delete();
             } catch (Exception e) {
             }
             try {
                 meta.delete();
             } catch (Exception e) {
+                logger.error("NODE0534 Exception common: " + e);
             }
         }
     }
             }
         }
     }
@@ -448,7 +502,7 @@ public class NodeServlet extends HttpServlet {
             int subId = Integer.parseInt(subscriptionId);
             pubid = fileid.substring(i + 1);
             String errorMessage = "Unable to delete files (" + pubid + ", " + pubid + ".M) from DR Node: "
             int subId = Integer.parseInt(subscriptionId);
             pubid = fileid.substring(i + 1);
             String errorMessage = "Unable to delete files (" + pubid + ", " + pubid + ".M) from DR Node: "
-                            + config.getMyName() + ".";
+                    + config.getMyName() + ".";
             int subIdDir = subId - (subId % 100);
             if (!isAuthorizedToDelete(resp, subscriptionId, errorMessage)) {
                 return;
             int subIdDir = subId - (subId % 100);
             if (!isAuthorizedToDelete(resp, subscriptionId, errorMessage)) {
                 return;
diff --git a/datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/PathUtil.java b/datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/PathUtil.java
new file mode 100644 (file)
index 0000000..a403441
--- /dev/null
@@ -0,0 +1,88 @@
+/**\r
+ * -\r
+ * ============LICENSE_START=======================================================\r
+ * Copyright (C) 2019 Nordix Foundation.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * <p>\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * <p>\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * <p>\r
+ * SPDX-License-Identifier: Apache-2.0\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+package org.onap.dmaap.datarouter.node;\r
+\r
+/**\r
+ * FORTIFY SCAN FIXES\r
+ * <p>This Utility is used for Fortify fixes. It Validates the path url formed from\r
+ *  the string passed in the request parameters.</p>\r
+ *\r
+ */\r
+class PathUtil {\r
+\r
+    /**\r
+     * This method takes String as the parameter and return the filtered path string.\r
+     * @param aString String to clean\r
+     * @return A cleaned String\r
+     */\r
+    static String cleanString(String aString) {\r
+        if (aString == null) return null;\r
+        String cleanString = "";\r
+        for (int i = 0; i < aString.length(); ++i) {\r
+            cleanString += cleanChar(aString.charAt(i));\r
+        }\r
+        return cleanString;\r
+    }\r
+\r
+    /**\r
+     * This method filters the valid special characters in path string.\r
+     * @param aChar The char to be cleaned\r
+     * @return The cleaned char\r
+     */\r
+    private static char cleanChar(char aChar) {\r
+        // 0 - 9\r
+        for (int i = 48; i < 58; ++i) {\r
+            if (aChar == i) return (char) i;\r
+        }\r
+        // 'A' - 'Z'\r
+        for (int i = 65; i < 91; ++i) {\r
+            if (aChar == i) return (char) i;\r
+        }\r
+        // 'a' - 'z'\r
+        for (int i = 97; i < 123; ++i) {\r
+            if (aChar == i) return (char) i;\r
+        }\r
+        // other valid characters\r
+        switch (aChar) {\r
+            case '/':\r
+                return '/';\r
+            case '.':\r
+                return '.';\r
+            case '-':\r
+                return '-';\r
+            case ':':\r
+                return ':';\r
+            case '?':\r
+                return '?';\r
+            case '&':\r
+                return '&';\r
+            case '=':\r
+                return '=';\r
+            case '#':\r
+                return '#';\r
+            case '_':\r
+                return '_';\r
+            case ' ':\r
+                return ' ';\r
+        }\r
+        return '%';\r
+    }\r
+}\r
index 77c5e99..a9c5c6f 100644 (file)
@@ -135,7 +135,17 @@ public class ProvData {
                     String fid = gvas(jfeed, "feedid");
                     String fname = gvas(jfeed, "name");
                     String fver = gvas(jfeed, "version");
                     String fid = gvas(jfeed, "feedid");
                     String fname = gvas(jfeed, "name");
                     String fver = gvas(jfeed, "version");
-                    pfv.add(new NodeConfig.ProvFeed(fid, fname + "//" + fver, stat));
+                    String createdDate = gvas(jfeed, "created_date");
+                    /*
+                     * START - AAF changes
+                     * TDP EPIC US# 307413
+                     * Passing aafInstance to ProvFeed from feeds json passed by prov to identify legacy/AAF feeds
+                     */
+                    String aafInstance = gvas(jfeed, "aaf_instance");
+                    pfv.add(new NodeConfig.ProvFeed(fid, fname + "//" + fver, stat,createdDate, aafInstance));
+                    /*
+                     * END - AAF changes
+                     */
                     JSONObject jauth = jfeed.optJSONObject("authorization");
                     if (jauth == null) {
                         continue;
                     JSONObject jauth = jfeed.optJSONObject("authorization");
                     if (jauth == null) {
                         continue;
@@ -175,7 +185,8 @@ public class ProvData {
                     boolean use100 = jdel.getBoolean("use100");
                     boolean privilegedSubscriber = jsub.getBoolean("privilegedSubscriber");
                     boolean decompress = jsub.getBoolean("decompress");
                     boolean use100 = jdel.getBoolean("use100");
                     boolean privilegedSubscriber = jsub.getBoolean("privilegedSubscriber");
                     boolean decompress = jsub.getBoolean("decompress");
-                    psv.add(new NodeConfig.ProvSubscription(sid, fid, delurl, id, NodeUtils.getAuthHdr(id, password), monly, use100, privilegedSubscriber, decompress));
+                    boolean followRedirect = jsub.getBoolean("follow_redirect");
+                    psv.add(new NodeConfig.ProvSubscription(sid, fid, delurl, id, NodeUtils.getAuthHdr(id, password), monly, use100, privilegedSubscriber, followRedirect, decompress));
                 }
             }
             JSONObject jparams = jcfg.optJSONObject("parameters");
                 }
             }
             JSONObject jparams = jcfg.optJSONObject("parameters");
index 2e83e22..6f74df4 100644 (file)
@@ -24,8 +24,6 @@
 
 package org.onap.dmaap.datarouter.node;
 
 
 package org.onap.dmaap.datarouter.node;
 
-import java.net.*;
-
 /**
  * Compare IP addresses as byte arrays to a subnet specified as a CIDR
  */
 /**
  * Compare IP addresses as byte arrays to a subnet specified as a CIDR
  */
diff --git a/datarouter-node/src/main/resources/drNodeCadi.properties b/datarouter-node/src/main/resources/drNodeCadi.properties
new file mode 100644 (file)
index 0000000..8dfcab1
--- /dev/null
@@ -0,0 +1,23 @@
+cadi_x509_issuers=CN=intermediateCA_1, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_7, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_9, OU=OSAAF, O=ONAP, C=US
+cadi_keyfile=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.keyfile
+cadi_keystore=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.jks
+cadi_keystore_password=]3V)($O&.Mv]W{f8^]6SxGNL
+cadi_key_password=]3V)($O&.Mv]W{f8^]6SxGNL
+cadi_alias=dmaap-dr-node@dmaap-dr.onap.org
+cadi_truststore=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.trust.jks
+cadi_truststore_password=(Rd,&{]%ePdp}4JZjqoJ2G+g
+
+aaf_env=DEV
+aaf_locate_url=https://aaf-onap-test.osaaf.org:8095
+aaf_oauth2_introspect_url=https://AAF_LOCATE_URL/AAF_NS.introspect:2.1/introspect
+aaf_oauth2_token_url=https://AAF_LOCATE_URL/AAF_NS.token:2.1/token
+aaf_url=https://AAF_LOCATE_URL/AAF_NS.service:2.1
+cadi_protocols=TLSv1.1,TLSv1.2
+cm_url=https://AAF_LOCATE_URL/AAF_NS.cm:2.1
+fs_url=https://AAF_LOCATE_URL/AAF_NS.fs.2.1
+gui_url=https://AAF_LOCATE_URL/AAF_NS.gui.2.1
+
+cadi_latitude=53.423
+cadi_longitude=7.940
+
+cadi_loglevel=DEBUG
\ No newline at end of file
index 8b5568b..27e91c9 100644 (file)
 # *
 #-------------------------------------------------------------------------------
 #
 # *
 #-------------------------------------------------------------------------------
 #
-#    Configuration parameters fixed at startup for the DataRouter node
+#    Configuration parameters set at startup for the DataRouter node
 #
 #    URL to retrieve dynamic configuration
 #
 #    URL to retrieve dynamic configuration
-#
-#ProvisioningURL:    ${DRTR_PROV_INTURL}
-ProvisioningURL=https://dmaap-dr-prov:8443/internal/prov
-
+ProvisioningURL = https://dmaap-dr-prov:8443/internal/prov
 #
 #    URL to upload PUB/DEL/EXP logs
 #
 #    URL to upload PUB/DEL/EXP logs
-#
-#LogUploadURL:    ${DRTR_LOG_URL}
-LogUploadURL=https://dmaap-dr-prov:8443/internal/logs
-
+LogUploadURL = https://dmaap-dr-prov:8443/internal/logs
 #
 #    The port number for http as seen within the server
 #
 #    The port number for http as seen within the server
-#
-#IntHttpPort:    ${DRTR_NODE_INTHTTPPORT:-8080}
-IntHttpPort=8080
+IntHttpPort = 8080
 #
 #    The port number for https as seen within the server
 #
 #    The port number for https as seen within the server
-#
-IntHttpsPort=8443
+IntHttpsPort = 8443
 #
 #    The external port number for https taking port mapping into account
 #
 #    The external port number for https taking port mapping into account
+ExtHttpsPort = 443
 #
 #
-ExtHttpsPort=443
-#
-#    The minimum interval between fetches of the dynamic configuration
-#    from the provisioning server
-#
-MinProvFetchInterval=10000
+#    The minimum interval between fetches of the dynamic configuration from the provisioning server
+MinProvFetchInterval = 10000
 #
 #    The minimum interval between saves of the redirection data file
 #
 #    The minimum interval between saves of the redirection data file
-#
-MinRedirSaveInterval=10000
+MinRedirSaveInterval = 10000
 #
 #    The path to the directory where log files are stored
 #
 #    The path to the directory where log files are stored
-#
-LogDir=/opt/app/datartr/logs
+LogDir = /opt/app/datartr/logs
 #
 #    The retention interval (in days) for log files
 #
 #    The retention interval (in days) for log files
-#
-LogRetention=30
+LogRetention = 30
 #
 #    The path to the directories where data and meta data files are stored
 #
 #    The path to the directories where data and meta data files are stored
-#
-SpoolDir=/opt/app/datartr/spool
+SpoolDir = /opt/app/datartr/spool
 #
 #    The path to the redirection data file
 #
 #    The path to the redirection data file
-#
-#RedirectionFile:    etc/redirections.dat
+RedirectionFile = etc/redirections.dat
 #
 #    The type of keystore for https
 #
 #    The type of keystore for https
-KeyStoreType:    jks
+KeyStoreType = jks
 #
 #    The path to the keystore for https
 #
 #    The path to the keystore for https
-#
-KeyStoreFile:/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.jks
+KeyStoreFile = /opt/app/datartr/aaf_certs/org.onap.dmaap-dr.jks
 #
 #    The password for the https keystore
 #
 #    The password for the https keystore
-#
 KeyStorePassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The password for the private key in the https keystore
 KeyStorePassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The password for the private key in the https keystore
-#
 KeyPassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The type of truststore for https
 KeyPassword=]3V)($O&.Mv]W{f8^]6SxGNL
 #
 #    The type of truststore for https
-#
-TrustStoreType=jks
+TrustStoreType = jks
 #
 #    The path to the truststore for https
 #
 #    The path to the truststore for https
-#
-#TrustStoreFile=/usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts
-TrustStoreFile=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.trust.jks
+TrustStoreFile = /opt/app/datartr/aaf_certs/org.onap.dmaap-dr.trust.jks
 #
 #    The password for the https truststore
 #
 #    The password for the https truststore
-#
 TrustStorePassword=(Rd,&{]%ePdp}4JZjqoJ2G+g
 #
 #    The path to the file used to trigger an orderly shutdown
 TrustStorePassword=(Rd,&{]%ePdp}4JZjqoJ2G+g
 #
 #    The path to the file used to trigger an orderly shutdown
-#
-QuiesceFile=etc/SHUTDOWN
+QuiesceFile = etc/SHUTDOWN
 #
 #    The key used to generate passwords for node to node transfers
 #
 #    The key used to generate passwords for node to node transfers
+NodeAuthKey = Node123!
+#
+#    DR_NODE DEFAULT ENABLED TLS PROTOCOLS
+NodeHttpsProtocols = TLSv1.1|TLSv1.2
+#
+#    AAF type to generate permission string
+AAFType = org.onap.dmaap-dr.feed
+#
+#    AAF default instance to generate permission string - default should be legacy
+AAFInstance = legacy
+#
+#    AAF action to generate permission string - default should be publish
+AAFAction = publish
+#
+#    AAF URL to connect to AAF server
+AafUrl = https://aaf-onap-test.osaaf.org:8095
 #
 #
-NodeAuthKey=Node123!
+#    AAF CADI enabled flag
+CadiEnabled = false
 
 
diff --git a/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/DRNodeCadiFilterTest.java b/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/DRNodeCadiFilterTest.java
new file mode 100644 (file)
index 0000000..f6737b1
--- /dev/null
@@ -0,0 +1,121 @@
+/**-\r
+ * ============LICENSE_START=======================================================\r
+ *  Copyright (C) 2019 Nordix Foundation.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * SPDX-License-Identifier: Apache-2.0\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.dmaap.datarouter.node;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.mockito.Mock;\r
+import org.onap.aaf.cadi.PropAccess;\r
+import org.onap.aaf.cadi.filter.CadiFilter;\r
+import org.powermock.api.mockito.PowerMockito;\r
+import org.powermock.api.support.membermodification.MemberMatcher;\r
+import org.powermock.core.classloader.annotations.PrepareForTest;\r
+import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;\r
+import org.powermock.modules.junit4.PowerMockRunner;\r
+\r
+import javax.servlet.FilterChain;\r
+import javax.servlet.ServletException;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+import java.io.IOException;\r
+\r
+import static org.mockito.Mockito.*;\r
+\r
+@SuppressStaticInitializationFor("org.onap.dmaap.datarouter.node.NodeConfigManager")\r
+@PrepareForTest({CadiFilter.class})\r
+@RunWith(PowerMockRunner.class)\r
+public class DRNodeCadiFilterTest\r
+{\r
+\r
+    @Mock\r
+    private PropAccess access;\r
+\r
+    @Mock\r
+    private HttpServletRequest request;\r
+\r
+    @Mock\r
+    private HttpServletResponse response;\r
+\r
+    @Mock\r
+    private FilterChain chain;\r
+\r
+    private DRNodeCadiFilter cadiFilter;\r
+\r
+\r
+    @Before\r
+    public void setUp() throws ServletException {\r
+        cadiFilter = new DRNodeCadiFilter(false, access);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_Called_And_Method_Is_GET_And_AAF_DB_Instance_Is_NULL_Then_Chain_doFilter_Called() throws Exception {\r
+        PowerMockito.mockStatic(NodeConfigManager.class);\r
+        NodeConfigManager config = mock(NodeConfigManager.class);\r
+\r
+        PowerMockito.when(NodeConfigManager.getInstance()).thenReturn(config);\r
+        PowerMockito.when(config.getAafInstance("/other/5")).thenReturn("legacy");\r
+        when(request.getPathInfo()).thenReturn("/publish/5");\r
+        when(request.getMethod()).thenReturn("GET");\r
+        cadiFilter.doFilter(request,response,chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_Called_And_Method_Is_GET_And_Path_Includes_Internal_Then_Chain_doFilter_Called() throws Exception {\r
+        PowerMockito.mockStatic(NodeConfigManager.class);\r
+        NodeConfigManager config = mock(NodeConfigManager.class);\r
+\r
+        PowerMockito.when(NodeConfigManager.getInstance()).thenReturn(config);\r
+        PowerMockito.when(config.getAafInstance("/other/5")).thenReturn("legacy");\r
+        when(request.getPathInfo()).thenReturn("/internal/5");\r
+        when(request.getMethod()).thenReturn("GET");\r
+        cadiFilter.doFilter(request,response,chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_Called_And_Method_Is_GET_And_AAF_DB_Is_Not_Null_Then_Super_doFilter_Called() throws Exception {\r
+        PowerMockito.mockStatic(NodeConfigManager.class);\r
+        NodeConfigManager config = mock(NodeConfigManager.class);\r
+\r
+        PowerMockito.when(NodeConfigManager.getInstance()).thenReturn(config);\r
+        PowerMockito.when(config.getAafInstance("5")).thenReturn("EXISTS");\r
+        when(request.getPathInfo()).thenReturn("/publish/5/fileId");\r
+        when(request.getMethod()).thenReturn("GET");\r
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(CadiFilter.class));\r
+        cadiFilter.doFilter(request,response,chain);\r
+        verify(chain, times(0)).doFilter(request, response);\r
+    }\r
+\r
+    @Test\r
+    public void Given_getFileid_Called_And_SendError_Fails_Then_Throw_IOException_And_Call_chain_doFilter() throws Exception {\r
+        PowerMockito.mockStatic(NodeConfigManager.class);\r
+        NodeConfigManager config = mock(NodeConfigManager.class);\r
+\r
+        PowerMockito.when(NodeConfigManager.getInstance()).thenReturn(config);\r
+        when(request.getPathInfo()).thenReturn("/publish/5");\r
+        when(request.getMethod()).thenReturn("DELETE");\r
+        doThrow(new IOException()).when(response).sendError(HttpServletResponse.SC_NOT_FOUND, "Invalid request URI.  Expecting <feed-publishing-url>/<fileid>.  Possible missing fileid.");\r
+        cadiFilter.doFilter(request,response,chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+    }\r
+}\r
index 97904a5..9a3d82e 100644 (file)
@@ -22,6 +22,7 @@
  ******************************************************************************/
 
 package org.onap.dmaap.datarouter.node;
  ******************************************************************************/
 
 package org.onap.dmaap.datarouter.node;
+
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.junit.Before;
 import org.junit.Test;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.junit.Before;
 import org.junit.Test;
@@ -29,12 +30,10 @@ import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.mockito.Mock;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import static org.junit.Assert.*;
 import java.io.File;
 
 import java.io.File;
 
-
-
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.when;
 
 @RunWith(PowerMockRunner.class)
 public class DeliveryQueueTest {
 
 @RunWith(PowerMockRunner.class)
 public class DeliveryQueueTest {
@@ -55,7 +54,7 @@ public class DeliveryQueueTest {
     }
 
     @Test
     }
 
     @Test
-    public void Given_New_DeliveryQueue_Directory_Is_Created_As_Defined_By_DestInfo() throws Exception {
+    public void Given_New_DeliveryQueue_Directory_Is_Created_As_Defined_By_DestInfo() {
         when(destInfo.getSpool()).thenReturn("tmp");
         File file = new File("tmp");
         assertTrue(file.exists());
         when(destInfo.getSpool()).thenReturn("tmp");
         File file = new File("tmp");
         assertTrue(file.exists());
@@ -63,14 +62,14 @@ public class DeliveryQueueTest {
     }
 
     @Test
     }
 
     @Test
-    public void Given_Delivery_Task_Failed_And_Resume_Time_Not_Reached_Return_Null() throws Exception{
+    public void Given_Delivery_Task_Failed_And_Resume_Time_Not_Reached_Return_Null() throws Exception {
         FieldUtils.writeField(deliveryQueue,"failed",true,true);
         FieldUtils.writeField(deliveryQueue,"resumetime",System.currentTimeMillis()*2,true);
         assertNull(deliveryQueue.peekNext());
     }
 
     @Test
         FieldUtils.writeField(deliveryQueue,"failed",true,true);
         FieldUtils.writeField(deliveryQueue,"resumetime",System.currentTimeMillis()*2,true);
         assertNull(deliveryQueue.peekNext());
     }
 
     @Test
-    public void Given_Delivery_Task_Return_Next_Delivery_Task_Id() throws Exception{
+    public void Given_Delivery_Task_Return_Next_Delivery_Task_Id() throws Exception {
         prepareFiles();
         when(destInfo.getSpool()).thenReturn(dirPath);
         deliveryQueue = new DeliveryQueue(deliveryQueueHelper, destInfo);
         prepareFiles();
         when(destInfo.getSpool()).thenReturn(dirPath);
         deliveryQueue = new DeliveryQueue(deliveryQueueHelper, destInfo);
@@ -81,19 +80,19 @@ public class DeliveryQueueTest {
     }
 
     @Test
     }
 
     @Test
-    public void Given_Delivery_Task_Cancel_And_FileId_Is_Null_Return_Zero() throws Exception{
+    public void Given_Delivery_Task_Cancel_And_FileId_Is_Null_Return_Zero() {
         long rc = deliveryQueue.cancelTask("123.node.datarouternew.com");
         assertEquals(0, rc);
     }
 
         long rc = deliveryQueue.cancelTask("123.node.datarouternew.com");
         assertEquals(0, rc);
     }
 
-    private void prepareFiles() throws Exception{
+    private void prepareFiles() throws Exception {
         createFolder(dirPath);
         createFile(FileName1, dirPath);
         String[] files = new String[2];
         files[0] = dirPath + FileName1;
     }
 
         createFolder(dirPath);
         createFile(FileName1, dirPath);
         String[] files = new String[2];
         files[0] = dirPath + FileName1;
     }
 
-    private void createFolder(String dirName) throws Exception{
+    private void createFolder(String dirName) throws Exception {
         String dirPath = dirName;
 
         File newDirectory = new File(dirPath);
         String dirPath = dirName;
 
         File newDirectory = new File(dirPath);
@@ -101,13 +100,13 @@ public class DeliveryQueueTest {
         if (isCreated) {
             System.out.println("1. Successfully created directories, path: " + newDirectory.getCanonicalPath());
         } else if (newDirectory.exists()) {
         if (isCreated) {
             System.out.println("1. Successfully created directories, path: " + newDirectory.getCanonicalPath());
         } else if (newDirectory.exists()) {
-            System.out.printf("1. Directory path already exist, path: " + newDirectory.getCanonicalPath());
+            System.out.print("1. Directory path already exist, path: " + newDirectory.getCanonicalPath());
         } else {
             System.out.println("1. Unable to create directory");
         }
     }
 
         } else {
             System.out.println("1. Unable to create directory");
         }
     }
 
-    private void createFile( String file, String dir) throws Exception{
+    private void createFile(String file, String dir) throws Exception {
         String FileName = file;
         String dirPath = dir;
 
         String FileName = file;
         String dirPath = dir;
 
index 4ca907f..efa43e1 100644 (file)
@@ -97,7 +97,7 @@ public class DeliveryTest {
 
   private DestInfo[] createDestInfoObjects() {
     DestInfo[] destInfos = new DestInfo[1];
 
   private DestInfo[] createDestInfoObjects() {
     DestInfo[] destInfos = new DestInfo[1];
-    DestInfo destInfo = new DestInfo("node.datarouternew.com", "spool/s/0/1", "1", "logs/", "/subs/1", "user1", "Basic dXNlcjE6cGFzc3dvcmQx", false, true, false, false);
+    DestInfo destInfo = new DestInfo("node.datarouternew.com", "spool/s/0/1", "1", "logs/", "/subs/1", "user1", "Basic dXNlcjE6cGFzc3dvcmQx", false, true, false, false, false);
     destInfos[0] = destInfo;
     return destInfos;
   }
     destInfos[0] = destInfo;
     return destInfos;
   }
index 4b614d5..7dddd67 100644 (file)
@@ -193,6 +193,7 @@ public class NodeConfigTest {
         endpointAddrs.put("172.0.0.1");
         auth.put("endpoint_addrs", endpointAddrs);
         feed.put("authorization", auth);
         endpointAddrs.put("172.0.0.1");
         auth.put("endpoint_addrs", endpointAddrs);
         feed.put("authorization", auth);
+        feed.put("aaf_instance", "legacy");
         feeds.put(feed);
         provData.put("feeds", feeds);
     }
         feeds.put(feed);
         provData.put("feeds", feeds);
     }
@@ -211,6 +212,7 @@ public class NodeConfigTest {
         delivery.put("use100", true);
         subscription.put("delivery", delivery);
         subscription.put("privilegedSubscriber", false);
         delivery.put("use100", true);
         subscription.put("delivery", delivery);
         subscription.put("privilegedSubscriber", false);
+        subscription.put("follow_redirect", false);
         subscription.put("decompress", false);
         subscriptions.put(subscription);
         provData.put("subscriptions", subscriptions);
         subscription.put("decompress", false);
         subscriptions.put(subscription);
         provData.put("subscriptions", subscriptions);
index 065565d..99e34c6 100644 (file)
@@ -59,7 +59,9 @@ public class NodeServletTest {
     @Mock
     private HttpServletResponse response;
 
     @Mock
     private HttpServletResponse response;
 
-    ListAppender<ILoggingEvent> listAppender;
+    private ListAppender<ILoggingEvent> listAppender;
+
+    private NodeConfigManager config = mock(NodeConfigManager.class);
 
     @Before
     public void setUp() throws Exception {
 
     @Before
     public void setUp() throws Exception {
@@ -215,6 +217,17 @@ public class NodeServletTest {
         verifyEnteringExitCalled(listAppender);
     }
 
         verifyEnteringExitCalled(listAppender);
     }
 
+    @Test
+    public void Given_Request_Is_HTTP_PUT_On_Publish_On_AAF_Feed_And_Cadi_Enabled_And_No_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(config.getCadiEnabeld()).thenReturn(true);
+        when(config.getAafInstance("1")).thenReturn("*");
+        when(request.getPathInfo()).thenReturn("/publish/1/fileName");
+        setHeadersForValidRequest(true);
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+        verifyEnteringExitCalled(listAppender);
+    }
+
     @Test
     public void Given_Request_Is_HTTP_DELETE_On_Publish_With_Meta_Data_Malformed_Then_Bad_Request_Response_Is_Generated() throws Exception {
         when(request.getPathInfo()).thenReturn("/publish/1/fileName");
     @Test
     public void Given_Request_Is_HTTP_DELETE_On_Publish_With_Meta_Data_Malformed_Then_Bad_Request_Response_Is_Generated() throws Exception {
         when(request.getPathInfo()).thenReturn("/publish/1/fileName");
@@ -286,7 +299,6 @@ public class NodeServletTest {
     }
 
     private void setUpConfig() throws IllegalAccessException {
     }
 
     private void setUpConfig() throws IllegalAccessException {
-        NodeConfigManager config = mock(NodeConfigManager.class);
         PowerMockito.mockStatic(NodeConfigManager.class);
         when(config.isShutdown()).thenReturn(false);
         when(config.isConfigured()).thenReturn(true);
         PowerMockito.mockStatic(NodeConfigManager.class);
         when(config.isShutdown()).thenReturn(false);
         when(config.isConfigured()).thenReturn(true);
diff --git a/datarouter-prov/aaf_certs/org.onap.dmaap-dr.keyfile b/datarouter-prov/aaf_certs/org.onap.dmaap-dr.keyfile
new file mode 100755 (executable)
index 0000000..a586a72
--- /dev/null
@@ -0,0 +1,27 @@
+VDu7g5rP2-JMemc6RwP0HqM4ILJnuja8R_bzdCG1u0_Z2EQJN_7ZNPDb28V6JCDF-59sX10_i9vT
+-nw77ViAuwJO7ffSut8ipVhESeQxTokZsErzMFpeJZDhMM16W5LLtxwUs_tgh_EQIJSc-WcFUNYS
+NagugzjmNE5-hUosLgnt7mZ1nX4zFER9Nq1ce0EQS--kAB9rxcRmoywPlBlHvPmP_caiwpa1SzJp
+gbFF6smyLEWhjDhJkgvM_4FwaQCbJBVGcy2a3Lc9orHsz9S1RJTZ9CExhasM0qEp3kk0fMEFE9k6
+TomOpUBGizLfHPpg18KtXyM8zErj8qdS0KMwaCKtwGzCWw08MF5rVZrMYWLKDMOs8U2ESU7x28nV
+KSrAsR11QD7vX4PTVTfjEpcHSGe-9nPD7TckY8_O-9l67v_OUW1Fw4MSESCN0RtT7ZlNYwDV0syA
+X94rv1Y45N41tfX76jz8PDB9G-PF36BtkICJWK24zwuQDgpkURhCLPYzvBhPmCPyQil810X9s_bX
+icmV2cSN3oYQRz5dNSjUYH1CDt9edAJt4p2PQhM3A2xXyw1FVvbAIYA7iF-3qYG9csroBzsCcS5C
+hX8929jZHQWU5pygtpedEWhX__tnSrd-xIpxPnhOxrb-lNLva5JGKauU2DrGoLd_7RTwbuRdCiQo
+uGFtYOtjLciPz81oEEpXQTReeSnvGyGiZNxRrKWMEmq-biyQd4DuRVmTDuLAG4rd92QWS6qUz0uf
+9TtJiYlN3mNkxz3ahEGWLKR79rH9juJ3xqpcF-Rb7Y1bmiCDBv3DVVFiYIpwQuto1iSIYabL34Ql
+QqX65E1c3uvPksN6Nl1nvAVxSKM94wAFsMiA9Rp8AN9pDSxtj7D3kZCG8I0YaIxF_s-OeJtr1RPx
+ifv8vrwN23GUQCmpGBbyNXNe6zz-hz_HJdAsBr6WjLny9LQkeYszHGF-OL5ps6K5gHBRV0Ui1C7H
+Gj7egsjnV_Lu5MpBxhTrquDrZKK3t38kf0zrV-zfSGzJlGbLS91h8bR-7FAZiNEzgXPWYi26w81i
+W3Csx4oqsfKswp0pO80rggkFf9LL9pjCkSUTTVyF-toa9kY2h7JsVtqntP4Mjagp4Tnj01988kne
+Mj8SLm2mJySTLdH5Hi4arKW943iCqYjEaZ7wXFNJSZ6vvBm3KC1XX6C0DjRrgQoKIHw_4JcGhvOU
+P5LdpBT1AOcE8lIKrGGq8hyfJKLVUMec-NkzAT2aIl0YJoUcJv4fs-lKccGL4FDrq5y_yvD3xQ6v
+xt7KTanFxntqLYmM72Y2eFwJGlDEHhm0SejAV64-odksA_zMLLuYwkq_KSj0If9AVpRXz7KzIj9P
+9y-WMfAWKFfIyqGWXt5sYdMTQPG4qKCcFQBx3T0E6kiQMBuOZz0dR032eFPMexrymEowjosr2jt3
+ib8rFxmPMyyUWoV1iBafFMLf5PN2oapTq76gqeQQGGwpmYJB8cWlS1Eq_ZbzZpK2PSwX-fC6NSf3
+KtOV_r2VI3e_V6csnWTY8nxCJj9FlQCvLOzp964DNsBeUwDpsD7T_pgQy0THgAnq32ZtDvQfgeUE
+TUJC7oQeOEY7QBWjbZkumds51j7oTlsp2dPForlHwBk_2Nd5VCwVRNa1QMS8WcghLYbUCX5zeplc
+u2bopHn9GD614gt7f7wysDgTGegOCAuMoL7wA9TXN4BSfAF9mwpdtRFE4lT3N1xmfhKt9rM6Lu8T
+RGvBOmTOTT5IwJrrE5mpvmESw05sHUcCZ9ENv-VhoeC3Ffk9uXqrDggQgaDs9XcXqzEPBp9wDPTt
+UJpbtBGECSSTuXAZyUh3I0WFz96kVuHmQpDYVTpy1sxPjmgjgKyhu_6jLGSsYpVBH063n7KSKVdF
+ROKojZN4-FsBlPhoOhNEd7x1OBfgCG79HKGk33jhESObZkPIrcTc17jiE-ud2D1B1_Fl-OJNR7Vh
+GIk4WMZrH9NeVwDuIgBxF74plqg6tSl0Cdd4m7e3Drsq-wRfsU2gNTo5oL-2SgbsO5n3ubQf
\ No newline at end of file
index 44f70f5..284a8ca 100755 (executable)
                 </exclusion>\r
             </exclusions>\r
         </dependency>\r
                 </exclusion>\r
             </exclusions>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.onap.aaf.authz</groupId>\r
+            <artifactId>aaf-cadi-aaf</artifactId>\r
+            <version>${aaf-cadi-aaf.version}</version>\r
+        </dependency>\r
     </dependencies>\r
     <profiles>\r
         <profile>\r
     </dependencies>\r
     <profiles>\r
         <profile>\r
index 2d4f85f..50ec1b4 100755 (executable)
 
 package org.onap.dmaap.datarouter.provisioning;
 
 
 package org.onap.dmaap.datarouter.provisioning;
 
-import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
-
-import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
-import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
-import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
-
-
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.cert.X509Certificate;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
+import org.json.JSONArray;
+import org.json.JSONException;
 import org.json.JSONObject;
 import org.json.JSONTokener;
 import org.onap.dmaap.datarouter.authz.Authorizer;
 import org.onap.dmaap.datarouter.authz.impl.ProvAuthorizer;
 import org.onap.dmaap.datarouter.authz.impl.ProvDataProvider;
 import org.json.JSONObject;
 import org.json.JSONTokener;
 import org.onap.dmaap.datarouter.authz.Authorizer;
 import org.onap.dmaap.datarouter.authz.impl.ProvAuthorizer;
 import org.onap.dmaap.datarouter.authz.impl.ProvDataProvider;
-import org.onap.dmaap.datarouter.provisioning.beans.Deleteable;
-import org.onap.dmaap.datarouter.provisioning.beans.Feed;
-import org.onap.dmaap.datarouter.provisioning.beans.Group;
-import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
-import org.onap.dmaap.datarouter.provisioning.beans.NodeClass;
-import org.onap.dmaap.datarouter.provisioning.beans.Parameters;
-import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
-import org.onap.dmaap.datarouter.provisioning.beans.Updateable;
+import org.onap.dmaap.datarouter.provisioning.beans.*;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
+import org.onap.dmaap.datarouter.provisioning.utils.PasswordProcessor;
 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
-import org.json.JSONException;
 import org.slf4j.MDC;
 import org.slf4j.MDC;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.UUID;
-import java.util.regex.Pattern;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.AddressException;
+
+import javax.mail.*;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.GeneralSecurityException;
+import java.security.cert.X509Certificate;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.*;
+import java.util.regex.Pattern;
+
+import static com.att.eelf.configuration.Configuration.*;
 
 /**
  * This is the base class for all Servlets in the provisioning code. It provides standard constants and some common
 
 /**
  * This is the base class for all Servlets in the provisioning code. It provides standard constants and some common
@@ -98,6 +72,24 @@ import javax.mail.internet.MimeMultipart;
 public class BaseServlet extends HttpServlet implements ProvDataProvider {
 
     public static final String BEHALF_HEADER = "X-DMAAP-DR-ON-BEHALF-OF";
 public class BaseServlet extends HttpServlet implements ProvDataProvider {
 
     public static final String BEHALF_HEADER = "X-DMAAP-DR-ON-BEHALF-OF";
+
+    public static final String EXCLUDE_AAF_HEADER = "X-EXCLUDE-AAF";
+
+    private static final String AAF_CADI_FEED_TYPE = "org.onap.dmaap.datarouter.provserver.aaf.feed.type";
+    private static final String AAF_CADI_SUB_TYPE = "org.onap.dmaap.datarouter.provserver.aaf.sub.type";
+    private static final String AAF_INSTANCE = "org.onap.dmaap.datarouter.provserver.aaf.instance";
+    private static final String AAF_CADI_FEED = "org.onap.dmaap-dr.feed";
+    private static final String AAF_CADI_SUB = "org.onap.dmaap-dr.sub";
+
+    static final String CREATE_PERMISSION = "create";
+    static final String EDIT_PERMISSION = "edit";
+    static final String DELETE_PERMISSION = "delete";
+    static final String PUBLISH_PERMISSION = "publish";
+    static final String SUSPEND_PERMISSION = "suspend";
+    static final String RESTORE_PERMISSION = "restore";
+    static final String SUBSCRIBE_PERMISSION = "subscribe";
+    static final String APPROVE_SUB_PERMISSION = "approveSub";
+
     static final String FEED_BASECONTENT_TYPE = "application/vnd.dmaap-dr.feed";
     public static final String FEED_CONTENT_TYPE = "application/vnd.dmaap-dr.feed; version=2.0";
     public static final String FEEDFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.feed-full; version=2.0";
     static final String FEED_BASECONTENT_TYPE = "application/vnd.dmaap-dr.feed";
     public static final String FEED_CONTENT_TYPE = "application/vnd.dmaap-dr.feed; version=2.0";
     public static final String FEEDFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.feed-full; version=2.0";
@@ -110,7 +102,9 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
 
     //Adding groups functionality, ...1610
     static final String GROUP_BASECONTENT_TYPE = "application/vnd.dmaap-dr.group";
 
     //Adding groups functionality, ...1610
     static final String GROUP_BASECONTENT_TYPE = "application/vnd.dmaap-dr.group";
-    static final String GROUPFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.group-full; version=2.0";
+    static final String GROUP_CONTENT_TYPE = "application/vnd.dmaap-dr.group; version=2.0";
+    public static final String GROUPFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.group-full; version=2.0";
+    public static final String GROUPLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.fegrouped-list; version=1.0";
 
 
     public static final String LOGLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.log-list; version=1.0";
 
 
     public static final String LOGLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.log-list; version=1.0";
@@ -172,6 +166,10 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * Array of nodes names and/or FQDNs
      */
     private static String[] nodes = new String[0];
      * Array of nodes names and/or FQDNs
      */
     private static String[] nodes = new String[0];
+    /**
+     * [DATARTR-27] Poke all the DR nodes : Array of nodes names and/or FQDNs
+     */
+    private static String[] drnodes = new String[0];
     /**
      * Array of node IP addresses
      */
     /**
      * Array of node IP addresses
      */
@@ -196,10 +194,12 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * The current number of subscriptions in the system
      */
     static int activeSubs = 0;
      * The current number of subscriptions in the system
      */
     static int activeSubs = 0;
+
     /**
      * The domain used to generate a FQDN from the "bare" node names
      */
     private static String provDomain = "web.att.com";
     /**
      * The domain used to generate a FQDN from the "bare" node names
      */
     private static String provDomain = "web.att.com";
+
     /**
      * The standard FQDN of the provisioning server in this Data Router ecosystem
      */
     /**
      * The standard FQDN of the provisioning server in this Data Router ecosystem
      */
@@ -210,7 +210,8 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      */
     private static String activeProvName = "feeds-drtr.web.att.com";
 
      */
     private static String activeProvName = "feeds-drtr.web.att.com";
 
-    private static String staticRoutingNodes = STATIC_ROUTING_NODES; //Adding new param for static Routing - Rally:US664862-1610
+    //Adding new param for static Routing - Rally:US664862-1610
+    private static String staticRoutingNodes = STATIC_ROUTING_NODES;
 
     /**
      * This logger is used to log provisioning events
 
     /**
      * This logger is used to log provisioning events
@@ -239,7 +240,10 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
 
     //DMAAP-597 (Tech Dept) REST request source IP auth relaxation to accommodate OOM kubernetes deploy
     private static String isAddressAuthEnabled = (new DB()).getProperties()
 
     //DMAAP-597 (Tech Dept) REST request source IP auth relaxation to accommodate OOM kubernetes deploy
     private static String isAddressAuthEnabled = (new DB()).getProperties()
-        .getProperty("org.onap.dmaap.datarouter.provserver.isaddressauthenabled", "false");
+            .getProperty("org.onap.dmaap.datarouter.provserver.isaddressauthenabled", "false");
+
+    static String isCadiEnabled = (new DB()).getProperties()
+            .getProperty("org.onap.dmaap.datarouter.provserver.cadi.enabled", "false");
 
     /**
      * Initialize data common to all the provisioning server servlets.
 
     /**
      * Initialize data common to all the provisioning server servlets.
@@ -277,7 +281,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         }
     }
 
         }
     }
 
-    int getIdFromPath(HttpServletRequest req) {
+    public static int getIdFromPath(HttpServletRequest req) {
         String path = req.getPathInfo();
         if (path == null || path.length() < 2) {
             return -1;
         String path = req.getPathInfo();
         if (path == null || path.length() < 2) {
             return -1;
@@ -308,6 +312,36 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         return jo;
     }
 
         return jo;
     }
 
+    /**
+     * This method encrypt/decrypt the key in the JSON passed by user request inside the authorisation header object in request before logging the JSON.
+     *
+     * @param jo-      the JSON passed in http request.
+     * @param maskKey- the key to be masked in the JSON passed.
+     * @param action-  whether to mask the key or unmask it in a JSON passed.
+     * @return the JSONObject, or null if the stream cannot be parsed.
+     */
+    public static JSONObject maskJSON(JSONObject jo, String maskKey, boolean action) {
+        if (!jo.isNull("authorization")) {
+            JSONObject j2 = jo.getJSONObject("authorization");
+            JSONArray ja = j2.getJSONArray("endpoint_ids");
+            for (int i = 0; i < ja.length(); i++) {
+                if ((!ja.getJSONObject(i).isNull(maskKey))) {
+                    String password = ja.getJSONObject(i).get(maskKey).toString();
+                    try {
+                        if (action) {
+                            ja.getJSONObject(i).put(maskKey, PasswordProcessor.encrypt(password));
+                        } else {
+                            ja.getJSONObject(i).put(maskKey, PasswordProcessor.decrypt(password));
+                        }
+                    } catch (JSONException | GeneralSecurityException e) {
+                        intlogger.info("Error reading JSON while masking: " + e);
+                    }
+                }
+            }
+        }
+        return jo;
+    }
+
     /**
      * Check if the remote host is authorized to perform provisioning. Is the request secure? Is it coming from an
      * authorized IP address or network (configured via PROV_AUTH_ADDRESSES)? Does it have a valid client certificate
     /**
      * Check if the remote host is authorized to perform provisioning. Is the request secure? Is it coming from an
      * authorized IP address or network (configured via PROV_AUTH_ADDRESSES)? Does it have a valid client certificate
@@ -324,7 +358,6 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         if (requireSecure && !request.isSecure()) {
             return "Request must be made over an HTTPS connection.";
         }
         if (requireSecure && !request.isSecure()) {
             return "Request must be made over an HTTPS connection.";
         }
-
         // Is remote IP authorized?
         String remote = request.getRemoteAddr();
         try {
         // Is remote IP authorized?
         String remote = request.getRemoteAddr();
         try {
@@ -337,12 +370,12 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 return "Unauthorized address: " + remote;
             }
         } catch (UnknownHostException e) {
                 return "Unauthorized address: " + remote;
             }
         } catch (UnknownHostException e) {
+            intlogger.error("PROV0051 BaseServlet.isAuthorizedForProvisioning: ", e);
             return "Unauthorized address: " + remote;
         }
             return "Unauthorized address: " + remote;
         }
-
         // Does remote have a valid certificate?
         if (requireCert) {
         // Does remote have a valid certificate?
         if (requireCert) {
-            X509Certificate certs[] = (X509Certificate[]) request.getAttribute(CERT_ATTRIBUTE);
+            X509Certificate[] certs = (X509Certificate[]) request.getAttribute(CERT_ATTRIBUTE);
             if (certs == null || certs.length == 0) {
                 return "Client certificate is missing.";
             }
             if (certs == null || certs.length == 0) {
                 return "Client certificate is missing.";
             }
@@ -353,7 +386,6 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 return "No authorized certificate found.";
             }
         }
                 return "No authorized certificate found.";
             }
         }
-
         // No problems!
         return null;
     }
         // No problems!
         return null;
     }
@@ -365,7 +397,6 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * @return true iff authorized
      */
     boolean isAuthorizedForInternal(HttpServletRequest request) {
      * @return true iff authorized
      */
     boolean isAuthorizedForInternal(HttpServletRequest request) {
-
         try {
             if (!Boolean.parseBoolean(isAddressAuthEnabled)) {
                 return true;
         try {
             if (!Boolean.parseBoolean(isAddressAuthEnabled)) {
                 return true;
@@ -388,7 +419,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 return true;
             }
         } catch (UnknownHostException e) {
                 return true;
             }
         } catch (UnknownHostException e) {
-            // ignore
+            intlogger.error("PROV0052 BaseServlet.isAuthorizedForInternal: ", e);
         }
         return false;
     }
         }
         return false;
     }
@@ -397,7 +428,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * Check if an IP address matches a network address.
      *
      * @param ip the IP address
      * Check if an IP address matches a network address.
      *
      * @param ip the IP address
-     * @param s the network address; a bare IP address may be matched also
+     * @param s  the network address; a bare IP address may be matched also
      * @return true if they intersect
      */
     private static boolean addressMatchesNetwork(InetAddress ip, String s) {
      * @return true if they intersect
      */
     private static boolean addressMatchesNetwork(InetAddress ip, String s) {
@@ -416,8 +447,8 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             }
             if (mlen > 0) {
                 byte[] masks = {
             }
             if (mlen > 0) {
                 byte[] masks = {
-                    (byte) 0x00, (byte) 0x80, (byte) 0xC0, (byte) 0xE0,
-                    (byte) 0xF0, (byte) 0xF8, (byte) 0xFC, (byte) 0xFE
+                        (byte) 0x00, (byte) 0x80, (byte) 0xC0, (byte) 0xE0,
+                        (byte) 0xF0, (byte) 0xF8, (byte) 0xFC, (byte) 0xFE
                 };
                 byte mask = masks[mlen % 8];
                 for (n = mlen / 8; n < b1.length; n++) {
                 };
                 byte mask = masks[mlen % 8];
                 for (n = mlen / 8; n < b1.length; n++) {
@@ -432,6 +463,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 }
             }
         } catch (UnknownHostException e) {
                 }
             }
         } catch (UnknownHostException e) {
+            intlogger.error("PROV0053 BaseServlet.addressMatchesNetwork: ", e);
             return false;
         }
         return true;
             return false;
         }
         return true;
@@ -441,7 +473,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * Something has changed in the provisioning data. Start the timers that will cause the pre-packaged JSON string to
      * be regenerated, and cause nodes and the other provisioning server to be notified.
      */
      * Something has changed in the provisioning data. Start the timers that will cause the pre-packaged JSON string to
      * be regenerated, and cause nodes and the other provisioning server to be notified.
      */
-    public static void provisioningDataChanged() {
+    static void provisioningDataChanged() {
         long now = System.currentTimeMillis();
         Poker p = Poker.getPoker();
         p.setTimers(now + (pokeTimer1 * 1000L), now + (pokeTimer2 * 1000L));
         long now = System.currentTimeMillis();
         Poker p = Poker.getPoker();
         p.setTimers(now + (pokeTimer1 * 1000L), now + (pokeTimer2 * 1000L));
@@ -450,7 +482,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     /**
      * Something in the parameters has changed, reload all parameters from the DB.
      */
     /**
      * Something in the parameters has changed, reload all parameters from the DB.
      */
-    public static void provisioningParametersChanged() {
+    static void provisioningParametersChanged() {
         Map<String, String> map = Parameters.getParameters();
         requireSecure = getBoolean(map, Parameters.PROV_REQUIRE_SECURE);
         requireCert = getBoolean(map, Parameters.PROV_REQUIRE_CERT);
         Map<String, String> map = Parameters.getParameters();
         requireSecure = getBoolean(map, Parameters.PROV_REQUIRE_SECURE);
         requireCert = getBoolean(map, Parameters.PROV_REQUIRE_CERT);
@@ -461,15 +493,16 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         maxSubs = getInt(map, Parameters.PROV_MAXSUB_COUNT, DEFAULT_MAX_SUBS);
         pokeTimer1 = getInt(map, Parameters.PROV_POKETIMER1, DEFAULT_POKETIMER1);
         pokeTimer2 = getInt(map, Parameters.PROV_POKETIMER2, DEFAULT_POKETIMER2);
         maxSubs = getInt(map, Parameters.PROV_MAXSUB_COUNT, DEFAULT_MAX_SUBS);
         pokeTimer1 = getInt(map, Parameters.PROV_POKETIMER1, DEFAULT_POKETIMER1);
         pokeTimer2 = getInt(map, Parameters.PROV_POKETIMER2, DEFAULT_POKETIMER2);
+        /**
+         * The domain used to generate a FQDN from the "bare" node names
+         */
         provDomain = getString(map, Parameters.PROV_DOMAIN, DEFAULT_DOMAIN);
         provName = getString(map, Parameters.PROV_NAME, DEFAULT_PROVSRVR_NAME);
         activeProvName = getString(map, Parameters.PROV_ACTIVE_NAME, provName);
         provDomain = getString(map, Parameters.PROV_DOMAIN, DEFAULT_DOMAIN);
         provName = getString(map, Parameters.PROV_NAME, DEFAULT_PROVSRVR_NAME);
         activeProvName = getString(map, Parameters.PROV_ACTIVE_NAME, provName);
-        staticRoutingNodes = getString(map, Parameters.STATIC_ROUTING_NODES,
-            ""); //Adding new param for static Routing - Rally:US664862-1610
         initialActivePod = getString(map, Parameters.ACTIVE_POD, "");
         initialStandbyPod = getString(map, Parameters.STANDBY_POD, "");
         staticRoutingNodes = getString(map, Parameters.STATIC_ROUTING_NODES,
         initialActivePod = getString(map, Parameters.ACTIVE_POD, "");
         initialStandbyPod = getString(map, Parameters.STANDBY_POD, "");
         staticRoutingNodes = getString(map, Parameters.STATIC_ROUTING_NODES,
-            ""); //Adding new param for static Routing - Rally:US664862-1610
+                ""); //Adding new param for static Routing - Rally:US664862-1610
         activeFeeds = Feed.countActiveFeeds();
         activeSubs = Subscription.countActiveSubscriptions();
         try {
         activeFeeds = Feed.countActiveFeeds();
         activeSubs = Subscription.countActiveSubscriptions();
         try {
@@ -491,6 +524,9 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             }
         }
 
             }
         }
 
+        //[DATARTR-27] Poke all the DR nodes: assigning DR Nodes
+        drnodes = nodes.clone();
+
         //Reset Nodes arr after - removing static routing Nodes, Rally Userstory - US664862 .
         List<String> filterNodes = new ArrayList<>();
         for (String node : nodes) {
         //Reset Nodes arr after - removing static routing Nodes, Rally Userstory - US664862 .
         List<String> filterNodes = new ArrayList<>();
         for (String node : nodes) {
@@ -498,7 +534,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 filterNodes.add(node);
             }
         }
                 filterNodes.add(node);
             }
         }
-        nodes = filterNodes.toArray(new String[filterNodes.size()]);
+        nodes = filterNodes.toArray(new String[0]);
 
         nodeAddresses = na;
         NodeClass.setNodes(nodes);        // update NODES table
 
         nodeAddresses = na;
         NodeClass.setNodes(nodes);        // update NODES table
@@ -535,17 +571,11 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     private void loadMailProperties() {
         if (mailprops == null) {
             mailprops = new Properties();
     private void loadMailProperties() {
         if (mailprops == null) {
             mailprops = new Properties();
-            InputStream inStream = getClass().getClassLoader().getResourceAsStream(MAILCONFIG_FILE);
-            try {
+            try (InputStream inStream = getClass().getClassLoader().getResourceAsStream(MAILCONFIG_FILE)) {
                 mailprops.load(inStream);
             } catch (IOException e) {
                 intlogger.fatal("PROV9003 Opening properties: " + e.getMessage());
                 System.exit(1);
                 mailprops.load(inStream);
             } catch (IOException e) {
                 intlogger.fatal("PROV9003 Opening properties: " + e.getMessage());
                 System.exit(1);
-            } finally {
-                try {
-                    inStream.close();
-                } catch (IOException e) {
-                }
             }
         }
     }
             }
         }
     }
@@ -602,18 +632,16 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             msg.addRecipients(Message.RecipientType.TO, addressTo);
             msg.setSubject(mailprops.get("com.att.dmaap.datarouter.mail.subject").toString());
             htmlPart.setContent(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
             msg.addRecipients(Message.RecipientType.TO, addressTo);
             msg.setSubject(mailprops.get("com.att.dmaap.datarouter.mail.subject").toString());
             htmlPart.setContent(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
-                .replace("[SERVER]", InetAddress.getLocalHost().getHostName()), "text/html");
+                    .replace("[SERVER]", InetAddress.getLocalHost().getHostName()), "text/html");
             mp.addBodyPart(htmlPart);
             msg.setContent(mp);
 
             System.out.println(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
             mp.addBodyPart(htmlPart);
             msg.setContent(mp);
 
             System.out.println(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
-                .replace("[SERVER]", InetAddress.getLocalHost().getHostName()));
+                    .replace("[SERVER]", InetAddress.getLocalHost().getHostName()));
 
             Transport.send(msg);
             intlogger.info("HTTPS relaxation mail is sent to - : " + email);
 
 
             Transport.send(msg);
             intlogger.info("HTTPS relaxation mail is sent to - : " + email);
 
-        } catch (AddressException e) {
-            intlogger.error("Invalid email address, unable to send https relaxation mail to - : " + email);
         } catch (MessagingException e) {
             intlogger.error("Invalid email address, unable to send https relaxation mail to - : " + email);
         }
         } catch (MessagingException e) {
             intlogger.error("Invalid email address, unable to send https relaxation mail to - : " + email);
         }
@@ -636,6 +664,16 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         return nodes;
     }
 
         return nodes;
     }
 
+    /**
+     * [DATARTR-27] Poke all the DR nodes
+     * Get an array of all node names in the DR network.
+     *
+     * @return an array of Strings
+     */
+    public static String[] getDRNodes() {
+        return drnodes;
+    }
+
     /**
      * Get an array of all node InetAddresses in the DR network.
      *
     /**
      * Get an array of all node InetAddresses in the DR network.
      *
@@ -981,7 +1019,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         setMDC(req, "X-InvocationID", "InvocationId");
     }
 
         setMDC(req, "X-InvocationID", "InvocationId");
     }
 
-    void setMDC(HttpServletRequest req, String headerName, String keyName) {
+    private void setMDC(HttpServletRequest req, String headerName, String keyName) {
         String mdcId = req.getHeader(headerName);
         if (StringUtils.isBlank(mdcId)) {
             mdcId = UUID.randomUUID().toString();
         String mdcId = req.getHeader(headerName);
         if (StringUtils.isBlank(mdcId)) {
             mdcId = UUID.randomUUID().toString();
@@ -1004,4 +1042,95 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         }
 
     }
         }
 
     }
+
+    /*
+     * AAF changes: TDP EPIC US# 307413
+     * @Method - getFeedPermission - Forming permission string for feed part to check AAF access in CADI Framework
+     * @Params - aafInstance Passing aafInstance as it's used in permission string
+     * @Params - userAction Passing CONST values to set different actions in permission string
+     */
+    String getFeedPermission(String aafInstance, String userAction) {
+        try {
+            Properties props = (new DB()).getProperties();
+            String type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
+            String action;
+            switch (userAction) {
+                case CREATE_PERMISSION:
+                    action = CREATE_PERMISSION;
+                    break;
+                case EDIT_PERMISSION:
+                    action = EDIT_PERMISSION;
+                    break;
+                case DELETE_PERMISSION:
+                    action = DELETE_PERMISSION;
+                    break;
+                case PUBLISH_PERMISSION:
+                    action = PUBLISH_PERMISSION;
+                    break;
+                case SUSPEND_PERMISSION:
+                    action = SUSPEND_PERMISSION;
+                    break;
+                case RESTORE_PERMISSION:
+                    action = RESTORE_PERMISSION;
+                    break;
+                default:
+                    action = "*";
+            }
+            if (aafInstance == null || aafInstance.equals("")) {
+                aafInstance = props.getProperty(AAF_INSTANCE, "org.onap.dmaap-dr.NoInstanceDefined");
+            }
+            return type + "|" + aafInstance + "|" + action;
+        } catch (Exception e) {
+            intlogger.error("PROV7005 BaseServlet.getFeedPermission: ", e);
+        }
+        return null;
+    }
+
+    /*
+     * AAF changes: TDP EPIC US# 307413
+     * @Method - getSubscriberPermission - Forming permission string for subscription part to check AAF access in CADI Framework
+     * @Params - aafInstance Passing aafInstance as it's used in permission string
+     * @Params - userAction Passing CONST values to set different actions in permission string
+     */
+    String getSubscriberPermission(String aafInstance, String userAction) {
+        try {
+            Properties props = (new DB()).getProperties();
+            String type = props.getProperty(AAF_CADI_SUB_TYPE, AAF_CADI_SUB);
+            String action;
+            switch (userAction) {
+                case SUBSCRIBE_PERMISSION:
+                    action = SUBSCRIBE_PERMISSION;
+                    type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
+                    break;
+                case EDIT_PERMISSION:
+                    action = EDIT_PERMISSION;
+                    break;
+                case DELETE_PERMISSION:
+                    action = DELETE_PERMISSION;
+                    break;
+                case RESTORE_PERMISSION:
+                    action = RESTORE_PERMISSION;
+                    break;
+                case SUSPEND_PERMISSION:
+                    action = SUSPEND_PERMISSION;
+                    break;
+                case PUBLISH_PERMISSION:
+                    action = PUBLISH_PERMISSION;
+                    break;
+                case APPROVE_SUB_PERMISSION:
+                    action = APPROVE_SUB_PERMISSION;
+                    type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
+                    break;
+                default:
+                    action = "*";
+            }
+            if (aafInstance == null || aafInstance.equals("")) {
+                aafInstance = props.getProperty(AAF_INSTANCE, "org.onap.dmaap-dr.NoInstanceDefined");
+            }
+            return type + "|" + aafInstance + "|" + action;
+        } catch (Exception e) {
+            intlogger.error("PROV7005 BaseServlet.getSubscriberPermission: ", e);
+        }
+        return null;
+    }
 }
 }
index 895eba0..9bc9162 100644 (file)
 
 package org.onap.dmaap.datarouter.provisioning;
 
 
 package org.onap.dmaap.datarouter.provisioning;
 
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
 import org.json.JSONObject;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;
 import org.json.JSONObject;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;
@@ -38,8 +33,11 @@ import org.onap.dmaap.datarouter.provisioning.beans.Feed;
 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;
 import org.onap.dmaap.datarouter.provisioning.utils.JSONUtilities;
 
 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;
 import org.onap.dmaap.datarouter.provisioning.utils.JSONUtilities;
 
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.util.List;
 
 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
 
 
 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
 
@@ -55,7 +53,7 @@ public class DRFeedsServlet extends ProxyServlet {
 
     //Adding EELF Logger Rally:US664892
     private static EELFLogger eelflogger = EELFManager.getInstance()
 
     //Adding EELF Logger Rally:US664892
     private static EELFLogger eelflogger = EELFManager.getInstance()
-        .getLogger(DRFeedsServlet.class);
+            .getLogger(DRFeedsServlet.class);
 
     /**
      * DELETE on the &lt;drFeedsURL&gt; -- not supported.
 
     /**
      * DELETE on the &lt;drFeedsURL&gt; -- not supported.
@@ -109,8 +107,8 @@ public class DRFeedsServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
-            String path = req
-                    .getRequestURI(); // Note: I think this should be getPathInfo(), but that doesn't work (Jetty bug?)
+            // Note: I think this should be getPathInfo(), but that doesn't work (Jetty bug?)
+            String path = req.getRequestURI();
             if (path != null && !path.equals("/")) {
                 message = "Bad URL.";
                 elr.setMessage(message);
             if (path != null && !path.equals("/")) {
                 message = "Bad URL.";
                 elr.setMessage(message);
@@ -236,8 +234,8 @@ public class DRFeedsServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
-            String path = req
-                    .getRequestURI(); // Note: I think this should be getPathInfo(), but that doesn't work (Jetty bug?)
+            // Note: I think this should be getPathInfo(), but that doesn't work (Jetty bug?)
+            String path = req.getRequestURI();
             if (path != null && !path.equals("/")) {
                 message = "Bad URL.";
                 elr.setMessage(message);
             if (path != null && !path.equals("/")) {
                 message = "Bad URL.";
                 elr.setMessage(message);
@@ -257,16 +255,6 @@ public class DRFeedsServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
                 return;
             }
-            // Check with the Authorizer
-            AuthorizationResponse aresp = authz.decide(req);
-            if (!aresp.isAuthorized()) {
-                message = "Policy Engine disallows access.";
-                elr.setMessage(message);
-                elr.setResult(HttpServletResponse.SC_FORBIDDEN);
-                eventlogger.info(elr);
-                sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
-                return;
-            }
             JSONObject jo = getJSONfromInput(req);
             if (jo == null) {
                 message = "Badly formed JSON";
             JSONObject jo = getJSONfromInput(req);
             if (jo == null) {
                 message = "Badly formed JSON";
@@ -288,7 +276,7 @@ public class DRFeedsServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_CONFLICT, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_CONFLICT, message, eventlogger);
                 return;
             }
-            Feed feed = null;
+            Feed feed;
             try {
                 feed = new Feed(jo);
             } catch (InvalidObjectException e) {
             try {
                 feed = new Feed(jo);
             } catch (InvalidObjectException e) {
@@ -299,6 +287,60 @@ public class DRFeedsServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
+
+            /*
+             * START - AAF changes
+             * TDP EPIC US# 307413
+             * CADI code - No legacy user check as all new users will be AAF users
+             */
+            String aafInstance = feed.getAafInstance();
+            if (Boolean.parseBoolean(isCadiEnabled)) {
+                if ((aafInstance == null || aafInstance.equals("") || (aafInstance.equalsIgnoreCase("legacy")) && req.getHeader(EXCLUDE_AAF_HEADER).equalsIgnoreCase("true"))) {
+                    // Check with the Authorizer
+                    AuthorizationResponse aresp = authz.decide(req);
+                    if (!aresp.isAuthorized()) {
+                        message = "Policy Engine disallows access.";
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                        eventlogger.info(elr);
+                        sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                        return;
+                    }
+                } else {
+                    if (req.getHeader(EXCLUDE_AAF_HEADER).equalsIgnoreCase("true")) {
+                        message = "DRFeedsServlet.doPost() -Invalid request exclude_AAF should not be true if passing AAF_Instance value= " + aafInstance;
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                        eventlogger.info(elr);
+                        sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                        return;
+                    }
+                    String permission = getFeedPermission(aafInstance, BaseServlet.CREATE_PERMISSION);
+                    eventlogger.info("DRFeedsServlet.doPost().. Permission String - " + permission);
+                    if (!req.isUserInRole(permission)) {
+                        message = "AAF disallows access to permission - " + permission;
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                        eventlogger.info(elr);
+                        sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                        return;
+                    }
+                }
+            } else {
+                AuthorizationResponse aresp = authz.decide(req);
+                if (!aresp.isAuthorized()) {
+                    message = "Policy Engine disallows access.";
+                    elr.setMessage(message);
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                    eventlogger.info(elr);
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                    return;
+                }
+            }
+            /*
+             * END - AAF changes
+             */
+
             feed.setPublisher(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header
 
             // Check if this feed already exists
             feed.setPublisher(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header
 
             // Check if this feed already exists
index e64f2c6..4ab3ef4 100644 (file)
@@ -107,17 +107,37 @@ public class FeedServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
                 return;
             }
-            // Check with the Authorizer
-            AuthorizationResponse aresp = authz.decide(req);
-            if (! aresp.isAuthorized()) {
-                message = "Policy Engine disallows access.";
-                elr.setMessage(message);
-                elr.setResult(HttpServletResponse.SC_FORBIDDEN);
-                eventlogger.info(elr);
-                sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
-                return;
+            /*
+             * START - AAF changes
+             * TDP EPIC US# 307413
+             * CADI code - check on permissions based on Legacy/AAF users to allow to delete/remove feed
+             */
+            String aafInstance = feed.getAafInstance();
+            if (aafInstance == null || aafInstance.equals("") || aafInstance.equalsIgnoreCase("legacy")) {
+                AuthorizationResponse aresp = authz.decide(req);
+                if (! aresp.isAuthorized()) {
+                    message = "Policy Engine disallows access.";
+                    elr.setMessage(message);
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                    eventlogger.info(elr);
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                    return;
+                }
+            } else {
+                String permission = getFeedPermission(aafInstance, BaseServlet.DELETE_PERMISSION);
+                eventlogger.info("FeedServlet.doDelete().. Permission String - " + permission);
+                if (!req.isUserInRole(permission)) {
+                    message = "AAF disallows access to permission - " + permission;
+                    elr.setMessage(message);
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                    eventlogger.info(elr);
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                    return;
+                }
             }
             }
-
+            /*
+             * END - AAF changes
+             */
             // Delete FEED table entry (set DELETED flag)
             feed.setDeleted(true);
             if (doUpdate(feed)) {
             // Delete FEED table entry (set DELETED flag)
             feed.setDeleted(true);
             if (doUpdate(feed)) {
@@ -286,7 +306,7 @@ public class FeedServlet extends ProxyServlet {
             }
             if (intlogger.isDebugEnabled())
                 intlogger.debug(jo.toString());
             }
             if (intlogger.isDebugEnabled())
                 intlogger.debug(jo.toString());
-            Feed feed = null;
+            Feed feed;
             try {
                 feed = new Feed(jo);
             } catch (InvalidObjectException e) {
             try {
                 feed = new Feed(jo);
             } catch (InvalidObjectException e) {
@@ -317,24 +337,50 @@ public class FeedServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
                 return;
             }
-            if (!oldFeed.getVersion().equals(feed.getVersion())) {
-                message = "The version of the feed may not be updated.";
-                elr.setMessage(message);
-                elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
-                eventlogger.info(elr);
-                sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
-                return;
+            //  US DSCDR-19 for DCAE if version is not null, version can't be changed
+            if ((oldFeed.getVersion() != null) && (feed.getVersion() != null)) {
+                if (!oldFeed.getVersion().equals(feed.getVersion())) {
+                    message = "The version of the feed may not be updated.";
+                    elr.setMessage(message);
+                    elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
+                    eventlogger.info(elr);
+                    sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
+                    return;
+                }
             }
             }
-            // Check with the Authorizer
-            AuthorizationResponse aresp = authz.decide(req);
-            if (! aresp.isAuthorized()) {
-                message = "Policy Engine disallows access.";
-                elr.setMessage(message);
-                elr.setResult(HttpServletResponse.SC_FORBIDDEN);
-                eventlogger.info(elr);
-                sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
-                return;
+
+            /*
+             * START - AAF changes
+             * TDP EPIC US# 307413
+             * CADI code - check on permissions based on Legacy/AAF users to allow feed edit/update/modify
+             */
+            String aafInstance = feed.getAafInstance();
+            if (aafInstance == null || aafInstance.equals("") || aafInstance.equalsIgnoreCase("legacy")) {
+                // Check with the Authorizer
+                AuthorizationResponse aresp = authz.decide(req);
+                if (!aresp.isAuthorized()) {
+                    message = "Policy Engine disallows access.";
+                    elr.setMessage(message);
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                    eventlogger.info(elr);
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                    return;
+                }
+            } else {
+                String permission = getFeedPermission(aafInstance, BaseServlet.EDIT_PERMISSION);
+                eventlogger.info("FeedServlet.doPut().. Permission String - " + permission);
+                if (!req.isUserInRole(permission)) {
+                    message = "AAF disallows access to permission - " + permission;
+                    elr.setMessage(message);
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                    eventlogger.info(elr);
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                    return;
+                }
             }
             }
+            /*
+             * END - AAF changes
+             */
 
             // Update FEEDS table entries
             if (doUpdate(feed)) {
 
             // Update FEEDS table entries
             if (doUpdate(feed)) {
index 651d731..1bd3cbf 100644 (file)
 
 package org.onap.dmaap.datarouter.provisioning;
 
 
 package org.onap.dmaap.datarouter.provisioning;
 
-import java.security.*;
-import java.util.*;
-
 import org.apache.log4j.Logger;
 import org.eclipse.jetty.http.HttpVersion;
 import org.apache.log4j.Logger;
 import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.NCSARequestLog;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.*;
 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
 import org.eclipse.jetty.server.handler.DefaultHandler;
 import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.server.handler.RequestLogHandler;
 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
 import org.eclipse.jetty.server.handler.DefaultHandler;
 import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.server.handler.RequestLogHandler;
-import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.util.thread.QueuedThreadPool;
 import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.onap.dmaap.datarouter.provisioning.utils.DB;
-import org.onap.dmaap.datarouter.provisioning.utils.LogfileLoader;
-import org.onap.dmaap.datarouter.provisioning.utils.PurgeLogDirTask;
-import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.dmaap.datarouter.provisioning.utils.*;
 
 import javax.servlet.DispatcherType;
 
 import javax.servlet.DispatcherType;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Security;
+import java.util.EnumSet;
+import java.util.Properties;
+import java.util.Timer;
 
 /**
  * <p>
 
 /**
  * <p>
@@ -87,18 +81,31 @@ public class Main {
     /**
      * The truststore to use if none is specified
      */
     /**
      * The truststore to use if none is specified
      */
-    public static final String DEFAULT_TRUSTSTORE = "/opt/java/jdk/jdk180/jre/lib/security/cacerts";
-    public static final String KEYSTORE_TYPE_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.type";
-    public static final String KEYSTORE_PATH_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.path";
-    public static final String KEYSTORE_PASS_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.password";
-    public static final String TRUSTSTORE_PATH_PROPERTY = "org.onap.dmaap.datarouter.provserver.truststore.path";
-    public static final String TRUSTSTORE_PASS_PROPERTY = "org.onap.dmaap.datarouter.provserver.truststore.password";
+    static final String DEFAULT_TRUSTSTORE = "/opt/java/jdk/jdk180/jre/lib/security/cacerts";
+    static final String KEYSTORE_TYPE_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.type";
+    static final String KEYSTORE_PATH_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.path";
+    static final String KEYSTORE_PASS_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.password";
+    static final String TRUSTSTORE_PATH_PROPERTY = "org.onap.dmaap.datarouter.provserver.truststore.path";
+    static final String TRUSTSTORE_PASS_PROPERTY = "org.onap.dmaap.datarouter.provserver.truststore.password";
+    public static final Logger intlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");
 
     /**
      * The one and only {@link Server} instance in this JVM
      */
     private static Server server;
 
 
     /**
      * The one and only {@link Server} instance in this JVM
      */
     private static Server server;
 
+    class Inner {
+        InputStream getCadiProps() {
+            InputStream in = null;
+            try {
+                in = getClass().getClassLoader().getResourceAsStream("drProvCadi.properties");
+            } catch (Exception e) {
+                intlogger.error("Exception in Main.getCadiProps() method ", e);
+            }
+            return in;
+        }
+    }
+
     /**
      * Starts the Data Router Provisioning server.
      *
     /**
      * Starts the Data Router Provisioning server.
      *
@@ -106,29 +113,19 @@ public class Main {
      * @throws Exception if Jetty has a problem starting
      */
     public static void main(String[] args) throws Exception {
      * @throws Exception if Jetty has a problem starting
      */
     public static void main(String[] args) throws Exception {
-        Security.setProperty("networkaddress.cache.ttl", "4");
-        Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");
+        // Get prov properties
+        Properties provProperties = (new DB()).getProperties();
 
         // Check DB is accessible and contains the expected tables
         if (!checkDatabase()) {
             System.exit(1);
         }
 
 
         // Check DB is accessible and contains the expected tables
         if (!checkDatabase()) {
             System.exit(1);
         }
 
-        logger.info("PROV0000 **** AT&T Data Router Provisioning Server starting....");
+        intlogger.info("PROV0000 **** AT&T Data Router Provisioning Server starting....");
 
 
-        // Get properties
-        Properties p = (new DB()).getProperties();
-        int httpPort = Integer.parseInt(p.getProperty("org.onap.dmaap.datarouter.provserver.http.port", "8080"));
-        int httpsPort = Integer.parseInt(p.getProperty("org.onap.dmaap.datarouter.provserver.https.port", "8443"));
-
-        // HTTP configuration
-        HttpConfiguration httpConfiguration = new HttpConfiguration();
-        httpConfiguration.setSecureScheme("https");
-        httpConfiguration.setSecurePort(httpsPort);
-        httpConfiguration.setOutputBufferSize(32768);
-        httpConfiguration.setRequestHeaderSize(2048);
-        httpConfiguration.setSendServerVersion(true);
-        httpConfiguration.setSendDateHeader(false);
+        Security.setProperty("networkaddress.cache.ttl", "4");
+        int httpPort = Integer.parseInt(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.http.port", "8080"));
+        int httpsPort = Integer.parseInt(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.https.port", "8443"));
 
         // Server's thread pool
         QueuedThreadPool queuedThreadPool = new QueuedThreadPool();
 
         // Server's thread pool
         QueuedThreadPool queuedThreadPool = new QueuedThreadPool();
@@ -138,121 +135,155 @@ public class Main {
 
         // The server itself
         server = new Server(queuedThreadPool);
 
         // The server itself
         server = new Server(queuedThreadPool);
+        server.setStopAtShutdown(true);
+        server.setStopTimeout(5000);
+        server.setDumpAfterStart(false);
+        server.setDumpBeforeStop(false);
+
+        // Request log configuration
+        NCSARequestLog ncsaRequestLog = new NCSARequestLog();
+        ncsaRequestLog.setFilename(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir") + "/request.log.yyyy_mm_dd");
+        ncsaRequestLog.setFilenameDateFormat("yyyyMMdd");
+        ncsaRequestLog.setRetainDays(90);
+        ncsaRequestLog.setAppend(true);
+        ncsaRequestLog.setExtended(false);
+        ncsaRequestLog.setLogCookies(false);
+        ncsaRequestLog.setLogTimeZone("GMT");
+
+        RequestLogHandler requestLogHandler = new RequestLogHandler();
+        requestLogHandler.setRequestLog(ncsaRequestLog);
+        server.setRequestLog(ncsaRequestLog);
+
+        // HTTP configuration
+        HttpConfiguration httpConfiguration = new HttpConfiguration();
+        httpConfiguration.setSecureScheme("https");
+        httpConfiguration.setSecurePort(httpsPort);
+        httpConfiguration.setOutputBufferSize(32768);
+        httpConfiguration.setRequestHeaderSize(8192);
+        httpConfiguration.setResponseHeaderSize(8192);
+        httpConfiguration.setSendServerVersion(true);
+        httpConfiguration.setSendDateHeader(false);
 
 
-        // HTTP connector
-        HandlerCollection hc;
-        try (ServerConnector httpServerConnector = new ServerConnector(server,
-            new HttpConnectionFactory(httpConfiguration))) {
+        //HTTP Connector
+        HandlerCollection handlerCollection;
+        try (ServerConnector httpServerConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration))) {
             httpServerConnector.setPort(httpPort);
             httpServerConnector.setAcceptQueueSize(2);
             httpServerConnector.setIdleTimeout(300000);
 
             httpServerConnector.setPort(httpPort);
             httpServerConnector.setAcceptQueueSize(2);
             httpServerConnector.setIdleTimeout(300000);
 
+            // SSL Context
+            SslContextFactory sslContextFactory = new SslContextFactory();
+            sslContextFactory.setKeyStoreType(provProperties.getProperty(KEYSTORE_TYPE_PROPERTY, "jks"));
+            sslContextFactory.setKeyStorePath(provProperties.getProperty(KEYSTORE_PATH_PROPERTY));
+            sslContextFactory.setKeyStorePassword(provProperties.getProperty(KEYSTORE_PASS_PROPERTY));
+            sslContextFactory.setKeyManagerPassword(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.keymanager.password"));
+
+            String ts = provProperties.getProperty(TRUSTSTORE_PATH_PROPERTY);
+            if (ts != null && ts.length() > 0) {
+                intlogger.info("@@ TS -> " + ts);
+                sslContextFactory.setTrustStorePath(ts);
+                sslContextFactory.setTrustStorePassword(provProperties.getProperty(TRUSTSTORE_PASS_PROPERTY));
+            } else {
+                sslContextFactory.setTrustStorePath(DEFAULT_TRUSTSTORE);
+                sslContextFactory.setTrustStorePassword("changeit");
+            }
+
+            sslContextFactory.setWantClientAuth(true);
+            sslContextFactory.setExcludeCipherSuites(
+                    "SSL_RSA_WITH_DES_CBC_SHA",
+                    "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+                    "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+                    "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+                    "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
+            );
+            sslContextFactory.addExcludeProtocols("SSLv3");
+            sslContextFactory.setIncludeProtocols(provProperties.getProperty(
+                    "org.onap.dmaap.datarouter.provserver.https.include.protocols", "TLSv1.1|TLSv1.2").trim().split("\\|"));
+
+            intlogger.info("Not supported protocols prov server:-" + String.join(",", sslContextFactory.getExcludeProtocols()));
+            intlogger.info("Supported protocols prov server:-" + String.join(",", sslContextFactory.getIncludeProtocols()));
+            intlogger.info("Not supported ciphers prov server:-" + String.join(",", sslContextFactory.getExcludeCipherSuites()));
+            intlogger.info("Supported ciphers prov server:-" + String.join(",", sslContextFactory.getIncludeCipherSuites()));
+
             // HTTPS configuration
             HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
             httpsConfiguration.setRequestHeaderSize(8192);
 
             // HTTPS connector
             // HTTPS configuration
             HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
             httpsConfiguration.setRequestHeaderSize(8192);
 
             // HTTPS connector
-            SslContextFactory sslContextFactory = new SslContextFactory();
-            sslContextFactory.setKeyStorePath(p.getProperty(KEYSTORE_PATH_PROPERTY));
-            sslContextFactory.setKeyStorePassword(p.getProperty(KEYSTORE_PASS_PROPERTY));
-            sslContextFactory
-                    .setKeyManagerPassword(p.getProperty("org.onap.dmaap.datarouter.provserver.keymanager.password"));
-            // SSL stuff
-            /* Skip SSLv3 Fixes */
-            sslContextFactory.addExcludeProtocols("SSLv3");
-            logger.info("Excluded protocols prov-" + Arrays.toString(sslContextFactory.getExcludeProtocols()));
-            /* End of SSLv3 Fixes */
-
             try (ServerConnector httpsServerConnector = new ServerConnector(server,
                     new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                     new HttpConnectionFactory(httpsConfiguration))) {
             try (ServerConnector httpsServerConnector = new ServerConnector(server,
                     new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                     new HttpConnectionFactory(httpsConfiguration))) {
+
                 httpsServerConnector.setPort(httpsPort);
                 httpsServerConnector.setIdleTimeout(30000);
                 httpsServerConnector.setAcceptQueueSize(2);
 
                 httpsServerConnector.setPort(httpsPort);
                 httpsServerConnector.setIdleTimeout(30000);
                 httpsServerConnector.setAcceptQueueSize(2);
 
-                sslContextFactory.setKeyStoreType(p.getProperty(KEYSTORE_TYPE_PROPERTY, "jks"));
-                sslContextFactory.setKeyStorePath(p.getProperty(KEYSTORE_PATH_PROPERTY));
-                sslContextFactory.setKeyStorePassword(p.getProperty(KEYSTORE_PASS_PROPERTY));
-                sslContextFactory
-                        .setKeyManagerPassword(p.getProperty("org.onap.dmaap.datarouter.provserver.keymanager.password"));
-
-                String ts = p.getProperty(TRUSTSTORE_PATH_PROPERTY);
-                if (ts != null && ts.length() > 0) {
-                    logger.info("@@ TS -> " + ts);
-                    sslContextFactory.setTrustStorePath(ts);
-                    sslContextFactory.setTrustStorePassword(p.getProperty(TRUSTSTORE_PASS_PROPERTY));
-                } else {
-                    sslContextFactory.setTrustStorePath(DEFAULT_TRUSTSTORE);
-                    sslContextFactory.setTrustStorePassword("changeit");
+                // Servlet and Filter configuration
+                ServletContextHandler servletContextHandler = new ServletContextHandler(0);
+                servletContextHandler.setContextPath("/");
+                servletContextHandler.addServlet(new ServletHolder(new FeedServlet()), "/feed/*");
+                servletContextHandler.addServlet(new ServletHolder(new FeedLogServlet()), "/feedlog/*");
+                servletContextHandler.addServlet(new ServletHolder(new PublishServlet()), "/publish/*");
+                servletContextHandler.addServlet(new ServletHolder(new SubscribeServlet()), "/subscribe/*");
+                servletContextHandler.addServlet(new ServletHolder(new StatisticsServlet()), "/statistics/*");
+                servletContextHandler.addServlet(new ServletHolder(new SubLogServlet()), "/sublog/*");
+                servletContextHandler.addServlet(new ServletHolder(new GroupServlet()), "/group/*");
+                servletContextHandler.addServlet(new ServletHolder(new SubscriptionServlet()), "/subs/*");
+                servletContextHandler.addServlet(new ServletHolder(new InternalServlet()), "/internal/*");
+                servletContextHandler.addServlet(new ServletHolder(new RouteServlet()), "/internal/route/*");
+                servletContextHandler.addServlet(new ServletHolder(new DRFeedsServlet()), "/");
+                servletContextHandler.addFilter(new FilterHolder(new ThrottleFilter()), "/publish/*", EnumSet.of(DispatcherType.REQUEST));
+
+                //CADI Filter activation check
+                if (Boolean.parseBoolean(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.cadi.enabled", "false"))) {
+                    //Get cadi properties
+                    Properties cadiProperties = null;
+                    try {
+                        intlogger.info("PROV0001 Prov - Loading CADI properties");
+                        cadiProperties = new Properties();
+                        Inner obj = new Main().new Inner();
+                        InputStream in = obj.getCadiProps();
+                        cadiProperties.load(in);
+                    } catch (IOException e1) {
+                        intlogger.error("PROV0001 Exception loading CADI properties", e1);
+                    }
+                    cadiProperties.setProperty("aaf_locate_url", provProperties.getProperty("org.onap.dmaap.datarouter.provserver.cadi.aaf.url", "https://aaf-onap-test.osaaf.org:8095"));
+                    intlogger.info("PROV0001  aaf_url set to - " + cadiProperties.getProperty("aaf_url"));
+
+                    PropAccess access = new PropAccess(cadiProperties);
+                    servletContextHandler.addFilter(new FilterHolder(new DRProvCadiFilter(true, access)), "/*", EnumSet.of(DispatcherType.REQUEST));
                 }
                 }
-                sslContextFactory.setWantClientAuth(true);
 
 
-                // Servlet and Filter configuration
-                ServletContextHandler ctxt = new ServletContextHandler(0);
-                ctxt.setContextPath("/");
-                ctxt.addServlet(new ServletHolder(new FeedServlet()), "/feed/*");
-                ctxt.addServlet(new ServletHolder(new FeedLogServlet()), "/feedlog/*");
-                ctxt.addServlet(new ServletHolder(new PublishServlet()), "/publish/*");
-                ctxt.addServlet(new ServletHolder(new SubscribeServlet()), "/subscribe/*");
-                ctxt.addServlet(new ServletHolder(new StatisticsServlet()), "/statistics/*");
-                ctxt.addServlet(new ServletHolder(new SubLogServlet()), "/sublog/*");
-                ctxt.addServlet(new ServletHolder(new GroupServlet()),
-                        "/group/*"); //Provision groups - Rally US708115 -1610
-                ctxt.addServlet(new ServletHolder(new SubscriptionServlet()), "/subs/*");
-                ctxt.addServlet(new ServletHolder(new InternalServlet()), "/internal/*");
-                ctxt.addServlet(new ServletHolder(new RouteServlet()), "/internal/route/*");
-                ctxt.addServlet(new ServletHolder(new DRFeedsServlet()), "/");
-                ctxt.addFilter(new FilterHolder(new ThrottleFilter()), "/publish/*", EnumSet.of(DispatcherType.REQUEST));
-
-                ContextHandlerCollection contexts = new ContextHandlerCollection();
-                contexts.addHandler(ctxt);
-
-                // Request log configuration
-                NCSARequestLog nrl = new NCSARequestLog();
-                nrl.setFilename(
-                        p.getProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir") + "/request.log.yyyy_mm_dd");
-                nrl.setFilenameDateFormat("yyyyMMdd");
-                nrl.setRetainDays(90);
-                nrl.setAppend(true);
-                nrl.setExtended(false);
-                nrl.setLogCookies(false);
-                nrl.setLogTimeZone("GMT");
-
-                RequestLogHandler reqlog = new RequestLogHandler();
-                reqlog.setRequestLog(nrl);
+                ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
+                contextHandlerCollection.addHandler(servletContextHandler);
 
                 // Server's Handler collection
 
                 // Server's Handler collection
-                hc = new HandlerCollection();
-                hc.setHandlers(new Handler[]{contexts, new DefaultHandler()});
-                hc.addHandler(reqlog);
-
-                // Daemon to clean up the log directory on a daily basis
-                Timer rolex = new Timer();
-                rolex.scheduleAtFixedRate(new PurgeLogDirTask(), 0, 86400000L);    // run once per day
-
-                // Start LogfileLoader
-                LogfileLoader.getLoader();
-
-                try (ServerConnector serverConnector = new ServerConnector(server,
-                        new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
-                        new HttpConnectionFactory(httpsConfiguration))) {
-                    serverConnector.setPort(httpsPort);
-                    serverConnector.setIdleTimeout(500000);
-                }
+                handlerCollection = new HandlerCollection();
+                handlerCollection.setHandlers(new Handler[]{contextHandlerCollection, new DefaultHandler()});
+                handlerCollection.addHandler(requestLogHandler);
 
                 server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
             }
         }
 
                 server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
             }
         }
-        server.setHandler(hc);
-        server.setStopAtShutdown(true);
-        server.setStopTimeout(5000);
+        server.setHandler(handlerCollection);
 
 
-        server.setDumpAfterStart(false);
-        server.setDumpBeforeStop(false);
+        // Daemon to clean up the log directory on a daily basis
+        Timer rolex = new Timer();
+        rolex.scheduleAtFixedRate(new PurgeLogDirTask(), 0, 86400000L);    // run once per day
+
+        // Start LogfileLoader
+        LogfileLoader.getLoader();
 
 
-        server.start();
+        try {
+            server.start();
+            intlogger.info("Prov Server started-" + server.getState());
+        } catch (Exception e) {
+            intlogger.info("Jetty failed to start. Reporting will we unavailable", e);
+        }
         server.join();
         server.join();
-        logger.info("PROV0001 **** AT&T Data Router Provisioning Server halted.");
+        intlogger.info("PROV0001 **** AT&T Data Router Provisioning Server halted.");
     }
 
     private static boolean checkDatabase() {
     }
 
     private static boolean checkDatabase() {
@@ -270,7 +301,7 @@ public class Main {
                 Thread.sleep(5000L);
                 System.exit(0);
             } catch (Exception e) {
                 Thread.sleep(5000L);
                 System.exit(0);
             } catch (Exception e) {
-                // ignore
+                intlogger.error("Exception in Main.shutdown() method " + e);
             }
         });
     }
             }
         });
     }
index 2127f00..35ce062 100644 (file)
@@ -128,17 +128,6 @@ public class SubscribeServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
                 return;
             }
-            // Check with the Authorizer
-            AuthorizationResponse aresp = authz.decide(req);
-            if (!aresp.isAuthorized()) {
-                message = "Policy Engine disallows access.";
-                elr.setMessage(message);
-                elr.setResult(HttpServletResponse.SC_FORBIDDEN);
-                eventlogger.info(elr);
-                sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
-                return;
-            }
-
             // Display a list of URLs
             Collection<String> list = Subscription.getSubscriptionUrlList(feedid);
             String t = JSONUtilities.createJSONArray(list);
             // Display a list of URLs
             Collection<String> list = Subscription.getSubscriptionUrlList(feedid);
             String t = JSONUtilities.createJSONArray(list);
@@ -228,17 +217,6 @@ public class SubscribeServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
                 return;
             }
-            // Check with the Authorizer
-            AuthorizationResponse aresp = authz.decide(req);
-            if (!aresp.isAuthorized()) {
-                message = "Policy Engine disallows access.";
-                elr.setMessage(message);
-                elr.setResult(HttpServletResponse.SC_FORBIDDEN);
-                eventlogger.info(elr);
-                sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
-                return;
-            }
-
             // check content type is SUB_CONTENT_TYPE, version 1.0
             ContentHeader ch = getContentHeader(req);
             String ver = ch.getAttribute("version");
             // check content type is SUB_CONTENT_TYPE, version 1.0
             ContentHeader ch = getContentHeader(req);
             String ver = ch.getAttribute("version");
@@ -272,7 +250,7 @@ public class SubscribeServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_CONFLICT, message, eventlogger);
                 return;
             }
                 sendResponseError(resp, HttpServletResponse.SC_CONFLICT, message, eventlogger);
                 return;
             }
-            Subscription sub = null;
+            Subscription sub;
             try {
                 sub = new Subscription(jo);
             } catch (InvalidObjectException e) {
             try {
                 sub = new Subscription(jo);
             } catch (InvalidObjectException e) {
@@ -286,13 +264,70 @@ public class SubscribeServlet extends ProxyServlet {
             }
             sub.setFeedid(feedid);
             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header
             }
             sub.setFeedid(feedid);
             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header
+            /*
+             * START - AAF changes
+             * TDP EPIC US# 307413
+             * CADI code - check on permissions based on Legacy/AAF users to allow to create/add subscription
+             */
+            String feedAafInstance = feed.getAafInstance();
+            String subAafInstance = sub.getAafInstance();
+            boolean subAafLegacyEmptyOrNull = (subAafInstance == null || subAafInstance.equals("") || subAafInstance.equalsIgnoreCase("legacy"));
 
 
+            // This extra check added to verify AAF feed with AAF subscriber having empty aaf instance check
+            if (feedAafInstance == null || feedAafInstance.equals("") || feedAafInstance.equalsIgnoreCase("legacy")) {
+                if (subAafLegacyEmptyOrNull) {
+                    AuthorizationResponse aresp = authz.decide(req);
+                    if (!aresp.isAuthorized()) {
+                        message = "Policy Engine disallows access";
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                        eventlogger.info(elr);
+                        sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                        return;
+                    }
+                } else {
+                    //If Legacy Feed and AAF instance provided in Subscriber JSON
+                    message = "AAF Subscriber can not be added to legacy Feed- " + feedid;
+                    elr.setMessage(message);
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                    eventlogger.info(elr);
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                    return;
+                }
+            } else {
+                //New AAF Requirement to add legacy subscriber to AAF Feed
+                if (subAafLegacyEmptyOrNull) {
+                    AuthorizationResponse aresp = authz.decide(req);
+                    if (!aresp.isAuthorized()) {
+                        message = "Policy Engine disallows access.";
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                        eventlogger.info(elr);
+                        sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                        return;
+                    }
+                } else {
+                    //New AAF Requirement to add subscriber by publisher on publisher approval only
+                    String permission = getSubscriberPermission(subAafInstance, BaseServlet.APPROVE_SUB_PERMISSION);
+                    eventlogger.info("SubscribeServlet.doPost().. Permission String - " + permission);
+                    if (!req.isUserInRole(permission)) {
+                        message = "AAF disallows access to permission - " + permission;
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_FORBIDDEN);
+                        eventlogger.info(elr);
+                        sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
+                        return;
+                    }
+                }
+            }
+            /*
+             * END - AAF changes
+             */
             // Check if this subscription already exists; not an error (yet), just warn
             Subscription sub2 = Subscription.getSubscriptionMatching(sub);
             if (sub2 != null) {
                 intlogger.warn(
             // Check if this subscription already exists; not an error (yet), just warn
             Subscription sub2 = Subscription.getSubscriptionMatching(sub);
             if (sub2 != null) {
                 intlogger.warn(
-                    "PROV0011 Creating a duplicate subscription: new subid=" + sub.getSubid() + ", old subid=" + sub2
-                        .getSubid());
+                    "PROV0011 Creating a duplicate subscription: new subid=" + sub.getSubid() + ", old subid=" + sub2.getSubid());
             }
 
             // Create SUBSCRIPTIONS table entries
             }
 
             // Create SUBSCRIPTIONS table entries
index ec4d33a..d7c4657 100644 (file)
@@ -58,7 +58,7 @@ import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.send
 @SuppressWarnings("serial")\r
 public class SubscriptionServlet extends ProxyServlet {\r
 \r
 @SuppressWarnings("serial")\r
 public class SubscriptionServlet extends ProxyServlet {\r
 \r
-    public static final String SUBCNTRL_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription-control";\r
+    private static final String SUBCNTRL_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription-control";\r
     //Adding EELF Logger Rally:US664892\r
     private static EELFLogger eelflogger = EELFManager.getInstance()\r
         .getLogger(SubscriptionServlet.class);\r
     //Adding EELF Logger Rally:US664892\r
     private static EELFLogger eelflogger = EELFManager.getInstance()\r
         .getLogger(SubscriptionServlet.class);\r
@@ -113,17 +113,37 @@ public class SubscriptionServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
                 return;\r
             }\r
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
                 return;\r
             }\r
-            // Check with the Authorizer\r
-            AuthorizationResponse aresp = authz.decide(req);\r
-            if (!aresp.isAuthorized()) {\r
-                message = "Policy Engine disallows access.";\r
-                elr.setMessage(message);\r
-                elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
-                eventlogger.info(elr);\r
-                sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
-                return;\r
+            /*\r
+             * START - AAF changes\r
+             * TDP EPIC US# 307413\r
+             * CADI code - check on permissions based on Legacy/AAF users to allow to delete/remove subscription\r
+             */\r
+            String aafInstance = sub.getAafInstance();\r
+            if (aafInstance == null || aafInstance.equals("") || aafInstance.equalsIgnoreCase("legacy")) {\r
+                AuthorizationResponse aresp = authz.decide(req);\r
+                if (!aresp.isAuthorized()) {\r
+                    message = "Policy Engine disallows access.";\r
+                    elr.setMessage(message);\r
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
+                    eventlogger.info(elr);\r
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
+                    return;\r
+                }\r
+            } else {\r
+                String permission = getSubscriberPermission(aafInstance, BaseServlet.DELETE_PERMISSION);\r
+                eventlogger.info("SubscriptionServlet.doDelete().. Permission String - " + permission);\r
+                if (!req.isUserInRole(permission)) {\r
+                    message = "AAF disallows access to permission - " + permission;\r
+                    elr.setMessage(message);\r
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
+                    eventlogger.info(elr);\r
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
+                    return;\r
+                }\r
             }\r
             }\r
-\r
+            /*\r
+             * END - AAF changes\r
+             */\r
             // Delete Subscription\r
             if (doDelete(sub)) {\r
                 activeSubs--;\r
             // Delete Subscription\r
             if (doDelete(sub)) {\r
                 activeSubs--;\r
@@ -270,16 +290,6 @@ public class SubscriptionServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
                 return;\r
             }\r
                 sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);\r
                 return;\r
             }\r
-            // Check with the Authorizer\r
-            AuthorizationResponse aresp = authz.decide(req);\r
-            if (!aresp.isAuthorized()) {\r
-                message = "Policy Engine disallows access.";\r
-                elr.setMessage(message);\r
-                elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
-                eventlogger.info(elr);\r
-                sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
-                return;\r
-            }\r
             // check content type is SUB_CONTENT_TYPE, version 1.0\r
             ContentHeader ch = getContentHeader(req);\r
             String ver = ch.getAttribute("version");\r
             // check content type is SUB_CONTENT_TYPE, version 1.0\r
             ContentHeader ch = getContentHeader(req);\r
             String ver = ch.getAttribute("version");\r
@@ -314,6 +324,38 @@ public class SubscriptionServlet extends ProxyServlet {
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
                 return;\r
             }\r
                 sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);\r
                 return;\r
             }\r
+\r
+            /*\r
+             * START - AAF changes\r
+             * TDP EPIC US# 307413\r
+             * CADI code - check on permissions based on Legacy/AAF users to allow to delete/remove subscription\r
+             */\r
+            String aafInstance = sub.getAafInstance();\r
+            if (aafInstance == null || aafInstance.equals("") || aafInstance.equalsIgnoreCase("legacy")) {\r
+                AuthorizationResponse aresp = authz.decide(req);\r
+                if (!aresp.isAuthorized()) {\r
+                    message = "Policy Engine disallows access.";\r
+                    elr.setMessage(message);\r
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
+                    eventlogger.info(elr);\r
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
+                    return;\r
+                }\r
+            } else {\r
+                String permission = getSubscriberPermission(aafInstance, BaseServlet.EDIT_PERMISSION);\r
+                eventlogger.info("SubscriptionServlet.doDelete().. Permission String - " + permission);\r
+                if (!req.isUserInRole(permission)) {\r
+                    message = "AAF disallows access to permission - " + permission;\r
+                    elr.setMessage(message);\r
+                    elr.setResult(HttpServletResponse.SC_FORBIDDEN);\r
+                    eventlogger.info(elr);\r
+                    sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);\r
+                    return;\r
+                }\r
+            }\r
+            /*\r
+             * END - AAF changes\r
+             */\r
             sub.setSubid(oldsub.getSubid());\r
             sub.setFeedid(oldsub.getFeedid());\r
             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header\r
             sub.setSubid(oldsub.getSubid());\r
             sub.setFeedid(oldsub.getFeedid());\r
             sub.setSubscriber(bhdr);    // set from X-DMAAP-DR-ON-BEHALF-OF header\r
@@ -373,13 +415,6 @@ public class SubscriptionServlet extends ProxyServlet {
      */\r
     @Override\r
     public void doPost(HttpServletRequest req, HttpServletResponse resp) {\r
      */\r
     @Override\r
     public void doPost(HttpServletRequest req, HttpServletResponse resp) {\r
-// OLD pre-3.0 code\r
-//        String message = "POST not allowed for the subscriptionURL.";\r
-//        EventLogRecord elr = new EventLogRecord(req);\r
-//        elr.setMessage(message);\r
-//        elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);\r
-//        eventlogger.info(elr);\r
-//        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, message);\r
 \r
         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);\r
         eelflogger.info(EelfMsgs.ENTRY);\r
 \r
         setIpFqdnRequestIDandInvocationIDForEelf("doPost", req);\r
         eelflogger.info(EelfMsgs.ENTRY);\r
index a2076b0..502dbbd 100644 (file)
 \r
 package org.onap.dmaap.datarouter.provisioning.beans;\r
 \r
 \r
 package org.onap.dmaap.datarouter.provisioning.beans;\r
 \r
+import org.apache.log4j.Level;\r
 import org.apache.log4j.Logger;\r
 import org.json.JSONArray;\r
 import org.apache.log4j.Logger;\r
 import org.json.JSONArray;\r
+import org.json.JSONException;\r
 import org.json.JSONObject;\r
 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
 import org.onap.dmaap.datarouter.provisioning.utils.JSONUtilities;\r
 import org.json.JSONObject;\r
 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
 import org.onap.dmaap.datarouter.provisioning.utils.JSONUtilities;\r
+import org.onap.dmaap.datarouter.provisioning.utils.PasswordProcessor;\r
 import org.onap.dmaap.datarouter.provisioning.utils.URLUtilities;\r
 \r
 import java.io.InvalidObjectException;\r
 import org.onap.dmaap.datarouter.provisioning.utils.URLUtilities;\r
 \r
 import java.io.InvalidObjectException;\r
+import java.security.GeneralSecurityException;\r
 import java.sql.*;\r
 import java.sql.*;\r
-import java.util.*;\r
 import java.util.Date;\r
 import java.util.Date;\r
+import java.util.*;\r
 \r
 /**\r
  * The representation of a Feed.  Feeds can be retrieved from the DB, or stored/updated in the DB.\r
 \r
 /**\r
  * The representation of a Feed.  Feeds can be retrieved from the DB, or stored/updated in the DB.\r
@@ -59,6 +63,7 @@ public class Feed extends Syncable {
     private boolean suspended;\r
     private Date last_mod;\r
     private Date created_date;\r
     private boolean suspended;\r
     private Date last_mod;\r
     private Date created_date;\r
+    private String aaf_instance;\r
 \r
     /**\r
      * Check if a feed ID is valid.\r
 \r
     /**\r
      * Check if a feed ID is valid.\r
@@ -82,7 +87,7 @@ public class Feed extends Syncable {
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
-            intlogger.error("SQLException " + e.getMessage());\r
+            intlogger.log(Level.WARN, "PROV0024 Feed.isFeedValid: ", e);\r
         }\r
         return count != 0;\r
     }\r
         }\r
         return count != 0;\r
     }\r
@@ -132,8 +137,8 @@ public class Feed extends Syncable {
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
-            intlogger.info("countActiveFeeds: " + e.getMessage());\r
-            intlogger.error("SQLException " + e.getMessage());\r
+            intlogger.info("PROV0025 Feed.countActiveFeeds: " + e.getMessage());\r
+            intlogger.log(Level.WARN, "PROV0025 Feed.countActiveFeeds: ", e);\r
         }\r
         return count;\r
     }\r
         }\r
         return count;\r
     }\r
@@ -153,8 +158,8 @@ public class Feed extends Syncable {
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
-            intlogger.info("getMaxFeedID: " + e.getMessage());\r
-            intlogger.error("SQLException " + e.getMessage());\r
+            intlogger.info("PROV0026 Feed.getMaxFeedID: "+e.getMessage());\r
+            intlogger.log(Level.WARN, "PROV0026 Feed.getMaxFeedID: ", e);\r
         }\r
         return max;\r
     }\r
         }\r
         return max;\r
     }\r
@@ -200,7 +205,7 @@ public class Feed extends Syncable {
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
-            intlogger.error("SQLException " + e.getMessage());\r
+            intlogger.log(Level.WARN, "PROV0027 Feed.getAllFeeds: ", e);\r
         }\r
         return map.values();\r
     }\r
         }\r
         return map.values();\r
     }\r
@@ -234,7 +239,7 @@ public class Feed extends Syncable {
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
-            intlogger.error("SQLException " + e.getMessage());\r
+            intlogger.log(Level.WARN, "PROV0028 Feed.getFilteredFeedUrlList: ", e);\r
         }\r
         return list;\r
     }\r
         }\r
         return list;\r
     }\r
@@ -271,7 +276,7 @@ public class Feed extends Syncable {
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
             }\r
             db.release(conn);\r
         } catch (SQLException e) {\r
-            intlogger.error("SQLException " + e.getMessage());\r
+            intlogger.log(Level.WARN, "PROV0029 Feed.getFeedBySQL: ", e);\r
         }\r
         return feed;\r
     }\r
         }\r
         return feed;\r
     }\r
@@ -294,6 +299,7 @@ public class Feed extends Syncable {
         this.suspended = false;\r
         this.last_mod = new Date();\r
         this.created_date = new Date();\r
         this.suspended = false;\r
         this.last_mod = new Date();\r
         this.created_date = new Date();\r
+        this.aaf_instance = "";\r
     }\r
 \r
     public Feed(ResultSet rs) throws SQLException {\r
     }\r
 \r
     public Feed(ResultSet rs) throws SQLException {\r
@@ -315,6 +321,7 @@ public class Feed extends Syncable {
         this.suspended = rs.getBoolean("SUSPENDED");\r
         this.last_mod = rs.getDate("LAST_MOD");\r
         this.created_date = rs.getTimestamp("CREATED_DATE");\r
         this.suspended = rs.getBoolean("SUSPENDED");\r
         this.last_mod = rs.getDate("LAST_MOD");\r
         this.created_date = rs.getTimestamp("CREATED_DATE");\r
+        this.aaf_instance = rs.getString("AAF_INSTANCE");\r
     }\r
 \r
     public Feed(JSONObject jo) throws InvalidObjectException {\r
     }\r
 \r
     public Feed(JSONObject jo) throws InvalidObjectException {\r
@@ -322,41 +329,49 @@ public class Feed extends Syncable {
         try {\r
             // The JSONObject is assumed to contain a vnd.dmaap-dr.feed representation\r
             this.feedid = jo.optInt("feedid", -1);\r
         try {\r
             // The JSONObject is assumed to contain a vnd.dmaap-dr.feed representation\r
             this.feedid = jo.optInt("feedid", -1);\r
-            this.groupid = jo.optInt("groupid"); //New field is added - Groups feature Rally:US708115 - 1610\r
+            this.groupid = jo.optInt("groupid");\r
             this.name = jo.getString("name");\r
             this.name = jo.getString("name");\r
+            this.aaf_instance = jo.optString("aaf_instance", "legacy");\r
+            if(!(aaf_instance.equalsIgnoreCase("legacy"))){\r
+                if (aaf_instance.length() > 255){\r
+                    throw new InvalidObjectException("aaf_instance field is too long");\r
+                }\r
+            }\r
             if (name.length() > 255)\r
                 throw new InvalidObjectException("name field is too long");\r
             if (name.length() > 255)\r
                 throw new InvalidObjectException("name field is too long");\r
-            this.version = jo.getString("version");\r
-            if (version.length() > 20)\r
+            try {\r
+                this.version = jo.getString("version");\r
+            } catch (JSONException e) {\r
+                this.version = null;\r
+            }\r
+            if(version != null && version.length() > 20)\r
                 throw new InvalidObjectException("version field is too long");\r
             this.description = jo.optString("description");\r
                 throw new InvalidObjectException("version field is too long");\r
             this.description = jo.optString("description");\r
-            this.business_description = jo.optString("business_description"); // New field is added - Groups feature Rally:US708102 - 1610\r
+            this.business_description = jo.optString("business_description");\r
             if (description.length() > 1000)\r
                 throw new InvalidObjectException("technical description field is too long");\r
             if (description.length() > 1000)\r
                 throw new InvalidObjectException("technical description field is too long");\r
-\r
-            if (business_description.length() > 1000) // New field is added - Groups feature Rally:US708102 - 1610\r
+            if (business_description.length() > 1000)\r
                 throw new InvalidObjectException("business description field is too long");\r
                 throw new InvalidObjectException("business description field is too long");\r
-\r
             this.authorization = new FeedAuthorization();\r
             JSONObject jauth = jo.getJSONObject("authorization");\r
             this.authorization.setClassification(jauth.getString("classification"));\r
             if (this.authorization.getClassification().length() > 32)\r
                 throw new InvalidObjectException("classification field is too long");\r
             this.authorization = new FeedAuthorization();\r
             JSONObject jauth = jo.getJSONObject("authorization");\r
             this.authorization.setClassification(jauth.getString("classification"));\r
             if (this.authorization.getClassification().length() > 32)\r
                 throw new InvalidObjectException("classification field is too long");\r
-            JSONArray ja = jauth.getJSONArray("endpoint_ids");\r
-            for (int i = 0; i < ja.length(); i++) {\r
-                JSONObject id = ja.getJSONObject(i);\r
+            JSONArray endPointIds = jauth.getJSONArray("endpoint_ids");\r
+            for (int i = 0; i < endPointIds.length(); i++) {\r
+                JSONObject id = endPointIds.getJSONObject(i);\r
                 FeedEndpointID fid = new FeedEndpointID(id.getString("id"), id.getString("password"));\r
                 FeedEndpointID fid = new FeedEndpointID(id.getString("id"), id.getString("password"));\r
-                if (fid.getId().length() > 20)\r
+                if (fid.getId().length() > 60)\r
                     throw new InvalidObjectException("id field is too long (" + fid.getId() + ")");\r
                 if (fid.getPassword().length() > 32)\r
                     throw new InvalidObjectException("id field is too long (" + fid.getId() + ")");\r
                 if (fid.getPassword().length() > 32)\r
-                    throw new InvalidObjectException("password field is too long (" + fid.getPassword() + ")");\r
+                    throw new InvalidObjectException("password field is too long ("+ fid.getPassword()+")");  //Fortify scan fixes - Privacy Violation\r
                 this.authorization.getEndpoint_ids().add(fid);\r
             }\r
             if (this.authorization.getEndpoint_ids().size() < 1)\r
                 throw new InvalidObjectException("need to specify at least one endpoint_id");\r
                 this.authorization.getEndpoint_ids().add(fid);\r
             }\r
             if (this.authorization.getEndpoint_ids().size() < 1)\r
                 throw new InvalidObjectException("need to specify at least one endpoint_id");\r
-            ja = jauth.getJSONArray("endpoint_addrs");\r
-            for (int i = 0; i < ja.length(); i++) {\r
-                String addr = ja.getString(i);\r
+            endPointIds = jauth.getJSONArray("endpoint_addrs");\r
+            for (int i = 0; i < endPointIds.length(); i++) {\r
+                String addr = endPointIds.getString(i);\r
                 if (!JSONUtilities.validIPAddrOrSubnet(addr))\r
                     throw new InvalidObjectException("bad IP addr or subnet mask: " + addr);\r
                 this.authorization.getEndpoint_addrs().add(addr);\r
                 if (!JSONUtilities.validIPAddrOrSubnet(addr))\r
                     throw new InvalidObjectException("bad IP addr or subnet mask: " + addr);\r
                 this.authorization.getEndpoint_addrs().add(addr);\r
@@ -368,8 +383,10 @@ public class Feed extends Syncable {
             JSONObject jol = jo.optJSONObject("links");\r
             this.links = (jol == null) ? (new FeedLinks()) : (new FeedLinks(jol));\r
         } catch (InvalidObjectException e) {\r
             JSONObject jol = jo.optJSONObject("links");\r
             this.links = (jol == null) ? (new FeedLinks()) : (new FeedLinks(jol));\r
         } catch (InvalidObjectException e) {\r
+            intlogger.log(Level.WARN, "PROV0030 Feed.Feed: ", e);\r
             throw e;\r
         } catch (Exception e) {\r
             throw e;\r
         } catch (Exception e) {\r
+            intlogger.error("PROV0031 Feed.Feed: invalid JSON: "+e);\r
             throw new InvalidObjectException("invalid JSON: " + e.getMessage());\r
         }\r
     }\r
             throw new InvalidObjectException("invalid JSON: " + e.getMessage());\r
         }\r
     }\r
@@ -389,6 +406,14 @@ public class Feed extends Syncable {
         fl.setLog(URLUtilities.generateFeedLogURL(feedid));\r
     }\r
 \r
         fl.setLog(URLUtilities.generateFeedLogURL(feedid));\r
     }\r
 \r
+    public String getAafInstance() {\r
+        return aaf_instance;\r
+    }\r
+\r
+    public void setAaf_instance(String aaf_instance) {\r
+        this.aaf_instance = aaf_instance;\r
+    }\r
+\r
     //new getter setters for groups- Rally:US708115 - 1610\r
     public int getGroupid() {\r
         return groupid;\r
     //new getter setters for groups- Rally:US708115 - 1610\r
     public int getGroupid() {\r
         return groupid;\r
@@ -499,6 +524,7 @@ public class Feed extends Syncable {
         jo.put("suspend", suspended);\r
         jo.put("last_mod", last_mod.getTime());\r
         jo.put("created_date", created_date.getTime());\r
         jo.put("suspend", suspended);\r
         jo.put("last_mod", last_mod.getTime());\r
         jo.put("created_date", created_date.getTime());\r
+        jo.put("aaf_instance", aaf_instance);\r
         return jo;\r
     }\r
 \r
         return jo;\r
     }\r
 \r
@@ -581,7 +607,7 @@ public class Feed extends Syncable {
             }\r
 \r
             // Finally, create the FEEDS row\r
             }\r
 \r
             // Finally, create the FEEDS row\r
-            sql = "insert into FEEDS (FEEDID, NAME, VERSION, DESCRIPTION, AUTH_CLASS, PUBLISHER, SELF_LINK, PUBLISH_LINK, SUBSCRIBE_LINK, LOG_LINK, DELETED, SUSPENDED,BUSINESS_DESCRIPTION, GROUPID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?)";\r
+            sql = "insert into FEEDS (FEEDID, NAME, VERSION, DESCRIPTION, AUTH_CLASS, PUBLISHER, SELF_LINK, PUBLISH_LINK, SUBSCRIBE_LINK, LOG_LINK, DELETED, SUSPENDED,BUSINESS_DESCRIPTION, GROUPID, AAF_INSTANCE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";\r
             try(PreparedStatement ps2 = c.prepareStatement(sql)) {\r
                 ps2.setInt(1, feedid);\r
                 ps2.setString(2, getName());\r
             try(PreparedStatement ps2 = c.prepareStatement(sql)) {\r
                 ps2.setInt(1, feedid);\r
                 ps2.setString(2, getName());\r
@@ -595,8 +621,9 @@ public class Feed extends Syncable {
                 ps2.setString(10, getLinks().getLog());\r
                 ps2.setBoolean(11, isDeleted());\r
                 ps2.setBoolean(12, isSuspended());\r
                 ps2.setString(10, getLinks().getLog());\r
                 ps2.setBoolean(11, isDeleted());\r
                 ps2.setBoolean(12, isSuspended());\r
-                ps2.setString(13, getBusiness_description()); // New field is added - Groups feature Rally:US708102 - 1610\r
-                ps2.setInt(14, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
+                ps2.setString(13, getBusiness_description());\r
+                ps2.setInt(14, groupid);\r
+                ps2.setString(15, getAafInstance());\r
                 ps2.executeUpdate();\r
             }\r
         } catch (SQLException e) {\r
                 ps2.executeUpdate();\r
             }\r
         } catch (SQLException e) {\r
@@ -675,8 +702,8 @@ public class Feed extends Syncable {
             ps.setString(2, getAuthorization().getClassification());\r
             ps.setInt(3, deleted ? 1 : 0);\r
             ps.setInt(4, suspended ? 1 : 0);\r
             ps.setString(2, getAuthorization().getClassification());\r
             ps.setInt(3, deleted ? 1 : 0);\r
             ps.setInt(4, suspended ? 1 : 0);\r
-            ps.setString(5, getBusiness_description()); // New field is added - Groups feature Rally:US708102 - 1610\r
-            ps.setInt(6, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
+            ps.setString(5, getBusiness_description());\r
+            ps.setInt(6, groupid);\r
             ps.setInt(7, feedid);\r
             ps.executeUpdate();\r
             ps.close();\r
             ps.setInt(7, feedid);\r
             ps.executeUpdate();\r
             ps.close();\r
@@ -760,6 +787,8 @@ public class Feed extends Syncable {
             return false;\r
         if (suspended != of.suspended)\r
             return false;\r
             return false;\r
         if (suspended != of.suspended)\r
             return false;\r
+        if (!aaf_instance.equals(of.aaf_instance))\r
+            return false;\r
         return true;\r
     }\r
 \r
         return true;\r
     }\r
 \r
@@ -770,6 +799,6 @@ public class Feed extends Syncable {
 \r
     @Override\r
     public int hashCode() {\r
 \r
     @Override\r
     public int hashCode() {\r
-        return Objects.hash(feedid, groupid, name, version, description, business_description, authorization, publisher, links, deleted, suspended, last_mod, created_date);\r
+        return super.hashCode();\r
     }\r
     }\r
-}\r
+}
\ No newline at end of file
index 0c0c546..bdc062f 100644 (file)
 \r
 package org.onap.dmaap.datarouter.provisioning.beans;\r
 \r
 \r
 package org.onap.dmaap.datarouter.provisioning.beans;\r
 \r
-import java.io.InvalidObjectException;\r
-import java.sql.Connection;\r
-import java.sql.PreparedStatement;\r
-import java.sql.ResultSet;\r
-import java.sql.SQLException;\r
-import java.sql.Statement;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Date;\r
-import java.util.List;\r
-import java.util.Objects;\r
-import java.util.Properties;\r
+import org.apache.log4j.Level;\r
 import org.apache.log4j.Logger;\r
 import org.json.JSONObject;\r
 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
 import org.apache.log4j.Logger;\r
 import org.json.JSONObject;\r
 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
+import org.onap.dmaap.datarouter.provisioning.utils.PasswordProcessor;\r
 import org.onap.dmaap.datarouter.provisioning.utils.URLUtilities;\r
 \r
 import org.onap.dmaap.datarouter.provisioning.utils.URLUtilities;\r
 \r
+import java.io.InvalidObjectException;\r
+import java.security.GeneralSecurityException;\r
+import java.sql.*;\r
+import java.util.Date;\r
+import java.util.*;\r
+\r
 /**\r
  * The representation of a Subscription.  Subscriptions can be retrieved from the DB, or stored/updated in the DB.\r
  *\r
 /**\r
  * The representation of a Subscription.  Subscriptions can be retrieved from the DB, or stored/updated in the DB.\r
  *\r
@@ -62,6 +58,7 @@ public class Subscription extends Syncable {
     private int feedid;\r
     private int groupid; //New field is added - Groups feature Rally:US708115 - 1610\r
     private SubDelivery delivery;\r
     private int feedid;\r
     private int groupid; //New field is added - Groups feature Rally:US708115 - 1610\r
     private SubDelivery delivery;\r
+    private boolean followRedirect;\r
     private boolean metadataOnly;\r
     private String subscriber;\r
     private SubLinks links;\r
     private boolean metadataOnly;\r
     private String subscriber;\r
     private SubLinks links;\r
@@ -69,18 +66,20 @@ public class Subscription extends Syncable {
     private Date lastMod;\r
     private Date createdDate;\r
     private boolean privilegedSubscriber;\r
     private Date lastMod;\r
     private Date createdDate;\r
     private boolean privilegedSubscriber;\r
+    private String aafInstance;\r
     private boolean decompress;\r
 \r
     public static Subscription getSubscriptionMatching(Subscription sub) {\r
         SubDelivery deli = sub.getDelivery();\r
         String sql = String.format(\r
     private boolean decompress;\r
 \r
     public static Subscription getSubscriptionMatching(Subscription sub) {\r
         SubDelivery deli = sub.getDelivery();\r
         String sql = String.format(\r
-                "select * from SUBSCRIPTIONS where FEEDID = %d and DELIVERY_URL = \"%s\" and DELIVERY_USER = \"%s\" and DELIVERY_PASSWORD = \"%s\" and DELIVERY_USE100 = %d and METADATA_ONLY = %d",\r
+                "select * from SUBSCRIPTIONS where FEEDID = %d and DELIVERY_URL = \"%s\" and DELIVERY_USER = \"%s\" and DELIVERY_PASSWORD = \"%s\" and DELIVERY_USE100 = %d and METADATA_ONLY = %d and FOLLOW_REDIRECTS = %d",\r
                 sub.getFeedid(),\r
                 deli.getUrl(),\r
                 deli.getUser(),\r
                 deli.getPassword(),\r
                 deli.isUse100() ? 1 : 0,\r
                 sub.getFeedid(),\r
                 deli.getUrl(),\r
                 deli.getUser(),\r
                 deli.getPassword(),\r
                 deli.isUse100() ? 1 : 0,\r
-                sub.isMetadataOnly() ? 1 : 0\r
+                sub.isMetadataOnly() ? 1 : 0,\r
+                sub.isFollowRedirect() ? 1 :0\r
         );\r
         List<Subscription> list = getSubscriptionsForSQL(sql);\r
         return !list.isEmpty() ? list.get(0) : null;\r
         );\r
         List<Subscription> list = getSubscriptionsForSQL(sql);\r
         return !list.isEmpty() ? list.get(0) : null;\r
@@ -145,7 +144,6 @@ public class Subscription extends Syncable {
             DB db = new DB();\r
             @SuppressWarnings("resource")\r
             Connection conn = db.getConnection();\r
             DB db = new DB();\r
             @SuppressWarnings("resource")\r
             Connection conn = db.getConnection();\r
-\r
             try (PreparedStatement stmt = conn.prepareStatement(sql)) {\r
                 stmt.setString(1, String.valueOf(feedid));\r
                 try (ResultSet rs = stmt.executeQuery()) {\r
             try (PreparedStatement stmt = conn.prepareStatement(sql)) {\r
                 stmt.setString(1, String.valueOf(feedid));\r
                 try (ResultSet rs = stmt.executeQuery()) {\r
@@ -197,12 +195,14 @@ public class Subscription extends Syncable {
         this.groupid = -1; //New field is added - Groups feature Rally:US708115 - 1610\r
         this.delivery = new SubDelivery(url, user, password, false);\r
         this.metadataOnly = false;\r
         this.groupid = -1; //New field is added - Groups feature Rally:US708115 - 1610\r
         this.delivery = new SubDelivery(url, user, password, false);\r
         this.metadataOnly = false;\r
+        this.followRedirect = false;\r
         this.subscriber = "";\r
         this.links = new SubLinks();\r
         this.suspended = false;\r
         this.lastMod = new Date();\r
         this.createdDate = new Date();\r
         this.privilegedSubscriber = false;\r
         this.subscriber = "";\r
         this.links = new SubLinks();\r
         this.suspended = false;\r
         this.lastMod = new Date();\r
         this.createdDate = new Date();\r
         this.privilegedSubscriber = false;\r
+        this.aafInstance = "";\r
         this.decompress = false;\r
     }\r
 \r
         this.decompress = false;\r
     }\r
 \r
@@ -212,13 +212,14 @@ public class Subscription extends Syncable {
         this.groupid = rs.getInt("GROUPID"); //New field is added - Groups feature Rally:US708115 - 1610\r
         this.delivery = new SubDelivery(rs);\r
         this.metadataOnly = rs.getBoolean("METADATA_ONLY");\r
         this.groupid = rs.getInt("GROUPID"); //New field is added - Groups feature Rally:US708115 - 1610\r
         this.delivery = new SubDelivery(rs);\r
         this.metadataOnly = rs.getBoolean("METADATA_ONLY");\r
+        this.followRedirect = rs.getBoolean("FOLLOW_REDIRECTS");\r
         this.subscriber = rs.getString("SUBSCRIBER");\r
         this.subscriber = rs.getString("SUBSCRIBER");\r
-        this.links = new SubLinks(rs.getString("SELF_LINK"), URLUtilities.generateFeedURL(feedid),\r
-                rs.getString("LOG_LINK"));\r
+        this.links = new SubLinks(rs.getString("SELF_LINK"), URLUtilities.generateFeedURL(feedid), rs.getString("LOG_LINK"));\r
         this.suspended = rs.getBoolean("SUSPENDED");\r
         this.lastMod = rs.getDate("LAST_MOD");\r
         this.createdDate = rs.getDate("CREATED_DATE");\r
         this.privilegedSubscriber = rs.getBoolean("PRIVILEGED_SUBSCRIBER");\r
         this.suspended = rs.getBoolean("SUSPENDED");\r
         this.lastMod = rs.getDate("LAST_MOD");\r
         this.createdDate = rs.getDate("CREATED_DATE");\r
         this.privilegedSubscriber = rs.getBoolean("PRIVILEGED_SUBSCRIBER");\r
+        this.aafInstance = rs.getString("AAF_INSTANCE");\r
         this.decompress  = rs.getBoolean("DECOMPRESS");\r
     }\r
 \r
         this.decompress  = rs.getBoolean("DECOMPRESS");\r
     }\r
 \r
@@ -229,7 +230,11 @@ public class Subscription extends Syncable {
             this.subid = jo.optInt(SUBID_KEY, -1);\r
             this.feedid = jo.optInt(FEEDID_KEY, -1);\r
             this.groupid = jo.optInt(GROUPID_KEY, -1); //New field is added - Groups feature Rally:US708115 - 1610\r
             this.subid = jo.optInt(SUBID_KEY, -1);\r
             this.feedid = jo.optInt(FEEDID_KEY, -1);\r
             this.groupid = jo.optInt(GROUPID_KEY, -1); //New field is added - Groups feature Rally:US708115 - 1610\r
-\r
+            this.aafInstance = jo.optString("aaf_instance", "legacy");\r
+            if(!(aafInstance.equalsIgnoreCase("legacy"))){\r
+                if (aafInstance.length() > 255)\r
+                    throw new InvalidObjectException("aaf_instance field is too long");\r
+            }\r
             JSONObject jdeli = jo.getJSONObject("delivery");\r
             String url = jdeli.getString("url");\r
             String user = jdeli.getString("user");\r
             JSONObject jdeli = jo.getJSONObject("delivery");\r
             String url = jdeli.getString("url");\r
             String user = jdeli.getString("user");\r
@@ -245,15 +250,15 @@ public class Subscription extends Syncable {
             if (url.length() > 256) {\r
                 throw new InvalidObjectException("delivery url field is too long");\r
             }\r
             if (url.length() > 256) {\r
                 throw new InvalidObjectException("delivery url field is too long");\r
             }\r
-            if (user.length() > 20) {\r
+            if (user.length() > 60) {\r
                 throw new InvalidObjectException("delivery user field is too long");\r
             }\r
             if (password.length() > 32) {\r
                 throw new InvalidObjectException("delivery password field is too long");\r
             }\r
             this.delivery = new SubDelivery(url, user, password, use100);\r
                 throw new InvalidObjectException("delivery user field is too long");\r
             }\r
             if (password.length() > 32) {\r
                 throw new InvalidObjectException("delivery password field is too long");\r
             }\r
             this.delivery = new SubDelivery(url, user, password, use100);\r
-\r
             this.metadataOnly = jo.getBoolean("metadataOnly");\r
             this.metadataOnly = jo.getBoolean("metadataOnly");\r
+            this.followRedirect = jo.optBoolean("follow_redirect", false);\r
             this.suspended = jo.optBoolean("suspend", false);\r
             this.privilegedSubscriber = jo.optBoolean("privilegedSubscriber", false);\r
             this.decompress = jo.optBoolean("decompress", false);\r
             this.suspended = jo.optBoolean("suspend", false);\r
             this.privilegedSubscriber = jo.optBoolean("privilegedSubscriber", false);\r
             this.decompress = jo.optBoolean("decompress", false);\r
@@ -296,6 +301,13 @@ public class Subscription extends Syncable {
         SubLinks sl = getLinks();\r
         sl.setFeed(URLUtilities.generateFeedURL(feedid));\r
     }\r
         SubLinks sl = getLinks();\r
         sl.setFeed(URLUtilities.generateFeedURL(feedid));\r
     }\r
+    public String getAafInstance() {\r
+        return aafInstance;\r
+    }\r
+\r
+    public void setAafInstance(String aafInstance) {\r
+        this.aafInstance = aafInstance;\r
+    }\r
 \r
     //New getter setters for Groups feature Rally:US708115 - 1610\r
     public int getGroupid() {\r
 \r
     //New getter setters for Groups feature Rally:US708115 - 1610\r
     public int getGroupid() {\r
@@ -322,7 +334,14 @@ public class Subscription extends Syncable {
         this.metadataOnly = metadataOnly;\r
     }\r
 \r
         this.metadataOnly = metadataOnly;\r
     }\r
 \r
-    public boolean isSuspended() {\r
+    private boolean isFollowRedirect() {\r
+        return followRedirect;\r
+    }\r
+    public void setFollowRedirect(boolean followRedirect) {\r
+        this.followRedirect = followRedirect;\r
+    }\r
+\r
+    boolean isSuspended() {\r
         return suspended;\r
     }\r
 \r
         return suspended;\r
     }\r
 \r
@@ -355,7 +374,7 @@ public class Subscription extends Syncable {
         return links;\r
     }\r
 \r
         return links;\r
     }\r
 \r
-    public void setLinks(SubLinks links) {\r
+    void setLinks(SubLinks links) {\r
         this.links = links;\r
     }\r
 \r
         this.links = links;\r
     }\r
 \r
@@ -375,12 +394,14 @@ public class Subscription extends Syncable {
         jo.put(GROUPID_KEY, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
         jo.put("delivery", delivery.asJSONObject());\r
         jo.put("metadataOnly", metadataOnly);\r
         jo.put(GROUPID_KEY, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
         jo.put("delivery", delivery.asJSONObject());\r
         jo.put("metadataOnly", metadataOnly);\r
+        jo.put("follow_redirect", followRedirect);\r
         jo.put("subscriber", subscriber);\r
         jo.put("links", links.asJSONObject());\r
         jo.put("suspend", suspended);\r
         jo.put(LAST_MOD_KEY, lastMod.getTime());\r
         jo.put(CREATED_DATE, createdDate.getTime());\r
         jo.put("privilegedSubscriber", privilegedSubscriber);\r
         jo.put("subscriber", subscriber);\r
         jo.put("links", links.asJSONObject());\r
         jo.put("suspend", suspended);\r
         jo.put(LAST_MOD_KEY, lastMod.getTime());\r
         jo.put(CREATED_DATE, createdDate.getTime());\r
         jo.put("privilegedSubscriber", privilegedSubscriber);\r
+        jo.put("aaf_instance", aafInstance);\r
         jo.put("decompress", decompress);\r
         return jo;\r
     }\r
         jo.put("decompress", decompress);\r
         return jo;\r
     }\r
@@ -419,7 +440,7 @@ public class Subscription extends Syncable {
             }\r
 \r
             // Create the SUBSCRIPTIONS row\r
             }\r
 \r
             // Create the SUBSCRIPTIONS row\r
-            String sql = "insert into SUBSCRIPTIONS (SUBID, FEEDID, DELIVERY_URL, DELIVERY_USER, DELIVERY_PASSWORD, DELIVERY_USE100, METADATA_ONLY, SUBSCRIBER, SUSPENDED, GROUPID, PRIVILEGED_SUBSCRIBER, DECOMPRESS) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";\r
+            String sql = "insert into SUBSCRIPTIONS (SUBID, FEEDID, DELIVERY_URL, DELIVERY_USER, DELIVERY_PASSWORD, DELIVERY_USE100, METADATA_ONLY, SUBSCRIBER, SUSPENDED, GROUPID, PRIVILEGED_SUBSCRIBER, FOLLOW_REDIRECTS, DECOMPRESS, AAF_INSTANCE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";\r
             ps = c.prepareStatement(sql, new String[]{SUBID_COL});\r
             ps.setInt(1, subid);\r
             ps.setInt(2, feedid);\r
             ps = c.prepareStatement(sql, new String[]{SUBID_COL});\r
             ps.setInt(1, subid);\r
             ps.setInt(2, feedid);\r
@@ -432,7 +453,9 @@ public class Subscription extends Syncable {
             ps.setBoolean(9, isSuspended());\r
             ps.setInt(10, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
             ps.setBoolean(11, isPrivilegedSubscriber());\r
             ps.setBoolean(9, isSuspended());\r
             ps.setInt(10, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
             ps.setBoolean(11, isPrivilegedSubscriber());\r
-            ps.setBoolean(12, isDecompress());\r
+            ps.setInt(12, isFollowRedirect() ? 1 : 0);\r
+            ps.setBoolean(13, isDecompress());\r
+            ps.setString(14, getAafInstance());\r
             ps.execute();\r
             ps.close();\r
             // Update the row to set the URLs\r
             ps.execute();\r
             ps.close();\r
             // Update the row to set the URLs\r
@@ -446,6 +469,7 @@ public class Subscription extends Syncable {
         } catch (SQLException e) {\r
             rv = false;\r
             intlogger.warn("PROV0005 doInsert: " + e.getMessage());\r
         } catch (SQLException e) {\r
             rv = false;\r
             intlogger.warn("PROV0005 doInsert: " + e.getMessage());\r
+            intlogger.log(Level.WARN, "PROV0005 Subscription.doInsert(1): ", e);\r
         } finally {\r
             try {\r
                 if (ps != null) {\r
         } finally {\r
             try {\r
                 if (ps != null) {\r
@@ -463,7 +487,7 @@ public class Subscription extends Syncable {
         boolean rv = true;\r
         PreparedStatement ps = null;\r
         try {\r
         boolean rv = true;\r
         PreparedStatement ps = null;\r
         try {\r
-            String sql = "update SUBSCRIPTIONS set DELIVERY_URL = ?, DELIVERY_USER = ?, DELIVERY_PASSWORD = ?, DELIVERY_USE100 = ?, METADATA_ONLY = ?, SUSPENDED = ?, GROUPID = ?, PRIVILEGED_SUBSCRIBER = ?, DECOMPRESS = ? where SUBID = ?";\r
+            String sql = "update SUBSCRIPTIONS set DELIVERY_URL = ?, DELIVERY_USER = ?, DELIVERY_PASSWORD = ?, DELIVERY_USE100 = ?, METADATA_ONLY = ?, SUSPENDED = ?, GROUPID = ?, PRIVILEGED_SUBSCRIBER = ?, FOLLOW_REDIRECTS = ?, DECOMPRESS = ? where SUBID = ?";\r
             ps = c.prepareStatement(sql);\r
             ps.setString(1, delivery.getUrl());\r
             ps.setString(2, delivery.getUser());\r
             ps = c.prepareStatement(sql);\r
             ps.setString(1, delivery.getUrl());\r
             ps.setString(2, delivery.getUser());\r
@@ -473,8 +497,9 @@ public class Subscription extends Syncable {
             ps.setInt(6, suspended ? 1 : 0);\r
             ps.setInt(7, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
             ps.setInt(8, privilegedSubscriber ? 1 : 0);\r
             ps.setInt(6, suspended ? 1 : 0);\r
             ps.setInt(7, groupid); //New field is added - Groups feature Rally:US708115 - 1610\r
             ps.setInt(8, privilegedSubscriber ? 1 : 0);\r
-            ps.setInt(9, decompress ? 1 : 0);\r
-            ps.setInt(10, subid);\r
+            ps.setInt(9, isFollowRedirect() ? 1 : 0);\r
+            ps.setInt(10, isDecompress() ? 1 : 0);\r
+            ps.setInt(11, subid);\r
             ps.executeUpdate();\r
         } catch (SQLException e) {\r
             rv = false;\r
             ps.executeUpdate();\r
         } catch (SQLException e) {\r
             rv = false;\r
@@ -576,19 +601,27 @@ public class Subscription extends Syncable {
         if (metadataOnly != os.metadataOnly) {\r
             return false;\r
         }\r
         if (metadataOnly != os.metadataOnly) {\r
             return false;\r
         }\r
+        if (followRedirect != os.followRedirect) {\r
+            return false;\r
+        }\r
         if (!subscriber.equals(os.subscriber)) {\r
             return false;\r
         }\r
         if (!links.equals(os.links)) {\r
             return false;\r
         }\r
         if (!subscriber.equals(os.subscriber)) {\r
             return false;\r
         }\r
         if (!links.equals(os.links)) {\r
             return false;\r
         }\r
-        return suspended == os.suspended;\r
+        if (suspended != os.suspended) {\r
+            return false;\r
+        }\r
+        if (!aafInstance.equals(os.aafInstance)) {\r
+            return false;\r
+        }\r
+        return true;\r
     }\r
 \r
     @Override\r
     public int hashCode() {\r
     }\r
 \r
     @Override\r
     public int hashCode() {\r
-        return Objects.hash(subid, feedid, groupid, delivery, metadataOnly, subscriber, links, suspended, lastMod,\r
-                createdDate);\r
+        return super.hashCode();\r
     }\r
 \r
     @Override\r
     }\r
 \r
     @Override\r
index 3e2436f..8ca7118 100644 (file)
@@ -185,8 +185,8 @@ public class DB {
             connection = getConnection();\r
             Set<String> actualTables = getTableSet(connection);\r
             boolean initialize = false;\r
             connection = getConnection();\r
             Set<String> actualTables = getTableSet(connection);\r
             boolean initialize = false;\r
-            for (String table : expectedTables) {\r
-                initialize |= !actualTables.contains(table.toLowerCase());\r
+            for (String tableName : expectedTables) {\r
+                initialize |= !actualTables.contains(tableName);\r
             }\r
             if (initialize) {\r
                 intlogger.info("PROV9001: First time startup; The database is being initialized.");\r
             }\r
             if (initialize) {\r
                 intlogger.info("PROV9001: First time startup; The database is being initialized.");\r
@@ -211,13 +211,13 @@ public class DB {
      * @return the set of table names\r
      */\r
     private Set<String> getTableSet(Connection connection) {\r
      * @return the set of table names\r
      */\r
     private Set<String> getTableSet(Connection connection) {\r
-        Set<String> tables = new HashSet<String>();\r
+        Set<String> tables = new HashSet<>();\r
         try {\r
             DatabaseMetaData md = connection.getMetaData();\r
             ResultSet rs = md.getTables(null, null, "%", null);\r
             if (rs != null) {\r
                 while (rs.next()) {\r
         try {\r
             DatabaseMetaData md = connection.getMetaData();\r
             ResultSet rs = md.getTables(null, null, "%", null);\r
             if (rs != null) {\r
                 while (rs.next()) {\r
-                    tables.add(rs.getString("TABLE_NAME"));\r
+                    tables.add(rs.getString("TABLE_NAME").toUpperCase());\r
                 }\r
                 rs.close();\r
             }\r
                 }\r
                 rs.close();\r
             }\r
diff --git a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DRProvCadiFilter.java b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DRProvCadiFilter.java
new file mode 100644 (file)
index 0000000..fb8b072
--- /dev/null
@@ -0,0 +1,259 @@
+/**
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * <p>
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.datarouter.provisioning.utils;
+
+import org.apache.log4j.Logger;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.filter.CadiFilter;
+import org.onap.dmaap.datarouter.provisioning.BaseServlet;
+import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;
+import org.onap.dmaap.datarouter.provisioning.beans.Feed;
+import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+public class DRProvCadiFilter extends CadiFilter {
+    private static Logger eventlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.events");
+    private static Logger intlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");
+    private String aafInstance = "";
+
+    public DRProvCadiFilter(boolean init, PropAccess access) throws ServletException {
+        super(init, access);
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest httpRequest = null;
+        HttpServletResponse httpResponse = null;
+        //cadi code
+        try {
+            httpRequest = (HttpServletRequest) request;
+            httpResponse = (HttpServletResponse) response;
+        } catch (ClassCastException e) {
+            try {
+                throw new ServletException("Only serving HTTP today", e);
+            } catch (ServletException e1) {
+                intlogger.error("PROV7001 DRProvCadiFilter.doFilter: ", e1);
+            }
+        }
+        EventLogRecord elr = new EventLogRecord(httpRequest);
+        String excludeAAF = httpRequest.getHeader(BaseServlet.EXCLUDE_AAF_HEADER);//send this param value as true, if want to add legacy feed/subscriber in AAF env
+
+        String pathUrl = httpRequest.getServletPath();
+        if (!(pathUrl.contains("internal") ||
+                pathUrl.contains("sublog") ||
+                pathUrl.contains("feedlog") ||
+                pathUrl.contains("statistics") ||
+                pathUrl.contains("publish") ||
+                pathUrl.contains("group"))) {
+
+            String method = httpRequest.getMethod().toUpperCase();
+            if (!(method.equals("POST"))) { // if request method is PUT method (publish or Feed update) Needs to check for DELETE
+                if (method.equals("PUT") || method.equals("DELETE")) {
+                    if ((pathUrl.contains("subs"))) {//edit subscriber
+                        int subId = BaseServlet.getIdFromPath(httpRequest);
+                        if (subId <= 0) {
+                            String message = String.format("Invalid request URI - %s", httpRequest.getPathInfo());
+                            elr.setMessage(message);
+                            elr.setResult(HttpServletResponse.SC_NOT_FOUND);
+                            eventlogger.info(elr);
+                            httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+                            return;
+                        }
+                        if (isAAFSubscriber(subId)) {//edit AAF Subscriber
+                            String message = String.format("DRProvCadiFilter - Edit AAF Subscriber : %d : AAF Instance - %s", subId, aafInstance);
+                            elr.setMessage(message);
+                            eventlogger.info(elr);
+                            //request.setAttribute("aafInstance", aafInstance);// no need to set it in request since it is taken care in respective servlets
+                            super.doFilter(request, response, chain);
+
+                        } else {//Edit or publish legacy Subscriber
+                            String message = "DRProvCadiFilter - Edit/Publish Legacy Subscriber :" + subId;
+                            elr.setMessage(message);
+                            eventlogger.info(elr);
+                            chain.doFilter(request, response);
+                        }
+
+                    } else {//edit or publish Feed
+                        int feedId = BaseServlet.getIdFromPath(httpRequest);
+                        if (feedId <= 0) {
+                            String message = "Invalid request URI - " + httpRequest.getPathInfo();
+                            elr.setMessage(message);
+                            elr.setResult(HttpServletResponse.SC_NOT_FOUND);
+                            eventlogger.info(elr);
+                            httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+                            return;
+                        }
+
+                        if (isAAFFeed(feedId)) {//edit AAF Feed
+                            String message = "DRProvCadiFilter - Edit AAF Feed:" + feedId + ":" + "AAF Instance -" + aafInstance;
+                            elr.setMessage(message);
+                            eventlogger.info(elr);
+                            super.doFilter(request, response, chain);
+
+                        } else {//Edit or publish legacy Feed
+                            String message = "DRProvCadiFilter - Edit/Publish Legacy Feed:" + feedId;
+                            elr.setMessage(message);
+                            eventlogger.info(elr);
+                            chain.doFilter(request, response);
+                        }
+                    }
+                } else {// in all other cases defaults to legacy behavior
+                    String message = "DRProvCadiFilter - Default Legacy Feed/Subscriber URI -:" + httpRequest.getPathInfo();
+                    elr.setMessage(message);
+                    eventlogger.info(elr);
+                    chain.doFilter(request, response);
+                }
+            } else {
+                //check to add legacy/AAF subscriber
+                if ((pathUrl.contains("subscribe"))) {//add subscriber
+                    int feedId = BaseServlet.getIdFromPath(httpRequest);
+                    if (feedId <= 0) {
+                        String message = "Invalid request URI - " + httpRequest.getPathInfo();
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_NOT_FOUND);
+                        eventlogger.info(elr);
+                        httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+                        return;
+                    }
+                    if (isAAFFeed(feedId)) {//check if AAF Feed or legacy to add new subscriber
+                        if (excludeAAF == null) {
+                            String message = "DRProvCadiFilter -Invalid request Header Parmeter " + BaseServlet.EXCLUDE_AAF_HEADER + " = " + httpRequest.getHeader(BaseServlet.EXCLUDE_AAF_HEADER);
+                            elr.setMessage(message);
+                            elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
+                            eventlogger.info(elr);
+                            httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+                            return;
+                        }
+                        if (excludeAAF.equalsIgnoreCase("true")) {//Check to add legacy subscriber to AAF Feed
+                            String message = "DRProvCadiFilter - add legacy subscriber to AAF Feed, FeedID:" + feedId;
+                            elr.setMessage(message);
+                            eventlogger.info(elr);
+                            chain.doFilter(request, response);
+                        } else {
+                            String message = "DRProvCadiFilter - Add AAF subscriber to AAF Feed, FeedID:" + feedId + ":" + "AAF Instance -" + aafInstance;
+                            elr.setMessage(message);
+                            eventlogger.info(elr);
+                            super.doFilter(request, response, chain);
+                        }
+                    } else {//Add legacy susbcriber to legacy Feed
+                        String message = "DRProvCadiFilter - add legacy subscriber to legacy Feed:" + feedId;
+                        elr.setMessage(message);
+                        eventlogger.info(elr);
+                        chain.doFilter(request, response);
+                    }
+                } else {//add AAF feed
+                    if (excludeAAF == null) {
+                        String message = "DRProvCadiFilter -Invalid request Header Parmeter " + BaseServlet.EXCLUDE_AAF_HEADER + " = " + httpRequest.getHeader(BaseServlet.EXCLUDE_AAF_HEADER);
+                        elr.setMessage(message);
+                        elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
+                        eventlogger.info(elr);
+                        httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+                        return;
+                    }
+                    if (excludeAAF.equalsIgnoreCase("true")) {//add legacy feed
+                        String message = "DRProvCadiFilter - Create new legacy Feed : EXCLUDE_AAF = " + excludeAAF;
+                        elr.setMessage(message);
+                        eventlogger.info(elr);
+                        chain.doFilter(request, response);
+                    } else {//add AAF Feed
+                        String message = "DRProvCadiFilter - Create new AAF Feed : EXCLUDE_AAF = " + excludeAAF;
+                        elr.setMessage(message);
+                        eventlogger.info(elr);
+                        super.doFilter(request, response, chain);
+                    }
+                }
+            }
+        } else {
+            //All other requests default to (Non CADI) legacy
+            chain.doFilter(request, response);
+        }
+    }
+
+    /**
+     * Check if it is AAF feed OR existing feed.
+     *
+     * @param feedId the Feed ID
+     * @return true if it is valid
+     */
+    @SuppressWarnings("resource")
+    private boolean isAAFFeed(int feedId) {
+        try {
+            Feed feed = Feed.getFeedById(feedId);
+            if (feed != null) {
+                if (!((feed.getAafInstance().equalsIgnoreCase("legacy")) || feed.getAafInstance() == null || feed.getAafInstance().equals(""))) { //also apply null check and empty check too
+                    aafInstance = feed.getAafInstance();
+                    String message = "DRProvCadiFilter.isAAFFeed: aafInstance-:" + aafInstance + "; feedId:- " + feedId;
+                    intlogger.debug(message);
+                    return true;
+                } else {
+                    return false;
+                }
+            } else {
+                String message = "DRProvCadiFilter.isAAFFeed; Feed does not exist FeedID:-" + feedId;
+                intlogger.debug(message);
+            }
+
+        } catch (Exception e) {
+            intlogger.error("PROV0073 DRProvCadiFilter.isAAFFeed: ", e);
+            return false;
+        }
+        return false;
+    }
+
+    /**
+     * Check if it is AAF sub OR existing sub.
+     *
+     * @param subId the Sub ID
+     * @return true if it is valid
+     */
+    @SuppressWarnings("resource")
+    private boolean isAAFSubscriber(int subId) {
+        try {
+            Subscription subscriber = Subscription.getSubscriptionById(subId);
+            if (subscriber != null) {
+                if (!((subscriber.getAafInstance().equalsIgnoreCase("legacy")) || subscriber.getAafInstance() == null || subscriber.getAafInstance().equals(""))) { //also apply null check and empty check too
+                    aafInstance = subscriber.getAafInstance();
+                    String message = "DRProvCadiFilter.isAAFSubscriber: aafInstance-:" + aafInstance + "; subId:- " + subId;
+                    intlogger.debug(message);
+                    return true;
+                } else {
+                    return false;
+                }
+            } else {
+                String message = "DRProvCadiFilter.isAAFSubscriber; Subscriber does not exist subId:-" + subId;
+                intlogger.debug(message);
+            }
+        } catch (Exception e) {
+            intlogger.error("PROV0073 DRProvCadiFilter.isAAFSubscriber: ", e);
+            return false;
+        }
+        return false;
+    }
+
+}
index af9f829..6c5a13f 100644 (file)
@@ -82,7 +82,7 @@ public class LogfileLoader extends Thread {
     /**\r
      * This is a singleton -- there is only one LogfileLoader object in the server\r
      */\r
     /**\r
      * This is a singleton -- there is only one LogfileLoader object in the server\r
      */\r
-    private static LogfileLoader p;\r
+    private static LogfileLoader logfileLoader;\r
 \r
     /**\r
      * Get the singleton LogfileLoader object, and start it if it is not running.\r
 \r
     /**\r
      * Get the singleton LogfileLoader object, and start it if it is not running.\r
@@ -90,11 +90,11 @@ public class LogfileLoader extends Thread {
      * @return the LogfileLoader\r
      */\r
     public static synchronized LogfileLoader getLoader() {\r
      * @return the LogfileLoader\r
      */\r
     public static synchronized LogfileLoader getLoader() {\r
-        if (p == null)\r
-            p = new LogfileLoader();\r
-        if (!p.isAlive())\r
-            p.start();\r
-        return p;\r
+        if (logfileLoader == null)\r
+            logfileLoader = new LogfileLoader();\r
+        if (!logfileLoader.isAlive())\r
+            logfileLoader.start();\r
+        return logfileLoader;\r
     }\r
 \r
     /**\r
     }\r
 \r
     /**\r
diff --git a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/PasswordProcessor.java b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/PasswordProcessor.java
new file mode 100644 (file)
index 0000000..4414203
--- /dev/null
@@ -0,0 +1,73 @@
+/**\r
+ * -\r
+ * ============LICENSE_START=======================================================\r
+ * Copyright (C) 2019 Nordix Foundation.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * <p>\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * <p>\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * <p>\r
+ * SPDX-License-Identifier: Apache-2.0\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.dmaap.datarouter.provisioning.utils;\r
+\r
+import javax.crypto.Cipher;\r
+import javax.crypto.SecretKey;\r
+import javax.crypto.SecretKeyFactory;\r
+import javax.crypto.spec.PBEKeySpec;\r
+import javax.crypto.spec.PBEParameterSpec;\r
+import java.nio.charset.StandardCharsets;\r
+import java.security.GeneralSecurityException;\r
+import java.util.Base64;\r
+\r
+/**\r
+ * The Processing of a Password.  Password can be encrypted and decrypted.\r
+ * @author Vikram Singh\r
+ * @version $Id: PasswordProcessor.java,v 1.0 2016/12/14 10:16:52 EST\r
+ */\r
+public class PasswordProcessor {\r
+\r
+    private PasswordProcessor(){}\r
+\r
+    private static final String SECRET_KEY_FACTORY_TYPE = "PBEWithMD5AndDES";\r
+    private static final String PASSWORD_ENCRYPTION_STRING = (new DB()).getProperties().getProperty("org.onap.dmaap.datarouter.provserver.passwordencryption");\r
+    private static final char[] PASSWORD = PASSWORD_ENCRYPTION_STRING.toCharArray();\r
+    private static final byte[] SALT = {(byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,};\r
+\r
+    /**\r
+     * Encrypt password.\r
+     * @param property the Password\r
+     * @return Encrypted password.\r
+     */\r
+    public static String encrypt(String property) throws GeneralSecurityException {\r
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_TYPE);\r
+        SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));\r
+        Cipher pbeCipher = Cipher.getInstance(SECRET_KEY_FACTORY_TYPE);\r
+        pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 32));\r
+        return Base64.getEncoder().encodeToString(pbeCipher.doFinal(property.getBytes(StandardCharsets.UTF_8)));\r
+    }\r
+\r
+    /**\r
+     * Decrypt password.\r
+     * @param property the Password\r
+     * @return Decrypt password.\r
+     */\r
+    public static String decrypt(String property) throws GeneralSecurityException {\r
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_TYPE);\r
+        SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));\r
+        Cipher pbeCipher = Cipher.getInstance(SECRET_KEY_FACTORY_TYPE);\r
+        pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 32));\r
+        return new String(pbeCipher.doFinal(Base64.getDecoder().decode(property)), StandardCharsets.UTF_8);\r
+    }\r
+\r
+}\r
diff --git a/datarouter-prov/src/main/resources/drProvCadi.properties b/datarouter-prov/src/main/resources/drProvCadi.properties
new file mode 100644 (file)
index 0000000..56f2e5c
--- /dev/null
@@ -0,0 +1,23 @@
+cadi_x509_issuers=CN=intermediateCA_1, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_7, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_9, OU=OSAAF, O=ONAP, C=US
+cadi_keyfile=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.keyfile
+cadi_keystore=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.jks
+cadi_keystore_password=AT{];bvaDiytVD&oWhMZj0N5
+cadi_key_password=AT{];bvaDiytVD&oWhMZj0N5
+cadi_alias=dmaap-dr-prov@dmaap-dr.onap.org
+cadi_truststore=/opt/app/datartr/aaf_certs/org.onap.dmaap-dr.trust.jks
+cadi_truststore_password=ljlS@Y}0]{UO(TnwvEWkgJ%]
+
+aaf_env=DEV
+aaf_locate_url=https://aaf-onap-test.osaaf.org:8095
+aaf_oauth2_introspect_url=https://AAF_LOCATE_URL/AAF_NS.introspect:2.1/introspect
+aaf_oauth2_token_url=https://AAF_LOCATE_URL/AAF_NS.token:2.1/token
+aaf_url=https://AAF_LOCATE_URL/AAF_NS.service:2.1
+cadi_protocols=TLSv1.1,TLSv1.2
+cm_url=https://AAF_LOCATE_URL/AAF_NS.cm:2.1
+fs_url=https://AAF_LOCATE_URL/AAF_NS.fs.2.1
+gui_url=https://AAF_LOCATE_URL/AAF_NS.gui.2.1
+
+cadi_latitude=53.423
+cadi_longitude=7.940
+
+cadi_loglevel=DEBUG
\ No newline at end of file
index 14c59a6..55f0aee 100755 (executable)
@@ -1,10 +1,8 @@
-use datarouter;
-
 CREATE TABLE FEEDS (
     FEEDID         INT UNSIGNED NOT NULL PRIMARY KEY,
     GROUPID        INT(10) UNSIGNED NOT NULL DEFAULT 0,
     NAME           VARCHAR(255) NOT NULL,
 CREATE TABLE FEEDS (
     FEEDID         INT UNSIGNED NOT NULL PRIMARY KEY,
     GROUPID        INT(10) UNSIGNED NOT NULL DEFAULT 0,
     NAME           VARCHAR(255) NOT NULL,
-    VERSION        VARCHAR(20) NOT NULL,
+    VERSION        VARCHAR(20) NULL,
     DESCRIPTION    VARCHAR(1000),
     BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL,
     AUTH_CLASS     VARCHAR(32) NOT NULL,
     DESCRIPTION    VARCHAR(1000),
     BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL,
     AUTH_CLASS     VARCHAR(32) NOT NULL,
@@ -16,13 +14,14 @@ CREATE TABLE FEEDS (
     DELETED        BOOLEAN DEFAULT FALSE,
     LAST_MOD       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED      BOOLEAN DEFAULT FALSE,
     DELETED        BOOLEAN DEFAULT FALSE,
     LAST_MOD       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED      BOOLEAN DEFAULT FALSE,
-    CREATED_DATE   TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+    CREATED_DATE   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    AAF_INSTANCE   VARCHAR(256)
 );
 
 CREATE TABLE FEED_ENDPOINT_IDS (
     FEEDID        INT UNSIGNED NOT NULL,
 );
 
 CREATE TABLE FEED_ENDPOINT_IDS (
     FEEDID        INT UNSIGNED NOT NULL,
-    USERID        VARCHAR(20) NOT NULL,
-    PASSWORD      VARCHAR(32) NOT NULL
+    USERID        VARCHAR(60) NOT NULL,
+    PASSWORD      VARCHAR(100) NOT NULL
 );
 
 CREATE TABLE FEED_ENDPOINT_ADDRS (
 );
 
 CREATE TABLE FEED_ENDPOINT_ADDRS (
@@ -35,8 +34,9 @@ CREATE TABLE SUBSCRIPTIONS (
     FEEDID                      INT UNSIGNED NOT NULL,
     GROUPID                     INT(10) UNSIGNED NOT NULL DEFAULT 0,
     DELIVERY_URL                VARCHAR(256),
     FEEDID                      INT UNSIGNED NOT NULL,
     GROUPID                     INT(10) UNSIGNED NOT NULL DEFAULT 0,
     DELIVERY_URL                VARCHAR(256),
-    DELIVERY_USER               VARCHAR(20),
-    DELIVERY_PASSWORD           VARCHAR(32),
+    FOLLOW_REDIRECTS            TINYINT(1) NOT NULL DEFAULT 0,
+    DELIVERY_USER               VARCHAR(60),
+    DELIVERY_PASSWORD           VARCHAR(100),
     DELIVERY_USE100             BOOLEAN DEFAULT FALSE,
     METADATA_ONLY               BOOLEAN DEFAULT FALSE,
     SUBSCRIBER                  VARCHAR(8) NOT NULL,
     DELIVERY_USE100             BOOLEAN DEFAULT FALSE,
     METADATA_ONLY               BOOLEAN DEFAULT FALSE,
     SUBSCRIBER                  VARCHAR(8) NOT NULL,
@@ -45,8 +45,9 @@ CREATE TABLE SUBSCRIPTIONS (
     LAST_MOD                    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED                   BOOLEAN DEFAULT FALSE,
     PRIVILEGED_SUBSCRIBER       BOOLEAN DEFAULT FALSE,
     LAST_MOD                    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED                   BOOLEAN DEFAULT FALSE,
     PRIVILEGED_SUBSCRIBER       BOOLEAN DEFAULT FALSE,
+    CREATED_DATE                TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     DECOMPRESS                  BOOLEAN DEFAULT FALSE,
     DECOMPRESS                  BOOLEAN DEFAULT FALSE,
-    CREATED_DATE                TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+    AAF_INSTANCE                VARCHAR(256)
 
 );
 
 
 );
 
@@ -89,7 +90,7 @@ CREATE TABLE LOG_RECORDS (
 CREATE TABLE INGRESS_ROUTES (
     SEQUENCE  INT UNSIGNED NOT NULL,
     FEEDID    INT UNSIGNED NOT NULL,
 CREATE TABLE INGRESS_ROUTES (
     SEQUENCE  INT UNSIGNED NOT NULL,
     FEEDID    INT UNSIGNED NOT NULL,
-    USERID    VARCHAR(20),
+    USERID    VARCHAR(50),
     SUBNET    VARCHAR(44),
     NODESET   INT UNSIGNED NOT NULL
 );
     SUBNET    VARCHAR(44),
     NODESET   INT UNSIGNED NOT NULL
 );
@@ -144,6 +145,6 @@ INSERT INTO PARAMETERS VALUES
     ('PROV_MAXFEED_COUNT',  '10000'),
     ('PROV_MAXSUB_COUNT',   '100000'),
     ('PROV_REQUIRE_CERT', 'false'),
     ('PROV_MAXFEED_COUNT',  '10000'),
     ('PROV_MAXSUB_COUNT',   '100000'),
     ('PROV_REQUIRE_CERT', 'false'),
-    ('PROV_REQUIRE_SECURE', 'false'),
+    ('PROV_REQUIRE_SECURE', 'true'),
     ('_INT_VALUES', 'LOGROLL_INTERVAL|PROV_MAXFEED_COUNT|PROV_MAXSUB_COUNT|DELIVERY_INIT_RETRY_INTERVAL|DELIVERY_MAX_RETRY_INTERVAL|DELIVERY_RETRY_RATIO|DELIVERY_MAX_AGE|DELIVERY_FILE_PROCESS_INTERVAL')
     ('_INT_VALUES', 'LOGROLL_INTERVAL|PROV_MAXFEED_COUNT|PROV_MAXSUB_COUNT|DELIVERY_INIT_RETRY_INTERVAL|DELIVERY_MAX_RETRY_INTERVAL|DELIVERY_RETRY_RATIO|DELIVERY_MAX_AGE|DELIVERY_FILE_PROCESS_INTERVAL')
-    ;
+    ;
\ No newline at end of file
index 4dcdee5..4539346 100755 (executable)
@@ -47,6 +47,22 @@ org.onap.dmaap.datarouter.provserver.localhost = 127.0.0.1
 
 # Database access
 org.onap.dmaap.datarouter.db.driver   = org.mariadb.jdbc.Driver
 
 # Database access
 org.onap.dmaap.datarouter.db.driver   = org.mariadb.jdbc.Driver
-org.onap.dmaap.datarouter.db.url      = jdbc:mariadb://172.100.0.2:3306/datarouter
+org.onap.dmaap.datarouter.db.url      = jdbc:mariadb://datarouter-mariadb:3306/datarouter
 org.onap.dmaap.datarouter.db.login    = datarouter
 org.onap.dmaap.datarouter.db.password = datarouter
 org.onap.dmaap.datarouter.db.login    = datarouter
 org.onap.dmaap.datarouter.db.password = datarouter
+
+# PROV - DEFAULT ENABLED TLS PROTOCOLS
+org.onap.dmaap.datarouter.provserver.https.include.protocols = TLSv1.1|TLSv1.2
+
+# AAF config
+org.onap.dmaap.datarouter.provserver.cadi.enabled = false
+
+org.onap.dmaap.datarouter.provserver.passwordencryption   = PasswordEncryptionKey#@$%^&1234#
+org.onap.dmaap.datarouter.provserver.aaf.feed.type        = org.onap.dmaap-dr.feed
+org.onap.dmaap.datarouter.provserver.aaf.sub.type         = org.onap.dmaap-dr.sub
+org.onap.dmaap.datarouter.provserver.aaf.instance         = legacy
+org.onap.dmaap.datarouter.provserver.aaf.action.publish   = publish
+org.onap.dmaap.datarouter.provserver.aaf.action.subscribe = subscribe
+
+# AAF URL to connect to AAF server
+org.onap.dmaap.datarouter.provserver.cadi.aaf.url = https://aaf-onap-test.osaaf.org:8095
\ No newline at end of file
index a8f9c56..e2a2bc2 100755 (executable)
  ******************************************************************************/
 package org.onap.dmaap.datarouter.provisioning;
 
  ******************************************************************************/
 package org.onap.dmaap.datarouter.provisioning;
 
-import static org.hamcrest.Matchers.notNullValue;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.argThat;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.read.ListAppender;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.jetbrains.annotations.NotNull;
 import org.json.JSONArray;
 import org.json.JSONObject;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.read.ListAppender;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.jetbrains.annotations.NotNull;
 import org.json.JSONArray;
 import org.json.JSONObject;
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
 import org.onap.dmaap.datarouter.authz.Authorizer;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
 import org.onap.dmaap.datarouter.authz.Authorizer;
-import org.onap.dmaap.datarouter.provisioning.beans.Feed;
 import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
 import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
+import org.onap.dmaap.datarouter.provisioning.utils.DB;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.powermock.modules.junit4.PowerMockRunner;
 
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Mockito.*;
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
+
 
 @RunWith(PowerMockRunner.class)
 
 @RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.onap.dmaap.datarouter.provisioning.beans.Feed")
 public class DRFeedsServletTest extends DrServletTestBase {
 
     private static DRFeedsServlet drfeedsServlet;
 public class DRFeedsServletTest extends DrServletTestBase {
 
     private static DRFeedsServlet drfeedsServlet;
+    private static EntityManagerFactory emf;
+    private static EntityManager em;
+    private DB db;
 
     @Mock
     private HttpServletRequest request;
     @Mock
     private HttpServletResponse response;
 
 
     @Mock
     private HttpServletRequest request;
     @Mock
     private HttpServletResponse response;
 
-    ListAppender<ILoggingEvent> listAppender;
+    private ListAppender<ILoggingEvent> listAppender;
+
+    @BeforeClass
+    public static void init() {
+        emf = Persistence.createEntityManagerFactory("dr-unit-tests");
+        em = emf.createEntityManager();
+        System.setProperty(
+                "org.onap.dmaap.datarouter.provserver.properties",
+                "src/test/resources/h2Database.properties");
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        em.clear();
+        em.close();
+        emf.close();
+    }
 
     @Before
     public void setUp() throws Exception {
 
     @Before
     public void setUp() throws Exception {
-        super.setUp();
         listAppender = setTestLogger(DRFeedsServlet.class);
         drfeedsServlet = new DRFeedsServlet();
         listAppender = setTestLogger(DRFeedsServlet.class);
         drfeedsServlet = new DRFeedsServlet();
+        db = new DB();
         setAuthoriserToReturnRequestIsAuthorized();
         setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
         setupValidAuthorisedRequest();
         setAuthoriserToReturnRequestIsAuthorized();
         setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
         setupValidAuthorisedRequest();
@@ -137,14 +153,11 @@ public class DRFeedsServletTest extends DrServletTestBase {
     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds_With_Valid_Name_And_Version() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds_With_Valid_Name_And_Version() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
-        when(request.getParameter("name")).thenReturn("stub_name");
-        when(request.getParameter("version")).thenReturn("stub_version");
-        PowerMockito.mockStatic(Feed.class);
-        Feed feed = mock(Feed.class);
-        PowerMockito.when(Feed.getFeedByNameVersion(anyString(), anyString())).thenReturn(feed);
-        when(feed.asJSONObject(true)).thenReturn(mock(JSONObject.class));
+        when(request.getParameter("name")).thenReturn("Feed1");
+        when(request.getParameter("version")).thenReturn("v0.1");
         drfeedsServlet.doGet(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
         drfeedsServlet.doGet(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+        verify(response).setContentType(BaseServlet.FEEDFULL_CONTENT_TYPE);
         verifyEnteringExitCalled(listAppender);
     }
 
         verifyEnteringExitCalled(listAppender);
     }
 
@@ -205,54 +218,70 @@ public class DRFeedsServletTest extends DrServletTestBase {
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
+    public void Given_Request_Is_HTTP_POST_And_CadiEnabled_Is_True_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
         throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
         throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isCadiEnabled", "true", true);
+        when(request.getHeader(DRFeedsServlet.EXCLUDE_AAF_HEADER)).thenReturn("true");
+        JSONObject JSObject = buildRequestJsonObject();
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "not_stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "legacy");
+                return jo;
+            }
+        };
         drfeedsServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
         drfeedsServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated()
-        throws Exception {
-        drfeedsServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
-    }
-
-    @Test
-    public void Given_Request_Is_HTTP_POST_And_Active_Feeds_Equals_Max_Feeds_Then_Bad_Request_Response_Is_Generated()
-        throws Exception {
-        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxFeeds", 0, true);
+    public void Given_Request_Is_HTTP_POST_And_CadiEnabled_Is_False_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
+            throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isCadiEnabled", "false", true);
+        when(request.getHeader(DRFeedsServlet.EXCLUDE_AAF_HEADER)).thenReturn("true");
+        JSONObject JSObject = buildRequestJsonObject();
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
-                return new JSONObject();
+                JSONObject jo = new JSONObject();
+                jo.put("name", "not_stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "legacy");
+                return jo;
             }
         };
         drfeedsServlet.doPost(request, response);
             }
         };
         drfeedsServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Feed_Is_Not_Valid_Object_Bad_Request_Response_Is_Generated()
-        throws Exception {
-        when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn(null);
+    public void Given_Request_Is_HTTP_POST_And_AAF_DRFeed_And_Exclude_AAF_Is_True_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getHeader(DRFeedsServlet.EXCLUDE_AAF_HEADER)).thenReturn("true");
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isCadiEnabled", "true", true);
         JSONObject JSObject = buildRequestJsonObject();
         JSONObject JSObject = buildRequestJsonObject();
-
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
+                jo.put("name", "not_stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "https://aaf-onap-test.osaaf.org:8095");
                 return jo;
             }
         };
                 return jo;
             }
         };
-
         drfeedsServlet.doPost(request, response);
         drfeedsServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("Invalid request exclude_AAF"));
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Feed_Already_Exists_Bad_Request_Response_Is_Generated()
-        throws Exception {
-        setFeedToReturnInvalidFeedIdSupplied();
+    public void Given_Request_Is_HTTP_POST_And_AAF_DRFeed_And_Exclude_AAF_Is_False_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getHeader(DRFeedsServlet.EXCLUDE_AAF_HEADER)).thenReturn("false");
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isCadiEnabled", "true", true);
         JSONObject JSObject = buildRequestJsonObject();
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         JSONObject JSObject = buildRequestJsonObject();
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
@@ -260,59 +289,119 @@ public class DRFeedsServletTest extends DrServletTestBase {
                 jo.put("name", "not_stub_name");
                 jo.put("version", "1.0");
                 jo.put("authorization", JSObject);
                 jo.put("name", "not_stub_name");
                 jo.put("version", "1.0");
                 jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "*");
                 return jo;
             }
         };
         drfeedsServlet.doPost(request, response);
                 return jo;
             }
         };
         drfeedsServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access to permission"));
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_POST_Fails_Bad_Request_Response_Is_Generated() throws Exception {
+    public void Given_Request_Is_HTTP_POST_And_AAF_DRFeed_And_Exclude_AAF_Is_False_With_Permissions_Then_Created_OK_Response_Is_Generated() throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isCadiEnabled", "true", true);
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getHeader(DRFeedsServlet.EXCLUDE_AAF_HEADER)).thenReturn("false");
         JSONObject JSObject = buildRequestJsonObject();
         JSONObject JSObject = buildRequestJsonObject();
+        when(request.isUserInRole("org.onap.dmaap-dr.feed|*|create")).thenReturn(true);
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
-                jo.put("name", "stub_name");
-                jo.put("version", "2.0");
+                jo.put("name", "not_stub_name");
+                jo.put("version", "1.0");
                 jo.put("authorization", JSObject);
                 jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "*");
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
-                return false;
+                return true;
             }
         };
         drfeedsServlet.doPost(request, response);
             }
         };
         drfeedsServlet.doPost(request, response);
-        verify(response)
-            .sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+        verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
+        verifyEnteringExitCalled(listAppender);
     }
 
     }
 
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated()
+        throws Exception {
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
 
     @Test
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Change_On_Feeds_Succeeds_A_STATUS_OK_Response_Is_Generated()
+    public void Given_Request_Is_HTTP_POST_And_Active_Feeds_Equals_Max_Feeds_Then_Bad_Request_Response_Is_Generated()
         throws Exception {
         throws Exception {
-        ServletOutputStream outStream = mock(ServletOutputStream.class);
-        when(response.getOutputStream()).thenReturn(outStream);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxFeeds", 0, true);
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                return new JSONObject();
+            }
+        };
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Feed_Is_Not_Valid_Object_Bad_Request_Response_Is_Generated()
+        throws Exception {
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                return new JSONObject();
+            }
+        };
+
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Feed_Already_Exists_Bad_Request_Response_Is_Generated()
+        throws Exception {
+        when(request.getParameter("name")).thenReturn("AafFeed");
+        when(request.getParameter("version")).thenReturn("v0.1");
+        when(request.getHeader(DRFeedsServlet.EXCLUDE_AAF_HEADER)).thenReturn("false");
+        when(request.isUserInRole("org.onap.dmaap-dr.feed|*|create")).thenReturn(true);
         JSONObject JSObject = buildRequestJsonObject();
         JSONObject JSObject = buildRequestJsonObject();
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "AafFeed");
+                jo.put("version", "v0.1");
+                jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "*");
+                return jo;
+            }
+        };
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), contains("This feed already exists in the database"));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_POST_Fails_Bad_Request_Response_Is_Generated() throws Exception {
+        JSONObject JSObject = buildRequestJsonObject();
+        when(request.getHeader(DRFeedsServlet.EXCLUDE_AAF_HEADER)).thenReturn("true");
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
                 jo.put("name", "stub_name");
         DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
                 jo.put("name", "stub_name");
-                jo.put("version", "1.0");
+                jo.put("version", "2.0");
                 jo.put("authorization", JSObject);
                 jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "legacy");
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
-                return true;
+                return false;
             }
         };
         drfeedsServlet.doPost(request, response);
             }
         };
         drfeedsServlet.doPost(request, response);
-        verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
-        verifyEnteringExitCalled(listAppender);
+        verify(response)
+            .sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
     }
 
     @NotNull
     }
 
     @NotNull
@@ -335,7 +424,7 @@ public class DRFeedsServletTest extends DrServletTestBase {
 
     private void setUpValidSecurityOnHttpRequest() throws Exception {
         when(request.isSecure()).thenReturn(true);
 
     private void setUpValidSecurityOnHttpRequest() throws Exception {
         when(request.isSecure()).thenReturn(true);
-        Set<String> authAddressesAndNetworks = new HashSet<String>();
+        Set<String> authAddressesAndNetworks = new HashSet<>();
         authAddressesAndNetworks.add(("127.0.0.1"));
         FieldUtils
             .writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks,
         authAddressesAndNetworks.add(("127.0.0.1"));
         FieldUtils
             .writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks,
@@ -348,29 +437,6 @@ public class DRFeedsServletTest extends DrServletTestBase {
         when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
     }
 
         when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
     }
 
-    private void setValidPathInfoInHttpHeader() {
-        when(request.getPathInfo()).thenReturn("/123");
-    }
-
-    private void setFeedToReturnInvalidFeedIdSupplied() {
-        PowerMockito.mockStatic(Feed.class);
-        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(null);
-        when(Feed.getFeedByNameVersion(anyString(), anyString())).thenReturn(mock(Feed.class));
-    }
-
-    private void setFeedToReturnValidFeedForSuppliedId() {
-        PowerMockito.mockStatic(Feed.class);
-        Feed feed = mock(Feed.class);
-        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
-        when(feed.isDeleted()).thenReturn(false);
-        when(feed.asJSONObject(true)).thenReturn(mock(JSONObject.class));
-        when(feed.getPublisher()).thenReturn("Stub_Value");
-        when(feed.getName()).thenReturn("stub_name");
-        when(feed.getVersion()).thenReturn("1.0");
-        when(feed.asLimitedJSONObject()).thenReturn(mock(JSONObject.class));
-        PowerMockito.when(feed.getFeedByNameVersion(anyString(), anyString())).thenReturn(null);
-    }
-
     private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
         Authorizer authorizer = mock(Authorizer.class);
     private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
         Authorizer authorizer = mock(Authorizer.class);
@@ -395,13 +461,10 @@ public class DRFeedsServletTest extends DrServletTestBase {
     private void setupValidAuthorisedRequest() throws Exception {
         setUpValidSecurityOnHttpRequest();
         setBehalfHeader("Stub_Value");
     private void setupValidAuthorisedRequest() throws Exception {
         setUpValidSecurityOnHttpRequest();
         setBehalfHeader("Stub_Value");
-        setValidPathInfoInHttpHeader();
-        setFeedToReturnValidFeedForSuppliedId();
     }
 
     }
 
-    private void setUpValidContentHeadersAndJSONOnHttpRequest() {
+    private void setUpValidContentHeadersAndJSONOnHttpRequest() throws IllegalAccessException {
         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed; version=1.0");
         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed; version=1.0");
         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
-
     }
 }
     }
 }
index 265a2ee..bad6e2c 100644 (file)
@@ -28,17 +28,11 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.read.ListAppender;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.junit.After;
 import ch.qos.logback.core.read.ListAppender;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Assert;
 import org.junit.Before;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
 import org.slf4j.LoggerFactory;
 
 import org.junit.Before;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.PrintWriter;
 import java.util.Properties;
 import java.util.Properties;
-import java.util.Scanner;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
@@ -46,7 +40,6 @@ import static org.mockito.Mockito.when;
 
 public class DrServletTestBase {
 
 
 public class DrServletTestBase {
 
-
     @Before
     public void setUp() throws Exception {
         Properties props = new Properties();
     @Before
     public void setUp() throws Exception {
         Properties props = new Properties();
@@ -61,7 +54,7 @@ public class DrServletTestBase {
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "synctask", synchronizerTask, true);
     }
 
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "synctask", synchronizerTask, true);
     }
 
-    public ListAppender<ILoggingEvent> setTestLogger(Class c) {
+    ListAppender<ILoggingEvent> setTestLogger(Class c) {
         Logger logger = (Logger) LoggerFactory.getLogger(c);
         ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
         listAppender.start();
         Logger logger = (Logger) LoggerFactory.getLogger(c);
         ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
         listAppender.start();
@@ -69,7 +62,7 @@ public class DrServletTestBase {
         return listAppender;
     }
 
         return listAppender;
     }
 
-    public void verifyEnteringExitCalled(ListAppender<ILoggingEvent> listAppender) {
+    void verifyEnteringExitCalled(ListAppender<ILoggingEvent> listAppender) {
         assertEquals("EELF0004I  Entering data router provisioning component with RequestId and InvocationId", listAppender.list.get(0).getMessage());
         assertEquals("EELF0005I  Exiting data router provisioning component with RequestId and InvocationId", listAppender.list.get(2).getMessage());
         assertEquals(3, listAppender.list.size());
         assertEquals("EELF0004I  Entering data router provisioning component with RequestId and InvocationId", listAppender.list.get(0).getMessage());
         assertEquals("EELF0005I  Exiting data router provisioning component with RequestId and InvocationId", listAppender.list.get(2).getMessage());
         assertEquals(3, listAppender.list.size());
index f042e11..f4eac05 100755 (executable)
@@ -71,7 +71,7 @@ public class FeedServletTest extends DrServletTestBase {
     private static EntityManager em;
     private DB db;
 
     private static EntityManager em;
     private DB db;
 
-    ListAppender<ILoggingEvent> listAppender;
+    private ListAppender<ILoggingEvent> listAppender;
 
     @BeforeClass
     public static void init() {
 
     @BeforeClass
     public static void init() {
@@ -120,8 +120,7 @@ public class FeedServletTest extends DrServletTestBase {
 
 
     @Test
 
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated()
-        throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
         when(request.getPathInfo()).thenReturn(null);
         feedServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
         when(request.getPathInfo()).thenReturn(null);
         feedServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
@@ -129,8 +128,7 @@ public class FeedServletTest extends DrServletTestBase {
 
 
     @Test
 
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated()
-        throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
         when(request.getPathInfo()).thenReturn("/123");
         feedServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
         when(request.getPathInfo()).thenReturn("/123");
         feedServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
@@ -138,13 +136,28 @@ public class FeedServletTest extends DrServletTestBase {
 
 
     @Test
 
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
-        throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
         feedServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
         setAuthoriserToReturnRequestNotAuthorized();
         feedServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_AAF_Feed_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/2");
+        feedServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access to permission"));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_AAF_Feed_With_Permissions_Then_A_NO_CONTENT_Response_Is_Generated() {
+        when(request.getPathInfo()).thenReturn("/3");
+        when(request.isUserInRole("org.onap.dmaap-dr.feed|*|delete")).thenReturn(true);
+        feedServlet.doDelete(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
+        verifyEnteringExitCalled(listAppender);
+    }
+
 
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Fails_An_Internal_Server_Error_Is_Reported()
 
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Fails_An_Internal_Server_Error_Is_Reported()
@@ -161,8 +174,7 @@ public class FeedServletTest extends DrServletTestBase {
 
 
     @Test
 
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Succeeds_A_NO_CONTENT_Response_Is_Generated()
-        throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Succeeds_A_NO_CONTENT_Response_Is_Generated() throws Exception {
         feedServlet.doDelete(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
         reinsertFeedIntoDb();
         feedServlet.doDelete(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
         reinsertFeedIntoDb();
@@ -209,6 +221,7 @@ public class FeedServletTest extends DrServletTestBase {
     public void Given_Request_Is_HTTP_GET_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
         throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
     public void Given_Request_Is_HTTP_GET_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
         throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
+        when(request.getPathInfo()).thenReturn("/2");
         feedServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
         feedServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
@@ -218,6 +231,7 @@ public class FeedServletTest extends DrServletTestBase {
     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getPathInfo()).thenReturn("/2");
         feedServlet.doGet(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
         verifyEnteringExitCalled(listAppender);
         feedServlet.doGet(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
         verifyEnteringExitCalled(listAppender);
@@ -264,9 +278,9 @@ public class FeedServletTest extends DrServletTestBase {
         throws Exception {
         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed-fail; version=2.0");
         when(request.getContentType()).thenReturn("stub_contentType");
         throws Exception {
         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed-fail; version=2.0");
         when(request.getContentType()).thenReturn("stub_contentType");
+        when(request.getPathInfo()).thenReturn("/2");
         feedServlet.doPut(request, response);
         feedServlet.doPut(request, response);
-        verify(response)
-            .sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
     }
 
     @Test
     }
 
     @Test
@@ -274,12 +288,19 @@ public class FeedServletTest extends DrServletTestBase {
         throws Exception {
         ServletInputStream inStream = mock(ServletInputStream.class);
         when(request.getInputStream()).thenReturn(inStream);
         throws Exception {
         ServletInputStream inStream = mock(ServletInputStream.class);
         when(request.getInputStream()).thenReturn(inStream);
+        when(request.getPathInfo()).thenReturn("/2");
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                return null;
+            }
+        };
         feedServlet.doPut(request, response);
         feedServlet.doPut(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), contains("Badly formed JSON"));
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Request_Contains_Invalid_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Request_Contains_Invalid_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/2");
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 return new JSONObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 return new JSONObject();
@@ -292,6 +313,7 @@ public class FeedServletTest extends DrServletTestBase {
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Feed_Change_Is_Not_Publisher_Who_Requested_Feed_Bad_Request_Response_Is_Generated() throws Exception {
         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn(null);
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Feed_Change_Is_Not_Publisher_Who_Requested_Feed_Bad_Request_Response_Is_Generated() throws Exception {
         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn(null);
+        when(request.getPathInfo()).thenReturn("/2");
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
@@ -302,13 +324,13 @@ public class FeedServletTest extends DrServletTestBase {
                 return jo;
             }
         };
                 return jo;
             }
         };
-
         feedServlet.doPut(request, response);
         feedServlet.doPut(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), contains("must be modified by the same publisher"));
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Feed_Name_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Feed_Name_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/2");
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
@@ -320,52 +342,99 @@ public class FeedServletTest extends DrServletTestBase {
             }
         };
         feedServlet.doPut(request, response);
             }
         };
         feedServlet.doPut(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), contains("name of the feed may not be updated"));
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Feed_Version_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Feed_Version_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/2");
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
-                jo.put("name", "stub_name");
-                jo.put("version", "2.0");
+                jo.put("name", "AafFeed");
+                jo.put("version", "v0.2");
                 jo.put("authorization", JSObject);
                 return jo;
             }
         };
         feedServlet.doPut(request, response);
                 jo.put("authorization", JSObject);
                 return jo;
             }
         };
         feedServlet.doPut(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), contains("version of the feed may not be updated"));
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        when(request.getPathInfo()).thenReturn("/2");
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
-                jo.put("name", "Feed1");
+                jo.put("name", "AafFeed");
                 jo.put("version", "v0.1");
                 jo.put("authorization", JSObject);
                 return jo;
             }
         };
                 jo.put("version", "v0.1");
                 jo.put("authorization", JSObject);
                 return jo;
             }
         };
-        setAuthoriserToReturnRequestNotAuthorized();
         feedServlet.doPut(request, response);
         feedServlet.doPut(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("Policy Engine disallows access"));
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Fails_An_Internal_Server_Error_Response_Is_Generated() throws Exception {
+    public void Given_Request_Is_HTTP_PUT_And_AAF_Feed_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/2");
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "AafFeed");
+                jo.put("version", "v0.1");
+                jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "https://aaf-onap-test.osaaf.org:8095");
+                return jo;
+            }
+        };
+        feedServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access to permission"));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_AAF_Feed_With_Permissions_Then_STATUS_OK__Response_Is_Generated() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getPathInfo()).thenReturn("/2");
+        when(request.isUserInRole("org.onap.dmaap-dr.feed|*|edit")).thenReturn(true);
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "AafFeed");
+                jo.put("version", "v0.1");
+                jo.put("authorization", JSObject);
+                jo.put("aaf_instance", "*");
+                return jo;
+            }
+            @Override
+            protected boolean doUpdate(Updateable bean) {
+                return true;
+            }
+
+        };
+        feedServlet.doPut(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+        verifyEnteringExitCalled(listAppender);
+    }
 
 
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Fails_An_Internal_Server_Error_Response_Is_Generated() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getPathInfo()).thenReturn("/2");
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
-                jo.put("name", "Feed1");
+                jo.put("name", "AafFeed");
                 jo.put("version", "v0.1");
                 jo.put("authorization", JSObject);
                 return jo;
                 jo.put("version", "v0.1");
                 jo.put("authorization", JSObject);
                 return jo;
@@ -384,15 +453,20 @@ public class FeedServletTest extends DrServletTestBase {
     public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Suceeds_A_STATUS_OK_Response_Is_Generated() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
     public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Suceeds_A_STATUS_OK_Response_Is_Generated() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getPathInfo()).thenReturn("/2");
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
         JSONObject JSObject = buildRequestJsonObject();
         FeedServlet feedServlet = new FeedServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
                 JSONObject jo = new JSONObject();
-                jo.put("name", "Feed1");
+                jo.put("name", "AafFeed");
                 jo.put("version", "v0.1");
                 jo.put("authorization", JSObject);
                 return jo;
             }
                 jo.put("version", "v0.1");
                 jo.put("authorization", JSObject);
                 return jo;
             }
+            @Override
+            protected boolean doUpdate(Updateable bean) {
+                return true;
+            }
 
         };
         feedServlet.doPut(request, response);
 
         };
         feedServlet.doPut(request, response);
@@ -427,11 +501,9 @@ public class FeedServletTest extends DrServletTestBase {
 
     private void setUpValidSecurityOnHttpRequest() throws Exception {
         when(request.isSecure()).thenReturn(true);
 
     private void setUpValidSecurityOnHttpRequest() throws Exception {
         when(request.isSecure()).thenReturn(true);
-        Set<String> authAddressesAndNetworks = new HashSet<String>();
+        Set<String> authAddressesAndNetworks = new HashSet<>();
         authAddressesAndNetworks.add(("127.0.0.1"));
         authAddressesAndNetworks.add(("127.0.0.1"));
-        FieldUtils
-            .writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks,
-                true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks,true);
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
     }
 
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
     }
 
index 0b5c23f..b867c67 100755 (executable)
@@ -27,19 +27,24 @@ import ch.qos.logback.core.read.ListAppender;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.jetbrains.annotations.NotNull;
 import org.json.JSONObject;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.jetbrains.annotations.NotNull;
 import org.json.JSONObject;
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
 import org.onap.dmaap.datarouter.authz.Authorizer;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
 import org.onap.dmaap.datarouter.authz.Authorizer;
-import org.onap.dmaap.datarouter.provisioning.beans.Feed;
 import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
 import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
 import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
 import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
+import org.onap.dmaap.datarouter.provisioning.utils.DB;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
+import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.powermock.modules.junit4.PowerMockRunner;
 
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -54,20 +59,39 @@ import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
 
 
 @RunWith(PowerMockRunner.class)
 
 
 @RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor({"org.onap.dmaap.datarouter.provisioning.beans.Feed", "org.onap.dmaap.datarouter.provisioning.beans.Subscription"})
+@PrepareForTest(Subscription.class)
 public class SubscribeServletTest extends DrServletTestBase {
     private static SubscribeServlet subscribeServlet;
 public class SubscribeServletTest extends DrServletTestBase {
     private static SubscribeServlet subscribeServlet;
+    private static EntityManagerFactory emf;
+    private static EntityManager em;
+    private DB db;
 
     @Mock
     private HttpServletRequest request;
     @Mock
     private HttpServletResponse response;
 
 
     @Mock
     private HttpServletRequest request;
     @Mock
     private HttpServletResponse response;
 
-    ListAppender<ILoggingEvent> listAppender;
+    private ListAppender<ILoggingEvent> listAppender;
+
+    @BeforeClass
+    public static void init() {
+        emf = Persistence.createEntityManagerFactory("dr-unit-tests");
+        em = emf.createEntityManager();
+        System.setProperty(
+                "org.onap.dmaap.datarouter.provserver.properties",
+                "src/test/resources/h2Database.properties");
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        em.clear();
+        em.close();
+        emf.close();
+    }
 
     @Before
     public void setUp() throws Exception {
 
     @Before
     public void setUp() throws Exception {
-        super.setUp();
+        db = new DB();
         listAppender = setTestLogger(SubscribeServlet.class);
         subscribeServlet = new SubscribeServlet();
         setAuthoriserToReturnRequestIsAuthorized();
         listAppender = setTestLogger(SubscribeServlet.class);
         subscribeServlet = new SubscribeServlet();
         setAuthoriserToReturnRequestIsAuthorized();
@@ -110,26 +134,18 @@ public class SubscribeServletTest extends DrServletTestBase {
 
     @Test
     public void Given_Request_Is_HTTP_GET_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
 
     @Test
     public void Given_Request_Is_HTTP_GET_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
-        setFeedToReturnInvalidFeedIdSupplied();
+        when(request.getPathInfo()).thenReturn("/123");
         subscribeServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
 
         subscribeServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
 
-
-    @Test
-    public void Given_Request_Is_HTTP_GET_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
-        setAuthoriserToReturnRequestNotAuthorized();
-        subscribeServlet.doGet(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
-    }
-
-
     @Test
     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
     @Test
     public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getPathInfo()).thenReturn("/1");
         PowerMockito.mockStatic(Subscription.class);
         PowerMockito.mockStatic(Subscription.class);
-        List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
         list.add("{}");
         PowerMockito.when(Subscription.getSubscriptionUrlList(anyInt())).thenReturn(list);
         subscribeServlet.doGet(request, response);
         list.add("{}");
         PowerMockito.when(Subscription.getSubscriptionUrlList(anyInt())).thenReturn(list);
         subscribeServlet.doGet(request, response);
@@ -171,7 +187,7 @@ public class SubscribeServletTest extends DrServletTestBase {
 
     @Test
     public void Given_Request_Is_HTTP_POST_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
 
     @Test
     public void Given_Request_Is_HTTP_POST_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
-        setFeedToReturnInvalidFeedIdSupplied();
+        when(request.getPathInfo()).thenReturn("/123");
         subscribeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
         subscribeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -179,41 +195,107 @@ public class SubscribeServletTest extends DrServletTestBase {
     @Test
     public void Given_Request_Is_HTTP_POST_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
     @Test
     public void Given_Request_Is_HTTP_POST_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
+        when(request.getPathInfo()).thenReturn("/1");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscribeServlet subscribeServlet = new SubscribeServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("sync", false);
+                return jo;
+            }
+            @Override
+            protected boolean doInsert(Insertable bean) {
+                return false;
+            }
+        };
         subscribeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
         subscribeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
-        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed; version=1.1");
-        when(request.getContentType()).thenReturn("stub_contentType");
+    public void Given_Request_Is_HTTP_POST_And_AAF_Subscriber_Added_To_Legacy_Feed_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/1");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscribeServlet subscribeServlet = new SubscribeServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "*");
+                jo.put("follow_redirect", false);
+                jo.put("sync", false);
+                return jo;
+            }
+            @Override
+            protected boolean doInsert(Insertable bean) {
+                return false;
+            }
+        };
         subscribeServlet.doPost(request, response);
         subscribeServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF Subscriber can not be added to legacy Feed"));
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+    public void Given_Request_Is_HTTP_POST_And_Legacy_Subscriber_Added_To_AAF_Feed_And_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        when(request.getPathInfo()).thenReturn("/2");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscribeServlet subscribeServlet = new SubscribeServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "legacy");
+                jo.put("follow_redirect", false);
+                jo.put("sync", false);
+                return jo;
+            }
+        };
         subscribeServlet.doPost(request, response);
         subscribeServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("Policy Engine disallows access."));
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Active_Feeds_Equals_Max_Feeds_Then_Bad_Request_Response_Is_Generated() throws Exception {
-        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxSubs", 0, true);
+    public void Given_Request_Is_HTTP_POST_And_AAF_Subscriber_Added_To_AAF_Feed_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/2");
+        JSONObject JSObject = buildRequestJsonObject();
         SubscribeServlet subscribeServlet = new SubscribeServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         SubscribeServlet subscribeServlet = new SubscribeServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
-                return new JSONObject();
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "*");
+                jo.put("follow_redirect", false);
+                jo.put("sync", false);
+                return jo;
             }
         };
         subscribeServlet.doPost(request, response);
             }
         };
         subscribeServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access to permission"));
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_POST_Fails_Bad_Request_Response_Is_Generated() throws Exception {
+    public void Given_Request_Is_HTTP_POST_And_AAF_Subscriber_Added_To_AAF_Feed_With_Permissions_Then_OK_Response_Is_Generated() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getPathInfo()).thenReturn("/2");
+        when(request.isUserInRole("org.onap.dmaap-dr.feed|*|approveSub")).thenReturn(true);
         PowerMockito.mockStatic(Subscription.class);
         PowerMockito.mockStatic(Subscription.class);
-        PowerMockito.when(Subscription.getSubscriptionMatching(mock(Subscription.class))).thenReturn(null);
-        PowerMockito.when(Subscription.countActiveSubscriptions()).thenReturn(0);
+        PowerMockito.when(Subscription.getSubscriptionMatching(new Subscription())).thenReturn(null);
         JSONObject JSObject = buildRequestJsonObject();
         SubscribeServlet subscribeServlet = new SubscribeServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         JSONObject JSObject = buildRequestJsonObject();
         SubscribeServlet subscribeServlet = new SubscribeServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
@@ -223,26 +305,56 @@ public class SubscribeServletTest extends DrServletTestBase {
                 jo.put("metadataOnly", true);
                 jo.put("suspend", true);
                 jo.put("delivery", JSObject);
                 jo.put("metadataOnly", true);
                 jo.put("suspend", true);
                 jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "*");
+                jo.put("follow_redirect", false);
                 jo.put("sync", false);
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
                 jo.put("sync", false);
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
-                return false;
+                return true;
             }
         };
         subscribeServlet.doPost(request, response);
             }
         };
         subscribeServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+        verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
+        verifyEnteringExitCalled(listAppender);
     }
 
     }
 
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.feed; version=1.1");
+        when(request.getContentType()).thenReturn("stub_contentType");
+        when(request.getPathInfo()).thenReturn("/1");
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
+    }
 
     @Test
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Change_On_Feeds_Succeeds_A_STATUS_OK_Response_Is_Generated() throws Exception {
-        ServletOutputStream outStream = mock(ServletOutputStream.class);
-        when(response.getOutputStream()).thenReturn(outStream);
+    public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/1");
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Active_Feeds_Equals_Max_Feeds_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxSubs", 0, true);
+        when(request.getPathInfo()).thenReturn("/1");
+        SubscribeServlet subscribeServlet = new SubscribeServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                return new JSONObject();
+            }
+        };
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_POST_Fails_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/2");
         PowerMockito.mockStatic(Subscription.class);
         PowerMockito.mockStatic(Subscription.class);
-        PowerMockito.when(Subscription.getSubscriptionMatching(mock(Subscription.class))).thenReturn(null);
+        PowerMockito.when(Subscription.getSubscriptionMatching(new Subscription())).thenReturn(null);
         JSONObject JSObject = buildRequestJsonObject();
         SubscribeServlet subscribeServlet = new SubscribeServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         JSONObject JSObject = buildRequestJsonObject();
         SubscribeServlet subscribeServlet = new SubscribeServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
@@ -252,21 +364,21 @@ public class SubscribeServletTest extends DrServletTestBase {
                 jo.put("metadataOnly", true);
                 jo.put("suspend", true);
                 jo.put("delivery", JSObject);
                 jo.put("metadataOnly", true);
                 jo.put("suspend", true);
                 jo.put("delivery", JSObject);
-                jo.put("sync", true);
+                jo.put("aaf_instance", "legacy");
+                jo.put("follow_redirect", false);
+                jo.put("sync", false);
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
                 return jo;
             }
 
             @Override
             protected boolean doInsert(Insertable bean) {
-                return true;
+                return false;
             }
         };
         subscribeServlet.doPost(request, response);
             }
         };
         subscribeServlet.doPost(request, response);
-        verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
-        verifyEnteringExitCalled(listAppender);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
     }
 
     }
 
-
     @NotNull
     private JSONObject buildRequestJsonObject() {
         JSONObject JSObject = new JSONObject();
     @NotNull
     private JSONObject buildRequestJsonObject() {
         JSONObject JSObject = new JSONObject();
@@ -279,7 +391,7 @@ public class SubscribeServletTest extends DrServletTestBase {
 
     private void setUpValidSecurityOnHttpRequest() throws Exception {
         when(request.isSecure()).thenReturn(true);
 
     private void setUpValidSecurityOnHttpRequest() throws Exception {
         when(request.isSecure()).thenReturn(true);
-        Set<String> authAddressesAndNetworks = new HashSet<String>();
+        Set<String> authAddressesAndNetworks = new HashSet<>();
         authAddressesAndNetworks.add(("127.0.0.1"));
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks, true);
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
         authAddressesAndNetworks.add(("127.0.0.1"));
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks, true);
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
@@ -290,27 +402,6 @@ public class SubscribeServletTest extends DrServletTestBase {
         when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
     }
 
         when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
     }
 
-    private void setValidPathInfoInHttpHeader() {
-        when(request.getPathInfo()).thenReturn("/123");
-    }
-
-    private void setFeedToReturnInvalidFeedIdSupplied() {
-        PowerMockito.mockStatic(Feed.class);
-        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(null);
-    }
-
-    private void setFeedToReturnValidFeedForSuppliedId() {
-        PowerMockito.mockStatic(Feed.class);
-        Feed feed = mock(Feed.class);
-        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
-        when(feed.isDeleted()).thenReturn(false);
-        when(feed.asJSONObject(true)).thenReturn(mock(JSONObject.class));
-        when(feed.getPublisher()).thenReturn("Stub_Value");
-        when(feed.getName()).thenReturn("stub_name");
-        when(feed.getVersion()).thenReturn("1.0");
-        when(feed.asLimitedJSONObject()).thenReturn(mock(JSONObject.class));
-    }
-
     private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
         Authorizer authorizer = mock(Authorizer.class);
     private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
         AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
         Authorizer authorizer = mock(Authorizer.class);
@@ -335,8 +426,6 @@ public class SubscribeServletTest extends DrServletTestBase {
     private void setupValidAuthorisedRequest() throws Exception {
         setUpValidSecurityOnHttpRequest();
         setBehalfHeader("Stub_Value");
     private void setupValidAuthorisedRequest() throws Exception {
         setUpValidSecurityOnHttpRequest();
         setBehalfHeader("Stub_Value");
-        setValidPathInfoInHttpHeader();
-        setFeedToReturnValidFeedForSuppliedId();
     }
 
     private void setUpValidContentHeadersAndJSONOnHttpRequest() {
     }
 
     private void setUpValidContentHeadersAndJSONOnHttpRequest() {
index aede69c..a17e23e 100755 (executable)
@@ -27,7 +27,10 @@ import ch.qos.logback.core.read.ListAppender;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.jetbrains.annotations.NotNull;
 import org.json.JSONObject;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.jetbrains.annotations.NotNull;
 import org.json.JSONObject;
-import org.junit.*;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
@@ -37,6 +40,9 @@ import org.onap.dmaap.datarouter.provisioning.beans.SubDelivery;
 import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
 import org.onap.dmaap.datarouter.provisioning.beans.Updateable;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
 import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
 import org.onap.dmaap.datarouter.provisioning.beans.Updateable;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
+import org.onap.dmaap.datarouter.provisioning.utils.PasswordProcessor;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import javax.persistence.EntityManager;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import javax.persistence.EntityManager;
@@ -46,7 +52,6 @@ import javax.servlet.ServletInputStream;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.FileNotFoundException;
 import java.sql.SQLException;
 import java.util.HashSet;
 import java.util.Set;
 import java.sql.SQLException;
 import java.util.HashSet;
 import java.util.Set;
@@ -57,6 +62,7 @@ import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
 
 
 @RunWith(PowerMockRunner.class)
 
 
 @RunWith(PowerMockRunner.class)
+@PrepareForTest(PasswordProcessor.class)
 public class SubscriptionServletTest extends DrServletTestBase {
     private static EntityManagerFactory emf;
     private static EntityManager em;
 public class SubscriptionServletTest extends DrServletTestBase {
     private static EntityManagerFactory emf;
     private static EntityManager em;
@@ -72,7 +78,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
     @Mock
     private HttpServletResponse response;
 
     @Mock
     private HttpServletResponse response;
 
-    ListAppender<ILoggingEvent> listAppender;
+    private ListAppender<ILoggingEvent> listAppender;
 
     @BeforeClass
     public static void init() {
 
     @BeforeClass
     public static void init() {
@@ -84,7 +90,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
     }
 
     @AfterClass
     }
 
     @AfterClass
-    public static void tearDownClass() throws FileNotFoundException {
+    public static void tearDownClass() {
         em.clear();
         em.close();
         emf.close();
         em.clear();
         em.close();
         emf.close();
@@ -125,7 +131,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
 
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
 
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
-        when(request.getPathInfo()).thenReturn("/3");
+        when(request.getPathInfo()).thenReturn("/123");
         subscriptionServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
         subscriptionServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -149,11 +155,22 @@ public class SubscriptionServletTest extends DrServletTestBase {
     }
 
     @Test
     }
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Succeeds_A_NO_CONTENT_Response_Is_Generated() throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_AAF_CADI_Is_Enabled_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
+        when(request.getPathInfo()).thenReturn("/2");
+        subscriptionServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access"));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_AAF_CADI_Is_Enabled_With_Permissions_Then_A_NO_CONTENT_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
+        when(request.getPathInfo()).thenReturn("/2");
+        when(request.isUserInRole("org.onap.dmaap-dr.sub|*|delete")).thenReturn(true);
         subscriptionServlet.doDelete(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
         verifyEnteringExitCalled(listAppender);
         subscriptionServlet.doDelete(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
         verifyEnteringExitCalled(listAppender);
-        insertSubscriptionIntoDb();
+        resetAafSubscriptionInDB();
     }
 
     @Test
     }
 
     @Test
@@ -180,7 +197,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
 
     @Test
     public void Given_Request_Is_HTTP_GET_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
 
     @Test
     public void Given_Request_Is_HTTP_GET_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
-        when(request.getPathInfo()).thenReturn("/3");
+        when(request.getPathInfo()).thenReturn("/123");
         subscriptionServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
         subscriptionServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -225,7 +242,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
-        when(request.getPathInfo()).thenReturn("/3");
+        when(request.getPathInfo()).thenReturn("/123");
         subscriptionServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
         subscriptionServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -233,10 +250,82 @@ public class SubscriptionServletTest extends DrServletTestBase {
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
         setAuthoriserToReturnRequestNotAuthorized();
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "legacy");
+                jo.put("follow_redirect", false);
+                jo.put("decompress", true);
+                jo.put("sync", true);
+                jo.put("changeowner", true);
+                return jo;
+            }
+        };
         subscriptionServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
         subscriptionServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_AAF_CADI_Is_Enabled_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
+        when(request.getPathInfo()).thenReturn("/3");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "*");
+                jo.put("follow_redirect", false);
+                jo.put("sync", true);
+                jo.put("changeowner", true);
+                return jo;
+            }
+        };
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access"));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_AAF_CADI_Is_Enabled_With_Permissions_Then_OK_Response_Is_Generated() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
+        when(request.getPathInfo()).thenReturn("/3");
+        when(request.isUserInRole("org.onap.dmaap-dr.sub|*|edit")).thenReturn(true);
+        PowerMockito.mockStatic(PasswordProcessor.class);
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "*");
+                jo.put("follow_redirect", false);
+                jo.put("sync", true);
+                return jo;
+            }
+        };
+        subscriptionServlet.doPut(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+        resetAafSubscriptionInDB();
+        verifyEnteringExitCalled(listAppender);
+    }
+
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
         when(request.getContentType()).thenReturn("stub_ContentType");
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
         when(request.getContentType()).thenReturn("stub_ContentType");
@@ -281,6 +370,8 @@ public class SubscriptionServletTest extends DrServletTestBase {
                 jo.put("privilegedSubscriber", true);
                 jo.put("decompress", true);
                 jo.put("delivery", JSObject);
                 jo.put("privilegedSubscriber", true);
                 jo.put("decompress", true);
                 jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "legacy");
+                jo.put("follow_redirect", false);
                 jo.put("subscriber", "differentSubscriber");
                 jo.put("sync", true);
                 return jo;
                 jo.put("subscriber", "differentSubscriber");
                 jo.put("sync", true);
                 return jo;
@@ -304,7 +395,9 @@ public class SubscriptionServletTest extends DrServletTestBase {
                 jo.put("suspend", true);
                 jo.put("privilegedSubscriber", true);
                 jo.put("delivery", JSObject);
                 jo.put("suspend", true);
                 jo.put("privilegedSubscriber", true);
                 jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "legacy");
                 jo.put("decompress", true);
                 jo.put("decompress", true);
+                jo.put("follow_redirect", false);
                 jo.put("sync", true);
                 return jo;
             }
                 jo.put("sync", true);
                 return jo;
             }
@@ -324,6 +417,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
         when(response.getOutputStream()).thenReturn(outStream);
         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
         when(response.getOutputStream()).thenReturn(outStream);
         when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
+        PowerMockito.mockStatic(PasswordProcessor.class);
         JSONObject JSObject = buildRequestJsonObject();
         SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
         JSONObject JSObject = buildRequestJsonObject();
         SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
             protected JSONObject getJSONfromInput(HttpServletRequest req) {
@@ -335,6 +429,8 @@ public class SubscriptionServletTest extends DrServletTestBase {
                 jo.put("privilegedSubscriber", true);
                 jo.put("decompress", true);
                 jo.put("delivery", JSObject);
                 jo.put("privilegedSubscriber", true);
                 jo.put("decompress", true);
                 jo.put("delivery", JSObject);
+                jo.put("aaf_instance", "legacy");
+                jo.put("follow_redirect", false);
                 jo.put("sync", true);
                 jo.put("changeowner", true);
                 return jo;
                 jo.put("sync", true);
                 jo.put("changeowner", true);
                 return jo;
@@ -370,7 +466,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
 
     @Test
     public void Given_Request_Is_HTTP_POST_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
 
     @Test
     public void Given_Request_Is_HTTP_POST_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
-        when(request.getPathInfo()).thenReturn("/3");
+        when(request.getPathInfo()).thenReturn("/123");
         subscriptionServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
         subscriptionServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
@@ -435,6 +531,8 @@ public class SubscriptionServletTest extends DrServletTestBase {
                 jo.put("suspend", true);
                 jo.put("delivery", JSObject);
                 jo.put("privilegedSubscriber", false);
                 jo.put("suspend", true);
                 jo.put("delivery", JSObject);
                 jo.put("privilegedSubscriber", false);
+                jo.put("aaf_instance", "legacy");
+                jo.put("follow_redirect", false);
                 jo.put("decompress", false);
                 jo.put("failed", false);
                 return jo;
                 jo.put("decompress", false);
                 jo.put("failed", false);
                 return jo;
@@ -498,8 +596,8 @@ public class SubscriptionServletTest extends DrServletTestBase {
         setValidPathInfoInHttpHeader();
     }
 
         setValidPathInfoInHttpHeader();
     }
 
-    private void insertSubscriptionIntoDb() throws SQLException {
-        Subscription subscription = new Subscription(URL, USER, PASSWORD);
+    private void changeSubscriptionBackToNormal() throws SQLException {
+        Subscription subscription = new Subscription("https://172.100.0.5", "user1", "password1");
         subscription.setSubid(1);
         subscription.setSubscriber("user1");
         subscription.setFeedid(1);
         subscription.setSubid(1);
         subscription.setSubscriber("user1");
         subscription.setFeedid(1);
@@ -510,22 +608,23 @@ public class SubscriptionServletTest extends DrServletTestBase {
         subscription.setSuspended(false);
         subscription.setPrivilegedSubscriber(false);
         subscription.setDecompress(false);
         subscription.setSuspended(false);
         subscription.setPrivilegedSubscriber(false);
         subscription.setDecompress(false);
-        subscription.doInsert(db.getConnection());
+        subscription.changeOwnerShip();
+        subscription.doUpdate(db.getConnection());
     }
 
     }
 
-    private void changeSubscriptionBackToNormal() throws SQLException {
-        Subscription subscription = new Subscription("https://172.100.0.5", "user1", "password1");
-        subscription.setSubid(1);
-        subscription.setSubscriber("user1");
+    private void resetAafSubscriptionInDB() throws SQLException {
+        Subscription subscription = new Subscription("https://172.100.0.5:8080", "user2", "password2");
+        subscription.setSubid(2);
+        subscription.setSubscriber("user2");
         subscription.setFeedid(1);
         SubDelivery subDelivery = new SubDelivery(URL, USER, PASSWORD, true);
         subscription.setDelivery(subDelivery);
         subscription.setGroupid(1);
         subscription.setMetadataOnly(false);
         subscription.setSuspended(false);
         subscription.setFeedid(1);
         SubDelivery subDelivery = new SubDelivery(URL, USER, PASSWORD, true);
         subscription.setDelivery(subDelivery);
         subscription.setGroupid(1);
         subscription.setMetadataOnly(false);
         subscription.setSuspended(false);
-        subscription.setPrivilegedSubscriber(false);
+        subscription.setAafInstance("https://aaf-onap-test.osaaf.org:8095");
         subscription.setDecompress(false);
         subscription.setDecompress(false);
-        subscription.changeOwnerShip();
+        subscription.setPrivilegedSubscriber(false);
         subscription.doUpdate(db.getConnection());
     }
 }
\ No newline at end of file
         subscription.doUpdate(db.getConnection());
     }
 }
\ No newline at end of file
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/utils/DRProvCadiFilterTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/utils/DRProvCadiFilterTest.java
new file mode 100644 (file)
index 0000000..5e24c5a
--- /dev/null
@@ -0,0 +1,269 @@
+/**-\r
+ * ============LICENSE_START=======================================================\r
+ *  Copyright (C) 2019 Nordix Foundation.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * SPDX-License-Identifier: Apache-2.0\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.dmaap.datarouter.provisioning.utils;\r
+\r
+import org.junit.Before;\r
+import org.junit.BeforeClass;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.mockito.Mock;\r
+import org.onap.aaf.cadi.PropAccess;\r
+import org.onap.aaf.cadi.filter.CadiFilter;\r
+import org.onap.dmaap.datarouter.provisioning.BaseServlet;\r
+import org.powermock.api.mockito.PowerMockito;\r
+import org.powermock.api.support.membermodification.MemberMatcher;\r
+import org.powermock.core.classloader.annotations.PrepareForTest;\r
+import org.powermock.modules.junit4.PowerMockRunner;\r
+\r
+import javax.persistence.EntityManager;\r
+import javax.persistence.EntityManagerFactory;\r
+import javax.persistence.Persistence;\r
+import javax.servlet.FilterChain;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+\r
+import static org.hamcrest.Matchers.notNullValue;\r
+import static org.mockito.Matchers.argThat;\r
+import static org.mockito.Matchers.eq;\r
+import static org.mockito.Mockito.*;\r
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;\r
+\r
+@RunWith(PowerMockRunner.class)\r
+@PrepareForTest({CadiFilter.class})\r
+public class DRProvCadiFilterTest {\r
+\r
+    @Mock\r
+    private PropAccess access;\r
+\r
+    @Mock\r
+    private HttpServletRequest request;\r
+\r
+    @Mock\r
+    private HttpServletResponse response;\r
+\r
+    @Mock\r
+    private FilterChain chain;\r
+\r
+    private DRProvCadiFilter cadiFilter;\r
+\r
+\r
+    private static EntityManagerFactory emf;\r
+    private static EntityManager em;\r
+\r
+\r
+    @BeforeClass\r
+    public static void init() {\r
+        emf = Persistence.createEntityManagerFactory("dr-unit-tests");\r
+        em = emf.createEntityManager();\r
+        System.setProperty(\r
+                "org.onap.dmaap.datarouter.provserver.properties",\r
+                "src/test/resources/h2Database.properties");\r
+    }\r
+\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        cadiFilter = new DRProvCadiFilter(false, access);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_Called_And_Path_Contains_subs_And_SubId_Is_Incorrectly_Set_Then_Not_Found_Response_Returned() throws Exception{\r
+        setRequestMocking("PUT", "subs");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_And_Path_Contains_subs_And_Is_AAF_Subscriber_then_call_Super_doFilter() throws Exception{\r
+        setRequestMocking("PUT", "subs");\r
+        when(request.getPathInfo()).thenReturn("/2");\r
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(CadiFilter.class));\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(0)).doFilter(request, response);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_And_Path_Contains_subs_And_Is_Not_AAF_Subscriber_then_call_chain_doFilter() throws Exception{\r
+        setRequestMocking("PUT", "subs");\r
+        when(request.getPathInfo()).thenReturn("/5");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_And_FeedId_Is_Incorrectly_Set_Then_Not_Found_Response_Returned () throws Exception{\r
+        setRequestMocking("PUT", "feeds");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_And_FeedId_Is_Correctly_Set_And_Is_AAF_Feed_Then_Call_Super_doFilter() throws Exception{\r
+        setRequestMocking("PUT", "feeds");\r
+        when(request.getPathInfo()).thenReturn("/2");\r
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(CadiFilter.class));\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(0)).doFilter(request, response);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_And_FeedId_Is_Correctly_Set_And_Is_Not_AAF_Feed_then_call_chain_doFilter() throws Exception{\r
+        setRequestMocking("PUT", "feeds");\r
+        when(request.getPathInfo()).thenReturn("/1");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_Get_Then_call_chain_doFilter() throws Exception{\r
+        setRequestMocking("GET", "feeds");\r
+        when(request.getPathInfo()).thenReturn("/5");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+    }\r
+\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_Then_call_chain_doFilter() throws Exception{\r
+        setRequestMocking("POST", "subscribe");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_FeedId_Is_Incorrectly_Set_Then_Not_Found_Response_Returned() throws Exception{\r
+        setRequestMocking("POST", "subscribe");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_Exclude_AAF_Is_NULL_Then_Bad_Request_Response_Returned() throws Exception{\r
+        setRequestMocking("POST", "subscribe");\r
+        when(request.getPathInfo()).thenReturn("/2");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_Exclude_AAF_Equals_True_Then_Call_Chain_doFilter() throws Exception{\r
+        setRequestMocking("POST", "subscribe");\r
+        when(request.getPathInfo()).thenReturn("/2");\r
+        when(request.getHeader("X-EXCLUDE-AAF")).thenReturn("true");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_Exclude_AAF_Equals_False_Then_Call_Super_doFilter() throws Exception{\r
+        setRequestMocking("POST", "subscribe");\r
+        when(request.getPathInfo()).thenReturn("/2");\r
+        when(request.getHeader("X-EXCLUDE-AAF")).thenReturn("false");\r
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(CadiFilter.class));\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(0)).doFilter(request, response);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_Is_Not_AAF_Exclude_AAF_Equals_Then_Call_Chain_doFilter() throws Exception{\r
+        setRequestMocking("POST", "subscribe");\r
+        when(request.getPathInfo()).thenReturn("/5");\r
+        when(request.getHeader("X-EXCLUDE-AAF")).thenReturn("false");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_Path_Not_Includes_subscribe_And_Exclude_AAF_Is_NULL_Then_Bad_Request_Response_Returned() throws Exception{\r
+        setRequestMocking("POST", "other");\r
+        when(request.getPathInfo()).thenReturn("/5");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_Path_Not_Includes_subscribe_And_Exclude_AAF_Equals_True_Then_Call_Chain_doFilter() throws Exception{\r
+        setRequestMocking("POST", "other");\r
+        when(request.getPathInfo()).thenReturn("/5");\r
+        when(request.getHeader("X-EXCLUDE-AAF")).thenReturn("true");\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(1)).doFilter(request, response);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_With_POST_And_Path_Not_Includes_subscribe_And_Exclude_AAF_Equals_False_Then_Call_Super_doFilter() throws Exception{\r
+        setRequestMocking("POST", "other");\r
+        when(request.getPathInfo()).thenReturn("/5");\r
+        when(request.getHeader("X-EXCLUDE-AAF")).thenReturn("false");\r
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(CadiFilter.class));\r
+\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(chain, times(0)).doFilter(request, response);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_Called_And_Path_Contains_subs_And_getSubId_Throws_NumberFormatException_then_Not_Found_response_returned() throws Exception{\r
+            setRequestMocking("PUT", "subs");\r
+            when(request.getPathInfo()).thenReturn("5/");\r
+            cadiFilter.doFilter(request, response, chain);\r
+            verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));\r
+\r
+    }\r
+\r
+    @Test\r
+    public void Given_doFilter_called_And_FeedId_Throws_Set_Then_Not_Found_Response_Returned () throws Exception{\r
+        setRequestMocking("PUT", "feeds");\r
+        when(request.getPathInfo()).thenReturn("//5");\r
+        cadiFilter.doFilter(request, response, chain);\r
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));\r
+    }\r
+\r
+    private void setRequestMocking(String method, String servletPath)\r
+    {\r
+        when(request.getRemoteAddr()).thenReturn(null);\r
+        when(request.getHeader(BEHALF_HEADER)).thenReturn(null);\r
+        when(request.getAttribute(BaseServlet.CERT_ATTRIBUTE)).thenReturn(null);\r
+        when(request.getMethod()).thenReturn(method);\r
+        when(request.getServletPath()).thenReturn(servletPath);\r
+    }\r
+\r
+    }\r
index 9412adf..1fb30c9 100755 (executable)
@@ -2,7 +2,7 @@ CREATE TABLE FEEDS (
     FEEDID         INT UNSIGNED NOT NULL PRIMARY KEY,
     GROUPID        INT(10) UNSIGNED NOT NULL DEFAULT 0,
     NAME           VARCHAR(255) NOT NULL,
     FEEDID         INT UNSIGNED NOT NULL PRIMARY KEY,
     GROUPID        INT(10) UNSIGNED NOT NULL DEFAULT 0,
     NAME           VARCHAR(255) NOT NULL,
-    VERSION        VARCHAR(20) NOT NULL,
+    VERSION        VARCHAR(20) NULL,
     DESCRIPTION    VARCHAR(1000),
     BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL,
     AUTH_CLASS     VARCHAR(32) NOT NULL,
     DESCRIPTION    VARCHAR(1000),
     BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL,
     AUTH_CLASS     VARCHAR(32) NOT NULL,
@@ -14,13 +14,14 @@ CREATE TABLE FEEDS (
     DELETED        BOOLEAN DEFAULT FALSE,
     LAST_MOD       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED      BOOLEAN DEFAULT FALSE,
     DELETED        BOOLEAN DEFAULT FALSE,
     LAST_MOD       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED      BOOLEAN DEFAULT FALSE,
-    CREATED_DATE   TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+    CREATED_DATE   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    AAF_INSTANCE   VARCHAR(256)
 );
 
 CREATE TABLE FEED_ENDPOINT_IDS (
     FEEDID        INT UNSIGNED NOT NULL,
 );
 
 CREATE TABLE FEED_ENDPOINT_IDS (
     FEEDID        INT UNSIGNED NOT NULL,
-    USERID        VARCHAR(20) NOT NULL,
-    PASSWORD      VARCHAR(32) NOT NULL
+    USERID        VARCHAR(60) NOT NULL,
+    PASSWORD      VARCHAR(100) NOT NULL
 );
 
 CREATE TABLE FEED_ENDPOINT_ADDRS (
 );
 
 CREATE TABLE FEED_ENDPOINT_ADDRS (
@@ -33,8 +34,9 @@ CREATE TABLE SUBSCRIPTIONS (
     FEEDID                      INT UNSIGNED NOT NULL,
     GROUPID                     INT(10) UNSIGNED NOT NULL DEFAULT 0,
     DELIVERY_URL                VARCHAR(256),
     FEEDID                      INT UNSIGNED NOT NULL,
     GROUPID                     INT(10) UNSIGNED NOT NULL DEFAULT 0,
     DELIVERY_URL                VARCHAR(256),
-    DELIVERY_USER               VARCHAR(20),
-    DELIVERY_PASSWORD           VARCHAR(32),
+    FOLLOW_REDIRECTS            TINYINT(1) NOT NULL DEFAULT 0,
+    DELIVERY_USER               VARCHAR(60),
+    DELIVERY_PASSWORD           VARCHAR(100),
     DELIVERY_USE100             BOOLEAN DEFAULT FALSE,
     METADATA_ONLY               BOOLEAN DEFAULT FALSE,
     SUBSCRIBER                  VARCHAR(8) NOT NULL,
     DELIVERY_USE100             BOOLEAN DEFAULT FALSE,
     METADATA_ONLY               BOOLEAN DEFAULT FALSE,
     SUBSCRIBER                  VARCHAR(8) NOT NULL,
@@ -43,8 +45,9 @@ CREATE TABLE SUBSCRIPTIONS (
     LAST_MOD                    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED                   BOOLEAN DEFAULT FALSE,
     PRIVILEGED_SUBSCRIBER       BOOLEAN DEFAULT FALSE,
     LAST_MOD                    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     SUSPENDED                   BOOLEAN DEFAULT FALSE,
     PRIVILEGED_SUBSCRIBER       BOOLEAN DEFAULT FALSE,
+    CREATED_DATE                TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     DECOMPRESS                  BOOLEAN DEFAULT FALSE,
     DECOMPRESS                  BOOLEAN DEFAULT FALSE,
-    CREATED_DATE                TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+    AAF_INSTANCE                VARCHAR(256)
 
 );
 
 
 );
 
@@ -87,7 +90,7 @@ CREATE TABLE LOG_RECORDS (
 CREATE TABLE INGRESS_ROUTES (
     SEQUENCE  INT UNSIGNED NOT NULL,
     FEEDID    INT UNSIGNED NOT NULL,
 CREATE TABLE INGRESS_ROUTES (
     SEQUENCE  INT UNSIGNED NOT NULL,
     FEEDID    INT UNSIGNED NOT NULL,
-    USERID    VARCHAR(20),
+    USERID    VARCHAR(50),
     SUBNET    VARCHAR(44),
     NODESET   INT UNSIGNED NOT NULL
 );
     SUBNET    VARCHAR(44),
     NODESET   INT UNSIGNED NOT NULL
 );
@@ -136,7 +139,7 @@ INSERT INTO PARAMETERS VALUES
     ('DELIVERY_MAX_RETRY_INTERVAL', '3600'),
     ('DELIVERY_FILE_PROCESS_INTERVAL', '600'),
     ('DELIVERY_RETRY_RATIO', '2'),
     ('DELIVERY_MAX_RETRY_INTERVAL', '3600'),
     ('DELIVERY_FILE_PROCESS_INTERVAL', '600'),
     ('DELIVERY_RETRY_RATIO', '2'),
-    ('LOGROLL_INTERVAL', '300'),
+    ('LOGROLL_INTERVAL', '30'),
     ('PROV_AUTH_ADDRESSES', 'dmaap-dr-prov|dmaap-dr-node'),
     ('PROV_AUTH_SUBJECTS', ''),
     ('PROV_MAXFEED_COUNT',  '10000'),
     ('PROV_AUTH_ADDRESSES', 'dmaap-dr-prov|dmaap-dr-node'),
     ('PROV_AUTH_SUBJECTS', ''),
     ('PROV_MAXFEED_COUNT',  '10000'),
@@ -149,11 +152,17 @@ INSERT INTO PARAMETERS VALUES
 INSERT INTO GROUPS(GROUPID, AUTHID, NAME, DESCRIPTION, CLASSIFICATION, MEMBERS)
 VALUES (1, 'Basic dXNlcjE6cGFzc3dvcmQx', 'Group1', 'First Group for testing', 'Class1', 'Member1');
 
 INSERT INTO GROUPS(GROUPID, AUTHID, NAME, DESCRIPTION, CLASSIFICATION, MEMBERS)
 VALUES (1, 'Basic dXNlcjE6cGFzc3dvcmQx', 'Group1', 'First Group for testing', 'Class1', 'Member1');
 
-INSERT INTO SUBSCRIPTIONS(SUBID, FEEDID, DELIVERY_URL, DELIVERY_USER, DELIVERY_PASSWORD, DELIVERY_USE100, METADATA_ONLY, SUBSCRIBER, SUSPENDED, GROUPID, PRIVILEGED_SUBSCRIBER, DECOMPRESS)
-VALUES (1, 1, 'https://172.100.0.5:8080', 'user1', 'password1', true, false, 'user1', false, 1, false, false);
+INSERT INTO SUBSCRIPTIONS(SUBID, FEEDID, DELIVERY_URL, FOLLOW_REDIRECTS, DELIVERY_USER, DELIVERY_PASSWORD, DELIVERY_USE100, METADATA_ONLY, SUBSCRIBER, SUSPENDED, GROUPID, PRIVILEGED_SUBSCRIBER, AAF_INSTANCE, DECOMPRESS)
+VALUES (1, 1, 'https://172.100.0.5:8080', 0, 'user1', 'password1', true, false, 'user1', false, 1, false, 'legacy', false);
 
 
-INSERT INTO SUBSCRIPTIONS(SUBID, FEEDID, DELIVERY_URL, DELIVERY_USER, DELIVERY_PASSWORD, SUBSCRIBER, SELF_LINK, LOG_LINK)
-VALUES (23, 1, 'http://delivery_url', 'user1', 'somepassword', 'sub123', 'selflink', 'loglink');
+INSERT INTO SUBSCRIPTIONS(SUBID, FEEDID, DELIVERY_URL, FOLLOW_REDIRECTS, DELIVERY_USER, DELIVERY_PASSWORD, DELIVERY_USE100, METADATA_ONLY, SUBSCRIBER, SUSPENDED, GROUPID, AAF_INSTANCE)
+VALUES (2, 1, 'https://172.100.0.5:8080', 0, 'user2', 'password2', true, true, 'subsc2', false, 1, '*');
+
+INSERT INTO SUBSCRIPTIONS(SUBID, FEEDID, DELIVERY_URL, FOLLOW_REDIRECTS, DELIVERY_USER, DELIVERY_PASSWORD, DELIVERY_USE100, METADATA_ONLY, SUBSCRIBER, SUSPENDED, GROUPID, AAF_INSTANCE)
+VALUES (3, 1, 'https://172.100.0.5:8080', 0, 'user3', 'password3', true, true, 'subsc3', false, 1, '*');
+
+INSERT INTO SUBSCRIPTIONS(SUBID, FEEDID, DELIVERY_URL, DELIVERY_USER, DELIVERY_PASSWORD, SUBSCRIBER, SELF_LINK, LOG_LINK, AAF_INSTANCE)
+VALUES (23, 1, 'http://delivery_url', 'user1', 'somepassword', 'sub123', 'selflink', 'loglink', 'legacy');
 
 INSERT INTO FEED_ENDPOINT_IDS(FEEDID, USERID, PASSWORD)
 VALUES (1, 'USER', 'PASSWORD');
 
 INSERT INTO FEED_ENDPOINT_IDS(FEEDID, USERID, PASSWORD)
 VALUES (1, 'USER', 'PASSWORD');
@@ -164,6 +173,12 @@ VALUES (1, '172.0.0.1');
 INSERT INTO FEEDS(FEEDID, GROUPID, NAME, VERSION, DESCRIPTION, BUSINESS_DESCRIPTION, AUTH_CLASS, PUBLISHER, SELF_LINK, PUBLISH_LINK, SUBSCRIBE_LINK, LOG_LINK)
 VALUES (1, 1,'Feed1','v0.1', 'First Feed for testing', 'First Feed for testing', 'auth_class', 'pub','self_link','publish_link','subscribe_link','log_link');
 
 INSERT INTO FEEDS(FEEDID, GROUPID, NAME, VERSION, DESCRIPTION, BUSINESS_DESCRIPTION, AUTH_CLASS, PUBLISHER, SELF_LINK, PUBLISH_LINK, SUBSCRIBE_LINK, LOG_LINK)
 VALUES (1, 1,'Feed1','v0.1', 'First Feed for testing', 'First Feed for testing', 'auth_class', 'pub','self_link','publish_link','subscribe_link','log_link');
 
+INSERT INTO FEEDS(FEEDID, GROUPID, NAME, VERSION, DESCRIPTION, BUSINESS_DESCRIPTION, AUTH_CLASS, PUBLISHER, SELF_LINK, PUBLISH_LINK, SUBSCRIBE_LINK, LOG_LINK, AAF_INSTANCE)
+VALUES (2, 1,'AafFeed','v0.1', 'AAF Feed for testing', 'AAF Feed for testing', 'auth_class', 'pub','self_link','publish_link','subscribe_link','log_link','*');
+
+INSERT INTO FEEDS(FEEDID, GROUPID, NAME, VERSION, DESCRIPTION, BUSINESS_DESCRIPTION, AUTH_CLASS, PUBLISHER, SELF_LINK, PUBLISH_LINK, SUBSCRIBE_LINK, LOG_LINK, AAF_INSTANCE)
+VALUES (3, 1,'DeleteableAafFeed','v0.1', 'AAF Feed3 for testing', 'AAF Feed3 for testing', 'auth_class', 'pub','self_link','publish_link','subscribe_link','log_link','*');
+
 insert into INGRESS_ROUTES(SEQUENCE, FEEDID , USERID, SUBNET, NODESET)
 VALUES (1,1,'user',null,2);
 
 insert into INGRESS_ROUTES(SEQUENCE, FEEDID , USERID, SUBNET, NODESET)
 VALUES (1,1,'user',null,2);
 
index a7ed3fa..fee9c68 100755 (executable)
@@ -28,4 +28,5 @@ org.onap.dmaap.datarouter.provserver.isaddressauthenabled  = true
 org.onap.dmaap.datarouter.provserver.https.relaxation      = false
 org.onap.dmaap.datarouter.provserver.accesslog.dir         = unit-test-logs
 org.onap.dmaap.datarouter.provserver.spooldir              = unit-test-logs/spool
 org.onap.dmaap.datarouter.provserver.https.relaxation      = false
 org.onap.dmaap.datarouter.provserver.accesslog.dir         = unit-test-logs
 org.onap.dmaap.datarouter.provserver.spooldir              = unit-test-logs/spool
-org.onap.dmaap.datarouter.provserver.localhost             = 127.0.0.1
\ No newline at end of file
+org.onap.dmaap.datarouter.provserver.localhost             = 127.0.0.1
+org.onap.dmaap.datarouter.provserver.passwordencryption    = PasswordEncryptionKey#@$%^&1234#
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a515dc5..3de167a 100755 (executable)
--- a/pom.xml
+++ b/pom.xml
@@ -55,6 +55,7 @@
         <thoughtworks.version>1.4.10</thoughtworks.version>
         <google.guava.version>26.0-jre</google.guava.version>
         <qos.logback.version>1.2.3</qos.logback.version>
         <thoughtworks.version>1.4.10</thoughtworks.version>
         <google.guava.version>26.0-jre</google.guava.version>
         <qos.logback.version>1.2.3</qos.logback.version>
+        <aaf-cadi-aaf.version>2.1.10</aaf-cadi-aaf.version>
         <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
         <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
         <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>
         <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
         <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
         <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>