Merge "Change this "try" to a try-with-resource"
authorvarun gudisena <varuneshwar.gudisena@att.com>
Tue, 9 Apr 2019 21:17:21 +0000 (21:17 +0000)
committerGerrit Code Review <gerrit@onap.org>
Tue, 9 Apr 2019 21:17:21 +0000 (21:17 +0000)
77 files changed:
.classpath
INFO.yaml
README.md
docs/api.rst
etc/dmaapbc.properties
pom.xml
src/main/java/org/onap/dmaap/dbcapi/aaf/AafConnection.java
src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java
src/main/java/org/onap/dmaap/dbcapi/client/MrProvConnection.java
src/main/java/org/onap/dmaap/dbcapi/client/MrTopicConnection.java
src/main/java/org/onap/dmaap/dbcapi/database/ConnectionFactory.java
src/main/java/org/onap/dmaap/dbcapi/database/DBMap.java
src/main/java/org/onap/dmaap/dbcapi/database/DatabaseClass.java
src/main/java/org/onap/dmaap/dbcapi/model/ApiError.java
src/main/java/org/onap/dmaap/dbcapi/model/DR_Node.java
src/main/java/org/onap/dmaap/dbcapi/model/DR_Pub.java
src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java
src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilter.java [new file with mode: 0644]
src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilter.java [new file with mode: 0644]
src/main/java/org/onap/dmaap/dbcapi/resources/AuthorizationFilter.java
src/main/java/org/onap/dmaap/dbcapi/resources/BridgeResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/DR_NodeResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/DR_PubResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/DR_SubResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/DmaapResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/InfoResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClientResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResource.java
src/main/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilter.java [new file with mode: 0644]
src/main/java/org/onap/dmaap/dbcapi/resources/RequiredChecker.java [new file with mode: 0644]
src/main/java/org/onap/dmaap/dbcapi/resources/RequiredFieldException.java
src/main/java/org/onap/dmaap/dbcapi/resources/ResponseBuilder.java [new file with mode: 0644]
src/main/java/org/onap/dmaap/dbcapi/resources/TopicResource.java
src/main/java/org/onap/dmaap/dbcapi/server/ApplicationConfig.java
src/main/java/org/onap/dmaap/dbcapi/server/JettyServer.java
src/main/java/org/onap/dmaap/dbcapi/server/Main.java
src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java
src/main/java/org/onap/dmaap/dbcapi/service/DR_NodeService.java
src/main/java/org/onap/dmaap/dbcapi/service/DR_PubService.java
src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java
src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java
src/main/java/org/onap/dmaap/dbcapi/service/MirrorMakerService.java
src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java
src/main/java/org/onap/dmaap/dbcapi/util/PermissionBuilder.java [new file with mode: 0644]
src/main/resources/schema_12.sql
src/test/java/org/onap/dmaap/dbcapi/aaf/AafRoleTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/aaf/AafUserRoleTest.java
src/test/java/org/onap/dmaap/dbcapi/database/DBFieldHandlerTest.java
src/test/java/org/onap/dmaap/dbcapi/database/TableHandlerTest.java
src/test/java/org/onap/dmaap/dbcapi/model/BrTopicTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/model/DRSubTest.java
src/test/java/org/onap/dmaap/dbcapi/model/DmaapTest.java
src/test/java/org/onap/dmaap/dbcapi/model/MRClientTest.java
src/test/java/org/onap/dmaap/dbcapi/model/MR_ClusterTest.java
src/test/java/org/onap/dmaap/dbcapi/model/TopicTest.java
src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilterTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilterTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/DR_NodeResourceTest.java
src/test/java/org/onap/dmaap/dbcapi/resources/DR_PubResourceTest.java
src/test/java/org/onap/dmaap/dbcapi/resources/DR_SubResourceTest.java
src/test/java/org/onap/dmaap/dbcapi/resources/FastJerseyTestContainer.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResourceTest.java
src/test/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilterTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/RequiredCheckerTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/RequiredFieldExceptionTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/ResponseBuilderTest.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/TestFeedCreator.java [new file with mode: 0644]
src/test/java/org/onap/dmaap/dbcapi/resources/TopicResourceTest.java
src/test/java/org/onap/dmaap/dbcapi/service/ApiServiceTest.java
src/test/java/org/onap/dmaap/dbcapi/service/DmaapServiceTest.java
src/test/java/org/onap/dmaap/dbcapi/service/FeedServiceTest.java
src/test/java/org/onap/dmaap/dbcapi/service/TopicServiceTest.java
src/test/java/org/onap/dmaap/dbcapi/testframework/DmaapObjectFactory.java
src/test/java/org/onap/dmaap/dbcapi/util/PermissionBuilderTest.java [new file with mode: 0644]
version.properties

index 17efa84..30fa0bf 100644 (file)
@@ -15,6 +15,7 @@
                <attributes>
                        <attribute name="optional" value="true"/>
                        <attribute name="maven.pomderived" value="true"/>
+                       <attribute name="test" value="true"/>
                </attributes>
        </classpathentry>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
index 3c821b8..20a439a 100644 (file)
--- a/INFO.yaml
+++ b/INFO.yaml
@@ -1,5 +1,5 @@
 ---
-project: 'dmaap-messagerouter-msgrtr'
+project: 'dmaap-dbcapi'
 project_creation_date: '2017-08-29'
 lifecycle_state: 'Incubation'
 project_lead: &onap_releng_ptl
@@ -9,50 +9,67 @@ project_lead: &onap_releng_ptl
     company: 'ATT'
     timezone: 'America/Dallas'
 primary_contact: *onap_releng_ptl
+project_category: ''
 issue_tracking:
     type: 'jira'
     url: 'https://jira.onap.org/projects/DMAAP'
     key: 'DMAAP'
+mailing_list:
+    type: 'groups.io'
+    url: 'lists.onap.org'
+    tag: '<[sub-project_name]>'
+realtime_discussion: ''
 meetings:
     - type: 'zoom'
-        agenda: ''
-        url: 'https://wiki.onap.org/pages/viewpage.action?pageId=13599275'
-        server: 'n/a'
-        channel: 'n/a'
-        repeats: 'weekly'
-        time: '13:00 UTC'
+      agenda: ''
+      url: 'https://wiki.onap.org/pages/viewpage.action?pageId=13599275'
+      server: 'n/a'
+      channel: 'n/a'
+      repeats: 'weekly'
+      time: '13:00 UTC'
+repositories:
+    - 'dmaap-buscontroller'
+    - 'dmaap-datarouter'
+    - 'dmaap-dbcapi'
+    - 'dmaap-kafka11aaf'
+    - 'dmaap-messagerouter-dmaapclient'
+    - 'dmaap-messagerouter-messageservice'
+    - 'dmaap-messagerouter-mirroragent'
+    - 'dmaap-messagerouter-msgrtr'
+    - 'dmaap-oom'
+    - 'dmaap-zookeeper'
 committers:
     - <<: *onap_releng_ptl
     - name: 'Mandar Sawant'
-        email: 'ms5838@att.com'
-        company: 'ATT'
-        id: 'sawantmandar'
-        timezone: 'America/Dallas'
+      email: 'ms5838@att.com'
+      company: 'ATT'
+      id: 'sawantmandar'
+      timezone: 'America/Dallas'
     - name: 'Varun Gudisena'
-        email: 'vg411h@att.com'
-        company: 'ATT'
-        id: 'vg411h'
-        timezone: 'America/Dallas'
+      email: 'vg411h@att.com'
+      company: 'ATT'
+      id: 'vg411h'
+      timezone: 'America/Dallas'
     - name: 'Bhanu Ramesh'
-        email: 'bg6954@att.com'
-        company: 'ATT'
-        id: 'BhanuRamesh'
-        timezone: 'America/Dallas'
+      email: 'bg6954@att.com'
+      company: 'ATT'
+      id: 'BhanuRamesh'
+      timezone: 'America/Dallas'
     - name: 'Dominic Lunanuova'
-        email: 'dgl@research.att.com'
-        company: 'ATT'
-        id: 'dglFromAtt'
-        timezone: 'America/Dallas'
+      email: 'dgl@research.att.com'
+      company: 'ATT'
+      id: 'dglFromAtt'
+      timezone: 'America/Dallas'
     - name: 'Sunil Unnava'
-        email: 'su622b@att.com'
-        company: 'ATT'
-        id: 'su622b'
-        timezone: 'America/Louisville'
+      email: 'su622b@att.com'
+      company: 'ATT'
+      id: 'su622b'
+      timezone: 'America/Louisville'
     - name: 'Conor Ward'
-        email: 'conor.ward@ericsson.com'
-        company: 'ericsson'
-        id: 'econwar'
-        timezone: 'America/Dallas'
+      email: 'conor.ward@ericsson.com'
+      company: 'ericsson'
+      id: 'econwar'
+      timezone: 'America/Dallas'
 tsc:
     approval: 'https://lists.onap.org/pipermail/onap-tsc'
     changes:
index 235e0d0..ef81b86 100644 (file)
--- a/README.md
+++ b/README.md
@@ -98,6 +98,13 @@ The table below lists all the settings, default values (if not set), and shows a
 |-|-|-|-|
 |MR.projectID          | Value for some constructs of fully qualified topic names | 99999                                 | ONAP |
 |-|-|-|-|
+|MR.hostnameVerify     | Indicates if we want to relax hostname verification on SSL connection  | true                                 | false |
+|-|-|-|-|
+|MR.authentication     | Authentication method used when connecting to MR | none                                 | basicAuth |
+|                      | none = no creds sent (default)                   |  |  |
+|                      | basicAuth = formulate Basic Auth HTTP Header using name and pwd credentials |     |  |
+|                      | cert = use client certificate                    |  |  |
+|-|-|-|-|
 |cadi.properties       | Path to CADI properties file                            | /opt/app/osaaf/local/org.onap.dmaap-bc.props | /opt/app/osaaf/lcoal/org.onap.dmaap-bc.props |
 |-|-|-|-|
 |aaf.URL               | URL of the AAF server                                   | https://authentication.domain.netset.com:8095/proxy/ | https://aaf-authz/ |
index 9eab4da..7f187d4 100644 (file)
@@ -4928,3 +4928,54 @@ Topic Model Structure
         topicName | No | string |  |  | the short name used by humans, and utilized to construct the `FQTN`
         version | No | string |  |  | a hook for any versioning needed for managing a `Topic` over time
 
+Security
+~~~~~~~~
+As default security is in Dmaap Bus Controller disabled.
+
+Enable
+------
+Settings to turn on security is in file dmaapbc.properties. The file is located in OOM project in path: ./oom/kubernetes/dmaap/components/dmaap-bc/resources/config/dmaapbc.properties
+During deployment the the file is placed into ConfigMap XXX-dmaap-bus-controller-config (XXX depend on deployment setup). The config map is linked to volume with read only permission so it can not be changed from pod level.
+Ater updating ConfigMap the bus controller pod needs to be restarted.
+
+Settings
+++++++++
+
+In the dmaapbc.properties for security settings there is a main flag:
+
+1.UseAAF: true
+
+If set to true then creating topic also will create required perms in AAF. The perms will be created in org.onap.dmaap.mr.
+The last element -mr- is related to another setting - MR.projectID .
+
+Example:
+  Topic name:
+    aSimpleTopic
+  Permitions
+    org.onap.dmaap.mr.topic|:topic.org.onap.dmaap.mr.aSimpleTopic|pub
+    org.onap.dmaap.mr.topic|:topic.org.onap.dmaap.mr.aSimpleTopic|sub
+    org.onap.dmaap.mr.topic|:topic.org.onap.dmaap.mr.aSimpleTopic|view
+
+
+Hint: User defined in the certificate of cadi (property:cadi.properties, user:dmaap-bc@dmaap-bc.onap.org) needs to have permissions to create and view such topics (org.onap.dmaap.mr.topic|*|*).
+
+
+Authentication is using CADI
+
+CADI confilguration is stored in CADI files. Location of the files is defined in varaible:
+cadi.properties: /opt/app/osaaf/local/org.onap.dmaap-bc.props
+
+The configuration is a mandatory and missing parameter or file cause exception.
+
+Authorization is done by CADI - configuration is required as above
+
+Call to bus controller needs to have given user credentials. The user ich checked in AAF for permission to call topic.
+The check is done in org.onap.dmaap-bc.api according to ApiNamespace setting.
+
+Hint: User defined in the certificate of cadi (property:cadi.properties, user:dmaap-bc@dmaap-bc.onap.org) needs to have permission to read the namespace (org.onap.dmaap-bc.api.access|*|read).
+
+
+2.UseAAF: false
+
+For backward compatibility, if AAF flag is turned off the previous implementation is enabled based on AuthorizationFilter and ApiPermission class.
+This filter switching has been made due to the technology differences: Jersey filters do not implement directly servlet API, but CADI filter is based on it.
\ No newline at end of file
index 64e435e..b0dc7de 100644 (file)
@@ -129,7 +129,7 @@ MR.topicStyle:      FQTN_LEGACY_FORMAT
 #   MR topic ProjectID
 MR.projectID:  23456
 
-MR.multisite:  false
+MR.multisite:  true
 #
 # end of MR Related Properties
 ################################################################################
diff --git a/pom.xml b/pom.xml
index 8a27fa9..6517cd1 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                <groupId>org.glassfish.jersey.inject</groupId>
                <artifactId>jersey-hk2</artifactId>
                </dependency>
-       </dependencies>
+    <dependency>
+      <groupId>pl.pragmatists</groupId>
+      <artifactId>JUnitParams</artifactId>
+      <version>1.1.0</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
        <reporting>
                <plugins>
                        <plugin>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <jettyVersion>9.4.12.RC2</jettyVersion> 
                <eelf.version>1.0.0</eelf.version>
-               <artifact.version>1.0.23-SNAPSHOT</artifact.version>
+               <artifact.version>1.0.26-SNAPSHOT</artifact.version>
                <!-- SONAR -->
                <jacoco.version>0.7.7.201606060606</jacoco.version>
                <sonar-jacoco-listeners.version>3.2</sonar-jacoco-listeners.version>
index e22290a..934e541 100644 (file)
@@ -37,8 +37,11 @@ import java.net.UnknownHostException;
 import java.net.ConnectException;
 
 import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLHandshakeException;
 
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
 import org.apache.commons.codec.binary.Base64;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
@@ -129,6 +132,10 @@ public class AafConnection extends BaseLoggingClass {
                        uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
                        uc.setUseCaches(false);
                        uc.setDoOutput(true);
+
+                       SSLContext sc = SSLContext.getInstance("SSL");
+                       sc.init(null, trustAllCerts, new java.security.SecureRandom());
+                       uc.setSSLSocketFactory(sc.getSocketFactory());
                        OutputStream os = null;
 
                        
@@ -296,6 +303,27 @@ public class AafConnection extends BaseLoggingClass {
                return rc;
                
        }
+
+       private TrustManager[] trustAllCerts = new TrustManager[]{
+               new X509TrustManager() {
+
+                       @Override
+                       public java.security.cert.X509Certificate[] getAcceptedIssuers()
+                       {
+                               return null;
+                       }
+                       @Override
+                       public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
+                       {
+                               //No need to implement.
+                       }
+                       @Override
+                       public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
+                       {
+                               //No need to implement.
+                       }
+               }
+       };
        
 
 }
index 3cb3d67..54fa84e 100644 (file)
@@ -48,6 +48,8 @@ public class DrProvConnection extends BaseLoggingClass {
        private String  behalfHeader;
        private String  feedContentType;
        private String  subContentType;
+       private String unit_test;
+       private String  provURI;
        
        private HttpsURLConnection uc;
 
@@ -62,8 +64,10 @@ public class DrProvConnection extends BaseLoggingClass {
                behalfHeader = p.getProperty( "DR.onBehalfHeader", "X-DMAAP-DR-ON-BEHALF-OF");
                feedContentType = p.getProperty( "DR.feedContentType", "application/vnd.dmaap-dr.feed");
                subContentType = p.getProperty( "DR.subContentType", "application/vnd.dmaap-dr.subscription");
+               provURI = p.getProperty( "DR.ProvisioningURI", "/internal/prov");
                logger.info( "provURL=" + provURL + " provApi=" + provApi + " behalfHeader=" + behalfHeader
                                + " feedContentType=" + feedContentType + " subContentType=" + subContentType );
+               unit_test = p.getProperty( "UnitTest", "No" );
                        
        }
        
@@ -95,6 +99,10 @@ public class DrProvConnection extends BaseLoggingClass {
                                        sub,  nodep );
                return makeConnection( provURL + uri );
        }
+       public boolean makeDumpConnection() {
+               String url = provURL + provURI;
+               return makeConnection( url );
+       }
        public boolean makeNodesConnection( String varName ) {
                
                String uri = String.format("/internal/api/%s", varName);
@@ -122,7 +130,6 @@ public class DrProvConnection extends BaseLoggingClass {
                        return(true);
                } catch (Exception e) {
                        errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_ERROR,  pURL, e.getMessage() );
-            e.printStackTrace();
             return(false);
         }
 
@@ -214,20 +221,28 @@ public class DrProvConnection extends BaseLoggingClass {
                        err.setCode( 500 );
                        err.setMessage( "Unable to read response from DR");
         } catch (Exception e) {
-            logger.warn("Unable to read response  " );
-            e.printStackTrace();
-            try {
-                   err.setCode( uc.getResponseCode());
-                   err.setMessage(uc.getResponseMessage());
-            } catch (Exception e2) {
-               err.setCode( 500 );
-               err.setMessage("Unable to determine response message");
-            }
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPostFeed because unit_test =" + unit_test );
+               } else {
+                   logger.warn("Unable to read response  " );
+                   errorLogger.error("Unable to read response  ", e.getMessage());
+                   try {
+                           err.setCode( uc.getResponseCode());
+                           err.setMessage(uc.getResponseMessage());
+                   } catch (Exception e2) {
+                       err.setCode( 500 );
+                       err.setMessage("Unable to determine response message");
+                   }
+               }
         } 
                finally {
                        try {
                                uc.disconnect();
-                       } catch ( Exception e ) {}
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
 
@@ -270,9 +285,16 @@ public class DrProvConnection extends BaseLoggingClass {
                err.setMessage(responsemessage);
             }
                } catch (Exception e) {
-            logger.error("Unable to read response  " );
-            e.printStackTrace();
-        }              finally {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doXgressPost because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+               }
+        }              
+        finally {
                        try {
                                uc.disconnect();
                        } catch ( Exception e ) {
@@ -316,6 +338,7 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
             }
                        rc = uc.getResponseCode();
@@ -346,12 +369,20 @@ public class DrProvConnection extends BaseLoggingClass {
             }
             
                } catch (Exception e) {
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
-        }              finally {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPostDr_Sub because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
+        }              
+               finally {
                        try {
                                uc.disconnect();
-                       } catch ( Exception e ) {}
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
 
@@ -388,6 +419,7 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
             }
                        rc = uc.getResponseCode();
@@ -433,19 +465,28 @@ public class DrProvConnection extends BaseLoggingClass {
                        err.setCode( 500 );
                        err.setMessage( "Unable to read response from DR");
         } catch (Exception e) {
-            logger.warn("Unable to read response  " );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPutFeed because unit_test =" + unit_test );
+               } else {
+                   logger.warn("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+               }
             try {
                    err.setCode( uc.getResponseCode());
                    err.setMessage(uc.getResponseMessage());
             } catch (Exception e2) {
                err.setCode( 500 );
                err.setMessage("Unable to determine response message");
+               logger.error(e2.getMessage(), e2);
             }
         }              finally {
                        try {
                                uc.disconnect();
-                       } catch ( Exception e ) {}
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
        }
@@ -481,6 +522,7 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
             }
                        rc = uc.getResponseCode();
@@ -514,11 +556,20 @@ public class DrProvConnection extends BaseLoggingClass {
             errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
             err.setCode( 500 );
                err.setMessage("Backend connection refused");
+               logger.error(ce.getMessage(), ce);
                } catch (Exception e) {
-            logger.error("Unable to read response  " );
-            logger.error(e.getMessage(), e);
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPutDr_Sub because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+               }
         } finally {
-               uc.disconnect();
+               if(null != uc){
+                   uc.disconnect();
+               }
         }
                return responseBody;
 
@@ -530,40 +581,38 @@ public class DrProvConnection extends BaseLoggingClass {
                //logger.info( "get fields=" + postData );
                String responsemessage = null;
                String responseBody = null;
-               logger.info( "templog:doGetNodes at 12.10.14.10"  );
 
                try {
-               logger.info( "templog:doGetNodes at 12.10.14.11"  );
        
                        uc.setRequestMethod("GET");
                        int rc = -1;
                        
-               logger.info( "templog:doGetNodes at 12.10.14.12"  );
+
                        try {
                 uc.connect();
-                               logger.info( "templog:doGetNodes at 12.10.14.13"  );
-
+       
 
             } catch (ProtocolException pe) {
-               logger.info( "templog:doGetNodes at 12.10.14.14"  );
+
                  // Rcvd error instead of 100-Continue
                  try {
                      // work around glitch in Java 1.7.0.21 and likely others
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
             } 
-               logger.info( "templog:doGetNodes at 12.10.14.15"  );
+       
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
             logger.info( "responsemessage=" + responsemessage );
-               logger.info( "templog:doGetNodes at 12.10.14.16"  );
+       
 
 
             if (responsemessage == null) {
-               logger.info( "templog:doGetNodes at 12.10.14.17"  );
+
                  // work around for glitch in Java 1.7.0.21 and likely others
                  // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is
                  String h0 = uc.getHeaderField(0);
@@ -575,7 +624,7 @@ public class DrProvConnection extends BaseLoggingClass {
                      }
                  }
             }
-               logger.info( "templog:doGetNodes at 12.10.14.18"  );
+       
                err.setCode(rc);  // may not really be an error, but we save rc
             if (rc == 200 ) {
                        responseBody = bodyToString( uc.getInputStream() );
@@ -584,21 +633,26 @@ public class DrProvConnection extends BaseLoggingClass {
                err.setMessage(responsemessage);
             }
             
-               logger.info( "templog:doGetNodes at 12.10.14.19"  );
+
                } catch (ConnectException ce) {
-               logger.info( "templog:doGetNodes at 12.10.14.20"  );
+       
             errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
             err.setCode( 500 );
                err.setMessage("Backend connection refused");
+               logger.error(ce.getMessage(), ce);
                } catch (Exception e) {
-               logger.info( "templog:doGetNodes at 12.10.14.21"  );
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
         } finally {
-               logger.info( "templog:doGetNodes at 12.10.14.22"  );
+
                        if ( uc != null ) uc.disconnect();
         }
-               logger.info( "templog:doGetNodes at 12.10.14.23"  );
+
                return responseBody;
 
        }
@@ -665,8 +719,13 @@ public class DrProvConnection extends BaseLoggingClass {
             }
             
                } catch (Exception e) {
-            System.err.println("Unable to read response  " + e.getMessage() );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPutNodes because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
         } finally {
                        if ( uc != null ) {
                        uc.disconnect();
@@ -706,6 +765,7 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
             }
                        rc = uc.getResponseCode();
@@ -746,24 +806,37 @@ public class DrProvConnection extends BaseLoggingClass {
                        errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
             err.setCode( 500 );
                err.setMessage("Backend connection refused");
+               logger.error(ce.getMessage(), ce);
                } catch (SocketException se) {
                        errorLogger.error( DmaapbcLogMessageEnum.SOCKET_EXCEPTION, se.getMessage(), "response from Prov server" );
                        err.setCode( 500 );
                        err.setMessage( "Unable to read response from DR");
+                       logger.error(se.getMessage(), se);
         } catch (Exception e) {
-            logger.warn("Unable to read response  " );
-            e.printStackTrace();
-            try {
-                   err.setCode( uc.getResponseCode());
-                   err.setMessage(uc.getResponseMessage());
-            } catch (Exception e2) {
-               err.setCode( 500 );
-               err.setMessage("Unable to determine response message");
-            }
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doDeleteFeed because unit_test =" + unit_test );
+               } else {
+                   logger.warn("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+                   try {
+                           err.setCode( uc.getResponseCode());
+                           err.setMessage(uc.getResponseMessage());
+                   } catch (Exception e2) {
+                       err.setCode( 500 );
+                       err.setMessage("Unable to determine response message");
+                       logger.error(e2.getMessage(), e2);
+                   }
+               }
         }              finally {
                        try {
-                               uc.disconnect();
-                       } catch ( Exception e ) {}
+                               if(uc != null) {
+                                   uc.disconnect();
+                               }
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
        }
@@ -800,6 +873,7 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
             }
                        rc = uc.getResponseCode();
@@ -829,48 +903,176 @@ public class DrProvConnection extends BaseLoggingClass {
             }
             
                } catch (ConnectException ce) {
-            errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
-            err.setCode( 500 );
-               err.setMessage("Backend connection refused");
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doDeleteDr_Sub because unit_test =" + unit_test );
+               } else {
+                   errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+                   err.setCode( 500 );
+                       err.setMessage("Backend connection refused");
+               }
                } catch (Exception e) {
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doDeleteDr_Sub because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
         } finally {
-               uc.disconnect();
+               if(uc != null){
+                   uc.disconnect();
+               }
         }
                return responseBody;
 
        }
-       /*
-        public static void main( String[] args ) throws Exception {
-               PropertyConfigurator.configure("log4j.properties");
-               logger.info("Started.");
-               
-               RandomInteger ri = new RandomInteger(10000);
-                       //String postJSON = String.format("{\"name\": \"dgl feed %d\", \"version\": \"v1.0\", \"description\": \"dgl feed N for testing\", \"authorization\": { \"classification\": \"unclassified\", \"endpoint_addrs\": [],\"endpoint_ids\": [{\"password\": \"test\",\"id\": \"test\"}]}}", ri.next()) ;
-                       int i = ri.next();
-                       Feed tst = new Feed( "dgl feed " + i,
-                                                               "v1.0",
-                                                               "dgl feed " + i + "for testing",
-                                                               "TEST",
-                                                               "unclassified"
-                                       );
-                       ArrayList<DR_Pub> pubs = new ArrayList<DR_Pub>();
-                       pubs.add( new DR_Pub( "centralLocation" ) ); 
-                       tst.setPubs(pubs);
-
-               boolean rc;
-               DrProvConnection context = new DrProvConnection();
-               rc = context.makeFeedConnection();
-               logger.info( "makeFeedConnection returns " + rc);
-               ApiError err = new ApiError();
-               if ( rc ) {
-                       String tmp  = context.doPostFeed( tst, err );
-                       logger.info( "doPostFeed returns " + tmp);
-               }
-    
-        }
- */
        
+       // add double-quotes around a value
+       // hope his is easier to read than in-line escaping...
+       private String dq( String v ) {
+               return ( "\"" + v + "\"");
+       }
+       private String dq( String k, String v) {
+               return( dq(k) + ":" + dq(v));
+       }
+       private String dqc( String k, String v) {
+               return( dq(k) + ":" + dq(v) + ",");
+       }
+       
+       private String dumpSimulation() {
+               logger.info( "enter dumpSimulation()");
+               String                                  responseBody = 
+                               "{"
+                               + dq("feeds") + ":["
+                               + "{" + dq( "suspend") + ":false,"
+                                         + dq( "groupid") + ":0,"
+                                         + dqc( "description", "Some description" )
+                                         + dqc( "version", "m1.1") 
+                                         + dq( "authorization") + ":"
+                                         + "{" + dq( "endpoint_addrs" ) + ":[],"
+                                                       + dq( "classification", "unclassified")
+                                                       + dq( "endpoint_ids") + ":[{"
+                                                               + dqc( "password", "dradmin" )
+                                                               + dq( "id", "dradmin")
+                                                               + "}]}"
+                                               + dq( "last_mod") + ":1553738110000,"
+                                               + dq( "deleted") + ":false,"
+                                               + dq( "feedid") + ":1,"
+                                               + dqc( "name", "Default PM Feed")
+                                               + dq( "business_description") + ":\"\","
+                                               + dqc( "publisher", "onap")
+                                               + dq( "links") + ":{"
+                                                       + dqc( "subscribe", "https://dmaap-dr-prov/subscribe/1")
+                                                       + dqc( "log", "https://dmaap-dr-prov/feedlog/1")
+                                                       + dqc( "publish", "https://dmaap-dr-prov/publish/1")
+                                                       + dq( "self", "https:/dmaap-dr-prov/feed/1")
+                                                       + "}"
+                                               + dq( "created_date") + ":1553738110000 }"
+                               + "],"
+                               + dq( "groups") + ":["
+                               + "],"
+                               + dq( "subscriptions") + ":["
+                               + "],"
+                               + dq( "ingress") + ":["
+                               + "],"
+                               + dq( "egress") + ":{"
+                               + "},"
+                               + dq( "routing") + ":["
+                               + "],"
+                         + "}";
+               return responseBody;
+       }
+       
+       public String doGetDump( ApiError err ) {
+               logger.info( "entry: doGetDump() "  );
+
+               String responsemessage = null;
+               String responseBody = null;
+
+               try {
+       
+                       uc.setRequestMethod("GET");
+                       int rc = -1;
+                       
+
+                       try {
+                uc.connect();
+       
+
+            } catch (ProtocolException pe) {
+
+                 // Rcvd error instead of 100-Continue
+                 try {
+                     // work around glitch in Java 1.7.0.21 and likely others
+                     // without this, Java will connect multiple times to the server to run the same request
+                     uc.setDoOutput(false);
+                 } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
+                 }
+            } 
+       
+                       rc = uc.getResponseCode();
+                       logger.info( "http response code:" + rc );
+            responsemessage = uc.getResponseMessage();
+            logger.info( "responsemessage=" + responsemessage );
+       
+
+
+            if (responsemessage == null) {
+
+                 // work around for glitch in Java 1.7.0.21 and likely others
+                 // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is
+                 String h0 = uc.getHeaderField(0);
+                 if (h0 != null) {
+                     int i = h0.indexOf(' ');
+                     int j = h0.indexOf(' ', i + 1);
+                     if (i != -1 && j != -1) {
+                         responsemessage = h0.substring(j + 1);
+                     }
+                 }
+            }
+       
+               err.setCode(rc);  // may not really be an error, but we save rc
+            if (rc == 200 ) {
+                       responseBody = bodyToString( uc.getInputStream() );
+                       logger.info( "responseBody=" + responseBody );
+            } else {
+               err.setMessage(responsemessage);
+            }
+            
+
+               } catch (ConnectException ce) {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+                               responseBody = dumpSimulation();
+                                                         
+               } else {
+                   errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+                   err.setCode( 500 );
+                       err.setMessage("Backend connection refused");
+                       logger.error(ce.getMessage(), ce);
+               }
+               } catch (Exception e) {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+                               responseBody = dumpSimulation();
+                                                         
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
+        } finally {
+
+                       if ( uc != null ) uc.disconnect();
+        }
+
+               return responseBody;
+
+       }
                
 }
index 51bad4f..2be1b33 100644 (file)
@@ -30,137 +30,156 @@ import org.onap.dmaap.dbcapi.model.MR_Cluster;
 import org.onap.dmaap.dbcapi.model.Topic;
 import org.onap.dmaap.dbcapi.util.DmaapConfig;
 
+import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
 import java.io.*;
 import java.net.*;
 import java.util.Arrays;
 
 public class MrProvConnection extends BaseLoggingClass{
-           
-       private String provURL;
-       
-       private HttpURLConnection uc;
-
-       
-       private String topicMgrCred;
-       private boolean useAAF;
-       private String  user;
-       private String  encPwd;
-       
-       public MrProvConnection() {
-               String mechIdProperty = "aaf.TopicMgrUser";
-               String pwdProperty = "aaf.TopicMgrPassword";
-               DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
-               user = p.getProperty( mechIdProperty, "noMechId@domain.netset.com" );
-               encPwd = p.getProperty( pwdProperty, "notSet" );
-               useAAF= "true".equalsIgnoreCase(p.getProperty("UseAAF", "false"));
-               topicMgrCred =  getCred();
-               
-       }
-       
-       private String getCred( ) {
-
-
-               String pwd = "";
-               AafDecrypt decryptor = new AafDecrypt();        
-               pwd = decryptor.decrypt(encPwd);
-               return user + ":" + pwd;        
-       }
-       
-       
-       public boolean makeTopicConnection( MR_Cluster cluster ) {
-               logger.info( "connect to cluster: " + cluster.getDcaeLocationName());
-       
-
-               provURL = cluster.getTopicProtocol() + "://" + cluster.getFqdn() + ":" + cluster.getTopicPort() + "/topics/create";
-
-               if ( cluster.getTopicProtocol().equals( "https" ) ) {
-                       return makeSecureConnection( provURL );
-               }
-               return makeConnection( provURL );
-       }
-
-       private boolean makeSecureConnection( String pURL ) {
-               logger.info( "makeConnection to " + pURL );
-       
-               try {
-                       URL u = new URL( pURL );
-                       uc = (HttpsURLConnection) u.openConnection();
-                       uc.setInstanceFollowRedirects(false);
-                       logger.info( "open connect to " + pURL );
-                       return(true);
-               } catch( UnknownHostException uhe ){
-               logger.error( "Caught UnknownHostException for " + pURL);
-               return(false);
+        
+    private String provURL;
+    
+    private HttpURLConnection uc;
+
+    
+    private String topicMgrCred;
+    private String authMethod;
+    private    String    user;
+    private    String    encPwd;
+    private boolean hostnameVerify;
+    
+    public MrProvConnection() {
+        String mechIdProperty = "aaf.TopicMgrUser";
+        String pwdProperty = "aaf.TopicMgrPassword";
+        DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+        user = p.getProperty( mechIdProperty, "noMechId@domain.netset.com" );
+        encPwd = p.getProperty( pwdProperty, "notSet" );
+        authMethod = p.getProperty("MR.authentication", "none");
+        topicMgrCred =  getCred();
+        hostnameVerify= "true".equalsIgnoreCase(p.getProperty("MR.hostnameVerify", "true"));
+        
+    }
+    
+    private String getCred( ) {
+
+
+        String pwd = "";
+        AafDecrypt decryptor = new AafDecrypt();    
+        pwd = decryptor.decrypt(encPwd);
+        return user + ":" + pwd;    
+    }
+    
+    
+    public boolean makeTopicConnection( MR_Cluster cluster ) {
+        logger.info( "connect to cluster: " + cluster.getDcaeLocationName());
+    
+
+        provURL = cluster.getTopicProtocol() + "://" + cluster.getFqdn() + ":" + cluster.getTopicPort() + "/topics/create";
+
+        if ( cluster.getTopicProtocol().equals( "https" ) ) {
+            return makeSecureConnection( provURL );
+        }
+        return makeConnection( provURL );
+    }
+
+    private boolean makeSecureConnection( String pURL ) {
+        logger.info( "makeConnection to " + pURL );
+    
+        try {
+       
+                       HostnameVerifier hostnameVerifier = new HostnameVerifier() {
+                               @Override
+                               public boolean verify( String hostname, SSLSession session ) {
+                                       return true;
+                               }
+                       
+                       };
+            URL u = new URL( pURL );
+            uc = (HttpsURLConnection) u.openConnection();
+            uc.setInstanceFollowRedirects(false);
+            if ( ! hostnameVerify ) {
+                               HttpsURLConnection ucs = (HttpsURLConnection) uc;
+                               ucs.setHostnameVerifier(hostnameVerifier);
+                       }
+            logger.info( "open secure connect to " + pURL );
+            return(true);
+        } catch( UnknownHostException uhe ){
+            logger.error( "Caught UnknownHostException for " + pURL);
+            return(false);
         } catch (Exception e) {
             logger.error("Unexpected error during openConnection of " + pURL );
-            e.printStackTrace();
+            logger.error("Unexpected error during openConnection of ",e );
             return(false);
         } 
 
-       }
-       private boolean makeConnection( String pURL ) {
-               logger.info( "makeConnection to " + pURL );
-       
-               try {
-                       URL u = new URL( pURL );
-                       uc = (HttpURLConnection) u.openConnection();
-                       uc.setInstanceFollowRedirects(false);
-                       logger.info( "open connect to " + pURL );
-                       return(true);
-               } catch( UnknownHostException uhe ){
-               logger.error( "Caught UnknownHostException for " + pURL);
-               return(false);
+    }
+    private boolean makeConnection( String pURL ) {
+        logger.info( "makeConnection to " + pURL );
+    
+        try {
+            URL u = new URL( pURL );
+            uc = (HttpURLConnection) u.openConnection();
+            uc.setInstanceFollowRedirects(false);                      
+
+            logger.info( "open connect to " + pURL );
+            return(true);
+        } catch( UnknownHostException uhe ){
+            logger.error( "Caught UnknownHostException for " + pURL);
+            return(false);
         } catch (Exception e) {
             logger.error("Unexpected error during openConnection of " + pURL );
-            e.printStackTrace();
+            logger.error("Unexpected error during openConnection of ",e );
             return(false);
         } 
 
-       }
-       
-       static String bodyToString( InputStream is ) {
-               StringBuilder sb = new StringBuilder();
-               BufferedReader br = new BufferedReader( new InputStreamReader(is));
-               String line;
-               try {
-                       while ((line = br.readLine()) != null ) {
-                               sb.append( line );
-                       }
-               } catch (IOException ex ) {
-                       errorLogger.error( "IOexception:" + ex);
-               }
-                       
-               return sb.toString();
-       }
-       
-       public String doPostTopic( Topic postTopic, ApiError err ) {
-               String auth =  "Basic " + Base64.encodeBase64String(topicMgrCred.getBytes());
+    }
+    
+    static String bodyToString( InputStream is ) {
+        StringBuilder sb = new StringBuilder();
+        BufferedReader br = new BufferedReader( new InputStreamReader(is));
+        String line;
+        try {
+            while ((line = br.readLine()) != null ) {
+                sb.append( line );
+            }
+        } catch (IOException ex ) {
+            errorLogger.error( "IOexception:" + ex);
+        }
+            
+        return sb.toString();
+    }
+    
+    public String doPostTopic( Topic postTopic, ApiError err ) {
+        String auth =  "Basic " + Base64.encodeBase64String(topicMgrCred.getBytes());
 
 
-               String responsemessage = null;
-               int rc = -1;
+        String responsemessage = null;
+        int rc = -1;
 
 
-               try {
-                       byte[] postData = postTopic.getBytes();
-                       logger.info( "post fields=" + Arrays.toString(postData));
-                       
-                       // when not using AAF, do not attempt Basic Authentication
-                       if ( useAAF ) {
+        try {
+            byte[] postData = postTopic.getBytes();
+            logger.info( "post fields=" + Arrays.toString(postData));
+            
+                       if ( authMethod.equalsIgnoreCase("basicAuth") ) {
                                uc.setRequestProperty("Authorization", auth);
                                logger.info( "Authenticating with " + auth );
+                       } else if ( authMethod.equalsIgnoreCase("cert")) {
+                               logger.error( "MR.authentication set for client certificate.  Not supported yet.");
                        }
-                       uc.setRequestMethod("POST");
-                       uc.setRequestProperty("Content-Type", "application/json");
-                       uc.setRequestProperty( "charset", "utf-8");
-                       uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
-                       uc.setUseCaches(false);
-                       uc.setDoOutput(true);
-                       OutputStream os = null;
+            uc.setRequestMethod("POST");
+            uc.setRequestProperty("Content-Type", "application/json");
+            uc.setRequestProperty( "charset", "utf-8");
+            uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
+            uc.setUseCaches(false);
+            uc.setDoOutput(true);
+            OutputStream os = null;
 
-                       
-                       try {
+            
+            try {
                  uc.connect();
                  os = uc.getOutputStream();
                  os.write( postData );
@@ -174,21 +193,21 @@ public class MrProvConnection extends BaseLoggingClass{
                  } catch (Exception e) {
                  }
             } catch ( UnknownHostException uhe ) {
-               errorLogger.error( DmaapbcLogMessageEnum.UNKNOWN_HOST_EXCEPTION , "Unknown Host Exception" , provURL );
-               err.setCode(500);
-               err.setMessage("Unknown Host Exception");
-               err.setFields( uc.getURL().getHost());
-               return new String( "500: " + uhe.getMessage());
+                errorLogger.error( DmaapbcLogMessageEnum.UNKNOWN_HOST_EXCEPTION , "Unknown Host Exception" , provURL );
+                err.setCode(500);
+                err.setMessage("Unknown Host Exception");
+                err.setFields( uc.getURL().getHost());
+                return new String( "500: " + uhe.getMessage());
             }catch ( ConnectException ce ) {
-               errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, "HTTP Connection Exception"  );
-               err.setCode(500);
-               err.setMessage("HTTP Connection Exception");
-               err.setFields( uc.getURL().getHost());
-               return new String( "500: " + ce.getMessage());
+                errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, "HTTP Connection Exception"  );
+                err.setCode(500);
+                err.setMessage("HTTP Connection Exception");
+                err.setFields( uc.getURL().getHost());
+                return new String( "500: " + ce.getMessage());
             }
-                       rc = uc.getResponseCode();
-                       logger.info( "http response code:" + rc );
-                       err.setCode(rc);
+            rc = uc.getResponseCode();
+            logger.info( "http response code:" + rc );
+            err.setCode(rc);
             responsemessage = uc.getResponseMessage();
             logger.info( "responsemessage=" + responsemessage );
             err.setMessage(responsemessage);
@@ -207,29 +226,29 @@ public class MrProvConnection extends BaseLoggingClass{
                  }
             }
             if (rc >= 200 && rc < 300 ) {
-                       String responseBody = null;
-                       responseBody = bodyToString( uc.getInputStream() );
-                       logger.info( "responseBody=" + responseBody );
-                       return responseBody;
+                String responseBody = null;
+                 responseBody = bodyToString( uc.getInputStream() );
+                logger.info( "responseBody=" + responseBody );
+                return responseBody;
 
             } 
             
-               } catch (Exception e) {
-                       errorLogger.error("Unable to read response  " );
+        } catch (Exception e) {
+            errorLogger.error("Unable to read response:  " + e.getMessage() );
            
         }
-               finally {
-                       try {
-                               uc.disconnect();
-                       } catch ( Exception e ) {
-                               errorLogger.error("Unable to disconnect");
-                       }
-               }
-               return new String( rc +": " + responsemessage );
+        finally {
+            try {
+                uc.disconnect();
+            } catch ( Exception e ) {
+                errorLogger.error("Unable to disconnect");
+            }
+        }
+        return new String( rc +": " + responsemessage );
 
-       }
-       
+    }
+    
 
 
-               
+        
 }
index a92dbc7..0a5f91a 100644 (file)
@@ -31,8 +31,10 @@ import java.net.ProtocolException;
 import java.net.URL;
 import java.net.HttpURLConnection;
 
+import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
 
 import org.apache.commons.codec.binary.Base64;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
@@ -48,14 +50,15 @@ public class MrTopicConnection extends BaseLoggingClass  {
        
        private  String mmProvCred; 
        private String unit_test;
-       private boolean useAAF;
-
+       private String authMethod;
+       private boolean hostnameVerify;
 
        public MrTopicConnection(String user, String pwd ) {
                mmProvCred = new String( user + ":" + pwd );
                DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
         unit_test = p.getProperty( "UnitTest", "No" );
-       useAAF= "true".equalsIgnoreCase(p.getProperty("UseAAF", "false"));
+       authMethod = p.getProperty("MR.authentication", "none");
+       hostnameVerify= "true".equalsIgnoreCase(p.getProperty("MR.hostnameVerify", "true"));
        }
        
        public boolean makeTopicConnection( MR_Cluster cluster, String topic, String overrideFqdn ) {
@@ -71,13 +74,28 @@ public class MrTopicConnection extends BaseLoggingClass  {
                return makeConnection( topicURL );
        }
 
+       
        private boolean makeSecureConnection( String pURL ) {
                logger.info( "makeConnection to " + pURL );
-       
+               
                try {
+                       HostnameVerifier hostnameVerifier = new HostnameVerifier() {
+                               @Override
+                               public boolean verify( String hostname, SSLSession session ) {
+                                       return true;
+                               }
+                       
+                       };
+       
+               
                        URL u = new URL( pURL );
-                       uc = (HttpsURLConnection) u.openConnection();
+                       uc = (HttpsURLConnection) u.openConnection();                   
                        uc.setInstanceFollowRedirects(false);
+                       if ( ! hostnameVerify ) {
+                               HttpsURLConnection ucs = (HttpsURLConnection) uc;
+                               ucs.setHostnameVerifier(hostnameVerifier);
+                       }
+       
                        logger.info( "open connection to " + pURL );
                        return(true);
                } catch (Exception e) {
@@ -128,9 +146,11 @@ public class MrTopicConnection extends BaseLoggingClass  {
                try {
                        byte[] postData = postMessage.getBytes();
                        logger.info( "post fields=" + postMessage );
-                       if ( useAAF ) {
+                       if ( authMethod.equalsIgnoreCase("basicAuth") ) {
                                uc.setRequestProperty("Authorization", auth);
                                logger.info( "Authenticating with " + auth );
+                       } else if ( authMethod.equalsIgnoreCase("cert")) {
+                               logger.error( "MR.authentication set for client certificate.  Not supported yet.");
                        }
                        uc.setRequestMethod("POST");
                        uc.setRequestProperty("Content-Type", "application/json");
index 0f14e60..e32b8e0 100644 (file)
@@ -3,6 +3,7 @@
  * org.onap.dmaap
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 IBM.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -108,6 +109,7 @@ public class ConnectionFactory      {
                        TimeUnit.SECONDS.sleep(seconds);
                } catch (InterruptedException e) {
                        logger.debug("Waiting interrupted. ", e);
+                       Thread.currentThread().interrupt();
                }
        }
 }
index 6f63848..b3282ed 100644 (file)
@@ -59,7 +59,7 @@ public class DBMap<C> extends TableHandler<C> implements Map<String, C>       {
                return(2);
        }
        public Collection<C> values() {
-               Collection<C> ret = new Vector<>();
+               Collection<C> ret = new ArrayList<>();
                for (Map.Entry<String, C> x: list()) {
                        ret.add(x.getValue());
                }
@@ -110,7 +110,6 @@ public class DBMap<C> extends TableHandler<C> implements Map<String, C>     {
                } catch (Exception e) {
                        throw new DBException(e);
                }
-               PreparedStatement ps = null;
                return((new ConnWrapper<C, C>() {
                        protected C run(C val) throws Exception {
                                ps = c.prepareStatement(insorreplstmt);
index e2004bd..c853782 100644 (file)
@@ -32,201 +32,252 @@ import org.onap.dmaap.dbcapi.util.DmaapConfig;
 import org.onap.dmaap.dbcapi.util.Singleton;
 
 
+public class DatabaseClass extends BaseLoggingClass {
 
+    private static Singleton<Dmaap> dmaap;
+    private static Map<String, DcaeLocation> dcaeLocations;
+    private static Map<String, DR_Node> dr_nodes;
+    private static Map<String, DR_Pub> dr_pubs;
+    private static Map<String, DR_Sub> dr_subs;
+    private static Map<String, MR_Client> mr_clients;
+    private static Map<String, MR_Cluster> mr_clusters;
+    private static Map<String, Feed> feeds;
+    private static Map<String, Topic> topics;
+    private static Map<String, MirrorMaker> mirrors;
 
-public class DatabaseClass extends BaseLoggingClass {
-       
-       private static Singleton<Dmaap> dmaap;
-       private static Map<String, DcaeLocation> dcaeLocations;
-       private static Map<String, DR_Node> dr_nodes;
-       private static Map<String, DR_Pub> dr_pubs;
-       private static Map<String, DR_Sub> dr_subs;
-       private static Map<String, MR_Client> mr_clients;
-       private static Map<String, MR_Cluster> mr_clusters;
-       private static Map<String, Feed> feeds;
-       private static Map<String, Topic> topics;
-       private static Map<String, MirrorMaker> mirrors;
-       
-       private static long lastTime = 0L;
-       
-
-
-       private static class MirrorTopicsHandler implements DBFieldHandler.SqlOp {
-               public Object get(ResultSet rs, int index) throws Exception {
-                       String val = rs.getString(index);
-                       if (val == null) {
-                               return(null);
-                       }
-                       List<String> rv = new ArrayList<>();
-                       for (String s: val.split(",")) {
-                               rv.add(new String(s));
-                       }
-                       return(rv);
-               }
-               public void set(PreparedStatement ps, int index, Object val) throws Exception {
-                       if (val == null) {
-                               ps.setString(index, null);
-                               return;
-                       }
-                       @SuppressWarnings("unchecked")
-                       List<String> xv = (List<String>)val;
-                       StringBuilder sb = new StringBuilder();
-                       String sep = "";
-                       for (Object o: xv) {
-                               String rv = (String)o;
-                               sb.append(sep).append(DBFieldHandler.fesc(rv));
-                               sep = ",";
-                       }
-                       ps.setString(index, sb.toString());
-               }
-       }
-       private static class TopicReplicationTypeHandler implements DBFieldHandler.SqlOp {
-               public Object get(ResultSet rs, int index) throws Exception {
-                       int val = rs.getInt(index);
-
-                       return (ReplicationType.valueOf(val));
-               }
-               public void set(PreparedStatement ps, int index, Object val) throws Exception {
-                       if (val == null) {
-                               ps.setInt(index, 0);
-                               return;
-                       }
-                       @SuppressWarnings("unchecked")
-                       ReplicationType rep = (ReplicationType) val;
-                       ps.setInt(index, rep.getValue());
-               }       
-       }
-       public static Singleton<Dmaap> getDmaap() {
-               return dmaap;
-       }
-       
-
-       
-       public static Map<String, DcaeLocation> getDcaeLocations() {
-               return dcaeLocations;
-       }
-       
-       public static Map<String, DR_Node> getDr_nodes() {
-               return dr_nodes;
-       }
-       
-       public static Map<String, DR_Sub> getDr_subs() {
-               return dr_subs;
-       }
-       public static Map<String, DR_Pub> getDr_pubs() {
-               return dr_pubs;
-       }
-
-       public static Map<String, MR_Client> getMr_clients() {
-               return mr_clients;
-       }
-
-
-       public static Map<String, MR_Cluster> getMr_clusters() {
-               return mr_clusters;
-       }
-       
-       public static Map<String, Feed> getFeeds() {
-               return feeds;
-       }
-       public static Map<String, Topic> getTopics() {
-               return topics;
-       }
-       public static Map<String, MirrorMaker> getMirrorMakers() {
-               return mirrors;
-       }
-
-       static {
-               try {
-               appLogger.info( "begin static initialization");
-               appLogger.info( "initializing dmaap" );
-               DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
-               if ("true".equalsIgnoreCase(p.getProperty("UsePGSQL", "false"))) {
-                       appLogger.info("Data from database");
-                       try {
-                               LoadSchema.upgrade();
-                       } catch (Exception e) {
-                               appLogger.warn("Problem updating DB schema", e);
-                       }
-                       try {
-                               dmaap = new DBSingleton<>(Dmaap.class, "dmaap");
-                               dcaeLocations = new DBMap<>(DcaeLocation.class, "dcae_location", "dcae_location_name");
-                               dr_nodes = new DBMap<>(DR_Node.class, "dr_node", "fqdn");
-                               dr_pubs = new DBMap<>(DR_Pub.class, "dr_pub", "pub_id");
-                               dr_subs = new DBMap<>(DR_Sub.class, "dr_sub", "sub_id");
-                               mr_clients = new DBMap<>(MR_Client.class, "mr_client", "mr_client_id");
-                               mr_clusters = new DBMap<>(MR_Cluster.class, "mr_cluster", "dcae_location_name");
-                               feeds = new DBMap<>(Feed.class, "feed", "feed_id");
-                               TableHandler.setSpecialCase("topic", "replication_case", new TopicReplicationTypeHandler());
-                               topics = new DBMap<>(Topic.class, "topic", "fqtn");                     
-                               TableHandler.setSpecialCase("mirror_maker", "topics", new MirrorTopicsHandler());
-                               mirrors = new DBMap<>(MirrorMaker.class, "mirror_maker", "mm_name");
-                       } catch (Exception e) {
-                               errorLogger.error("Error initializing database access " + e, e);
-                               System.exit(1);
-                       }
-               } else {
-                       appLogger.info("Data from memory");
-                       dmaap = new Singleton<Dmaap>() {
-                               private Dmaap dmaap;
-                               public void remove() {
-                                       dmaap = null;
-                               }
-                               public void init(Dmaap val) {
-                                       if (dmaap == null) {
-                                               dmaap = val;
-                                       }
-                               }
-                               public Dmaap get() {
-                                       return(dmaap);
-                               }
-                               public void update(Dmaap nd) {
-                                       dmaap.setVersion(nd.getVersion());
-                                       dmaap.setTopicNsRoot(nd.getTopicNsRoot());
-                                       dmaap.setDmaapName(nd.getDmaapName());
-                                       dmaap.setDrProvUrl(nd.getDrProvUrl());
-                                       dmaap.setBridgeAdminTopic(nd.getBridgeAdminTopic());
-                                       dmaap.setLoggingUrl(nd.getLoggingUrl());
-                                       dmaap.setNodeKey(nd.getNodeKey());
-                                       dmaap.setAccessKeyOwner(nd.getAccessKeyOwner());
-                               }
-                       };
-                       dcaeLocations = new HashMap<>();
-                       dr_nodes = new HashMap<>();
-                       dr_pubs = new HashMap<>();
-                       dr_subs = new HashMap<>();
-                       mr_clients = new HashMap<>();
-                       mr_clusters = new HashMap<>();
-                       feeds = new HashMap<>();
-                       topics = new HashMap<>();
-                       mirrors = new HashMap<>();
-               }
-               dmaap.init(new Dmaap("0", "", "", "", "", "", "", ""));
-               // force initial read from DB, if it exists
-               @SuppressWarnings("unused")
-               Dmaap dmx = dmaap.get();
-               
-               // old code in this spot would read from properties file as part of init.
-               // but all those properties are now set via /dmaap API
-
-               } catch (Exception e) {
-                       errorLogger.error("Error", e);
-                       errorLogger.error(DmaapbcLogMessageEnum.DB_UPDATE_ERROR, e.getMessage());
-               }
-
-       }
-       
-       public static synchronized String getNextClientId() {
-               
-               long id = System.currentTimeMillis();
-               if ( id <= lastTime ) {
-                       id = lastTime + 1;
-               }
-               lastTime = id;
-               return Long.toString(id);
-       }
-
-       
+    private static long lastTime = 0L;
+    private static DBType databaseType;
+
+    private enum DBType {
+        PGSQL, MEMORY
+    }
+
+    public static Singleton<Dmaap> getDmaap() {
+        return dmaap;
+    }
+
+
+    public static Map<String, DcaeLocation> getDcaeLocations() {
+        return dcaeLocations;
+    }
+
+    public static Map<String, DR_Node> getDr_nodes() {
+        return dr_nodes;
+    }
+
+    public static Map<String, DR_Sub> getDr_subs() {
+        return dr_subs;
+    }
+
+    public static Map<String, DR_Pub> getDr_pubs() {
+        return dr_pubs;
+    }
+
+    public static Map<String, MR_Client> getMr_clients() {
+        return mr_clients;
+    }
+
+
+    public static Map<String, MR_Cluster> getMr_clusters() {
+        return mr_clusters;
+    }
+
+    public static Map<String, Feed> getFeeds() {
+        return feeds;
+    }
+
+    public static Map<String, Topic> getTopics() {
+        return topics;
+    }
+
+    public static Map<String, MirrorMaker> getMirrorMakers() {
+        return mirrors;
+    }
+
+    static {
+        try {
+            appLogger.info("begin static initialization");
+            appLogger.info("initializing dmaap");
+            determineDatabaseType();
+
+            switch (databaseType) {
+                case PGSQL:
+                    databaseResourceInit();
+                    break;
+                case MEMORY:
+                    inMemoryResourceInit();
+                    break;
+            }
+
+            dmaap.init(new Dmaap("0", "", "", "", "", "", "", ""));
+            // force initial read from DB, if it exists
+            @SuppressWarnings("unused")
+            Dmaap dmx = dmaap.get();
+
+            // old code in this spot would read from properties file as part of init.
+            // but all those properties are now set via /dmaap API
+
+        } catch (Exception e) {
+            errorLogger.error("Error", e);
+            errorLogger.error(DmaapbcLogMessageEnum.DB_UPDATE_ERROR, e.getMessage());
+        }
+
+    }
+
+    public static synchronized String getNextClientId() {
+
+        long id = System.currentTimeMillis();
+        if (id <= lastTime) {
+            id = lastTime + 1;
+        }
+        lastTime = id;
+        return Long.toString(id);
+    }
+
+    public static synchronized void clearDatabase() {
+        switch (databaseType) {
+            case PGSQL:
+                try {
+                    initDatabase();
+                } catch (Exception e) {
+                    errorLogger.error("Error initializing database access " + e, e);
+                }
+                break;
+            case MEMORY:
+                initMemoryDatabase();
+                break;
+        }
+    }
+
+    private static void inMemoryResourceInit() {
+        appLogger.info("Data from memory");
+        dmaap = new Singleton<Dmaap>() {
+            private Dmaap dmaap;
+
+            public void remove() {
+                dmaap = null;
+            }
+
+            public void init(Dmaap val) {
+                if (dmaap == null) {
+                    dmaap = val;
+                }
+            }
+
+            public Dmaap get() {
+                return (dmaap);
+            }
+
+            public void update(Dmaap nd) {
+                dmaap.setVersion(nd.getVersion());
+                dmaap.setTopicNsRoot(nd.getTopicNsRoot());
+                dmaap.setDmaapName(nd.getDmaapName());
+                dmaap.setDrProvUrl(nd.getDrProvUrl());
+                dmaap.setBridgeAdminTopic(nd.getBridgeAdminTopic());
+                dmaap.setLoggingUrl(nd.getLoggingUrl());
+                dmaap.setNodeKey(nd.getNodeKey());
+                dmaap.setAccessKeyOwner(nd.getAccessKeyOwner());
+            }
+        };
+        initMemoryDatabase();
+    }
+
+    private static void databaseResourceInit() {
+        appLogger.info("Data from database");
+        try {
+            LoadSchema.upgrade();
+        } catch (Exception e) {
+            appLogger.warn("Problem updating DB schema", e);
+        }
+        try {
+            dmaap = new DBSingleton<>(Dmaap.class, "dmaap");
+            TableHandler.setSpecialCase("topic", "replication_case", new TopicReplicationTypeHandler());
+            TableHandler.setSpecialCase("mirror_maker", "topics", new MirrorTopicsHandler());
+            initDatabase();
+        } catch (Exception e) {
+            errorLogger.error("Error initializing database access " + e, e);
+            System.exit(1);
+        }
+    }
+
+    private static class MirrorTopicsHandler implements DBFieldHandler.SqlOp {
+
+        public Object get(ResultSet rs, int index) throws Exception {
+            String val = rs.getString(index);
+            if (val == null) {
+                return (null);
+            }
+            List<String> rv = new ArrayList<>();
+            for (String s : val.split(",")) {
+                rv.add(new String(s));
+            }
+            return (rv);
+        }
+
+        public void set(PreparedStatement ps, int index, Object val) throws Exception {
+            if (val == null) {
+                ps.setString(index, null);
+                return;
+            }
+            @SuppressWarnings("unchecked")
+            List<String> xv = (List<String>) val;
+            StringBuilder sb = new StringBuilder();
+            String sep = "";
+            for (Object o : xv) {
+                String rv = (String) o;
+                sb.append(sep).append(DBFieldHandler.fesc(rv));
+                sep = ",";
+            }
+            ps.setString(index, sb.toString());
+        }
+    }
+
+    private static class TopicReplicationTypeHandler implements DBFieldHandler.SqlOp {
+
+        public Object get(ResultSet rs, int index) throws Exception {
+            int val = rs.getInt(index);
+
+            return (ReplicationType.valueOf(val));
+        }
+
+        public void set(PreparedStatement ps, int index, Object val) throws Exception {
+            if (val == null) {
+                ps.setInt(index, 0);
+                return;
+            }
+            @SuppressWarnings("unchecked")
+            ReplicationType rep = (ReplicationType) val;
+            ps.setInt(index, rep.getValue());
+        }
+    }
+
+    private static void initMemoryDatabase() {
+        dcaeLocations = new HashMap<>();
+        dr_nodes = new HashMap<>();
+        dr_pubs = new HashMap<>();
+        dr_subs = new HashMap<>();
+        mr_clients = new HashMap<>();
+        mr_clusters = new HashMap<>();
+        feeds = new HashMap<>();
+        topics = new HashMap<>();
+        mirrors = new HashMap<>();
+    }
 
+    private static void initDatabase() throws Exception {
+        dcaeLocations = new DBMap<>(DcaeLocation.class, "dcae_location", "dcae_location_name");
+        dr_nodes = new DBMap<>(DR_Node.class, "dr_node", "fqdn");
+        dr_pubs = new DBMap<>(DR_Pub.class, "dr_pub", "pub_id");
+        dr_subs = new DBMap<>(DR_Sub.class, "dr_sub", "sub_id");
+        mr_clients = new DBMap<>(MR_Client.class, "mr_client", "mr_client_id");
+        mr_clusters = new DBMap<>(MR_Cluster.class, "mr_cluster", "dcae_location_name");
+        feeds = new DBMap<>(Feed.class, "feed", "feed_id");
+        topics = new DBMap<>(Topic.class, "topic", "fqtn");
+        mirrors = new DBMap<>(MirrorMaker.class, "mirror_maker", "mm_name");
+    }
 
+    private static void determineDatabaseType() {
+        DmaapConfig dmaapConfig = (DmaapConfig) DmaapConfig.getConfig();
+        String isPgSQLset = dmaapConfig.getProperty("UsePGSQL", "false");
+        databaseType = isPgSQLset.equalsIgnoreCase("true") ? DBType.PGSQL : DBType.MEMORY;
+    }
 }
index 8d8e23f..c67e55b 100644 (file)
 package org.onap.dmaap.dbcapi.model;
 
 import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Objects;
 
 @XmlRootElement
-public class ApiError {
+public class ApiError implements Serializable {
        private int code;
        private String message;
        private String fields;
-       
+
+       public ApiError() {
+               this(0, null, null);
+       }
+
+       public ApiError(int code, String message) {
+               this(code, message, null);
+       }
+
+       public ApiError(int code, String message, String fields) {
+               this.code = code;
+               this.message = message;
+               this.fields = fields;
+       }
+
        public int getCode() {
                return code;
        }
@@ -58,4 +74,19 @@ public class ApiError {
                message = null;
                fields = null;
        }
+
+       @Override
+       public boolean equals(Object o) {
+               if (this == o) return true;
+               if (o == null || getClass() != o.getClass()) return false;
+               ApiError apiError = (ApiError) o;
+               return code == apiError.code &&
+                               Objects.equals(message, apiError.message) &&
+                               Objects.equals(fields, apiError.fields);
+       }
+
+       @Override
+       public int hashCode() {
+               return Objects.hash(code, message, fields);
+       }
 }
index a85f040..4b2ef90 100644 (file)
@@ -21,6 +21,7 @@
 package org.onap.dmaap.dbcapi.model;
 
 import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Objects;
 
 @XmlRootElement
 public class DR_Node extends DmaapObject {
@@ -75,4 +76,19 @@ public class DR_Node extends DmaapObject {
                this.version = version;
        }
 
+       @Override
+       public boolean equals(Object o) {
+               if (this == o) return true;
+               if (o == null || getClass() != o.getClass()) return false;
+               DR_Node dr_node = (DR_Node) o;
+               return Objects.equals(fqdn, dr_node.fqdn) &&
+                               Objects.equals(dcaeLocationName, dr_node.dcaeLocationName) &&
+                               Objects.equals(hostName, dr_node.hostName) &&
+                               Objects.equals(version, dr_node.version);
+       }
+
+       @Override
+       public int hashCode() {
+               return Objects.hash(fqdn, dcaeLocationName, hostName, version);
+       }
 }
index 0d146b7..4e64089 100644 (file)
@@ -24,6 +24,8 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 import org.onap.dmaap.dbcapi.util.RandomString;
 
+import java.util.Objects;
+
 @XmlRootElement
 public class DR_Pub extends DmaapObject {
 
@@ -151,5 +153,35 @@ public class DR_Pub extends DmaapObject {
                return ri.nextString();
                
        }
-       
+
+       @Override
+       public boolean equals(Object o) {
+               if (this == o) return true;
+               if (o == null || getClass() != o.getClass()) return false;
+               DR_Pub dr_pub = (DR_Pub) o;
+               return Objects.equals(dcaeLocationName, dr_pub.dcaeLocationName) &&
+                               Objects.equals(username, dr_pub.username) &&
+                               Objects.equals(userpwd, dr_pub.userpwd) &&
+                               Objects.equals(feedId, dr_pub.feedId) &&
+                               Objects.equals(pubId, dr_pub.pubId);
+       }
+
+       @Override
+       public int hashCode() {
+
+               return Objects.hash(dcaeLocationName, username, userpwd, feedId, pubId);
+       }
+
+       @Override
+       public String toString() {
+               return "DR_Pub{" +
+                               "dcaeLocationName='" + dcaeLocationName + '\'' +
+                               ", username='" + username + '\'' +
+                               ", userpwd='" + userpwd + '\'' +
+                               ", feedId='" + feedId + '\'' +
+                               ", pubId='" + pubId + '\'' +
+                               ", feedName='" + feedName + '\'' +
+                               ", feedVersion='" + feedVersion + '\'' +
+                               '}';
+       }
 }
index 9b6e2d7..90da956 100644 (file)
@@ -45,15 +45,16 @@ public class DR_Sub extends DmaapObject {
        private boolean guaranteedDelivery;
        private boolean guaranteedSequence;
        private boolean privilegedSubscriber;
-       
+       private boolean decompress;
+
        // NOTE: the following fields are optional in the API but not stored in the DB
+
        private String  feedName;
        private String  feedVersion;
-
        public DR_Sub() {
 
        }
-       
+
        public DR_Sub( String dLN,
                                        String uN,
                                        String uP,
@@ -71,12 +72,12 @@ public class DR_Sub extends DmaapObject {
                this.setStatus( DmaapObject_Status.NEW );
                this.subId = "0";
        }
-       
+
        public DR_Sub ( String json ) {
                logger.info( "DR_Sub:" + json );
                JSONParser parser = new JSONParser();
                JSONObject jsonObj;
-               
+
                try {
                        jsonObj = (JSONObject) parser.parse( json );
                } catch ( ParseException pe ) {
@@ -87,7 +88,7 @@ public class DR_Sub extends DmaapObject {
 
                this.setOwner( (String) jsonObj.get("subscriber"));
                this.setSuspended( (boolean) jsonObj.get("suspend"));
-               
+
                try {
                        JSONObject links = (JSONObject) jsonObj.get("links");
                        String url = (String) links.get("feed");
@@ -97,7 +98,7 @@ public class DR_Sub extends DmaapObject {
                        logger.info( "feedid="+ this.getFeedId() );
                        this.setLogURL( (String) links.get("log") );
                } catch (NullPointerException npe ) {
-                       
+
                }
                try {
                        this.setGuaranteedDelivery( (boolean) jsonObj.get("guaranteed_delivery"));
@@ -114,20 +115,23 @@ public class DR_Sub extends DmaapObject {
                } catch( NullPointerException npe ) {
                        this.setPrivilegedSubscriber(false);
                }
-               
+               try {
+                       this.setDecompress((boolean) jsonObj.get("decompress"));
+               } catch( NullPointerException npe ) {
+                       this.setDecompress(false);
+               }
+
                JSONObject del = (JSONObject) jsonObj.get("delivery");
-               this.setDeliveryURL( (String) del.get("url") ); 
+               this.setDeliveryURL( (String) del.get("url") );
                this.setUsername( (String) del.get("user"));
                this.setUserpwd( (String) del.get( "password"));
                this.setUse100((boolean) del.get( "use100"));
 
-               
-
                this.setStatus( DmaapObject_Status.VALID );
 
                logger.info( "new DR_Sub returning");
        }
-       
+
        public String getOwner() {
                return owner;
        }
@@ -234,8 +238,14 @@ public class DR_Sub extends DmaapObject {
        public void setPrivilegedSubscriber(boolean privilegedSubscriber) {
                this.privilegedSubscriber = privilegedSubscriber;
        }
-       
-       
+
+       public boolean isDecompress() {
+               return decompress;
+       }
+
+       public void setDecompress(boolean decompressData) {
+               this.decompress = decompressData;
+       }
 
        public String getFeedName() {
                return feedName;
@@ -260,31 +270,32 @@ public class DR_Sub extends DmaapObject {
                return toProvJSON().getBytes(StandardCharsets.UTF_8);
        }
        // returns the DR_Sub object in JSON that conforms to ONAP DR Prov Server expectations
-       public String toProvJSON() {    
+       public String toProvJSON() {
                // this is the original DR API that was contributed to ONAP
                String postJSON = String.format("{\"suspend\": %s, \"delivery\":"
                                + "{\"url\": \"%s\", \"user\": \"%s\", \"password\": \"%s\", \"use100\":  %s }"
                                + ", \"metadataOnly\": %s, \"groupid\": \"%s\", \"follow_redirect\": %s "
-                               + ", \"privilegedSubscriber\": %s "
+                               + ", \"privilegedSubscriber\": %s, \"decompress\": %s "
                                + "}"
                                ,this.suspended
                                ,this.getDeliveryURL()
                                ,this.getUsername()
                                ,this.getUserpwd()
-                               ,this.isUse100()                
+                               ,this.isUse100()
                                ,"false"
                                ,"0"
                                ,"true"
                                ,this.isPrivilegedSubscriber()
-                       );      
-               
+                               ,this.isDecompress()
+                       );
+
                logger.info( postJSON );
                return postJSON;
        }
        // returns the DR_Sub object in JSON that conforms to AT&T DR Prov Server expectations
        // In Jan, 2019, the DR API used internally at AT&T diverged, so this function can be used in
        // that runtime environment
-       public String toProvJSONforATT() {      
+       public String toProvJSONforATT() {
                // in DR 3.0, API v2.1 a new groupid field is added.  We are not using this required field so just set it to 0.
                // we send this regardless of DR Release because older versions of DR seem to safely ignore it
                // and soon those versions won't be around anyway...
@@ -312,15 +323,15 @@ public class DR_Sub extends DmaapObject {
                                ,"true"
                                ,this.isGuaranteedDelivery()
                                ,this.isGuaranteedSequence()
-                               );      
-               
+                               );
+
                logger.info( postJSON );
                return postJSON;
        }
-       
+
        @Override
        public String toString() {
-               String rc = String.format ( "DR_Sub: {dcaeLocationName=%s username=%s userpwd=%s feedId=%s deliveryURL=%s logURL=%s subid=%s use100=%s suspended=%s owner=%s}",
+               return String.format ( "DR_Sub: {dcaeLocationName=%s username=%s userpwd=%s feedId=%s deliveryURL=%s logURL=%s subid=%s use100=%s suspended=%s owner=%s}",
                                dcaeLocationName,
                                username,
                                userpwd,
@@ -332,6 +343,49 @@ public class DR_Sub extends DmaapObject {
                                suspended,
                                owner
                                );
-               return rc;
+       }
+
+       @Override
+       public boolean equals(Object o) {
+               if (this == o) {
+                       return true;
+               }
+               if (o == null || getClass() != o.getClass()) {
+                       return false;
+               }
+
+               DR_Sub drSub = (DR_Sub) o;
+
+               if (use100 != drSub.use100) {
+                       return false;
+               }
+               if (suspended != drSub.suspended) {
+                       return false;
+               }
+               if (!dcaeLocationName.equals(drSub.dcaeLocationName)) {
+                       return false;
+               }
+               if (!username.equals(drSub.username)) {
+                       return false;
+               }
+               if (!userpwd.equals(drSub.userpwd)) {
+                       return false;
+               }
+               if (!feedId.equals(drSub.feedId)) {
+                       return false;
+               }
+               return subId.equals(drSub.subId);
+       }
+
+       @Override
+       public int hashCode() {
+               int result = dcaeLocationName.hashCode();
+               result = 31 * result + username.hashCode();
+               result = 31 * result + userpwd.hashCode();
+               result = 31 * result + feedId.hashCode();
+               result = 31 * result + subId.hashCode();
+               result = 31 * result + (use100 ? 1 : 0);
+               result = 31 * result + (suspended ? 1 : 0);
+               return result;
        }
 }
diff --git a/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilter.java b/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilter.java
new file mode 100644 (file)
index 0000000..8739511
--- /dev/null
@@ -0,0 +1,128 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.resources;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.http.HttpStatus;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.filter.CadiFilter;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class AAFAuthenticationFilter implements Filter {
+
+    private static final Logger LOGGER = Logger.getLogger(AAFAuthenticationFilter.class.getName());
+    static final String CADI_PROPERTIES = "cadi.properties";
+    static final String AAF_AUTHN_FLAG = "UseAAF";
+
+    private boolean isAafEnabled;
+    private CadiFilter cadiFilter;
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        DmaapConfig dmaapConfig = getConfig();
+        String flag = dmaapConfig.getProperty(AAF_AUTHN_FLAG, "false");
+        isAafEnabled = "true".equalsIgnoreCase(flag);
+        initCadi(dmaapConfig);
+    }
+
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
+
+        if(isAafEnabled) {
+            cadiFilter.doFilter(servletRequest, servletResponse, filterChain);
+            updateResponseBody((HttpServletResponse)servletResponse);
+        } else {
+            filterChain.doFilter(servletRequest, servletResponse);
+        }
+    }
+
+    private void updateResponseBody(HttpServletResponse httpResponse)
+        throws IOException {
+        if(httpResponse.getStatus() == 401) {
+            String errorMsg = "invalid or no credentials provided";
+            LOGGER.error(errorMsg);
+            httpResponse.setContentType("application/json");
+            httpResponse.setCharacterEncoding("UTF-8");
+            httpResponse.getWriter().print(buildErrorResponse(errorMsg));
+            httpResponse.getWriter().flush();
+        }
+    }
+
+    private String buildErrorResponse(String msg) {
+        try {
+            return new ObjectMapper().writeValueAsString(new ApiError(HttpStatus.UNAUTHORIZED_401, msg, "Authentication"));
+        } catch (JsonProcessingException e) {
+            LOGGER.warn("Could not serialize response entity: " + e.getMessage());
+            return "";
+        }
+    }
+
+
+    @Override
+    public void destroy() {
+        //nothing to cleanup
+    }
+
+    private void initCadi(DmaapConfig dmaapConfig) throws ServletException {
+        if(isAafEnabled) {
+            try {
+                String cadiPropertiesFile = dmaapConfig.getProperty(CADI_PROPERTIES);
+                if(cadiPropertiesFile != null && !cadiPropertiesFile.isEmpty()) {
+                    cadiFilter = new CadiFilter(new PropAccess(cadiPropertiesFile));
+                } else {
+                    throw new ServletException("Cannot initialize CADI filter.CADI properties not available.");
+                }
+            } catch (ServletException e) {
+                LOGGER.error("CADI init error :" + e.getMessage());
+                throw e;
+            }
+        }
+    }
+
+    DmaapConfig getConfig() {
+        return (DmaapConfig) DmaapConfig.getConfig();
+    }
+
+    //tests only
+    CadiFilter getCadiFilter() {
+        return cadiFilter;
+    }
+
+    void setCadiFilter(CadiFilter cadiFilter) {
+        this.cadiFilter = cadiFilter;
+    }
+
+    boolean isAafEnabled() {
+        return isAafEnabled;
+    }
+}
diff --git a/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilter.java b/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilter.java
new file mode 100644 (file)
index 0000000..5bc3dec
--- /dev/null
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.resources;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.http.HttpStatus;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.PermissionBuilder;
+
+public class AAFAuthorizationFilter implements Filter{
+
+    private static final Logger LOGGER = Logger.getLogger(AAFAuthenticationFilter.class.getName());
+    static final String AAF_AUTHZ_FLAG = "UseAAF";
+    private boolean isAafEnabled = false;
+
+    private PermissionBuilder permissionBuilder;
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        DmaapConfig dmaapConfig = getConfig();
+        isAafEnabled = "true".equalsIgnoreCase(dmaapConfig.getProperty(AAF_AUTHZ_FLAG, "false"));
+        if(isAafEnabled) {
+            permissionBuilder = new PermissionBuilder(dmaapConfig, getDmaapService());
+        }
+    }
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
+
+        if(isAafEnabled) {
+            HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
+            permissionBuilder.updateDmaapInstance();
+            String permission = permissionBuilder.buildPermission(httpRequest);
+
+            if (httpRequest.isUserInRole(permission)) {
+                LOGGER.info("User " + httpRequest.getUserPrincipal().getName() + " has permission " + permission);
+                filterChain.doFilter(servletRequest, servletResponse);
+            } else {
+                String msg = "User " + httpRequest.getUserPrincipal().getName() + " does not have permission " + permission;
+                LOGGER.error(msg);
+                ((HttpServletResponse) servletResponse).setStatus(HttpStatus.FORBIDDEN_403);
+                servletResponse.setContentType("application/json");
+                servletResponse.setCharacterEncoding("UTF-8");
+                servletResponse.getWriter().print(buildErrorResponse(msg));
+                servletResponse.getWriter().flush();
+            }
+        } else {
+            filterChain.doFilter(servletRequest, servletResponse);
+        }
+    }
+
+    @Override
+    public void destroy() {
+        //nothing to cleanup
+    }
+
+    DmaapConfig getConfig() {
+        return (DmaapConfig) DmaapConfig.getConfig();
+    }
+
+    DmaapService getDmaapService() {
+        return new DmaapService();
+    }
+
+    private String buildErrorResponse(String msg) {
+        try {
+            return new ObjectMapper().writeValueAsString(new ApiError(HttpStatus.FORBIDDEN_403, msg, "Authorization"));
+        } catch (JsonProcessingException e) {
+            LOGGER.warn("Could not serialize response entity: " + e.getMessage());
+            return "";
+        }
+    }
+
+    PermissionBuilder getPermissionBuilder() {
+        return permissionBuilder;
+    }
+
+    void setPermissionBuilder(PermissionBuilder permissionBuilder) {
+        this.permissionBuilder = permissionBuilder;
+    }
+
+    void setAafEnabled(boolean aafEnabled) {
+        isAafEnabled = aafEnabled;
+    }
+}
index 9dafb55..3ed5717 100644 (file)
 
 package org.onap.dmaap.dbcapi.resources;
 
-import java.io.IOException;
-
 import javax.ws.rs.container.ContainerRequestContext;
 import javax.ws.rs.container.ContainerRequestFilter;
 
 import org.apache.log4j.Logger;
 import org.onap.dmaap.dbcapi.authentication.AuthenticationErrorException;
 import org.onap.dmaap.dbcapi.service.ApiService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
 
 
 @Authorization
 public class AuthorizationFilter implements ContainerRequestFilter   {
-       
-       private Logger logger = Logger.getLogger(AuthorizationFilter.class.getName());
-       
+
+       private static final String AAF_FLAG = "UseAAF";
+       private final Logger logger = Logger.getLogger(AuthorizationFilter.class.getName());
+       private final ResponseBuilder responseBuilder = new ResponseBuilder();
+       private final boolean isAafEnabled;
+
+
+       public AuthorizationFilter() {
+               DmaapConfig dmaapConfig = (DmaapConfig) DmaapConfig.getConfig();
+               String flag = dmaapConfig.getProperty(AAF_FLAG, "false");
+               isAafEnabled = "true".equalsIgnoreCase(flag);
+       }
+
        @Override
-       public void filter(ContainerRequestContext requestContext)
-                       throws IOException {
-
-               ApiService apiResp = new ApiService()
-                       .setAuth( requestContext.getHeaderString("Authorization") )
-                       .setUriPath(requestContext.getUriInfo().getPath())
-                       .setHttpMethod( requestContext.getMethod() )
-                       .setRequestId( requestContext.getHeaderString("X-ECOMP-RequestID") );
-               
-               try {
-                       apiResp.checkAuthorization();
-               } catch ( AuthenticationErrorException ae ) {
-                       logger.error("Error", ae);
-                       requestContext.abortWith( apiResp.unauthorized( apiResp.getErr().getMessage() ) );
-                       return ;
-               } catch ( Exception e ) {
-                       logger.error("Error", e);
-                       requestContext.abortWith( apiResp.unavailable() ); 
-                       return;
-               }
-               
+       public void filter(ContainerRequestContext requestContext) {
 
+               if(!isAafEnabled) {
+                       ApiService apiResp = new ApiService()
+                               .setAuth(requestContext.getHeaderString("Authorization"))
+                               .setUriPath(requestContext.getUriInfo().getPath())
+                               .setHttpMethod(requestContext.getMethod())
+                               .setRequestId(requestContext.getHeaderString("X-ECOMP-RequestID"));
+
+                       try {
+                               apiResp.checkAuthorization();
+                       } catch (AuthenticationErrorException ae) {
+                               logger.error("Error", ae);
+                               requestContext.abortWith(responseBuilder.unauthorized(apiResp.getErr().getMessage()));
+                       } catch (Exception e) {
+                               logger.error("Error", e);
+                               requestContext.abortWith(responseBuilder.unavailable());
+                       }
+               }
        }
 
 }
index 192b63d..299c48f 100644 (file)
@@ -32,13 +32,11 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
 
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.BrTopic;
 import org.onap.dmaap.dbcapi.model.MirrorMaker;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.MirrorMakerService;
 
 import io.swagger.annotations.Api;
@@ -46,6 +44,8 @@ import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+
 @Path("/bridge")
 @Api( value= "bridge", description = "Endpoint for retreiving MR Bridge metrics" )
 @Consumes(MediaType.APPLICATION_JSON)
@@ -54,6 +54,7 @@ import io.swagger.annotations.ApiResponses;
 public class BridgeResource extends BaseLoggingClass {
        
        private MirrorMakerService mmService = new MirrorMakerService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
 
        @GET
        @ApiOperation( value = "return BrTopic details", 
@@ -66,10 +67,9 @@ public class BridgeResource extends BaseLoggingClass {
 })
        public Response getBridgedTopics(@QueryParam("mmagent") String mmagent,
                                                                        @QueryParam("detail") Boolean detailFlag ){
-               ApiService check = new ApiService();
-               
+
                if ( mmagent == null ) {
-                       return check.success(getMMcounts(Boolean.TRUE.equals(detailFlag)));
+                       return responseBuilder.success(getMMcounts(Boolean.TRUE.equals(detailFlag)));
 
                }
                logger.info( "getBridgeTopics():" + " mmagent=" + mmagent);
@@ -81,7 +81,7 @@ public class BridgeResource extends BaseLoggingClass {
 
                        MirrorMaker mm = mmService.getMirrorMaker(mmagent);
                        if ( mm == null ) {             
-                               return check.notFound();
+                               return responseBuilder.notFound();
                        } 
                                        
                        brTopic.setTopicCount( mm.getTopicCount() );
@@ -91,16 +91,16 @@ public class BridgeResource extends BaseLoggingClass {
                        
                        logger.info( "topicCount [2 locations]: " + brTopic.getTopicCount() );
                
-                       return check.success(brTopic);
+                       return responseBuilder.success(brTopic);
                } else {        
                        logger.info( "getBridgeTopics() detail:" + " mmagent=" + mmagent);
                        // get topics between 2 bridged locations       
                        MirrorMaker mm = mmService.getMirrorMaker(mmagent);
                        if ( mm == null ) {             
-                               return check.notFound();
+                               return responseBuilder.notFound();
                        } 
 
-                       return check.success(mm);
+                       return responseBuilder.success(mm);
                }
        }
        
@@ -156,15 +156,13 @@ public class BridgeResource extends BaseLoggingClass {
                                                                        @QueryParam("refresh") Boolean refreshFlag,
                                                                        @QueryParam("split") Boolean splitFlag,
                                                                        MirrorMaker newBridge ){
-               ApiService check = new ApiService();    
-                       
                logger.info( "putBridgeTopics() mmagent:" +  mmagent );
 
                if ( mmagent != null ) {                // put topics between 2 bridged locations
                        
                        MirrorMaker mm = mmService.getMirrorMaker(mmagent);
                        if ( mm == null ) {             
-                               return check.notFound();
+                               return responseBuilder.notFound();
                        } 
                        
                        if ( splitFlag != null && splitFlag == true ) {
@@ -173,24 +171,20 @@ public class BridgeResource extends BaseLoggingClass {
                                logger.info( "setting whitelist from message body containing mmName=" + newBridge.getMmName());
                                if ( ! mmagent.equals(newBridge.getMmName()) ){
                                        logger.error( "mmagent query param does not match mmName in body");
-                                       check.setCode(Status.BAD_REQUEST.getStatusCode());
-                                       check.setMessage("mmagent query param does not match mmName in body");
-                                       return check.error();
+                                       return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(),
+                                                       "mmagent query param does not match mmName in body"));
                                }
                                mm.setTopics( newBridge.getTopics() );
                        } else {
                                logger.info( "refreshing whitelist from memory");
                        }
                        mmService.updateMirrorMaker(mm);
-                       return check.success(mm);
+                       return responseBuilder.success(mm);
                }
 
                else {
-
                        logger.error( "mmagent is required for PUT");
-                       check.setCode(Status.BAD_REQUEST.getStatusCode());
-                       check.setMessage("mmagent is required for PUT");
-                       return check.error();
+                       return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(), "mmagent is required for PUT"));
                }
 
        }
index 8091ac3..f001136 100644 (file)
@@ -38,14 +38,15 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.GenericEntity;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
 
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.DR_Node;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.DR_NodeService;
 
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+
 @Path("/dr_nodes")
 @Api( value= "dr_nodes", description = "Endpoint for a Data Router Node server" )
 @Consumes(MediaType.APPLICATION_JSON)
@@ -53,7 +54,9 @@ import org.onap.dmaap.dbcapi.service.DR_NodeService;
 @Authorization
 public class DR_NodeResource extends BaseLoggingClass {
 
-       DR_NodeService dr_nodeService = new DR_NodeService();
+       private DR_NodeService dr_nodeService = new DR_NodeService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
        
        @GET
        @ApiOperation( value = "return DR_Node details", 
@@ -64,13 +67,11 @@ public class DR_NodeResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        public Response getDr_Nodes() {
-               ApiService resp = new ApiService();
-
                List<DR_Node> nodes = dr_nodeService.getAllDr_Nodes();
 
                GenericEntity<List<DR_Node>> list = new GenericEntity<List<DR_Node>>(nodes) {
         };
-        return resp.success(list);
+        return responseBuilder.success(list);
        }
        
        @POST
@@ -81,26 +82,22 @@ public class DR_NodeResource extends BaseLoggingClass {
            @ApiResponse( code = 200, message = "Success", response = DR_Node.class),
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
-       public Response addDr_Node( 
-                       DR_Node node
-                       ) {
-               ApiService resp = new ApiService();
+       public Response addDr_Node(DR_Node node) {
+
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "dcaeLocation", node.getDcaeLocationName(), "");
-                       resp.required( "fqdn", node.getFqdn(), "");
+                       checker.required( "dcaeLocation", node.getDcaeLocationName());
+                       checker.required( "fqdn", node.getFqdn());
                } catch ( RequiredFieldException rfe ) {
-                       resp.setCode(Status.BAD_REQUEST.getStatusCode());
-                       resp.setMessage("missing required field");
-                       resp.setFields("dcaeLocation, fqdn");
-                       
-                       return resp.error();
+                       return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(),
+                                       "missing required field", "dcaeLocation, fqdn"));
                }
-               DR_Node nNode = dr_nodeService.addDr_Node(node, resp.getErr());
-               if ( resp.getErr().is2xx()) {
-                       return resp.success(nNode);
+               DR_Node nNode = dr_nodeService.addDr_Node(node, apiError);
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(nNode);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
        
        @PUT
@@ -112,24 +109,23 @@ public class DR_NodeResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{fqdn}")
-       public Response updateDr_Node( 
-                       @PathParam("fqdn") String name, 
-                       DR_Node node
-                       ) {
-               ApiService resp = new ApiService();
+       public Response updateDr_Node(@PathParam("fqdn") String name, DR_Node node) {
+
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "dcaeLocation", name, "");
-                       resp.required( "fqdn", node.getFqdn(), "");
+                       checker.required( "dcaeLocation", node.getDcaeLocationName());
+                       checker.required( "fqdn", node.getFqdn());
                } catch ( RequiredFieldException rfe ) {
-                       return resp.error();    
+                       return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(),
+                                       "missing required field", "dcaeLocation, fqdn"));
                }
                node.setFqdn(name);
-               DR_Node nNode = dr_nodeService.updateDr_Node(node, resp.getErr());
-               if ( resp.getErr().is2xx()) {
-                       return resp.success(nNode);
+               DR_Node nNode = dr_nodeService.updateDr_Node(node, apiError);
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(nNode);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
        
        @DELETE
@@ -142,22 +138,16 @@ public class DR_NodeResource extends BaseLoggingClass {
        })
        @Path("/{fqdn}")
        public Response deleteDr_Node( 
-                       @PathParam("fqdn") String name
-                       ){
+                       @PathParam("fqdn") String name){
 
-               ApiService resp = new ApiService();
 
-               try {
-                       resp.required( "fqdn", name, "");
-               } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
-               }
-               dr_nodeService.removeDr_Node(name, resp.getErr());
-               if ( resp.getErr().is2xx() ) {
-                       return resp.success(Status.NO_CONTENT.getStatusCode(), null);
+               ApiError apiError = new ApiError();
+
+               dr_nodeService.removeDr_Node(name, apiError);
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(NO_CONTENT.getStatusCode(), null);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
 
        @GET
@@ -169,15 +159,14 @@ public class DR_NodeResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{fqdn}")
-       public Response get( 
-                       @PathParam("fqdn") String name
-                       ) {
-               ApiService resp = new ApiService();
-
-               DR_Node nNode = dr_nodeService.getDr_Node( name, resp.getErr() );
-               if ( resp.getErr().is2xx() ) {
-                       return resp.success(nNode);
+       public Response get(@PathParam("fqdn") String name) {
+
+               ApiError apiError = new ApiError();
+
+               DR_Node nNode = dr_nodeService.getDr_Node( name, apiError );
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(nNode);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
 }
index 1673857..6e652a8 100644 (file)
@@ -46,7 +46,6 @@ import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.DR_Pub;
 import org.onap.dmaap.dbcapi.model.Feed;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.DR_PubService;
 import org.onap.dmaap.dbcapi.service.FeedService;
 
@@ -58,7 +57,9 @@ import org.onap.dmaap.dbcapi.service.FeedService;
 @Authorization
 public class DR_PubResource extends BaseLoggingClass {
 
-       DR_PubService dr_pubService = new DR_PubService();
+       private DR_PubService dr_pubService = new DR_PubService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
        
        @GET
        @ApiOperation( value = "return DR_Pub details", 
@@ -69,14 +70,12 @@ public class DR_PubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        public  Response getDr_Pubs() {
-               ApiService resp = new ApiService();
-
                logger.info( "Entry: GET /dr_pubs");
                List<DR_Pub> pubs = dr_pubService.getAllDr_Pubs();
 
                GenericEntity<List<DR_Pub>> list = new GenericEntity<List<DR_Pub>>(pubs) {
         };
-        return resp.success(list);
+        return responseBuilder.success(list);
        }
        
        @POST
@@ -87,47 +86,46 @@ public class DR_PubResource extends BaseLoggingClass {
            @ApiResponse( code = 200, message = "Success", response = DR_Pub.class),
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
-       public Response addDr_Pub( 
-                       DR_Pub pub
-                       ) {
-               ApiService resp = new ApiService();
+       public Response addDr_Pub(DR_Pub pub) {
+               ApiError apiError = new ApiError();
                FeedService feeds = new FeedService();
                Feed fnew = null;
 
                logger.info( "Entry: POST /dr_pubs");
 
                try {
-                       resp.required( "feedId", pub.getFeedId(), "");
+                       checker.required( "feedId", pub.getFeedId());
                } catch ( RequiredFieldException rfe ) {
                        try {
-                               resp.required( "feedName", pub.getFeedName(), "");
+                               checker.required( "feedName", pub.getFeedName());
                        }catch ( RequiredFieldException rfe2 ) {
-                               logger.debug( resp.toString() );
-                               return resp.error();
+                               logger.debug( rfe2.getApiError().toString() );
+                               return responseBuilder.error(rfe2.getApiError());
                        }
                        // if we found a FeedName instead of a FeedId then try to look it up.
                        List<Feed> nfeeds =  feeds.getAllFeeds( pub.getFeedName(), pub.getFeedVersion(), "equals");
-                       if ( nfeeds.size() != 1 ) {
-                               logger.debug( "Attempt to match "+ pub.getFeedName() + " ver="+pub.getFeedVersion() + " matched " + nfeeds.size() );
-                               return resp.error();
+                       if ( nfeeds.isEmpty() ) {
+                               apiError.setCode(Status.NOT_FOUND.getStatusCode());
+                               apiError.setFields("feedName");
+                               return responseBuilder.error(apiError);
                        }
                        fnew = nfeeds.get(0);
                }
                try {
-                       resp.required( "dcaeLocationName", pub.getDcaeLocationName(), "");
+                       checker.required( "dcaeLocationName", pub.getDcaeLocationName());
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.getErr().toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
 
 
                // we may have fnew already if located by FeedName
                if ( fnew == null ) {
-                       fnew = feeds.getFeed( pub.getFeedId(), resp.getErr() );
+                       fnew = feeds.getFeed(pub.getFeedId(), apiError);
                }
                if ( fnew == null ) {
                        logger.info( "Specified feed " + pub.getFeedId() + " or " + pub.getFeedName() + " not known to Bus Controller");        
-                       return resp.error();    
+                       return responseBuilder.error(apiError);
                }
 
                ArrayList<DR_Pub> pubs = fnew.getPubs();
@@ -143,16 +141,16 @@ public class DR_PubResource extends BaseLoggingClass {
                }
                pubs.add( pub );
                fnew.setPubs(pubs);
-               fnew = feeds.updateFeed( fnew, resp.getErr() ); 
+               fnew = feeds.updateFeed(fnew, apiError);
                
-               if ( ! resp.getErr().is2xx()) { 
-                       return resp.error();                    
+               if (!apiError.is2xx()) {
+                       return responseBuilder.error(apiError);
                }
                pubs = fnew.getPubs();
                logger.info( "num existing pubs after = " + pubs.size() );
                
-               DR_Pub pnew = dr_pubService.getDr_Pub(pub.getPubId(), resp.getErr());
-               return resp.success(Status.CREATED.getStatusCode(), pnew);
+               DR_Pub pnew = dr_pubService.getDr_Pub(pub.getPubId(), apiError);
+               return responseBuilder.success(Status.CREATED.getStatusCode(), pnew);
        }
        
        @PUT
@@ -164,16 +162,11 @@ public class DR_PubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{pubId}")
-       public Response updateDr_Pub( 
-                       @PathParam("pubId") String name, 
-                       DR_Pub pub
-                       ) {
-               ApiService resp = new ApiService();
-
+       public Response updateDr_Pub(@PathParam("pubId") String name, DR_Pub pub) {
                logger.info( "Entry: PUT /dr_pubs");
                pub.setPubId(name);
                DR_Pub res = dr_pubService.updateDr_Pub(pub);
-               return resp.success(res);
+               return responseBuilder.success(res);
        }
        
        @DELETE
@@ -185,33 +178,31 @@ public class DR_PubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{pubId}")
-       public Response deleteDr_Pub( 
-                       @PathParam("pubId") String id
-                       ){
+       public Response deleteDr_Pub(@PathParam("pubId") String id){
 
-               ApiService resp = new ApiService();
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "pubId", id, "");
+                       checker.required( "pubId", id);
                } catch ( RequiredFieldException rfe ) {
-                       return resp.error();
+                       return responseBuilder.error(rfe.getApiError());
                }
 
-               DR_Pub pub =  dr_pubService.getDr_Pub( id, resp.getErr() );
-               if ( ! resp.getErr().is2xx()) { 
-                       return resp.error();                                    
+               DR_Pub pub =  dr_pubService.getDr_Pub(id, apiError);
+               if ( !apiError.is2xx()) {
+                       return responseBuilder.error(apiError);
                }
                FeedService feeds = new FeedService();
-               Feed fnew = feeds.getFeed( pub.getFeedId(), resp.getErr() );
+               Feed fnew = feeds.getFeed(pub.getFeedId(), apiError);
                if ( fnew == null ) {
                        logger.info( "Specified feed " + pub.getFeedId() + " not known to Bus Controller");     
-                       return resp.error();
+                       return responseBuilder.error(apiError);
                }
                ArrayList<DR_Pub> pubs = fnew.getPubs();
                if ( pubs.size() == 1 ) {
-                       resp.setCode(Status.BAD_REQUEST.getStatusCode());
-                       resp.setMessage( "Can't delete the last publisher of a feed");
-                       return resp.error();    
+                       apiError.setCode(Status.BAD_REQUEST.getStatusCode());
+                       apiError.setMessage( "Can't delete the last publisher of a feed");
+                       return responseBuilder.error(apiError);
                }
                
                for( Iterator<DR_Pub> i = pubs.iterator(); i.hasNext(); ) {
@@ -221,16 +212,16 @@ public class DR_PubResource extends BaseLoggingClass {
                        }
                }
                fnew.setPubs(pubs);
-               fnew = feeds.updateFeed( fnew, resp.getErr() );
-               if ( ! resp.getErr().is2xx()) { 
-                       return resp.error();                    
+               fnew = feeds.updateFeed(fnew,apiError);
+               if (!apiError.is2xx()) {
+                       return responseBuilder.error(apiError);
                }
                
-               dr_pubService.removeDr_Pub(id, resp.getErr() );
-               if ( ! resp.getErr().is2xx()) { 
-                       return resp.error();            
+               dr_pubService.removeDr_Pub(id, apiError);
+               if (!apiError.is2xx()) {
+                       return responseBuilder.error(apiError);
                }
-               return resp.success(Status.NO_CONTENT.getStatusCode(), null);
+               return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
        }
 
        @GET
@@ -242,21 +233,19 @@ public class DR_PubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{pubId}")
-       public Response get( 
-                       @PathParam("pubId") String id
-                       ) {
-               ApiService resp = new ApiService();
+       public Response get(@PathParam("pubId") String id) {
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "feedId", id, "");
+                       checker.required( "feedId", id);
                } catch ( RequiredFieldException rfe ) {
-                       return resp.error();    
+                       return responseBuilder.error(rfe.getApiError());
                }
 
-               DR_Pub pub =  dr_pubService.getDr_Pub( id, resp.getErr() );
-               if ( ! resp.getErr().is2xx()) { 
-                       resp.getErr();                  
+               DR_Pub pub =  dr_pubService.getDr_Pub(id, apiError);
+               if (!apiError.is2xx()) {
+                       return responseBuilder.error(apiError);
                }
-               return resp.success(Status.OK.getStatusCode(), pub);
+               return responseBuilder.success(Status.OK.getStatusCode(), pub);
        }
 }
index 498454e..2fa6ccd 100644 (file)
@@ -22,6 +22,7 @@
 
 package org.onap.dmaap.dbcapi.resources;
 
+import com.google.common.collect.Iterables;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -42,7 +43,6 @@ import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.DR_Sub;
 import org.onap.dmaap.dbcapi.model.Feed;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.DR_SubService;
 import org.onap.dmaap.dbcapi.service.FeedService;
 
@@ -51,6 +51,8 @@ import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
+import static javax.ws.rs.core.Response.Status.CREATED;
+
 
 @Path("/dr_subs")
 @Api( value= "dr_subs", description = "Endpoint for a Data Router client that implements a Subscriber" )
@@ -58,6 +60,9 @@ import io.swagger.annotations.ApiResponses;
 @Produces(MediaType.APPLICATION_JSON)
 @Authorization
 public class DR_SubResource extends BaseLoggingClass {
+
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
                
        @GET
        @ApiOperation( value = "return DR_Sub details", 
@@ -68,15 +73,12 @@ public class DR_SubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        public Response getDr_Subs() {
-
-               ApiService resp = new ApiService();
-
                DR_SubService dr_subService = new DR_SubService();
                List<DR_Sub> subs = dr_subService.getAllDr_Subs();
 
                GenericEntity<List<DR_Sub>> list = new GenericEntity<List<DR_Sub>>(subs) {
         };
-        return resp.success(list);
+        return responseBuilder.success(list);
        }
                
        @POST
@@ -87,59 +89,63 @@ public class DR_SubResource extends BaseLoggingClass {
            @ApiResponse( code = 200, message = "Success", response = DR_Sub.class),
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
-       public Response addDr_Sub( 
-                       DR_Sub sub
-                       ) {
-       
-               ApiService resp = new ApiService();
+       public Response addDr_Sub(DR_Sub sub) {
+
+               ApiError apiError = new ApiError();
                FeedService feeds = new FeedService();
                Feed fnew = null;
                try {
-                       resp.required( "feedId", sub.getFeedId(), "");
+                       checker.required( "feedId", sub.getFeedId());
                } catch ( RequiredFieldException rfe ) {
                        try {
-                               resp.required( "feedName", sub.getFeedName(), "");
+                               checker.required( "feedName", sub.getFeedName());
                        }catch ( RequiredFieldException rfe2 ) {
-                               logger.debug( resp.toString() );
-                               return resp.error();
+                               logger.debug( rfe2.getApiError().toString() );
+                               return responseBuilder.error(rfe2.getApiError());
                        }
                        // if we found a FeedName instead of a FeedId then try to look it up.
                        List<Feed> nfeeds =  feeds.getAllFeeds( sub.getFeedName(), sub.getFeedVersion(), "equals");
-                       if ( nfeeds.size() != 1 ) {
+                       if ( nfeeds.isEmpty() ) {
+                               apiError.setCode(Status.NOT_FOUND.getStatusCode());
+                               apiError.setFields("feedName");
+                               return responseBuilder.error(apiError);
+                       } else if (nfeeds.size() > 1) {
                                logger.debug( "Attempt to match "+ sub.getFeedName() + " ver="+sub.getFeedVersion() + " matched " + nfeeds.size() );
-                               return resp.error();
+                               apiError.setCode(Status.CONFLICT.getStatusCode());
+                               apiError.setFields("feedName");
+                               return responseBuilder.error(apiError);
                        }
-                       fnew = nfeeds.get(0);
+                       fnew = Iterables.getOnlyElement(nfeeds);
                }
                        
                try {
-                       resp.required( "dcaeLocationName", sub.getDcaeLocationName(), "");
+                       checker.required( "dcaeLocationName", sub.getDcaeLocationName());
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
                // we may have fnew already if located by FeedName
                if ( fnew == null ) {
-                       fnew = feeds.getFeed( sub.getFeedId(), resp.getErr() );
+                       fnew = feeds.getFeed( sub.getFeedId(), apiError);
                }
                if ( fnew == null ) {
                        logger.warn( "Specified feed " + sub.getFeedId() + " or " + sub.getFeedName() + " not known to Bus Controller");
-                       resp.setCode(Status.NOT_FOUND.getStatusCode());
-                       return resp.error();
+                       apiError.setCode(Status.NOT_FOUND.getStatusCode());
+                       return responseBuilder.error(apiError);
                }
                DR_SubService dr_subService = new DR_SubService( fnew.getSubscribeURL());
                ArrayList<DR_Sub> subs = fnew.getSubs();
                logger.info( "num existing subs before = " + subs.size() );
-               DR_Sub snew = dr_subService.addDr_Sub(sub, resp.getErr() );
-               if ( ! resp.getErr().is2xx() ) {
-                       return resp.error();
+               DR_Sub snew = dr_subService.addDr_Sub(sub, apiError);
+               if (!apiError.is2xx()) {
+                       return responseBuilder.error(apiError);
                }
                subs.add( snew );
                logger.info( "num existing subs after = " + subs.size() );
                
                fnew.setSubs(subs);
                logger.info( "update feed");
-               return resp.success(Status.CREATED.getStatusCode(), snew);
+               return responseBuilder.success(CREATED.getStatusCode(), snew);
 
        }
                
@@ -152,36 +158,33 @@ public class DR_SubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{subId}")
-       public Response updateDr_Sub( 
-                       @PathParam("subId") String name, 
-                       DR_Sub sub
-                       ) {
+       public Response updateDr_Sub(@PathParam("subId") String name, DR_Sub sub) {
 
-               ApiService resp = new ApiService();
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "subId", name, "");
-                       resp.required( "feedId", sub.getFeedId(), "");
-                       resp.required( "dcaeLocationName", sub.getDcaeLocationName(), "");
+                       checker.required( "subId", name);
+                       checker.required( "feedId", sub.getFeedId());
+                       checker.required( "dcaeLocationName", sub.getDcaeLocationName());
        
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
                FeedService feeds = new FeedService();
-               Feed fnew = feeds.getFeed( sub.getFeedId(), resp.getErr() );
+               Feed fnew = feeds.getFeed(sub.getFeedId(), apiError);
                if ( fnew == null ) {
                        logger.warn( "Specified feed " + sub.getFeedId() + " not known to Bus Controller");
-                       return resp.error();
+                       return responseBuilder.error(apiError);
                }
 
                DR_SubService dr_subService = new DR_SubService();
                sub.setSubId(name);
-               DR_Sub nsub = dr_subService.updateDr_Sub(sub, resp.getErr() );
+               DR_Sub nsub = dr_subService.updateDr_Sub(sub, apiError);
                if ( nsub != null && nsub.isStatusValid() ) {
-                       return resp.success(nsub);
+                       return responseBuilder.success(nsub);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
                
        @DELETE
@@ -193,24 +196,22 @@ public class DR_SubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{subId}")
-       public Response deleteDr_Sub( 
-                       @PathParam("subId") String id
-                       ){
+       public Response deleteDr_Sub(@PathParam("subId") String id){
 
-               ApiService resp = new ApiService();
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "subId", id, "");
+                       checker.required( "subId", id);
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
                DR_SubService dr_subService = new DR_SubService();
-               dr_subService.removeDr_Sub(id, resp.getErr() );
-               if ( ! resp.getErr().is2xx() ) {
-                       return resp.error();
+               dr_subService.removeDr_Sub(id, apiError);
+               if (!apiError.is2xx() ) {
+                       return responseBuilder.error(apiError);
                }
-               return resp.success(Status.NO_CONTENT.getStatusCode(), null );
+               return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null );
        }
 
        @GET
@@ -222,22 +223,21 @@ public class DR_SubResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{subId}")
-       public Response get( 
-                       @PathParam("subId") String id
-                       ) {
-               ApiService resp = new ApiService();
+       public Response get(@PathParam("subId") String id) {
+
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "subId", id, "");
+                       checker.required( "subId", id);
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
                DR_SubService dr_subService = new DR_SubService();
-               DR_Sub sub =  dr_subService.getDr_Sub( id, resp.getErr() );
+               DR_Sub sub =  dr_subService.getDr_Sub(id, apiError);
                if ( sub != null && sub.isStatusValid() ) {
-                       return resp.success(sub);
+                       return responseBuilder.success(sub);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
 }
index 8cb5336..89c9b49 100644 (file)
@@ -41,13 +41,14 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.apache.log4j.Logger;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.DcaeLocation;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.DcaeLocationService;
 
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+
 
 @Path("/dcaeLocations")
 @Api( value= "dcaeLocations", description = "an OpenStack tenant purposed for OpenDCAE (i.e. where OpenDCAE components might be deployed)" )
@@ -55,8 +56,8 @@ import org.onap.dmaap.dbcapi.service.DcaeLocationService;
 @Produces(MediaType.APPLICATION_JSON)
 @Authorization
 public class DcaeLocationResource extends BaseLoggingClass {
-       static final Logger logger = Logger.getLogger(DcaeLocationResource.class);      
-       DcaeLocationService locationService = new DcaeLocationService();
+       private DcaeLocationService locationService = new DcaeLocationService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
        
        @GET
        @ApiOperation( value = "return dcaeLocation details", 
@@ -67,13 +68,10 @@ public class DcaeLocationResource extends BaseLoggingClass {
         @ApiResponse( code = 400, message = "Error", response = ApiError.class )
     })
        public Response getDcaeLocations() {
-               ApiService check = new ApiService();
-
                List<DcaeLocation> locs = locationService.getAllDcaeLocations();
 
-               GenericEntity<List<DcaeLocation>> list = new GenericEntity<List<DcaeLocation>>(locs) {
-        };
-        return check.success(list);
+               GenericEntity<List<DcaeLocation>> list = new GenericEntity<List<DcaeLocation>>(locs) {};
+        return responseBuilder.success(list);
        }
        
        @POST
@@ -84,22 +82,14 @@ public class DcaeLocationResource extends BaseLoggingClass {
         @ApiResponse( code = 200, message = "Success", response = DcaeLocation.class),
         @ApiResponse( code = 400, message = "Error", response = ApiError.class )
     })
-       public Response addDcaeLocation( 
-                       DcaeLocation location 
-                       ) {
-               ApiService check = new ApiService();
+       public Response addDcaeLocation(DcaeLocation location) {
 
                if ( locationService.getDcaeLocation(location.getDcaeLocationName()) != null ) {
-                               
-                       check.setCode(Status.CONFLICT.getStatusCode());
-                       check.setMessage("dcaeLocation already exists");
-                       check.setFields("dcaeLocation");
-                       
-                       return check.error();
-
+                       return responseBuilder.error(new ApiError(Status.CONFLICT.getStatusCode(),
+                                       "dcaeLocation already exists", "dcaeLocation"));
                }
                DcaeLocation loc = locationService.addDcaeLocation(location);
-               return check.success(Status.CREATED.getStatusCode(), loc);
+               return responseBuilder.success(Status.CREATED.getStatusCode(), loc);
        }
        
        @PUT
@@ -112,25 +102,15 @@ public class DcaeLocationResource extends BaseLoggingClass {
     })
        @Path("/{locationName}")
        public Response updateDcaeLocation( 
-                       @PathParam("locationName") String name, 
-                       DcaeLocation location
-                        ) {
-               ApiService check = new ApiService();
+                       @PathParam("locationName") String name, DcaeLocation location) {
 
                location.setDcaeLocationName(name);
                if ( locationService.getDcaeLocation(location.getDcaeLocationName()) == null ) {
-                       ApiError err = new ApiError();
-                               
-                       err.setCode(Status.NOT_FOUND.getStatusCode());
-                       err.setMessage("dcaeLocation does not exist");
-                       err.setFields("dcaeLocation");
-                       
-                       return check.notFound();
-
+                       return responseBuilder.notFound();
 
                }
                DcaeLocation loc = locationService.updateDcaeLocation(location);
-               return check.success(Status.CREATED.getStatusCode(), loc );
+               return responseBuilder.success(Status.CREATED.getStatusCode(), loc );
        }
        
        @DELETE
@@ -143,10 +123,8 @@ public class DcaeLocationResource extends BaseLoggingClass {
        public Response deleteDcaeLocation( 
                        @PathParam("locationName") String name
                         ){
-               ApiService check = new ApiService();
-
                locationService.removeDcaeLocation(name);
-               return check.success(Status.NO_CONTENT.getStatusCode(), null);
+               return responseBuilder.success(NO_CONTENT.getStatusCode(), null);
        }
 
        @GET
@@ -157,23 +135,19 @@ public class DcaeLocationResource extends BaseLoggingClass {
     })
        @Path("/{locationName}")
        public Response getDcaeLocation( 
-                       @PathParam("locationName") String name
-                        ) {
-               ApiService check = new ApiService();
+                       @PathParam("locationName") String name) {
 
                DcaeLocation loc =  locationService.getDcaeLocation( name );
                if ( loc == null ) {
                        ApiError err = new ApiError();
                                
-                       err.setCode(Status.NOT_FOUND.getStatusCode());
+                       err.setCode(NOT_FOUND.getStatusCode());
                        err.setMessage("dcaeLocation does not exist");
                        err.setFields("dcaeLocation");
                        
-                       return check.error();
-
-
+                       return responseBuilder.error(err);
                }
 
-               return check.success(loc);
+               return responseBuilder.success(loc);
        }
 }
index bd30055..955cab7 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 package org.onap.dmaap.dbcapi.resources;
 
 
-
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.service.DmaapService;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -41,13 +44,6 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
-import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
-import org.onap.dmaap.dbcapi.model.ApiError;
-import org.onap.dmaap.dbcapi.model.Dmaap;
-import org.onap.dmaap.dbcapi.service.ApiService;
-import org.onap.dmaap.dbcapi.service.DmaapService;
-
-
 
 @Path("/dmaap")
 @Api( value= "dmaap", description = "Endpoint for this instance of DMaaP object containing values for this OpenDCAE deployment" )
@@ -57,8 +53,10 @@ import org.onap.dmaap.dbcapi.service.DmaapService;
 public class DmaapResource extends BaseLoggingClass {
 
 
-       DmaapService dmaapService = new DmaapService();
-       
+       private DmaapService dmaapService = new DmaapService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
+
        @GET
        @ApiOperation( value = "return dmaap details", notes = "returns the `dmaap` object, which contains system wide configuration settings", response = Dmaap.class)
     @ApiResponses( value = {
@@ -67,12 +65,10 @@ public class DmaapResource extends BaseLoggingClass {
     })
 
        public Response getDmaap(@Context UriInfo uriInfo)  {
-               ApiService check = new ApiService();
-                       
                Dmaap d =  dmaapService.getDmaap();
-               return check.success(d);
+               return responseBuilder.success(d);
        }
-       
+
        @POST
        @ApiOperation( value = "return dmaap details", notes = "Create a new DMaaP set system wide configuration settings for the *dcaeEnvironment*.  Deprecated with introduction of persistence in 1610.", response = Dmaap.class)
     @ApiResponses( value = {
@@ -80,26 +76,22 @@ public class DmaapResource extends BaseLoggingClass {
         @ApiResponse( code = 400, message = "Error", response = ApiError.class )
     })
        public Response addDmaap( Dmaap obj ) {
-               ApiService check = new ApiService();    
 
-               try { //check for required fields
-                       check.required( "dmaapName", obj.getDmaapName(), "^\\S+$" );  //no white space allowed in dmaapName
-                       check.required( "dmaapProvUrl", obj.getDrProvUrl(), "" );
-                       check.required( "topicNsRoot", obj.getTopicNsRoot(), "" );
-                       check.required( "bridgeAdminTopic", obj.getBridgeAdminTopic(), "" );
+               try {
+                       validateRequiredFields(obj);
                } catch( RequiredFieldException rfe ) {
-                       return check.error();
+                       return responseBuilder.error(rfe.getApiError());
                }
-       
+
                Dmaap d =  dmaapService.addDmaap(obj);
                if ( d == null ) {
-                       return check.notFound();
+                       return responseBuilder.notFound();
 
-               } 
+               }
 
-               return check.success(d);
+               return responseBuilder.success(d);
        }
-       
+
        @PUT
        @ApiOperation( value = "return dmaap details", notes = "Update system settings for *dcaeEnvironment*.", response = Dmaap.class)
     @ApiResponses( value = {
@@ -107,23 +99,25 @@ public class DmaapResource extends BaseLoggingClass {
         @ApiResponse( code = 400, message = "Error", response = ApiError.class )
     })
        public Response updateDmaap(  Dmaap obj ) {
-               ApiService check = new ApiService();
 
-               try { //check for required fields
-                       check.required( "dmaapName", obj.getDmaapName(), "^\\S+$" );  //no white space allowed in dmaapName
-                       check.required( "dmaapProvUrl", obj.getDrProvUrl(), "" );
-                       check.required( "topicNsRoot", obj.getTopicNsRoot(), "" );
-                       check.required( "bridgeAdminTopic", obj.getBridgeAdminTopic(), "" );
+               try {
+                       validateRequiredFields(obj);
                } catch( RequiredFieldException rfe ) {
-                       return check.error();
+                       return responseBuilder.error(rfe.getApiError());
                }
+
                Dmaap d =  dmaapService.updateDmaap(obj);
                if ( d != null ) {
-                       return check.success(d);
+                       return responseBuilder.success(d);
                } else {
-                       return check.notFound();        
-               }       
+                       return responseBuilder.notFound();
+               }
+       }
+
+       private void validateRequiredFields(Dmaap obj) throws RequiredFieldException {
+               checker.required( "dmaapName", obj.getDmaapName(), "^\\S+$" );  //no white space allowed in dmaapName
+               checker.required( "dmaapProvUrl", obj.getDrProvUrl());
+               checker.required( "topicNsRoot", obj.getTopicNsRoot());
+               checker.required( "bridgeAdminTopic", obj.getBridgeAdminTopic());
        }
-       
-       
 }
index a7b4f73..6589c0d 100644 (file)
@@ -46,7 +46,6 @@ import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.DR_Pub;
 import org.onap.dmaap.dbcapi.model.Feed;
 import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.FeedService;
 
 
@@ -56,7 +55,10 @@ import org.onap.dmaap.dbcapi.service.FeedService;
 @Produces(MediaType.APPLICATION_JSON)
 @Authorization
 public class FeedResource extends BaseLoggingClass {
-       
+
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
+
        @GET
        @ApiOperation( value = "return Feed details", 
        notes = "Returns array of  `Feed` objects.", 
@@ -68,16 +70,13 @@ public class FeedResource extends BaseLoggingClass {
        public Response getFeeds(
                        @QueryParam("feedName") String feedName,
                        @QueryParam("version") String version,
-                       @QueryParam("match") String match
-                       ) {
-
-               ApiService resp = new ApiService();
+                       @QueryParam("match") String match) {
 
                FeedService feedService = new FeedService();
                List<Feed> nfeeds =  feedService.getAllFeeds( feedName, version, match );
                GenericEntity<List<Feed>> list = new GenericEntity<List<Feed>>(nfeeds) {
         };
-        return resp.success(list);
+        return responseBuilder.success(list);
        }
        
 
@@ -92,49 +91,48 @@ public class FeedResource extends BaseLoggingClass {
        })
        public Response addFeed( 
                        @WebParam(name = "feed") Feed feed,
-                       @QueryParam("useExisting") String useExisting
-                       ) {
+                       @QueryParam("useExisting") String useExisting) {
 
-               ApiService resp = new ApiService();
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "feedName", feed.getFeedName(), "");
-                       resp.required( "feedVersion", feed.getFeedVersion(), "");
-                       resp.required( "owner", feed.getOwner(), "" );
-                       resp.required( "asprClassification", feed.getAsprClassification(), "" );
+                       checker.required( "feedName", feed.getFeedName());
+                       checker.required( "feedVersion", feed.getFeedVersion());
+                       checker.required( "owner", feed.getOwner());
+                       checker.required( "asprClassification", feed.getAsprClassification());
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
                
                
                FeedService feedService = new FeedService();
-               Feed nfeed =  feedService.getFeedByName( feed.getFeedName(), feed.getFeedVersion(), resp.getErr() );
+               Feed nfeed =  feedService.getFeedByName( feed.getFeedName(), feed.getFeedVersion(), apiError);
                if ( nfeed == null ) {
-                       nfeed =  feedService.addFeed( feed, resp.getErr() );
+                       nfeed =  feedService.addFeed(feed, apiError);
                        if ( nfeed != null ) {
-                               return resp.success(nfeed);
+                               return responseBuilder.success(nfeed);
                        } else {
                                logger.error( "Unable to create: " + feed.getFeedName() + ":" + feed.getFeedVersion());
 
-                               return resp.error();                    
+                               return responseBuilder.error(apiError);
                        }
                } else if ( nfeed.getStatus() == DmaapObject_Status.DELETED ) {
                        feed.setFeedId( nfeed.getFeedId());
-                       nfeed =  feedService.updateFeed(feed, resp.getErr());
+                       nfeed =  feedService.updateFeed(feed, apiError);
                        if ( nfeed != null ) {
-                               return resp.success(nfeed);
+                               return responseBuilder.success(nfeed);
                        } else {
                                logger.info( "Unable to update: " + feed.getFeedName() + ":" + feed.getFeedVersion());
 
-                               return resp.error();    
+                               return responseBuilder.error(apiError);
                        }
                } else if ( (useExisting != null) && ("true".compareToIgnoreCase( useExisting ) == 0)) {
-                       return resp.success(nfeed);
+                       return responseBuilder.success(nfeed);
                }
 
-               resp.setCode(Status.CONFLICT.getStatusCode());
-               return resp.error();
+               apiError.setCode(Status.CONFLICT.getStatusCode());
+               return responseBuilder.error(apiError);
        }
        
        @PUT
@@ -148,22 +146,21 @@ public class FeedResource extends BaseLoggingClass {
        @Path("/{id}")
        public Response updateFeed( 
                        @PathParam("id") String id,
-                       @WebParam(name = "feed") Feed feed 
-                       ) {
+                       @WebParam(name = "feed") Feed feed) {
 
                FeedService feedService = new FeedService();
-               ApiService resp = new ApiService();
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "feedId", id, "");
+                       checker.required( "feedId", id);
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
 
-               Feed nfeed = feedService.getFeed( id, resp.getErr() );
+               Feed nfeed = feedService.getFeed(id, apiError);
                if ( nfeed == null || nfeed.getStatus() == DmaapObject_Status.DELETED ) {
-                       return resp.notFound();                                         
+                       return responseBuilder.notFound();
                }
        
                //  we assume there is no updates allowed for pubs and subs objects via this api...             
@@ -172,13 +169,13 @@ public class FeedResource extends BaseLoggingClass {
                nfeed.setFeedDescription(feed.getFeedDescription());
                nfeed.setFormatUuid(feed.getFormatUuid());
                
-               nfeed =  feedService.updateFeed(nfeed, resp.getErr());
+               nfeed =  feedService.updateFeed(nfeed, apiError);
                if ( nfeed != null ) {
-                       return resp.success(nfeed);
+                       return responseBuilder.success(nfeed);
                } else {
                        logger.info( "Unable to update: " + feed.getFeedName() + ":" + feed.getFeedVersion());
 
-                       return resp.error();    
+                       return responseBuilder.error(apiError);
                }
        }
        
@@ -191,25 +188,23 @@ public class FeedResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{id}")
-       public Response deleteFeed( 
-                       @PathParam("id") String id
-                       ){
-               ApiService resp = new ApiService();
+       public Response deleteFeed(@PathParam("id") String id){
+               ApiError apiError = new ApiError();
 
                logger.debug( "Entry: DELETE  " + id);
                FeedService feedService = new FeedService();
-               Feed nfeed =  feedService.getFeed( id, resp.getErr() );
+               Feed nfeed =  feedService.getFeed(id, apiError);
                if ( nfeed == null ) {
-                       resp.setCode(Status.NOT_FOUND.getStatusCode());
-                       return resp.error();
+                       apiError.setCode(Status.NOT_FOUND.getStatusCode());
+                       return responseBuilder.error(apiError);
                }
-               nfeed = feedService.removeFeed( nfeed, resp.getErr() );
+               nfeed = feedService.removeFeed(nfeed, apiError);
                if ( nfeed == null || nfeed.getStatus() == DmaapObject_Status.DELETED ) {
-                       return resp.success(Status.NO_CONTENT.getStatusCode(), null);
+                       return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
                }
                logger.info( "Unable to delete: " + id + ":" + nfeed.getFeedVersion());
 
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
 
        @GET
@@ -221,17 +216,45 @@ public class FeedResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{id}")
-       public Response getFeed( 
-                       @PathParam("id") String id
-                       ) {
-               ApiService resp = new ApiService();
+       public Response getFeed(@PathParam("id") String id) {
+               ApiError apiError = new ApiError();
 
                FeedService feedService = new FeedService();
-               Feed nfeed =  feedService.getFeed( id, resp.getErr() );
+               Feed nfeed =  feedService.getFeed(id, apiError);
                if ( nfeed == null ) {
-                       resp.setCode(Status.NOT_FOUND.getStatusCode());
-                       return resp.error();
+                       apiError.setCode(Status.NOT_FOUND.getStatusCode());
+                       return responseBuilder.error(apiError);
                }
-               return resp.success(nfeed);
+               return responseBuilder.success(nfeed);
        }
+       
+       @PUT
+       @ApiOperation( value = "sync feeds to existing DR",
+       notes = "When Bus Controller is deployed after DR, then it is possible"
+                       + "that DR has previous provisioning data that needs to be imported"
+                       + "into Bus Controller.",
+       response = Feed.class )
+       @ApiResponses( value =  {
+                       @ApiResponse( code = 200, message = "Success", response = Feed.class),
+                       @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+       })
+       @Path( "/sync")
+       public Response syncFeeds (@QueryParam("hard") String hardParam) {
+               ApiError error = new ApiError();
+               
+               FeedService feedService = new FeedService();
+               boolean hard = false;
+               if (  hardParam != null && hardParam.equalsIgnoreCase("true")) {
+                       hard = true;
+               }
+               feedService.sync( hard, error );
+               if ( error.is2xx()) {
+                       List<Feed> nfeeds =  feedService.getAllFeeds();
+                       GenericEntity<List<Feed>> list = new GenericEntity<List<Feed>>(nfeeds) {
+                       };
+                       return responseBuilder.success(list);
+               }
+               return responseBuilder.error(error);
+       }
+       
 }
index 31c22ba..bcb7ed2 100644 (file)
@@ -32,8 +32,6 @@ import io.swagger.annotations.ApiResponses;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
@@ -44,8 +42,6 @@ import javax.ws.rs.core.UriInfo;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.Dmaap;
-import org.onap.dmaap.dbcapi.service.ApiService;
-import org.onap.dmaap.dbcapi.service.DmaapService;
 
 
 
@@ -57,7 +53,7 @@ import org.onap.dmaap.dbcapi.service.DmaapService;
 public class InfoResource extends BaseLoggingClass {
 
 
-       DmaapService dmaapService = new DmaapService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
        
        @GET
        @ApiOperation( value = "return info details", notes = "returns the `info` object", response = Dmaap.class)
@@ -67,9 +63,7 @@ public class InfoResource extends BaseLoggingClass {
     })
 
        public Response getInfo(@Context UriInfo uriInfo)  {
-               ApiService check = new ApiService();
-                       
-                       return check.success(204, null);
+               return responseBuilder.success(204, null);
        }
        
 
index a621338..6df8ef6 100644 (file)
@@ -45,11 +45,12 @@ import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.MR_Client;
 import org.onap.dmaap.dbcapi.model.MR_Cluster;
 import org.onap.dmaap.dbcapi.model.Topic;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.MR_ClientService;
 import org.onap.dmaap.dbcapi.service.MR_ClusterService;
 import org.onap.dmaap.dbcapi.service.TopicService;
 
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+
 
 @Path("/mr_clients")
 @Api( value= "MR_Clients", description = "Endpoint for a Message Router Client that implements a Publisher or a Subscriber" )
@@ -59,6 +60,8 @@ import org.onap.dmaap.dbcapi.service.TopicService;
 public class MR_ClientResource extends BaseLoggingClass {
 
        private MR_ClientService mr_clientService = new MR_ClientService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
                
        @GET
        @ApiOperation( value = "return MR_Client details", 
@@ -69,13 +72,11 @@ public class MR_ClientResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        public Response getMr_Clients() {
-               ApiService resp = new ApiService();
-
                List<MR_Client> clients = mr_clientService.getAllMr_Clients();
 
                GenericEntity<List<MR_Client>> list = new GenericEntity<List<MR_Client>>(clients) {
         };
-        return resp.success(list);             
+        return responseBuilder.success(list);
        }
                
        @POST
@@ -89,59 +90,57 @@ public class MR_ClientResource extends BaseLoggingClass {
            @ApiResponse( code = 200, message = "Success", response = MR_Client.class),
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
-       public Response addMr_Client( 
-                       MR_Client client
-                       ) {
-               ApiService resp = new ApiService();
+       public Response addMr_Client(MR_Client client) {
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "fqtn", client.getFqtn(), "");
-                       resp.required( "dcaeLocationName", client.getDcaeLocationName(), "");
+                       checker.required( "fqtn", client.getFqtn());
+                       checker.required( "dcaeLocationName", client.getDcaeLocationName());
                        String s = client.getClientRole();
                        if ( s == null ) {
                                s = client.getClientIdentity();
                        }
-                       resp.required( "clientRole or clientIdentity", s, "" );
-                       resp.required( "action", client.getAction(), "");
+                       checker.required( "clientRole or clientIdentity", s);
+                       checker.required( "action", client.getAction());
 
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
                MR_ClusterService clusters = new MR_ClusterService();
 
-               MR_Cluster cluster = clusters.getMr_Cluster(client.getDcaeLocationName(), resp.getErr());
+               MR_Cluster cluster = clusters.getMr_Cluster(client.getDcaeLocationName(), apiError);
                if ( cluster == null ) {
 
-                       resp.setCode(Status.BAD_REQUEST.getStatusCode());
-                       resp.setMessage( "MR_Cluster alias not found for dcaeLocation: " + client.getDcaeLocationName());
-                       resp.setFields("dcaeLocationName");
-                       logger.warn( resp.toString() );
-                       return resp.error();
+                       apiError.setCode(Status.BAD_REQUEST.getStatusCode());
+                       apiError.setMessage( "MR_Cluster alias not found for dcaeLocation: " + client.getDcaeLocationName());
+                       apiError.setFields("dcaeLocationName");
+                       logger.warn(apiError.toString());
+                       return responseBuilder.error(apiError);
                }
                String url = cluster.getFqdn();
                if ( url == null || url.isEmpty() ) {
 
-                       resp.setCode(Status.BAD_REQUEST.getStatusCode());
-                       resp.setMessage("FQDN not set for dcaeLocation " + client.getDcaeLocationName() );
-                       resp.setFields("fqdn");
-                       logger.warn( resp.toString() );
-                       return resp.error();
+                       apiError.setCode(Status.BAD_REQUEST.getStatusCode());
+                       apiError.setMessage("FQDN not set for dcaeLocation " + client.getDcaeLocationName() );
+                       apiError.setFields("fqdn");
+                       logger.warn(apiError.toString());
+                       return responseBuilder.error(apiError);
                }
                TopicService topics = new TopicService();
 
-               Topic t = topics.getTopic(client.getFqtn(), resp.getErr() );
+               Topic t = topics.getTopic(client.getFqtn(), apiError);
                if ( t == null ) {
-                       return resp.error();            
+                       return responseBuilder.error(apiError);
                }
-               MR_Client nClient =  mr_clientService.addMr_Client(client, t, resp.getErr());
-               if ( resp.getErr().is2xx()) {
-                       t = topics.getTopic(client.getFqtn(),  resp.getErr());
-                       topics.checkForBridge(t, resp.getErr());
-                       return resp.success(nClient);
+               MR_Client nClient =  mr_clientService.addMr_Client(client, t, apiError);
+               if (apiError.is2xx()) {
+                       t = topics.getTopic(client.getFqtn(), apiError);
+                       topics.checkForBridge(t, apiError);
+                       return responseBuilder.success(nClient);
                }
                else {
-                       return resp.error();                    
+                       return responseBuilder.error(apiError);
                }
        }
                
@@ -154,30 +153,27 @@ public class MR_ClientResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{clientId}")
-       public Response updateMr_Client( 
-                       @PathParam("clientId") String clientId, 
-                       MR_Client client
-                       ) {
-               ApiService resp = new ApiService();
+       public Response updateMr_Client(@PathParam("clientId") String clientId, MR_Client client) {
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "fqtn", client.getFqtn(), "");
-                       resp.required( "dcaeLocationName", client.getDcaeLocationName(), "");
-                       resp.required( "clientRole", client.getClientRole(), "" );
-                       resp.required( "action", client.getAction(), "");
+                       checker.required( "fqtn", client.getFqtn());
+                       checker.required( "dcaeLocationName", client.getDcaeLocationName());
+                       checker.required( "clientRole", client.getClientRole());
+                       checker.required( "action", client.getAction());
 
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();            
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
                client.setMrClientId(clientId);
-               MR_Client nClient = mr_clientService.updateMr_Client(client, resp.getErr() );
-               if ( resp.getErr().is2xx()) {
+               MR_Client nClient = mr_clientService.updateMr_Client(client, apiError);
+               if (apiError.is2xx()) {
                        return Response.ok(nClient)
                                .build();
                }
-               return Response.status(resp.getErr().getCode())
-                               .entity( resp.getErr() )
+               return Response.status(apiError.getCode())
+                               .entity(apiError)
                                .build();
        }
                
@@ -190,23 +186,21 @@ public class MR_ClientResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{subId}")
-       public Response deleteMr_Client( 
-                       @PathParam("subId") String id
-                       ){
-               ApiService resp = new ApiService();
+       public Response deleteMr_Client(@PathParam("subId") String id){
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "clientId", id, "");
+                       checker.required( "clientId", id);
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
-               mr_clientService.removeMr_Client(id, true, resp.getErr() );
-               if ( resp.getErr().is2xx()) {
-                       return resp.success(Status.NO_CONTENT.getStatusCode(), null);
+               mr_clientService.removeMr_Client(id, true, apiError);
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(NO_CONTENT.getStatusCode(), null);
                }
                
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
 
        @GET
@@ -218,21 +212,19 @@ public class MR_ClientResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{subId}")
-       public Response test( 
-                       @PathParam("subId") String id
-                       ) {
-               ApiService resp = new ApiService();
+       public Response test(@PathParam("subId") String id) {
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "clientId", id, "");
+                       checker.required( "clientId", id);
                } catch ( RequiredFieldException rfe ) {
-                       logger.debug( resp.toString() );
-                       return resp.error();    
+                       logger.debug( rfe.getApiError().toString() );
+                       return responseBuilder.error(rfe.getApiError());
                }
-               MR_Client nClient =  mr_clientService.getMr_Client( id, resp.getErr() );
-               if ( resp.getErr().is2xx()) {
-                       return resp.success(nClient);
+               MR_Client nClient =  mr_clientService.getMr_Client(id, apiError);
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(nClient);
                }
-               return resp.error();    
+               return responseBuilder.error(apiError);
        }
 }
index 50ab4db..0a361ff 100644 (file)
@@ -43,8 +43,6 @@ import javax.ws.rs.core.Response.Status;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.MR_Cluster;
-import org.onap.dmaap.dbcapi.service.ApiService;
-import org.onap.dmaap.dbcapi.service.MR_ClientService;
 import org.onap.dmaap.dbcapi.service.MR_ClusterService;
 
 
@@ -55,8 +53,9 @@ import org.onap.dmaap.dbcapi.service.MR_ClusterService;
 @Authorization
 public class MR_ClusterResource extends BaseLoggingClass {
 
-       MR_ClusterService mr_clusterService = new MR_ClusterService();
-       MR_ClientService mr_clients = new MR_ClientService();
+       private MR_ClusterService mr_clusterService = new MR_ClusterService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
                
        @GET
        @ApiOperation( value = "return MR_Cluster details", 
@@ -67,13 +66,11 @@ public class MR_ClusterResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        public Response getMr_Clusters() {
-               ApiService resp = new ApiService();
-
                List<MR_Cluster> clusters = mr_clusterService.getAllMr_Clusters();
 
                GenericEntity<List<MR_Cluster>> list = new GenericEntity<List<MR_Cluster>>(clusters) {
         };
-        return resp.success(list);
+        return responseBuilder.success(list);
        }
                
        @POST
@@ -84,22 +81,20 @@ public class MR_ClusterResource extends BaseLoggingClass {
            @ApiResponse( code = 200, message = "Success", response = MR_Cluster.class),
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
-       public Response  addMr_Cluster( 
-                       MR_Cluster cluster
-                       ) {
-               ApiService resp = new ApiService();
+       public Response  addMr_Cluster(MR_Cluster cluster) {
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "dcaeLocationName", cluster.getDcaeLocationName(), "" );  
-                       resp.required( "fqdn", cluster.getFqdn(), "" );
+                       checker.required( "dcaeLocationName", cluster.getDcaeLocationName());
+                       checker.required( "fqdn", cluster.getFqdn());
                } catch( RequiredFieldException rfe ) {
-                       return resp.error();
+                       return responseBuilder.error(rfe.getApiError());
                }
-               MR_Cluster mrc =  mr_clusterService.addMr_Cluster(cluster, resp.getErr() );
+               MR_Cluster mrc =  mr_clusterService.addMr_Cluster(cluster, apiError);
                if ( mrc != null && mrc.isStatusValid() ) {
-                       return resp.success(Status.CREATED.getStatusCode(), mrc);
+                       return responseBuilder.success(Status.CREATED.getStatusCode(), mrc);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
 
        }
                
@@ -112,24 +107,21 @@ public class MR_ClusterResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{clusterId}")
-       public Response updateMr_Cluster( 
-                       @PathParam("clusterId") String clusterId, 
-                       MR_Cluster cluster
-                       ) {
-               ApiService resp = new ApiService();
+       public Response updateMr_Cluster(@PathParam("clusterId") String clusterId, MR_Cluster cluster) {
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "fqdn", clusterId, "" );
-                       resp.required( "dcaeLocationName", cluster.getDcaeLocationName(), "" );  
+                       checker.required( "fqdn", clusterId);
+                       checker.required( "dcaeLocationName", cluster.getDcaeLocationName());
                } catch( RequiredFieldException rfe ) {
-                       return resp.error();
+                       return responseBuilder.error(rfe.getApiError());
                }
                cluster.setDcaeLocationName(clusterId);
-               MR_Cluster mrc =  mr_clusterService.updateMr_Cluster(cluster, resp.getErr() );
+               MR_Cluster mrc =  mr_clusterService.updateMr_Cluster(cluster, apiError);
                if ( mrc != null && mrc.isStatusValid() ) {
-                       return resp.success(Status.CREATED.getStatusCode(), mrc);
+                       return responseBuilder.success(Status.CREATED.getStatusCode(), mrc);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
                
        @DELETE
@@ -141,21 +133,19 @@ public class MR_ClusterResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{clusterId}")
-       public Response deleteMr_Cluster( 
-                       @PathParam("clusterId") String id
-                       ){
-               ApiService resp = new ApiService();
+       public Response deleteMr_Cluster(@PathParam("clusterId") String id){
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "fqdn", id, "" );
+                       checker.required( "fqdn", id);
                } catch( RequiredFieldException rfe ) {
-                       return resp.error();
+                       return responseBuilder.error(rfe.getApiError());
                }
-               mr_clusterService.removeMr_Cluster(id, resp.getErr() );
-               if ( resp.getErr().is2xx()) {
-                       return resp.success(Status.NO_CONTENT.getStatusCode(), null);
+               mr_clusterService.removeMr_Cluster(id, apiError);
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
                } 
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
 
        @GET
@@ -167,20 +157,18 @@ public class MR_ClusterResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{clusterId}")
-       public Response getMR_Cluster( 
-                       @PathParam("clusterId") String id
-                       ) {
-               ApiService resp = new ApiService();
+       public Response getMR_Cluster(@PathParam("clusterId") String id) {
+               ApiError apiError = new ApiError();
 
                try {
-                       resp.required( "dcaeLocationName", id, "" );
+                       checker.required( "dcaeLocationName", id);
                } catch( RequiredFieldException rfe ) {
-                       return resp.error();
+                       return responseBuilder.error(rfe.getApiError());
                }
-               MR_Cluster mrc =  mr_clusterService.getMr_Cluster( id, resp.getErr() );
+               MR_Cluster mrc =  mr_clusterService.getMr_Cluster(id, apiError);
                if ( mrc != null && mrc.isStatusValid() ) {
-                       return resp.success(Status.CREATED.getStatusCode(), mrc);
+                       return responseBuilder.success(Status.CREATED.getStatusCode(), mrc);
                }
-               return resp.error();
+               return responseBuilder.error(apiError);
        }
 }
diff --git a/src/main/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilter.java b/src/main/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilter.java
new file mode 100644 (file)
index 0000000..b2b98b6
--- /dev/null
@@ -0,0 +1,55 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * org.onap.dmaap\r
+ * ================================================================================\r
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+package org.onap.dmaap.dbcapi.resources;\r
+\r
+import com.att.eelf.configuration.EELFLogger;\r
+import java.time.Clock;\r
+import javax.ws.rs.container.ContainerRequestContext;\r
+import javax.ws.rs.container.ContainerRequestFilter;\r
+import javax.ws.rs.container.ContainerResponseContext;\r
+import javax.ws.rs.container.ContainerResponseFilter;\r
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;\r
+\r
+public class RequestTimeLogFilter extends BaseLoggingClass implements ContainerRequestFilter, ContainerResponseFilter {\r
+\r
+    private final EELFLogger log;\r
+    private Clock clock;\r
+\r
+    public RequestTimeLogFilter() {\r
+        this(auditLogger, Clock.systemDefaultZone());\r
+    }\r
+\r
+    RequestTimeLogFilter(EELFLogger logger, Clock clock) {\r
+        this.log = logger;\r
+        this.clock = clock;\r
+    }\r
+\r
+    @Override\r
+    public void filter(ContainerRequestContext requestContext) {\r
+        requestContext.setProperty("start", clock.millis());\r
+    }\r
+\r
+    @Override\r
+    public void filter(ContainerRequestContext requestContext, ContainerResponseContext containerResponseContext) {\r
+        long startTime = (long) requestContext.getProperty("start");\r
+        long elapsedTime = clock.millis() - startTime;\r
+        log.info("Request took {} ms", elapsedTime);\r
+    }\r
+}\r
diff --git a/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredChecker.java b/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredChecker.java
new file mode 100644 (file)
index 0000000..36f0215
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dmaap.dbcapi.resources;
+
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+
+public class RequiredChecker {
+
+    public void required(String name, Object val) throws RequiredFieldException {
+        if (val == null) {
+            throw new RequiredFieldException(new ApiError(BAD_REQUEST.getStatusCode(),
+                    "missing required field", name));
+        }
+    }
+
+    public void required(String name, String val, String expr) throws RequiredFieldException {
+
+        required(name, val);
+
+        if (expr != null && !expr.isEmpty()) {
+            Pattern pattern = Pattern.compile(expr);
+            Matcher matcher = pattern.matcher(val);
+            if (!matcher.find()) {
+                throw new RequiredFieldException(new ApiError(BAD_REQUEST.getStatusCode(),
+                        "value '" + val + "' violates regexp check '" + expr + "'", name));
+            }
+        }
+    }
+
+}
index 74af356..2968d18 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 package org.onap.dmaap.dbcapi.resources;
 
+import org.onap.dmaap.dbcapi.model.ApiError;
+
 public class RequiredFieldException extends Exception {
 
-       /**
-        * 
-        */
-       private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
+
+    private final ApiError apiError;
+
+    public RequiredFieldException(ApiError apiError) {
+        super();
+        this.apiError = apiError;
+    }
+
+    public ApiError getApiError() {
+        return apiError;
+    }
 
+    @Override
+    public String toString() {
+        return "RequiredFieldException{" +
+                "apiError=" + apiError +
+                '}';
+    }
 }
diff --git a/src/main/java/org/onap/dmaap/dbcapi/resources/ResponseBuilder.java b/src/main/java/org/onap/dmaap/dbcapi/resources/ResponseBuilder.java
new file mode 100644 (file)
index 0000000..5d78aaf
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+
+package org.onap.dmaap.dbcapi.resources;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.slf4j.MDC;
+
+import javax.ws.rs.core.Response;
+
+import static com.att.eelf.configuration.Configuration.MDC_RESPONSE_CODE;
+import static com.att.eelf.configuration.Configuration.MDC_RESPONSE_DESC;
+import static com.att.eelf.configuration.Configuration.MDC_STATUS_CODE;
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE;
+import static javax.ws.rs.core.Response.Status.UNAUTHORIZED;
+
+public class ResponseBuilder extends BaseLoggingClass {
+
+    Response success(Object d) {
+        return buildSuccessResponse(d, Response.Status.OK.getStatusCode());
+    }
+
+    Response success(int code, Object d) {
+        return buildSuccessResponse(d, code);
+    }
+
+    Response error(ApiError err) {
+        return buildErrResponse(err);
+    }
+
+    Response unauthorized(String msg) {
+        return buildErrResponse(new ApiError(UNAUTHORIZED.getStatusCode(), msg, "Authorization"));
+    }
+
+    Response unavailable() {
+        return buildErrResponse(new ApiError(SERVICE_UNAVAILABLE.getStatusCode(),
+                "Request is unavailable due to unexpected condition"));
+    }
+
+    Response notFound() {
+        return buildErrResponse(new ApiError(NOT_FOUND.getStatusCode(),"Requested object not found"));
+    }
+
+    private Response buildSuccessResponse(Object d, int code) {
+        MDC.put(MDC_STATUS_CODE, "COMPLETE");
+        MDC.put(MDC_RESPONSE_DESC, "");
+        return buildResponse(d, code);
+    }
+
+    private Response buildErrResponse(ApiError err) {
+        MDC.put(MDC_STATUS_CODE, "ERROR");
+        MDC.put(MDC_RESPONSE_DESC, err.getMessage());
+
+        return buildResponse(err, err.getCode());
+    }
+
+    private Response buildResponse(Object obj, int code) {
+        MDC.put(MDC_RESPONSE_CODE, String.valueOf(code));
+
+        auditLogger.auditEvent("");
+        return Response.status(code)
+                .entity(obj)
+                .build();
+    }
+}
index be1b3ac..3206cf7 100644 (file)
@@ -46,10 +46,11 @@ import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.ReplicationType;
 import org.onap.dmaap.dbcapi.model.FqtnType;
 import org.onap.dmaap.dbcapi.model.Topic;
-import org.onap.dmaap.dbcapi.service.ApiService;
 import org.onap.dmaap.dbcapi.service.TopicService;
 import org.onap.dmaap.dbcapi.util.DmaapConfig;
 
+import static javax.ws.rs.core.Response.Status.CREATED;
+
 @Path("/topics")
 @Api( value= "topics", description = "Endpoint for retreiving MR Topics" )
 @Consumes(MediaType.APPLICATION_JSON)
@@ -59,7 +60,9 @@ public class TopicResource extends BaseLoggingClass {
        private static FqtnType defaultTopicStyle;
        private static String defaultPartitionCount;
        private static String defaultReplicationCount;
-       TopicService mr_topicService = new TopicService();
+       private TopicService mr_topicService = new TopicService();
+       private ResponseBuilder responseBuilder = new ResponseBuilder();
+       private RequiredChecker checker = new RequiredChecker();
        
        public TopicResource() {
                DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
@@ -79,14 +82,11 @@ public class TopicResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        public Response getTopics() {
-
-               ApiService check = new ApiService();
-
                List<Topic> allTopics = mr_topicService.getAllTopics();
                
                GenericEntity<List<Topic>> list = new GenericEntity<List<Topic>>(allTopics) {
                        };
-               return check.success(list);
+               return responseBuilder.success(list);
                
        }
                
@@ -101,20 +101,17 @@ public class TopicResource extends BaseLoggingClass {
            @ApiResponse( code = 200, message = "Success", response = Topic.class),
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
-       public Response  addTopic( 
-                       Topic topic,
-                       @QueryParam("useExisting") String useExisting
-                       ) {
+       public Response  addTopic(Topic topic, @QueryParam("useExisting") String useExisting) {
                logger.info( "addTopic request: " + topic  + " useExisting=" + useExisting );
-               ApiService check = new ApiService();
+               ApiError apiError = new ApiError();
 
                try {
-                       check.required( "topicName", topic.getTopicName(), "^\\S+$" );  //no white space allowed in topicName
-                       check.required( "topicDescription", topic.getTopicDescription(), "" );
-                       check.required( "owner", topic.getOwner(), "" );
+                       checker.required( "topicName", topic.getTopicName(), "^\\S+$" );  //no white space allowed in topicName
+                       checker.required( "topicDescription", topic.getTopicDescription());
+                       checker.required( "owner", topic.getOwner());
                } catch( RequiredFieldException rfe ) {
-                       logger.error("Error", rfe);
-                       return check.error();
+                       logger.error("Error", rfe.getApiError());
+                       return responseBuilder.error(rfe.getApiError());
                }
                
                ReplicationType t = topic.getReplicationCase();
@@ -140,11 +137,11 @@ public class TopicResource extends BaseLoggingClass {
                        flag = "true".compareToIgnoreCase( useExisting ) == 0;
                }
                
-               Topic mrc =  mr_topicService.addTopic(topic, check.getErr(), flag);
-               if ( mrc != null && check.getErr().is2xx() ) {
-                       return check.success(Status.CREATED.getStatusCode(), mrc);
+               Topic mrc =  mr_topicService.addTopic(topic, apiError, flag);
+               if ( mrc != null && apiError.is2xx() ) {
+                       return responseBuilder.success(CREATED.getStatusCode(), mrc);
                }
-               return check.error();
+               return responseBuilder.error(apiError);
        }
        
        @PUT
@@ -156,15 +153,13 @@ public class TopicResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{topicId}")
-       public Response updateTopic( 
-                       @PathParam("topicId") String topicId
-                       ) {
-               ApiService check = new ApiService();
+       public Response updateTopic(@PathParam("topicId") String topicId) {
+               ApiError apiError = new ApiError();
 
-               check.setCode(Status.BAD_REQUEST.getStatusCode());
-               check.setMessage( "Method /PUT not supported for /topics");
+               apiError.setCode(Status.BAD_REQUEST.getStatusCode());
+               apiError.setMessage( "Method /PUT not supported for /topics");
                
-               return check.error();
+               return responseBuilder.error(apiError);
        }
                
        @DELETE
@@ -176,23 +171,21 @@ public class TopicResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{topicId}")
-       public Response deleteTopic( 
-                       @PathParam("topicId") String id
-                       ){
-               ApiService check = new ApiService();
+       public Response deleteTopic(@PathParam("topicId") String id){
+               ApiError apiError = new ApiError();
 
                try {
-                       check.required( "fqtn", id, "" );
+                       checker.required( "fqtn", id);
                } catch( RequiredFieldException rfe ) {
-                       logger.error("Error", rfe);
-                       return check.error();
+                       logger.error("Error", rfe.getApiError());
+                       return responseBuilder.error(rfe.getApiError());
                }
                
-               mr_topicService.removeTopic(id, check.getErr());
-               if ( check.getErr().is2xx()) {
-                       return check.success(Status.NO_CONTENT.getStatusCode(), null);
+               mr_topicService.removeTopic(id, apiError);
+               if (apiError.is2xx()) {
+                       return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
                } 
-               return check.error();
+               return responseBuilder.error(apiError);
        }
        
 
@@ -205,22 +198,20 @@ public class TopicResource extends BaseLoggingClass {
            @ApiResponse( code = 400, message = "Error", response = ApiError.class )
        })
        @Path("/{topicId}")
-       public Response getTopic( 
-                       @PathParam("topicId") String id
-                       ) {
+       public Response getTopic(@PathParam("topicId") String id) {
                logger.info("Entry: /GET " + id);
-               ApiService check = new ApiService();
+               ApiError apiError = new ApiError();
 
                try {
-                       check.required( "topicName", id, "^\\S+$" );  //no white space allowed in topicName
+                       checker.required( "topicName", id, "^\\S+$" );  //no white space allowed in topicName
                } catch( RequiredFieldException rfe ) {
-                       logger.error("Error", rfe);
-                       return check.error();
+                       logger.error("Error", rfe.getApiError());
+                       return responseBuilder.error(rfe.getApiError());
                }
-               Topic mrc =  mr_topicService.getTopic( id, check.getErr() );
+               Topic mrc =  mr_topicService.getTopic(id, apiError);
                if ( mrc == null ) {
-                       return check.error();
+                       return responseBuilder.error(apiError);
                }
-               return check.success(mrc);
+               return responseBuilder.success(mrc);
                }
 }
index 2283ea2..2244b73 100644 (file)
@@ -20,8 +20,8 @@
 package org.onap.dmaap.dbcapi.server;
 
 import org.glassfish.jersey.server.ResourceConfig;
-
-
+import org.onap.dmaap.dbcapi.resources.RequestTimeLogFilter;
+import org.onap.dmaap.dbcapi.resources.AuthorizationFilter;
 
 public class ApplicationConfig extends ResourceConfig {
        
@@ -30,7 +30,8 @@ public class ApplicationConfig extends ResourceConfig {
         */
        public ApplicationConfig() {
                
-        register(org.onap.dmaap.dbcapi.resources.AuthorizationFilter.class);
+        register(AuthorizationFilter.class).
+                                       register(RequestTimeLogFilter.class);
   
     }
 }
index 81c08b2..7457ce9 100644 (file)
@@ -22,7 +22,8 @@
 
 package org.onap.dmaap.dbcapi.server;
 
-
+import com.google.common.collect.Sets;
+import javax.servlet.DispatcherType;
 import org.eclipse.jetty.server.*;
 import org.eclipse.jetty.servlet.DefaultServlet;
 import org.eclipse.jetty.servlet.ServletContextHandler;
@@ -31,6 +32,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 
 import java.util.Properties;
+
 /**
  * A  Jetty server which supports:
  *     - http and https (simultaneously for dev env)
@@ -38,59 +40,47 @@ import java.util.Properties;
  *  - static html pages (for documentation).
  */
 public class JettyServer extends BaseLoggingClass {
-       private Server server;
-
 
-       public Server getServer() {
-               return server;
-       }
+    private Server server;
 
-    public JettyServer( Properties params ) throws Exception {
-
-        server = new Server();
-       int httpPort = Integer.valueOf(params.getProperty("IntHttpPort", "80" ));
-               int sslPort = Integer.valueOf(params.getProperty("IntHttpsPort", "443" ));
-               boolean allowHttp = Boolean.valueOf(params.getProperty("HttpAllowed", "false"));
-       serverLogger.info( "port params: http=" + httpPort + " https=" + sslPort );
-       serverLogger.info( "allowHttp=" + allowHttp );
-        String keystore=null;
-        String keystorePwd = null;
-        String keyPwd = null;
-        
-        // HTTP Server
 
-       HttpConfiguration http_config = new HttpConfiguration();
-       http_config.setSecureScheme("https");
-       http_config.setSecurePort(sslPort);
-       http_config.setOutputBufferSize(32768);
+    public Server getServer() {
+        return server;
+    }
 
-       
-       
-        try(ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(http_config))) {
-                       httpConnector.setPort(httpPort);
-                       httpConnector.setIdleTimeout(30000);
+    public JettyServer(Properties params) throws Exception {
 
+        server = new Server();
+        int httpPort = Integer.valueOf(params.getProperty("IntHttpPort", "80"));
+        int sslPort = Integer.valueOf(params.getProperty("IntHttpsPort", "443"));
+        boolean allowHttp = Boolean.valueOf(params.getProperty("HttpAllowed", "false"));
+        serverLogger.info("port params: http=" + httpPort + " https=" + sslPort);
+        serverLogger.info("allowHttp=" + allowHttp);
 
-                       // HTTPS Server
+        // HTTP Server
+        HttpConfiguration http_config = new HttpConfiguration();
+        http_config.setSecureScheme("https");
+        http_config.setSecurePort(sslPort);
+        http_config.setOutputBufferSize(32768);
 
-                       HttpConfiguration https_config = new HttpConfiguration(http_config);
-                       https_config.addCustomizer(new SecureRequestCustomizer());
-                       SslContextFactory sslContextFactory = new SslContextFactory();
-                       keystore = params.getProperty("KeyStoreFile", "etc/keystore");
-                       logger.info("https Server using keystore at " + keystore);
-                       keystorePwd = params.getProperty("KeyStorePassword", "changeit");
-                       keyPwd = params.getProperty("KeyPassword", "changeit");
+        try (ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(http_config))) {
+            httpConnector.setPort(httpPort);
+            httpConnector.setIdleTimeout(30000);
 
+            // HTTPS Server
 
-                       sslContextFactory.setKeyStorePath(keystore);
-                       sslContextFactory.setKeyStorePassword(keystorePwd);
-                       sslContextFactory.setKeyManagerPassword(keyPwd);
+            HttpConfiguration https_config = new HttpConfiguration(http_config);
+            https_config.addCustomizer(new SecureRequestCustomizer());
+            SslContextFactory sslContextFactory = new SslContextFactory();
+            sslContextFactory.setWantClientAuth(true);
 
+            setUpKeystore(params, sslContextFactory);
+            setUpTrustStore(params, sslContextFactory);
 
-                       if (sslPort != 0) {
-                try(ServerConnector sslConnector = new ServerConnector(server,
-                                               new SslConnectionFactory(sslContextFactory, "http/1.1"),
-                                               new HttpConnectionFactory(https_config))) {
+            if (sslPort != 0) {
+                try (ServerConnector sslConnector = new ServerConnector(server,
+                    new SslConnectionFactory(sslContextFactory, "http/1.1"),
+                    new HttpConnectionFactory(https_config))) {
                     sslConnector.setPort(sslPort);
                     if (allowHttp) {
                         logger.info("Starting httpConnector on port " + httpPort);
@@ -102,47 +92,71 @@ public class JettyServer extends BaseLoggingClass {
                         server.setConnectors(new Connector[]{sslConnector});
                     }
                 }
-                       } else {
-                               serverLogger.info("NOT starting sslConnector on port " + sslPort + " for https");
-                               if (allowHttp) {
-                                       serverLogger.info("Starting httpConnector on port " + httpPort);
-                                       server.setConnectors(new Connector[]{httpConnector});
-                               }
-                       }
-               }
+            } else {
+                serverLogger.info("NOT starting sslConnector on port " + sslPort + " for https");
+                if (allowHttp) {
+                    serverLogger.info("Starting httpConnector on port " + httpPort);
+                    server.setConnectors(new Connector[]{httpConnector});
+                }
+            }
+        }
+
         // Set context for servlet.  This is shared for http and https
-               ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
-       context.setContextPath("/");
-        server.setHandler( context );
+        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+        context.setContextPath("/");
+        server.setHandler(context);
 
-        ServletHolder jerseyServlet = context.addServlet( org.glassfish.jersey.servlet.ServletContainer.class, "/webapi/*");
+        ServletHolder jerseyServlet = context
+            .addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/webapi/*");
         jerseyServlet.setInitOrder(1);
-        jerseyServlet.setInitParameter("jersey.config.server.provider.packages", "org.onap.dmaap.dbcapi.resources" );   
-        jerseyServlet.setInitParameter("javax.ws.rs.Application", "org.onap.dmaap.dbcapi.server.ApplicationConfig" );
-        
+        jerseyServlet.setInitParameter("jersey.config.server.provider.packages", "org.onap.dmaap.dbcapi.resources");
+        jerseyServlet.setInitParameter("javax.ws.rs.Application", "org.onap.dmaap.dbcapi.server.ApplicationConfig");
+
         // also serve up some static pages...
-        ServletHolder staticServlet = context.addServlet(DefaultServlet.class,"/*");
-        staticServlet.setInitParameter("resourceBase","www");
-        staticServlet.setInitParameter("pathInfoOnly","true");
+        ServletHolder staticServlet = context.addServlet(DefaultServlet.class, "/*");
+        staticServlet.setInitParameter("resourceBase", "www");
+        staticServlet.setInitParameter("pathInfoOnly", "true");
+
+        registerAuthFilters(context);
 
         try {
 
             serverLogger.info("Starting jetty server");
-               String unit_test = params.getProperty("UnitTest", "No");
+            String unit_test = params.getProperty("UnitTest", "No");
             serverLogger.info("UnitTest=" + unit_test);
-                       if ( unit_test.equals( "No" ) ) {
-                       server.start();
-                       server.dumpStdErr();
-               server.join();
-                       }
-        } catch ( Exception e ) {
-               errorLogger.error( "Exception " + e );
-               errorLogger.error( "possibly unable to use keystore " + keystore + " with passwords " + keystorePwd +  " and " + keyPwd );
-               //System.exit(1);
+            if (unit_test.equals("No")) {
+                server.start();
+                server.dumpStdErr();
+                server.join();
+            }
+        } catch (Exception e) {
+            errorLogger.error("Exception " + e);
         } finally {
-               server.destroy();
+            server.destroy();
         }
-        
+
+    }
+
+    private void registerAuthFilters(ServletContextHandler context) {
+        context.addFilter("org.onap.dmaap.dbcapi.resources.AAFAuthenticationFilter", "/webapi/*",
+            Sets.newEnumSet(Sets.newHashSet(DispatcherType.FORWARD, DispatcherType.REQUEST), DispatcherType.class));
+        context.addFilter("org.onap.dmaap.dbcapi.resources.AAFAuthorizationFilter", "/webapi/*",
+            Sets.newEnumSet(Sets.newHashSet(DispatcherType.FORWARD, DispatcherType.REQUEST), DispatcherType.class));
+    }
+
+    private void setUpKeystore(Properties params, SslContextFactory sslContextFactory) {
+        String keystore = params.getProperty("KeyStoreFile", "etc/keystore");
+        logger.info("https Server using keystore at " + keystore);
+        sslContextFactory.setKeyStorePath(keystore);
+        sslContextFactory.setKeyStorePassword(params.getProperty("KeyStorePassword", "changeit"));
+        sslContextFactory.setKeyManagerPassword(params.getProperty("KeyPassword", "changeit"));
+    }
+
+    private void setUpTrustStore(Properties params, SslContextFactory sslContextFactory) {
+        String truststore = params.getProperty("TrustStoreFile", "etc/org.onap.dmaap-bc.trust.jks");
+        logger.info("https Server using truststore at " + truststore);
+        sslContextFactory.setTrustStorePath(truststore);
+        sslContextFactory.setTrustStoreType(params.getProperty("TrustStoreType", "jks"));
+        sslContextFactory.setTrustStorePassword(params.getProperty("TrustStorePassword", "changeit"));
     }
 }
index d8ee278..906337a 100644 (file)
@@ -62,7 +62,7 @@ public class Main extends BaseLoggingClass {
             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
         } catch (Exception e) {
-            e.printStackTrace();
+               errorLogger.error("Error while getting hostname or address", e);
         }
         MDC.put(MDC_INSTANCE_UUID, UUID.randomUUID().toString());
         MDC.put(MDC_ALERT_SEVERITY, "0");
index 48f81db..e1beb28 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 package org.onap.dmaap.dbcapi.service;
 
-import static com.att.eelf.configuration.Configuration.MDC_BEGIN_TIMESTAMP;
-import static com.att.eelf.configuration.Configuration.MDC_ELAPSED_TIME;
-import static com.att.eelf.configuration.Configuration.MDC_END_TIMESTAMP;
 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
 import static com.att.eelf.configuration.Configuration.MDC_PARTNER_NAME;
-import static com.att.eelf.configuration.Configuration.MDC_RESPONSE_CODE;
-import static com.att.eelf.configuration.Configuration.MDC_RESPONSE_DESC;
 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
-import static com.att.eelf.configuration.Configuration.MDC_STATUS_CODE;
 
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
 import javax.xml.bind.DatatypeConverter;
-
 import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
 import org.onap.dmaap.dbcapi.authentication.ApiPolicy;
 import org.onap.dmaap.dbcapi.authentication.AuthenticationErrorException;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.Dmaap;
-import org.onap.dmaap.dbcapi.resources.RequiredFieldException;
 import org.onap.dmaap.dbcapi.util.DmaapConfig;
 import org.onap.dmaap.dbcapi.util.RandomString;
 import org.slf4j.MDC;
 
 public class ApiService extends BaseLoggingClass {
-       private class StopWatch {
-               private long clock = 0;
-               private long elapsed = 0;
-               
-
-               
-               public StopWatch() {
-                       clock = 0;
-                       elapsed = 0;
-               }
-               
-               public void reset() {
-                       clock = System.currentTimeMillis();
-                       elapsed = 0;
-               }
-               public void stop() {
-                       Long stopTime = System.currentTimeMillis();
-                       elapsed +=  stopTime - clock;
-                       clock = 0;
-                       MDC.put( MDC_END_TIMESTAMP, isoFormatter.format(new Date(stopTime)));
-                       MDC.put( MDC_ELAPSED_TIME, String.valueOf(elapsed));
-               }
-               public void start() {
-                       if ( clock != 0 ) {
-                               //not stopped
-                               return;
-                       }
-                       clock = System.currentTimeMillis();     
-                       MDC.put( MDC_BEGIN_TIMESTAMP, isoFormatter.format(new Date(clock)));
-               }
-               private long getElapsed() {
-                       return elapsed;
-               }
-       }
-
-        private String apiNamespace;
-
-        private String uri;
-        private String uriPath;
-        private String method;
-        private String authorization;
-        private String requestId;
-       private ApiError err;
-       private StopWatch stopwatch;
-       private ApiPolicy apiPolicy;
-       
-       public static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
-    public final static TimeZone utc = TimeZone.getTimeZone("UTC");
-    public final static SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT);
-       
-    static {
-       isoFormatter.setTimeZone(utc);
-    }  
-       public ApiService() {
-
-               stopwatch = new StopWatch();
-               stopwatch.start();
-               err = new ApiError();
-               requestId = (new RandomString(10)).nextString();
-               
-               if (apiNamespace == null) {
-                       DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
-                       apiNamespace = p.getProperty("ApiNamespace", "org.openecomp.dmaapBC.api");
-                       logger.info( "config param usePE has been deprecated.  Use ApiPermission.Class property instead.");
-               }
-               apiPolicy = new ApiPolicy();
-
-               logger.info(  "apiNamespace=" + apiNamespace);  
-       }
-
-       public ApiService setAuth( String auth ) {
-               this.authorization = auth;
-               logger.info( "setAuth:  authorization={} ",  authorization);
-               return this;
-       }
-       private void setServiceName(){
-               String svcRequest = new String( this.method + " " + this.uriPath );
-        MDC.put(MDC_SERVICE_NAME, svcRequest );
-       }
-       public ApiService setHttpMethod( String httpMethod ) {
-               this.method = httpMethod;
-               logger.info( "setHttpMethod: method={} ", method);
-               setServiceName();
-               return this;
-       }
-       public ApiService setUriPath( String uriPath ) {
-               this.uriPath = uriPath;
-               this.uri = setUriFromPath( uriPath );
-               logger.info( "setUriPath: uriPath={} uri={}", uriPath, uri);
-               setServiceName();
-               return this;
-       }
-       private String setUriFromPath( String uriPath ) {
-               int ch = uriPath.indexOf("/");
-               if ( ch > 0 ) {
-                       return( (String) uriPath.subSequence(0, ch ) );
-               } else {
-                       return uriPath;
-               }
-       }       
-       
-       public ApiError getErr() {
-               return err;
-       }
-
-
-       public void setErr(ApiError err) {
-               this.err = err;
-       }
-
-
-       // test for presence of a required field
-       public void required( String name, Object val, String expr ) throws RequiredFieldException {
-               err.setCode(0);
-               if ( val == null  ) {
-                       err.setCode(Status.BAD_REQUEST.getStatusCode());
-                       err.setMessage("missing required field");
-                       err.setFields( name );  
-                       throw new RequiredFieldException();
-               }
-               if ( expr != null && ! expr.isEmpty() ) {
-                       Pattern pattern = Pattern.compile(expr);
-                       Matcher matcher = pattern.matcher((CharSequence) val);
-                       if ( ! matcher.find() ) {
-                               err.setCode(Status.BAD_REQUEST.getStatusCode());
-                               err.setMessage( "value '" + val + "' violates regexp check '" + expr + "'");
-                               err.setFields( name );
-                               throw new RequiredFieldException();
-                       }
-               }
-       }
-       
-       // utility to serialize ApiErr object
-       public String toString() {
-               return String.format( "code=%d msg=%s fields=%s", err.getCode(), err.getMessage(), err.getFields() );
-       }
-
 
-       public void setCode(int statusCode) {
-               err.setCode(statusCode);        
-       }
-
-
-       public void setMessage(String string) {
-               err.setMessage(string);
-       }
-
-
-       public void setFields(String string) {
-               err.setFields(string);
-       }
-
-       private Response  buildResponse( Object obj ) {
-               stopwatch.stop();
-               MDC.put( MDC_RESPONSE_CODE, String.valueOf(err.getCode()) );
-               
-               auditLogger.auditEvent( "" );
-               return Response.status( err.getCode())
-                               .entity(obj)
-                               .build();
-       }
-       private Response  buildSuccessResponse(Object d) {
-               MDC.put( MDC_STATUS_CODE,  "COMPLETE");
-               MDC.put( MDC_RESPONSE_DESC, "");
-               return buildResponse( d );
-       }
-       private Response  buildErrResponse() {
-       
-               MDC.put( MDC_STATUS_CODE,  "ERROR");
-               MDC.put( MDC_RESPONSE_DESC, err.getMessage());
-               
-               return buildResponse(getErr());
-       }
-       public Response success( Object d ) {
-               err.setCode(Status.OK.getStatusCode());
-               return buildSuccessResponse(d);
-                               
-       }
-       public Response success( int code, Object d ) {
-               err.setCode(code);
-               return buildSuccessResponse(d);
-       }
-
-       public Response unauthorized( String msg ) {
-               err.setCode(Status.UNAUTHORIZED.getStatusCode());
-               err.setFields( "Authorization");
-               err.setMessage( msg );
-               return buildErrResponse();
-       }
-       public Response unauthorized() {
-               err.setCode(Status.UNAUTHORIZED.getStatusCode());
-               err.setFields( "Authorization");
-               err.setMessage( "User credentials in HTTP Header field Authorization are not authorized for the requested action");
-               return buildErrResponse();
-       }
-       public Response unavailable() {
-               err.setCode(Status.SERVICE_UNAVAILABLE.getStatusCode());
-               err.setMessage( "Request is unavailable due to unexpected condition");
-               return buildErrResponse();
-       }
-       public Response notFound() {
-               err.setCode(Status.NOT_FOUND.getStatusCode());
-               err.setMessage( "Requested object not found");
-               return buildErrResponse();
-       }
-       public Response error() {
-               return buildErrResponse();
-       }
-       
-       public void checkAuthorization( String auth, String uriPath, String httpMethod ) throws AuthenticationErrorException, Exception {
-               authorization = auth;
-               setUriFromPath( uriPath );
-               method = httpMethod;
-               
-               checkAuthorization();
-       }
-
-       
-       public void checkAuthorization() throws AuthenticationErrorException, Exception {
-
-               MDC.put(MDC_KEY_REQUEST_ID, requestId); 
-       
-               logger.info("request: uri={} method={} auth={}", uri, method, authorization );
-
-               if ( uri == null || uri.isEmpty()) {
-                       String errmsg = "No URI value provided ";
-                       err.setMessage(errmsg);
-                       logger.info( errmsg );
-                       throw new AuthenticationErrorException( );                      
-               }
-               if ( method == null || method.isEmpty()) {
-                       String errmsg = "No method value provided ";
-                       err.setMessage(errmsg);
-                       logger.info( errmsg );
-                       throw new AuthenticationErrorException( );                      
-               }
-               DmaapService dmaapService = new DmaapService();
-               Dmaap dmaap = dmaapService.getDmaap();
-               String env =            dmaap.getDmaapName();
-               
-               // special case during bootstrap of app when DMaaP environment may not be set.
-               // this allows us to authorize certain APIs used for initialization during this window.
-               if ( env == null || env.isEmpty() ) {
-                       env = "boot";
-               }
-               if ( ! apiPolicy.getUseAuthClass() ) return;  // skip authorization if not enabled
-               if ( authorization == null || authorization.isEmpty()) {
-                       String errmsg = "No basic authorization value provided ";
-                       err.setMessage(errmsg);
-                       logger.info( errmsg );
-                       throw new AuthenticationErrorException( );
-               }
-               String credentials = authorization.substring("Basic".length()).trim();
+    private String apiNamespace;
+    private String uri;
+    private String uriPath;
+    private String method;
+    private String authorization;
+    private String requestId;
+    private ApiError err;
+    private ApiPolicy apiPolicy;
+
+    public ApiService() {
+
+        err = new ApiError();
+        requestId = (new RandomString(10)).nextString();
+
+        if (apiNamespace == null) {
+            DmaapConfig p = (DmaapConfig) DmaapConfig.getConfig();
+            apiNamespace = p.getProperty("ApiNamespace", "org.openecomp.dmaapBC.api");
+            logger.info("config param usePE has been deprecated.  Use ApiPermission.Class property instead.");
+        }
+        apiPolicy = new ApiPolicy();
+
+        logger.info("apiNamespace=" + apiNamespace);
+    }
+
+    public ApiService setAuth(String auth) {
+        this.authorization = auth;
+        logger.info("setAuth:  authorization={} ", authorization);
+        return this;
+    }
+
+    private void setServiceName() {
+        String svcRequest = new String(this.method + " " + this.uriPath);
+        MDC.put(MDC_SERVICE_NAME, svcRequest);
+    }
+
+    public ApiService setHttpMethod(String httpMethod) {
+        this.method = httpMethod;
+        logger.info("setHttpMethod: method={} ", method);
+        setServiceName();
+        return this;
+    }
+
+    public ApiService setUriPath(String uriPath) {
+        this.uriPath = uriPath;
+        this.uri = setUriFromPath(uriPath);
+        logger.info("setUriPath: uriPath={} uri={}", uriPath, uri);
+        setServiceName();
+        return this;
+    }
+
+    private String setUriFromPath(String uriPath) {
+        int ch = uriPath.indexOf("/");
+        if (ch > 0) {
+            return ((String) uriPath.subSequence(0, ch));
+        } else {
+            return uriPath;
+        }
+    }
+
+    public ApiError getErr() {
+        return err;
+    }
+
+    public void checkAuthorization() throws Exception {
+
+        MDC.put(MDC_KEY_REQUEST_ID, requestId);
+
+        logger.info("request: uri={} method={} auth={}", uri, method, authorization);
+
+        if (uri == null || uri.isEmpty()) {
+            String errmsg = "No URI value provided ";
+            err.setMessage(errmsg);
+            logger.info(errmsg);
+            throw new AuthenticationErrorException();
+        }
+        if (method == null || method.isEmpty()) {
+            String errmsg = "No method value provided ";
+            err.setMessage(errmsg);
+            logger.info(errmsg);
+            throw new AuthenticationErrorException();
+        }
+        DmaapService dmaapService = new DmaapService();
+        Dmaap dmaap = dmaapService.getDmaap();
+        String env = dmaap.getDmaapName();
+
+        // special case during bootstrap of app when DMaaP environment may not be set.
+        // this allows us to authorize certain APIs used for initialization during this window.
+        if (env == null || env.isEmpty()) {
+            env = "boot";
+        }
+        if (!apiPolicy.getUseAuthClass()) {
+            return;  // skip authorization if not enabled
+        }
+        if (authorization == null || authorization.isEmpty()) {
+            String errmsg = "No basic authorization value provided ";
+            err.setMessage(errmsg);
+            logger.info(errmsg);
+            throw new AuthenticationErrorException();
+        }
+        String credentials = authorization.substring("Basic".length()).trim();
         byte[] decoded = DatatypeConverter.parseBase64Binary(credentials);
         String decodedString = new String(decoded);
         String[] actualCredentials = decodedString.split(":");
         String ID = actualCredentials[0];
         String Password = actualCredentials[1];
         MDC.put(MDC_PARTNER_NAME, ID);
-               try {
-                       
-                       DmaapPerm p = new DmaapPerm( apiNamespace + "." + uri, env, method );
-                       apiPolicy.check( ID, Password, p);
-               } catch ( AuthenticationErrorException ae ) {
-                       String errmsg =  "User " + ID + " failed authentication/authorization for " + apiNamespace + "." + uriPath + " " + env + " " + method;
-                       logger.info( errmsg );
-                       err.setMessage(errmsg);
-                       throw ae;
-
-               } 
-               
-
-       }
-       public String getRequestId() {
-               return requestId;
-       }
-       public ApiService setRequestId(String requestId) {
-               if ( requestId == null || requestId.isEmpty()) {        
-                       this.requestId = (new RandomString(10)).nextString();
-                       logger.warn( "X-ECOMP-RequestID not set in HTTP Header.  Setting RequestId value to: " + this.requestId );
-               } else {
-                       this.requestId = requestId;
-               }
-               MDC.put(MDC_KEY_REQUEST_ID, this.requestId); 
-               return this;
-       }
+        try {
+
+            DmaapPerm p = new DmaapPerm(apiNamespace + "." + uri, env, method);
+            apiPolicy.check(ID, Password, p);
+        } catch (AuthenticationErrorException ae) {
+            String errmsg =
+                "User " + ID + " failed authentication/authorization for " + apiNamespace + "." + uriPath + " " + env
+                    + " " + method;
+            logger.info(errmsg);
+            err.setMessage(errmsg);
+            throw ae;
+
+        }
+    }
+
+    public ApiService setRequestId(String requestId) {
+        if (requestId == null || requestId.isEmpty()) {
+            this.requestId = (new RandomString(10)).nextString();
+            logger.warn("X-ECOMP-RequestID not set in HTTP Header.  Setting RequestId value to: " + this.requestId);
+        } else {
+            this.requestId = requestId;
+        }
+        MDC.put(MDC_KEY_REQUEST_ID, this.requestId);
+        return this;
+    }
 }
+
index b478dca..9181154 100644 (file)
@@ -215,11 +215,11 @@ public class DR_NodeService extends BaseLoggingClass {
        }
        
        public DR_Node updateDr_Node( DR_Node node, ApiError apiError ) {
-               DR_Node old = dr_nodes.get( node );
+               DR_Node old = dr_nodes.get( node.getFqdn() );
                if ( old == null ) {
                        apiError.setCode(Status.NOT_FOUND.getStatusCode());
                        apiError.setFields( "fqdn");
-                       apiError.setMessage( "Node " + node + " does not exist");
+                       apiError.setMessage( "Node " + node.getFqdn() + " does not exist");
                        return null;
                }
                node.setLastMod();
index 13717da..eb5b514 100644 (file)
@@ -129,7 +129,11 @@ public class DR_PubService  extends BaseLoggingClass{
        }
                
        public DR_Pub removeDr_Pub( String pubId, ApiError err ) {
-
+               return removeDr_Pub( pubId, err, true );
+       }
+               
+       
+       public DR_Pub removeDr_Pub( String pubId, ApiError err, boolean hitDR ) {
                DR_Pub pub =  dr_pubs.get( pubId );
                if ( pub == null ) {
                        err.setCode(Status.NOT_FOUND.getStatusCode());
index 9d233a5..0a583a0 100644 (file)
@@ -173,6 +173,11 @@ public class DR_SubService extends BaseLoggingClass {
        }
                
        public void removeDr_Sub( String key, ApiError apiError ) {
+               removeDr_Sub( key, apiError, true );
+               return;
+       }
+       
+       public void removeDr_Sub( String key, ApiError apiError, boolean hitDR ) {
                logger.debug( "enter removeDR_Subs()");
                
                DR_Sub sub = dr_subs.get( key );
@@ -180,11 +185,15 @@ public class DR_SubService extends BaseLoggingClass {
                        apiError.setCode(Status.NOT_FOUND.getStatusCode());
                        apiError.setFields( "subId");
                        apiError.setMessage("subId " + key + " not found");
-               } else {        
-                       DrProvConnection prov = new DrProvConnection();
-                       prov.makeSubPutConnection( key );
-                       String resp = prov.doDeleteDr_Sub( sub, apiError );
-                       logger.debug( "resp=" + resp );
+               } else {
+                       if ( hitDR ) {
+                               DrProvConnection prov = new DrProvConnection();
+                               prov.makeSubPutConnection( key );
+                               String resp = prov.doDeleteDr_Sub( sub, apiError );
+                               logger.debug( "resp=" + resp );
+                       } else {
+                               apiError.setCode(200);
+                       }
                        
                        if ( apiError.is2xx() || unit_test.equals( "Yes" ) ) {
                                dr_subs.remove(key);
@@ -209,8 +218,8 @@ public class DR_SubService extends BaseLoggingClass {
                        server, subid, sub.getUsername(), sub.getUserpwd());
                String links = String.format( "\"links\": {\"feed\": \"https://dr-prov/feedlog/%s\", \"self\": \"https://dr-prov/sub/%s\", \"log\": \"https://dr-prov/sublog/%s\" }", 
                                sub.getFeedId(),
-                               sub.getSubId(),
-                               sub.getSubId() );
+                               subid,
+                               subid );
                ret += links + "}";
                logger.info( "DR_SubService:simulateResp=" + ret);
 
index de18d95..77d11ab 100644 (file)
@@ -25,12 +25,17 @@ package org.onap.dmaap.dbcapi.service;
 import org.onap.dmaap.dbcapi.util.RandomInteger;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.log4j.Logger;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
 import org.onap.dmaap.dbcapi.client.DrProvConnection;
 import org.onap.dmaap.dbcapi.database.DatabaseClass;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
@@ -38,12 +43,14 @@ import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.DR_Pub;
 import org.onap.dmaap.dbcapi.model.DR_Sub;
 import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.model.MR_Client;
 import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
 import org.onap.dmaap.dbcapi.util.DmaapConfig;
 
 public class FeedService  extends BaseLoggingClass {
        
        private Map<String, Feed> feeds = DatabaseClass.getFeeds();
+       private Map<String, DR_Sub> dr_subs = DatabaseClass.getDr_subs();
        private DR_PubService pubService = new DR_PubService();
        private DR_SubService subService = new DR_SubService();
        private DcaeLocationService dcaeLocations = new DcaeLocationService();
@@ -68,6 +75,10 @@ public class FeedService  extends BaseLoggingClass {
                ArrayList<DR_Sub> subs = subService.getDr_SubsByFeedId( f.getFeedId() );
                f.setSubs(subs);        
        }
+       
+       public List<Feed> getAllFeeds(){
+               return getAllFeeds(null, null, null);
+       }
                
        public List<Feed> getAllFeeds( String name, String ver, String match ) {
                logger.info( "getAllFeeds: name=" + name + " ver=" + ver + " match=" + match);
@@ -351,22 +362,30 @@ public class FeedService  extends BaseLoggingClass {
        // 2) Call the DR Delete function.  Feed with the same name and version can never be added again
        //
        public Feed removeFeed( Feed req, ApiError err ) {
+               return removeFeed( req, err, true );
+       }
+       
+       public Feed removeFeed( Feed req, ApiError err, boolean hitDR ) {
                
                // strip pubs and subs from feed first no matter what
                ArrayList<DR_Pub> pubs = pubService.getDr_PubsByFeedId( req.getFeedId() );
                for( DR_Pub pub: pubs ) {
-                       pubService.removeDr_Pub(pub.getPubId(), err);
+                       pubService.removeDr_Pub(pub.getPubId(), err, hitDR);
                        if ( ! err.is2xx()) {
                                return req;
                        }
                }
                ArrayList<DR_Sub> subs = subService.getDr_SubsByFeedId( req.getFeedId() );
                for ( DR_Sub sub: subs ) {
-                       subService.removeDr_Sub(sub.getSubId(), err);
+                       subService.removeDr_Sub(sub.getSubId(), err, hitDR);
                        if ( ! err.is2xx()) {
                                return req;
                        }
                }
+               
+               if ( ! hitDR ) {
+                       return feeds.remove(req.getFeedId());   
+               }
        
                if ( deleteHandling.equalsIgnoreCase("DeleteOnDR")) {
                        DrProvConnection prov = new DrProvConnection();
@@ -415,6 +434,92 @@ public class FeedService  extends BaseLoggingClass {
 
                
        }       
+       
+       
+       /*
+        * sync will retrieve current config from DR and add it to the DB
+        * when hard = true, then first git rid of current DR provisioning data (from the DB)
+        */
+       public void sync( boolean hard, ApiError err ) {
+       
+               if ( hard ) {
+                       
+                       ArrayList<Feed> flist = new ArrayList<Feed>(this.getAllFeeds());
+                       for ( Iterator<Feed> it = flist.iterator(); it.hasNext(); ) {
+                               Feed f = it.next();
+       
+                               @SuppressWarnings("unused")
+                               Feed old = removeFeed( f, err, false );
+                               if (! err.is2xx()) {
+                                       return;
+                               }
+                       }
+               }
+               
+               DrProvConnection prov = new DrProvConnection();
+               prov.makeDumpConnection();
+               String resp = prov.doGetDump( err );
+               if (! err.is2xx()) {
+                       return;
+               }
+               logger.debug("sync: resp from DR is: " + resp);
+               
+               JSONParser parser = new JSONParser();
+               JSONObject jsonObj;
+               try {
+                       jsonObj = (JSONObject) parser.parse( resp );
+               } catch ( ParseException pe ) {
+                       logger.error( "Error parsing provisioning data: " + resp );
+                       err.setCode(500);
+                       return;
+               }
+               
+               int i;
+
+               JSONArray feedsArray = (JSONArray) jsonObj.get( "feeds");
+               for( i = 0; i < feedsArray.size(); i++ ) {
+                       JSONObject entry = (JSONObject) feedsArray.get(i);
+                       Feed fnew = new Feed( entry.toJSONString() );
+                       
+                       logger.info( "fnew status is:" + fnew.getStatus() );
+                       if ( ! fnew.isStatusValid()) {          
+                               err.setCode(500);
+                               err.setMessage( "Unexpected response from DR backend" );
+                               err.setFields("response");              
+                               return;
+                       }
+                       
+                               if ( ! savePubs( fnew )  ) {
+                               err.setCode(Status.BAD_REQUEST.getStatusCode());
+                               err.setMessage("Unable to save Pub or Sub objects");
+                               return; 
+                       }
+                       fnew.setFormatUuid(fnew.getFormatUuid());
+                       fnew.setLastMod();
+                       feeds.put( fnew.getFeedId(), fnew );
+
+               }
+               
+               JSONArray subArray = (JSONArray) jsonObj.get( "subscriptions");
+               for( i = 0; i < subArray.size(); i++ ) {
+                       JSONObject entry = (JSONObject) subArray.get(i);
+                       DR_Sub snew = new DR_Sub( entry.toJSONString() );
+                       
+                       logger.info( "snew status is:" + snew.getStatus() );
+                       if ( ! snew.isStatusValid()) {          
+                               err.setCode(500);
+                               err.setMessage( "Unexpected response from DR backend" );
+                               err.setFields("response");              
+                               return;
+                       }
+                       
+                       dr_subs.put( snew.getSubId(), snew );
+
+               }
+               err.setCode(200);
+               return;
+               
+       }
 
        private String simulateResp( Feed f, String action ){
                String server = "localhost";
index da9d822..5d695f4 100644 (file)
@@ -57,6 +57,7 @@ public class MirrorMakerService extends BaseLoggingClass {
        private static String defaultConsumerPort;
        private static String centralFqdn;
        private int maxTopicsPerMM;
+       private boolean mmPerMR;
        
        public MirrorMakerService() {
                super();
@@ -68,6 +69,7 @@ public class MirrorMakerService extends BaseLoggingClass {
                defaultConsumerPort = p.getProperty( "MR.TargetReplicationPort", "2181");       
                centralFqdn = p.getProperty("MR.CentralCname", "notSet");
                maxTopicsPerMM = Integer.valueOf( p.getProperty( "MaxTopicsPerMM", "5"));
+               mmPerMR = "true".equalsIgnoreCase(p.getProperty("MirrorMakerPerMR", "true"));
        }
 
        // will create a MM on MMagent if needed
@@ -79,34 +81,43 @@ public class MirrorMakerService extends BaseLoggingClass {
        
                DmaapService dmaap = new DmaapService();
                MR_ClusterService clusters = new MR_ClusterService();
-       
-               // in 1610, MM should only exist for edge-to-central
-               //  we use a cname for the central MR cluster that is active, and provision on agent topic on that target
-               // but only send 1 message so MM Agents can read it relying on kafka delivery
-               for( MR_Cluster central: clusters.getCentralClusters() ) {
-                       prov.makeTopicConnection(central, dmaap.getBridgeAdminFqtn(), centralFqdn  );
-                       ApiError resp = prov.doPostMessage(mm.createMirrorMaker( defaultConsumerPort, defaultProducerPort ));
-                       if ( ! resp.is2xx() ) {
-       
-                               errorLogger.error( DmaapbcLogMessageEnum.MM_PUBLISH_ERROR, "create MM", Integer.toString(resp.getCode()), resp.getMessage());
-                               mm.setStatus(DmaapObject_Status.INVALID);
-                       } else {
-                               prov.makeTopicConnection(central, dmaap.getBridgeAdminFqtn(), centralFqdn );
-                               resp = prov.doPostMessage(mm.getWhitelistUpdateJSON());
-                               if ( ! resp.is2xx()) {
-                                       errorLogger.error( DmaapbcLogMessageEnum.MM_PUBLISH_ERROR,"MR Bridge", Integer.toString(resp.getCode()), resp.getMessage());
-                                       mm.setStatus(DmaapObject_Status.INVALID);
-                               } else {
-                                       mm.setStatus(DmaapObject_Status.VALID);
-                               }
-                       }
-                       
-                       // we only want to send one message even if there are multiple central clusters
-                       break;
+               MR_Cluster target_cluster = null;
+               String override = null;
                
-               } 
+               if ( ! mmPerMR ) {
+                       // in ECOMP, MM Agent is only deployed at central, so this case is needed for backwards compatibility
+                       //  we use a cname for the central MR cluster that is active, and provision on agent topic on that target
+                       // but only send 1 message so MM Agents can read it relying on kafka delivery
+                       for( MR_Cluster cluster: clusters.getCentralClusters() ) {
+
+                               target_cluster = cluster;
+                               override = centralFqdn;
+                               // we only want to send one message even if there are multiple central clusters
+                               break;
+                       
+                       } 
+               } else {
+                       // In ONAP deployment architecture, the MM Agent is deployed with each target MR
+                       target_cluster = clusters.getMr_ClusterByFQDN(mm.getTargetCluster());
+                       override = null;
+               }
                
+               prov.makeTopicConnection(target_cluster, dmaap.getBridgeAdminFqtn(), override  );
+               ApiError resp = prov.doPostMessage(mm.createMirrorMaker( defaultConsumerPort, defaultProducerPort ));
+               if ( ! resp.is2xx() ) {
 
+                       errorLogger.error( DmaapbcLogMessageEnum.MM_PUBLISH_ERROR, "create MM", Integer.toString(resp.getCode()), resp.getMessage());
+                       mm.setStatus(DmaapObject_Status.INVALID);
+               } else {
+                       prov.makeTopicConnection(target_cluster, dmaap.getBridgeAdminFqtn(), override );
+                       resp = prov.doPostMessage(mm.getWhitelistUpdateJSON());
+                       if ( ! resp.is2xx()) {
+                               errorLogger.error( DmaapbcLogMessageEnum.MM_PUBLISH_ERROR,"MR Bridge", Integer.toString(resp.getCode()), resp.getMessage());
+                               mm.setStatus(DmaapObject_Status.INVALID);
+                       } else {
+                               mm.setStatus(DmaapObject_Status.VALID);
+                       }
+               }
 
                mm.setLastMod();
                return mirrors.put( mm.getMmName(), mm);
index eeffa5b..a7991e8 100644 (file)
@@ -42,7 +42,6 @@ import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
 import org.onap.dmaap.dbcapi.model.ApiError;
 import org.onap.dmaap.dbcapi.model.DcaeLocation;
-import org.onap.dmaap.dbcapi.model.Dmaap;
 import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
 import org.onap.dmaap.dbcapi.model.MR_Client;
 import org.onap.dmaap.dbcapi.model.MR_Cluster;
@@ -70,6 +69,8 @@ public class TopicService extends BaseLoggingClass {
        
        private static String centralCname;
        private static boolean createTopicRoles;
+       private boolean strictGraph = true;
+       private boolean mmPerMR;
 
 
        public TopicService(){
@@ -77,11 +78,15 @@ public class TopicService extends BaseLoggingClass {
                defaultGlobalMrHost = p.getProperty("MR.globalHost", "global.host.not.set");
                centralCname = p.getProperty("MR.CentralCname");
                createTopicRoles = "true".equalsIgnoreCase(p.getProperty("aaf.CreateTopicRoles", "true"));
-
-               
+               String unit_test = p.getProperty( "UnitTest", "No" );
+               if ( unit_test.equals( "Yes" ) ) {
+                       strictGraph = false;
+               }
+               mmPerMR = "true".equalsIgnoreCase(p.getProperty("MirrorMakerPerMR", "true"));
                logger.info( "TopicService properties: CentralCname=" + centralCname + 
                                "   defaultGlobarlMrHost=" + defaultGlobalMrHost +
-                               " createTopicRoles=" + createTopicRoles );
+                               " createTopicRoles=" + createTopicRoles +
+                               " mmPerMR=" + mmPerMR );
        }
        
        public Map<String, Topic> getTopics() {                 
@@ -299,10 +304,13 @@ public class TopicService extends BaseLoggingClass {
        
                
        public Topic updateTopic( Topic topic, ApiError err ) {
-               logger.info( "Entry: updateTopic");
+               logger.info( "updateTopic: entry");
+               logger.info( "updateTopic: topic=" + topic);
+               logger.info( "updateTopic: fqtn=" + topic.getFqtn() );
                if ( topic.getFqtn().isEmpty()) {
                        return null;
                }
+               logger.info( "updateTopic: call checkForBridge");
                Topic ntopic = checkForBridge( topic, err );
                if ( ntopic == null ) {
                        topic.setStatus( DmaapObject_Status.INVALID);
@@ -311,6 +319,7 @@ public class TopicService extends BaseLoggingClass {
                        }
                }
                if(ntopic != null) {
+                       logger.info( "updateTopic: call put");
                        mr_topics.put( ntopic.getFqtn(), ntopic );
                }
                err.setCode(Status.OK.getStatusCode());
@@ -374,7 +383,8 @@ public class TopicService extends BaseLoggingClass {
        
        
        public Topic checkForBridge( Topic topic, ApiError err ) {
-               
+               logger.info( "checkForBridge: entry");
+               logger.info( "fqtn=" + topic.getFqtn() + "replicatonType=" + topic.getReplicationCase());
                if ( topic.getReplicationCase() == ReplicationType.REPLICATION_NONE ) {
                        topic.setStatus( DmaapObject_Status.VALID);
                        return topic;   
@@ -384,6 +394,7 @@ public class TopicService extends BaseLoggingClass {
                
                Set<String> groups = clusters.getGroups();
                for ( String g : groups ) {
+                       logger.info( "buildBridge for " + topic.getFqtn() + " on group" + g);
                        anythingWrong |= buildBridge( topic, err, g );
                }
                if ( anythingWrong ) {
@@ -398,19 +409,24 @@ public class TopicService extends BaseLoggingClass {
        }
                
        private boolean buildBridge( Topic topic, ApiError err, String group ) {
-
+               logger.info( "buildBridge: entry");
                boolean anythingWrong = false;
                Graph graph;
+               logger.info( "buildBridge: strictGraph=" + strictGraph );
                if ( group == null || group.isEmpty() ) {
-                       graph = new Graph( topic.getClients(), true );
+                       graph = new Graph( topic.getClients(), strictGraph );
                } else {
-                       graph = new Graph( topic.getClients(), true, group );
+                       graph = new Graph( topic.getClients(), strictGraph, group );
                }
+               logger.info( "buildBridge: graph=" + graph );
                MR_Cluster groupCentralCluster = null;
                
+               
                if ( graph.isEmpty() ) {
+                       logger.info( "buildBridge: graph is empty.  return false" );
                        return false;
                } else if ( group == null &&  topic.getReplicationCase().involvesFQDN() ) {
+                       logger.info( "buildBridge: group is null and replicationCaseInvolvesFQDN. return false" );
                        return false;
                } else if ( ! graph.hasCentral() ) {
                        logger.warn( "Topic " + topic.getFqtn() + " wants to be " + topic.getReplicationCase() + " but has no central clients");
@@ -438,11 +454,11 @@ public class TopicService extends BaseLoggingClass {
                                case REPLICATION_EDGE_TO_CENTRAL:
                                case REPLICATION_EDGE_TO_CENTRAL_TO_GLOBAL:  // NOTE: this is for E2C portion only
                                        source = cluster.getFqdn();
-                                       target = centralCname;
+                                       target = (mmPerMR)? groupCentralCluster.getFqdn() : centralCname;
                                        break;
                                case REPLICATION_CENTRAL_TO_EDGE:
                                case REPLICATION_GLOBAL_TO_CENTRAL_TO_EDGE:  // NOTE: this is for C2E portion only
-                                       source = centralCname;
+                                       source = (mmPerMR) ? groupCentralCluster.getFqdn() : centralCname;
                                        target = cluster.getFqdn();
                                        break;
                                case REPLICATION_CENTRAL_TO_GLOBAL:
diff --git a/src/main/java/org/onap/dmaap/dbcapi/util/PermissionBuilder.java b/src/main/java/org/onap/dmaap/dbcapi/util/PermissionBuilder.java
new file mode 100644 (file)
index 0000000..44c94af
--- /dev/null
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.util;
+
+import javax.servlet.http.HttpServletRequest;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+
+public class PermissionBuilder {
+
+    static final String API_NS_PROP = "ApiNamespace";
+    static final String DEFAULT_API_NS = "org.onap.dmaap-bc.api";
+    static final String BOOT_INSTANCE = "boot";
+    private static final String PERM_SEPARATOR = "|";
+    private static final String NS_SEPARATOR = ".";
+    private DmaapConfig dmaapConfig;
+    private DmaapService dmaapService;
+    private String instance;
+    private String apiNamespace;
+
+    public PermissionBuilder(DmaapConfig dmaapConfig, DmaapService dmaapService) {
+        this.dmaapConfig = dmaapConfig;
+        this.dmaapService = dmaapService;
+        initFields();
+    }
+
+    public synchronized void updateDmaapInstance() {
+        if(instance == null || instance.isEmpty() || instance.equalsIgnoreCase(BOOT_INSTANCE)) {
+            String dmaapName = getDmaapName();
+            instance = (dmaapName == null || dmaapName.isEmpty()) ? BOOT_INSTANCE : dmaapName;
+        }
+    }
+
+    public String buildPermission(HttpServletRequest httpRequest) {
+
+        StringBuilder sb = new StringBuilder(apiNamespace);
+        sb.append(NS_SEPARATOR)
+            .append(getPermissionType(httpRequest.getPathInfo()))
+            .append(PERM_SEPARATOR)
+            .append(instance)
+            .append(PERM_SEPARATOR)
+            .append(httpRequest.getMethod());
+        return sb.toString();
+    }
+
+
+    private void initFields() {
+        apiNamespace = dmaapConfig.getProperty(API_NS_PROP, DEFAULT_API_NS);
+        updateDmaapInstance();
+    }
+
+    private String getDmaapName() {
+        Dmaap dmaap = dmaapService.getDmaap();
+        return ( dmaap != null ) ? dmaap.getDmaapName() : BOOT_INSTANCE;
+    }
+
+    private String getPermissionType(String pathInfo) {
+        char pathSeparator = '/';
+        String relativePath = (pathInfo.charAt(pathInfo.length()-1) == pathSeparator) ?
+            pathInfo.substring(0,pathInfo.length()-1) : pathInfo;
+
+        String[] pathSlices = relativePath.split(String.valueOf(pathSeparator));
+        return pathSlices[pathSlices.length-1];
+    }
+
+    String getInstance() {
+        return instance;
+    }
+}
index 7aaab11..c4cef5f 100644 (file)
@@ -7,9 +7,9 @@
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
 -- You may obtain a copy of the License at
--- 
+--
 --      http://www.apache.org/licenses/LICENSE-2.0
--- 
+--
 -- Unless required by applicable law or agreed to in writing, software
 -- distributed under the License is distributed on an "AS IS" BASIS,
 -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 @alter table dr_sub
 
-       add column      guaranteed_delivery     boolean,
-       add column      guaranteed_sequence     boolean,
-       add column      privileged_subscriber   boolean
+    add column  guaranteed_delivery     boolean,
+    add column  guaranteed_sequence     boolean,
+    add column  privileged_subscriber    boolean,
+    add column  decompress                      boolean
 ;
 
 
diff --git a/src/test/java/org/onap/dmaap/dbcapi/aaf/AafRoleTest.java b/src/test/java/org/onap/dmaap/dbcapi/aaf/AafRoleTest.java
new file mode 100644 (file)
index 0000000..c53d8c6
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright 2019 IBM
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dmaap.dbcapi.aaf;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AafRoleTest {
+
+    AafRole aafRole;
+
+    @Before
+    public void setUp() {
+        aafRole = new AafRole("testNs", "testRole");
+    }
+
+    @Test
+    public void testAafRole() {
+        aafRole.setNamespace("namespace");
+        aafRole.setRole("role");
+        assertEquals("namespace", aafRole.getNamespace());
+        assertEquals("role", aafRole.getRole());
+        assertEquals("namespace.role", aafRole.getFullyQualifiedRole());
+        assertNotNull(aafRole.toJSON());
+    }
+}
index 6328c21..88fff87 100644 (file)
@@ -4,6 +4,8 @@
  * ================================================================================
  * Copyright (C) 2019 IBM Intellectual Property. All rights reserved.
  * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ===================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
 
 package org.onap.dmaap.dbcapi.aaf;
 
-import org.junit.Test;
-
 import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Before;
+import org.junit.Test;
 
 public class AafUserRoleTest {
 
+    AafUserRole aafUserRole;
+
+    @Before
+    public void setUp() {
+        aafUserRole = new AafUserRole("xyz", "admin");
+    }
+
+    @Test
+    public void testGetIdentity() {
+        aafUserRole.setIdentity("xyz");
+        assertEquals("xyz", aafUserRole.getIdentity());
+    }
+
+    @Test
+    public void testGetRole() {
+        aafUserRole.setRole("admin");
+        assertEquals("admin", aafUserRole.getRole());
+    }
+
     @Test
     public void toJSON() {
-        AafUserRole role = new AafUserRole("test","admin");
+        AafUserRole role = new AafUserRole("test", "admin");
         assertThat(role.toJSON(), is(" { \"user\": \"test\", \"role\": \"admin\" }"));
     }
 }
\ No newline at end of file
index c1e9c35..5171aaa 100644 (file)
@@ -1,10 +1,11 @@
-
 /*-
  * ============LICENSE_START=======================================================
  * org.onap.dmaap
  * ================================================================================
  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ===================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
+
 package org.onap.dmaap.dbcapi.database;
 
-import org.onap.dmaap.dbcapi.database.DBFieldHandler;
-import org.onap.dmaap.dbcapi.model.*;
-import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
-import static org.junit.Assert.*;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 
-import org.junit.After;
-import org.junit.Before;
+import org.apache.log4j.Logger;
 import org.junit.Test;
-import java.util.*;
-import java.sql.*;
+import org.onap.dmaap.dbcapi.authentication.AafLurAndFish;
+import org.onap.dmaap.dbcapi.model.ReplicationType;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
 
 public class DBFieldHandlerTest {
 
-       private static final String  fmt = "%24s: %s%n";
+    private static final Logger logger = Logger.getLogger(AafLurAndFish.class);
 
-       ReflectionHarness rh = new ReflectionHarness();
+    private static final String fmt = "%24s: %s%n";
 
-   private static class TopicReplicationTypeHandler implements DBFieldHandler.SqlOp {
+    ReflectionHarness rh = new ReflectionHarness();
+
+    private static class TopicReplicationTypeHandler implements DBFieldHandler.SqlOp {
         public Object get(ResultSet rs, int index) throws Exception {
             int val = rs.getInt(index);
 
             return (ReplicationType.valueOf(val));
         }
+
         public void set(PreparedStatement ps, int index, Object val) throws Exception {
             if (val == null) {
                 ps.setInt(index, 0);
@@ -55,53 +60,55 @@ public class DBFieldHandlerTest {
         }
     }
 
+    @Test
+    public void test1() {
+        // rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get",
+        // "idNotSet@namespaceNotSet:pwdNotSet" );
+    }
 
+    @Test
+    public void test2() {
+        String v = "Validate";
+        // rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "set", v );
+    }
 
-       @Before
-       public void setUp() throws Exception {
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-
-
-       @Test
-       public void test1() {
-
-
-               //rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );      
-       
-       }
-
-       @Test
-       public void test2() {
-               String v = "Validate";
-               //rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "set", v );
-
-       }
-
-       @Test
-       public void test3() {
-
-               try {
-                       DBFieldHandler fh = new DBFieldHandler( String.class, "aString", 1 );
-               } catch (Exception e ) {
-               }
-
-       }
-
-       @Test
-       public void test4() {
-
-               try {
-                       DBFieldHandler fh = new DBFieldHandler( String.class, "aString", 1, null );
-               } catch (Exception e ) {
-               }
+    @Test
+    public void test3() {
+        try {
+            DBFieldHandler fh = new DBFieldHandler(String.class, "aString", 1);
+        } catch (Exception e) {
+            logger.error("Error", e);
+        }
+    }
 
-       }
+    @Test
+    public void test4() {
+        try {
+            DBFieldHandler fh = new DBFieldHandler(String.class, "aString", 1, null);
+        } catch (Exception e) {
+            logger.error("Error", e);
+        }
+    }
 
+    @Test
+    public void testfesc() {
+        String sampleString = "@xyz,ww;,";
+        String finalString = DBFieldHandler.fesc(sampleString);
+        assertEquals("@axyz@cww@s@c", finalString);
+    }
 
+    @Test
+    public void testfunesc() {
+        String sampleString = "@axyz@cww@s@c";
+        String convertedString = DBFieldHandler.funesc(sampleString);
+        assertEquals("@xyz,ww;,", convertedString);
+    }
 
+    @Test
+    public void testfescWithNull() {
+        String sampleString1 = DBFieldHandler.fesc(null);
+        String sampleString2 = DBFieldHandler.funesc(null);
+        assertNull(null, sampleString1);
+        assertNull(null, sampleString2);
+    }
 }
-
index dc2bb2f..af44db0 100644 (file)
@@ -71,7 +71,7 @@ public class TableHandlerTest {
        public void test1() {
 
 
-               //rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );      
+               rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );        
        
        }
 
@@ -84,17 +84,21 @@ public class TableHandlerTest {
 
        @Test
        public void test3() {
-               TableHandler.setSpecialCase("topic", "replication_case", new TopicReplicationTypeHandler());
+               DBFieldHandler.SqlOp trth = new TopicReplicationTypeHandler();
+               TableHandler.setSpecialCase("topic", "replication_case", trth);
 
                try {
                ConnectionFactory cf = new ConnectionFactory();
                TableHandler th = new TableHandler( cf, TopicReplicationTypeHandler.class, "foo", "bar" );
+               DBFieldHandler.SqlOp t = th.getSpecialCase( "foo", "bar" );
+               assert( trth == t );
                } catch (Exception e ) {
                }
                try {
-               ConnectionFactory cf = new ConnectionFactory();
+
                TableHandler th = new TableHandler( TopicReplicationTypeHandler.class, "foo", "bar" );
-               th.getSpecialCase( "foo", "bar" );
+               DBFieldHandler.SqlOp t = th.getSpecialCase( "foo", "bar" );
+               assert( trth == t );
                } catch (Exception e ) {
                }
 
diff --git a/src/test/java/org/onap/dmaap/dbcapi/model/BrTopicTest.java b/src/test/java/org/onap/dmaap/dbcapi/model/BrTopicTest.java
new file mode 100644 (file)
index 0000000..11e7c85
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright 2019 IBM
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class BrTopicTest {
+
+    BrTopic brTopic;
+
+    @Before
+    public void setUp() {
+        brTopic = new BrTopic();
+    }
+
+    @Test
+    public void testGetBrSource() {
+        brTopic.setBrSource("brSource");
+        assertEquals("brSource", brTopic.getBrSource());
+    }
+
+    @Test
+    public void testGetBrTarget() {
+        brTopic.setBrTarget("brTarget");
+        assertEquals("brTarget", brTopic.getBrTarget());
+    }
+
+    @Test
+    public void testGetTopicCount() {
+        brTopic.setTopicCount(1);
+        assertEquals(1, brTopic.getTopicCount());
+    }
+
+    @Test
+    public void testGetMmAgentName() {
+        brTopic.setMmAgentName("Test");
+        assertEquals("Test", brTopic.getMmAgentName());
+    }
+}
index 480ff07..95cf9c9 100644 (file)
@@ -69,7 +69,7 @@ public class DRSubTest {
                assertTrue( t.isGuaranteedDelivery() == false );
                assertTrue( t.isGuaranteedSequence() == false );
                assertTrue( t.isPrivilegedSubscriber() == false );
-       
+               assertTrue( t.isDecompress() == false );
        }
 
        @Test
@@ -113,6 +113,8 @@ public class DRSubTest {
                assertTrue( t.isGuaranteedSequence() == v );
                t.setPrivilegedSubscriber(v);
                assertTrue( t.isPrivilegedSubscriber() == v );
+               t.setDecompress(v);
+               assertTrue( t.isDecompress() == v );
        }
 
        @Test
index fb83fe9..c0f3bef 100644 (file)
  */
 package org.onap.dmaap.dbcapi.model;
 
-import static org.junit.Assert.*;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+
 public class DmaapTest {
-       String ver, tnr, dn, dpu, lu, bat, nk, ako; 
+       private String ver, tnr, dn, dpu, lu, bat, nk, ako;
 
        @Before
        public void setUp() throws Exception {
index 15753cd..ba95a85 100644 (file)
@@ -4,6 +4,8 @@
  * ================================================================================
  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -17,6 +19,7 @@
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
+
 package org.onap.dmaap.dbcapi.model;
 
 import static org.junit.Assert.*;
@@ -26,67 +29,83 @@ import org.junit.Before;
 import org.junit.Test;
 import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
 
-
 public class MRClientTest {
 
-       private static final String  fmt = "%24s: %s%n";
-
-       ReflectionHarness rh = new ReflectionHarness();
-
-       String d, t, f, c, m;
-
-       @Before
-       public void setUp() throws Exception {
-               d = "central-onap";
-               t = "org.onap.dmaap.interestingTopic";
-               f = "mrc.onap.org:3904/events/org.onap.dmaap.interestingTopic";
-               c = "publisher";
-               m = "m12345";
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-
-
-       @Test
-       public void test1() {
-
-               // can't use simple reflection to test for null since null constructor initializes some fields.
-               //rh.reflect( "org.onap.dmaap.dbcapi.model.MR_Client", "get", null );   
-               // so brute force instead...
-               String[] a = { "put", "view" };
-               MR_Client m = new MR_Client();
-
-
-               assertTrue( null ==  m.getDcaeLocationName() );
-               assertTrue( null ==  m.getFqtn() );
-               assertTrue( null ==  m.getClientRole() );
-               assertTrue( null ==  m.getAction() );
-       
-       }
-
-       @Test
-       public void test2() {
-               String[] a = { "put", "view" };
-               MR_Client m = new MR_Client( d, f, c, a );
-
-
-               assertTrue( d.equals( m.getDcaeLocationName() ));
-               assertTrue( f.equals( m.getFqtn() ));
-               assertTrue( c.equals( m.getClientRole() ));
-               String[] ma = m.getAction();
-               assertTrue( a.length == ma.length );
-               for( int i = 0; i < a.length; i++ ) {
-                       assertTrue( a[i].equals( ma[i] ) );
-               }
-       }
-
-       @Test
-       public void test3() {
-
-               String v = "Validate";
-               rh.reflect( "org.onap.dmaap.dbcapi.model.MR_Client", "set", v );
-       }
+    private static final String fmt = "%24s: %s%n";
+
+    ReflectionHarness rh = new ReflectionHarness();
+
+    String d, t, f, c, m;
+
+    @Before
+    public void setUp() throws Exception {
+        d = "central-onap";
+        t = "org.onap.dmaap.interestingTopic";
+        f = "mrc.onap.org:3904/events/org.onap.dmaap.interestingTopic";
+        c = "publisher";
+        m = "m12345";
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void test1() {
+
+        // can't use simple reflection to test for null since null constructor
+        // initializes some fields.
+        // rh.reflect( "org.onap.dmaap.dbcapi.model.MR_Client", "get", null );
+        // so brute force instead...
+        String[] a = { "put", "view" };
+        MR_Client m = new MR_Client();
+
+        assertTrue(null == m.getDcaeLocationName());
+        assertTrue(null == m.getFqtn());
+        assertTrue(null == m.getClientRole());
+        assertTrue(null == m.getAction());
+
+    }
+
+    @Test
+    public void test2() {
+        String[] a = { "put", "view" };
+        MR_Client m = new MR_Client(d, f, c, a);
+
+        assertTrue(d.equals(m.getDcaeLocationName()));
+        assertTrue(f.equals(m.getFqtn()));
+        assertTrue(c.equals(m.getClientRole()));
+        String[] ma = m.getAction();
+        assertTrue(a.length == ma.length);
+        for (int i = 0; i < a.length; i++) {
+            assertTrue(a[i].equals(ma[i]));
+        }
+    }
+
+    @Test
+    public void test3() {
+
+        String v = "Validate";
+        rh.reflect("org.onap.dmaap.dbcapi.model.MR_Client", "set", v);
+    }
+
+    @Test
+    public void test4() {
+        MR_Client mrClient = new MR_Client();
+        String stringArray[] = { "test" };
+        mrClient.setAction(stringArray);
+        mrClient.hasAction("");
+        mrClient.setMrClientId("mrClientId");
+        mrClient.setTopicURL("testTopicURL");
+        mrClient.setClientIdentity("clientIdentity");
+
+        assertEquals("clientIdentity", mrClient.getClientIdentity());
+        assertEquals("testTopicURL", mrClient.getTopicURL());
+        assertEquals("mrClientId", mrClient.getMrClientId());
+        assertEquals(false, mrClient.isPublisher());
+        assertEquals(false, mrClient.isSubscriber());
+        assertEquals("test", mrClient.getAction()[0]);
+
+    }
 
 }
index ebe7b1e..514e0d1 100644 (file)
@@ -30,7 +30,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
 public class MR_ClusterTest {
-       String d, fqdn;
+       String d, fqdn, repGrp, p1, p2, prot, p0;
 
        ReflectionHarness rh = new ReflectionHarness();
 
@@ -38,6 +38,14 @@ public class MR_ClusterTest {
        public void setUp() throws Exception {
                d = "central-onap";
                fqdn = "mr.onap.org";
+               repGrp = "zeppelin";
+               prot = "http";
+               p0 = "3904";
+               p1 = "9092";
+               p2 = "2323";
+               
+       
+               
        }
 
        @After
@@ -58,10 +66,45 @@ public class MR_ClusterTest {
        @Test
        public void testMR_ClusterClassConstructor() {
 
-               MR_Cluster t = new MR_Cluster( d, fqdn, "http", "3904");
+               MR_Cluster t = new MR_Cluster( d, fqdn, prot, p0);
+       
+               assertTrue( t.getDcaeLocationName() == d  );
+               assertTrue( t.getFqdn() == fqdn  );
+               assertTrue( t.getTopicProtocol() == prot );
+               assertTrue( t.getTopicPort() == p0 );
+               
+               // pass null params to trigger default settings
+                t = new MR_Cluster( d, fqdn, null, null );
+               
+               assertTrue( t.getDcaeLocationName() == d  );
+               assertTrue( t.getFqdn() == fqdn  );
+               assertTrue( t.getTopicProtocol() != null );
+               assertTrue( t.getTopicPort() != null );
+       }
+       
+       @Test
+       public void testMR_ClusterManyArgsClassConstructor() {
+
+               MR_Cluster t = new MR_Cluster( d, fqdn, prot, p0, repGrp, p1, p2 );
        
                assertTrue( t.getDcaeLocationName() == d  );
                assertTrue( t.getFqdn() == fqdn  );
+               assertTrue( t.getTopicProtocol() == prot );
+               assertTrue( t.getTopicPort() == p0 );
+               assertTrue( t.getReplicationGroup() == repGrp  );
+               assertTrue( t.getSourceReplicationPort() == p1  );
+               assertTrue( t.getTargetReplicationPort() == p2 );
+               
+               // pass null params to trigger default settings
+               t = new MR_Cluster( d, fqdn, null, null, null, null, null );
+               
+               assertTrue( t.getDcaeLocationName() == d  );
+               assertTrue( t.getFqdn() == fqdn  );
+               assertTrue( t.getTopicProtocol() != null );
+               assertTrue( t.getTopicPort() != null );
+               assertTrue( t.getReplicationGroup() != null  );
+               assertTrue( t.getSourceReplicationPort() != null  );
+               assertTrue( t.getTargetReplicationPort() != null );
        }
 
        @Test
@@ -72,7 +115,13 @@ public class MR_ClusterTest {
                assertTrue( t.getDcaeLocationName() == null  );
                assertTrue( t.getFqdn() == null  );
 
-               String fqtn = t.genTopicURL( "cluster2.onap.org", "org.onap.topic2" );  
+               String override = "cluster2.onap.org";
+               String  topic2 = "org.onap.topic2";
+               String fqtn = t.genTopicURL( override, topic2 );        
+               assertTrue( fqtn.contains( override) && fqtn.contains(topic2));
+               
+               fqtn = t.genTopicURL( null, "org.onap.topic2" );
+               assertTrue(fqtn.contains(topic2));
        }
 
 
index 5180b99..5da3aed 100644 (file)
@@ -4,6 +4,8 @@
  * ================================================================================
  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  */
 package org.onap.dmaap.dbcapi.model;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
 import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
 
-
 public class TopicTest {
 
-       private static final String  fmt = "%24s: %s%n";
-
-       ReflectionHarness rh = new ReflectionHarness();
-
-       String f, t, d, e, o;
-
-       @Before
-       public void setUp() throws Exception {
-               f = "org.onap.dmaap.interestingTopic";
-               t = "interestingTopic";
-               d = "A so very interesting topic";
-               e = "Yes";
-               o = "m12345";
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-
-
-       @Test
-       public void test1() {
-
-
-               rh.reflect( "org.onap.dmaap.dbcapi.model.Topic", "get", null ); 
-       
-       }
-
-       @Test
-       public void test2() {
-               String[] a = { "put", "view" };
-               Topic obj = new Topic( f, t, d, e, o );
-
-
-               assertTrue( f.equals( obj.getFqtn() ));
-               assertTrue( t.equals( obj.getTopicName() ));
-               assertTrue( d.equals( obj.getTopicDescription() ));
-               assertTrue( e.equals( obj.getTnxEnabled() ));
-               assertTrue( o.equals( obj.getOwner() ));
-       }
-
-       @Test
-       public void test3() {
-
-               String v = "Validate";
-               rh.reflect( "org.onap.dmaap.dbcapi.model.Topic", "set", v );
-       }
+    ReflectionHarness rh = new ReflectionHarness();
+
+    String f, t, d, e, o;
+
+    @Before
+    public void setUp() throws Exception {
+        f = "org.onap.dmaap.interestingTopic";
+        t = "interestingTopic";
+        d = "A so very interesting topic";
+        e = "Yes";
+        o = "m12345";
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void test1() {
+        rh.reflect("org.onap.dmaap.dbcapi.model.Topic", "get", null);
+    }
+
+    @Test
+    public void test2() {
+        Topic obj = new Topic(f, t, d, e, o);
+        assertTrue(f.equals(obj.getFqtn()));
+        assertTrue(t.equals(obj.getTopicName()));
+        assertTrue(d.equals(obj.getTopicDescription()));
+        assertTrue(e.equals(obj.getTnxEnabled()));
+        assertTrue(o.equals(obj.getOwner()));
+    }
+
+    @Test
+    public void test3() {
+        String v = "Validate";
+        rh.reflect("org.onap.dmaap.dbcapi.model.Topic", "set", v);
+    }
+
+    @Test
+    public void getNumClientsHavingMRClientListNull() {
+        Topic obj = new Topic(f, t, d, e, o);
+        obj.setClients(null);
+        assertEquals(0, obj.getNumClients());
+    }
+
+    @Test
+    public void testTopicInitializationWithInvalidJsonString() {
+        String json = "{\"key\":\"value\"";
+        Topic obj = new Topic(json);
+        assertEquals(DmaapObject_Status.INVALID, obj.getStatus());
+    }
 
 }
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilterTest.java b/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilterTest.java
new file mode 100644 (file)
index 0000000..d5ae5fd
--- /dev/null
@@ -0,0 +1,178 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aaf.cadi.filter.CadiFilter;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AAFAuthenticationFilterTest {
+
+    @Spy
+    private AAFAuthenticationFilter filter;
+    @Mock
+    private FilterConfig filterConfig;
+    @Mock
+    private CadiFilter cadiFilterMock;
+    @Mock
+    private HttpServletRequest servletRequest;
+    @Mock
+    private HttpServletResponse servletResponse;
+    @Mock
+    private FilterChain filterChain;
+    @Mock
+    private DmaapConfig dmaapConfig;
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    @Before
+    public void setUp() throws Exception {
+        doReturn(dmaapConfig).when(filter).getConfig();
+    }
+
+    @Test
+    public void init_shouldNotInitializeCADI_whenAafIsNotUsed() throws Exception {
+        //given
+        doReturn("false").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.AAF_AUTHN_FLAG), anyString());
+
+        //when
+        filter.init(filterConfig);
+
+        //then
+        assertFalse(filter.isAafEnabled());
+        assertNull(filter.getCadiFilter());
+    }
+
+    @Test
+    public void doFilter_shouldSkipCADI_whenAafIsNotUsed() throws Exception {
+        //given
+        doReturn("false").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.AAF_AUTHN_FLAG), anyString());
+        filter.init(filterConfig);
+        filter.setCadiFilter(cadiFilterMock);
+
+        //when
+        filter.doFilter(servletRequest, servletResponse, filterChain);
+
+        //then
+        verify(filterChain).doFilter(servletRequest,servletResponse);
+        verifyZeroInteractions(cadiFilterMock,servletRequest,servletResponse);
+    }
+
+    @Test
+    public void init_shouldFail_whenAafIsUsed_andCadiPropertiesHasNotBeenSet() throws Exception {
+        //given
+        doReturn("true").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.AAF_AUTHN_FLAG), anyString());
+        doReturn("").when(dmaapConfig).getProperty(AAFAuthenticationFilter.CADI_PROPERTIES);
+
+        //then
+        thrown.expect(ServletException.class);
+        thrown.expectMessage("Cannot initialize CADI filter.CADI properties not available.");
+
+        //when
+        filter.init(filterConfig);
+    }
+
+    @Test
+    public void init_shouldInitializeCADI_whenAafIsUsed_andCadiPropertiesSet() throws Exception {
+        //given
+        doReturn("true").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.AAF_AUTHN_FLAG), anyString());
+        doReturn("cadi.properties").when(dmaapConfig).getProperty(AAFAuthenticationFilter.CADI_PROPERTIES);
+
+        //when
+        filter.init(filterConfig);
+
+        //then
+        assertTrue(filter.isAafEnabled());
+        assertNotNull(filter.getCadiFilter());
+    }
+
+    @Test
+    public void doFilter_shouldUseCADIfilter_andAuthenticateUser_whenAAFisUsed_andUserIsValid() throws Exception{
+        //given
+        initCADIFilter();
+        doReturn(200).when(servletResponse).getStatus();
+
+        //when
+        filter.doFilter(servletRequest,servletResponse,filterChain);
+
+        //then
+        verify(cadiFilterMock).doFilter(servletRequest,servletResponse,filterChain);
+        verify(servletResponse).getStatus();
+        verifyNoMoreInteractions(servletResponse);
+        verifyZeroInteractions(filterChain, servletRequest);
+    }
+
+    @Test
+    public void doFilter_shouldUseCADIfilter_andReturnAuthenticationError_whenAAFisUsed_andUserInvalid() throws Exception{
+        //given
+        String errorResponseJson = "{\"code\":401,\"message\":\"invalid or no credentials provided\",\"fields\":\"Authentication\",\"2xx\":false}";
+        initCADIFilter();
+        doReturn(401).when(servletResponse).getStatus();
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        doReturn(pw).when(servletResponse).getWriter();
+
+        //when
+        filter.doFilter(servletRequest,servletResponse,filterChain);
+
+        //then
+        verify(cadiFilterMock).doFilter(servletRequest,servletResponse,filterChain);
+        verify(servletResponse).getStatus();
+        verify(servletResponse).setContentType("application/json");
+        verifyZeroInteractions(filterChain, servletRequest);
+        assertEquals(errorResponseJson, sw.toString());
+    }
+
+    private void initCADIFilter() throws Exception{
+        doReturn("true").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.AAF_AUTHN_FLAG), anyString());
+        doReturn("cadi.properties").when(dmaapConfig).getProperty(AAFAuthenticationFilter.CADI_PROPERTIES);
+        filter.init(filterConfig);
+        filter.setCadiFilter(cadiFilterMock);
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilterTest.java b/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilterTest.java
new file mode 100644 (file)
index 0000000..73794cd
--- /dev/null
@@ -0,0 +1,172 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.PermissionBuilder;
+import sun.security.acl.PrincipalImpl;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AAFAuthorizationFilterTest {
+
+    @Spy
+    private AAFAuthorizationFilter filter;
+    @Mock
+    private FilterConfig filterConfig;
+    @Mock
+    private HttpServletRequest servletRequest;
+    @Mock
+    private HttpServletResponse servletResponse;
+    @Mock
+    private FilterChain filterChain;
+    @Mock
+    private DmaapConfig dmaapConfig;
+    @Mock
+    private PermissionBuilder permissionBuilder;
+    @Mock
+    private DmaapService dmaapService;
+
+    @Before
+    public void setUp() throws Exception {
+        filter.setPermissionBuilder(permissionBuilder);
+        doReturn(dmaapConfig).when(filter).getConfig();
+        doReturn(dmaapService).when(filter).getDmaapService();
+    }
+
+    @Test
+    public void init_shouldNotInitializePermissionBuilder_whenAAFnotUsed() throws Exception {
+        //given
+        filter.setPermissionBuilder(null);
+        configureAAFUsage(false);
+
+        //when
+        filter.init(filterConfig);
+
+        //then
+        assertNull(filter.getPermissionBuilder());
+    }
+
+    @Test
+    public void init_shouldInitializePermissionBuilder_whenAAFisUsed() throws Exception {
+        //given
+        filter.setPermissionBuilder(null);
+        configureAAFUsage(true);
+        //doReturn(provideEmptyInstance()).when(dmaapService).getDmaap();
+        when(dmaapService.getDmaap()).thenReturn(mock(Dmaap.class));
+
+        //when
+        filter.init(filterConfig);
+
+        //then
+        assertNotNull(permissionBuilder);
+    }
+
+    @Test
+    public void doFilter_shouldSkipAuthorization_whenAAFnotUsed() throws Exception {
+        //given
+        filter.setAafEnabled(false);
+
+        //when
+        filter.doFilter(servletRequest,servletResponse,filterChain);
+
+        //then
+        verify(filterChain).doFilter(servletRequest,servletResponse);
+        verifyNoMoreInteractions(filterChain);
+        verifyZeroInteractions(permissionBuilder, servletRequest, servletResponse);
+    }
+
+    @Test
+    public void doFilter_shouldPass_whenUserHasPermissionToResourceEndpoint() throws Exception {
+        //given
+        String user = "johnny";
+        String permission = "org.onap.dmaap-bc.api.topics|mr|GET";
+        when(permissionBuilder.buildPermission(servletRequest)).thenReturn(permission);
+        configureServletRequest(permission, user, true);
+        filter.setAafEnabled(true);
+
+        //when
+        filter.doFilter(servletRequest,servletResponse,filterChain);
+
+        //then
+        verify(filterChain).doFilter(servletRequest,servletResponse);
+        verify(permissionBuilder).updateDmaapInstance();
+        verifyZeroInteractions(servletResponse);
+    }
+
+    @Test
+    public void doFilter_shouldReturnError_whenUserDontHavePermissionToResourceEndpoint() throws Exception {
+        //given
+        String user = "jack";
+        String permission = "org.onap.dmaap-bc.api.topics|mr|GET";
+        when(permissionBuilder.buildPermission(servletRequest)).thenReturn(permission);
+        configureServletRequest(permission, user, false);
+        filter.setAafEnabled(true);
+
+        String errorMsgJson = "{\"code\":403,\"message\":\"User "+user+" does not have permission "
+            + permission +"\",\"fields\":\"Authorization\",\"2xx\":false}";
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        when(servletResponse.getWriter()).thenReturn(pw);
+
+        //when
+        filter.doFilter(servletRequest,servletResponse,filterChain);
+
+        //then
+        verifyZeroInteractions(filterChain);
+        verify(permissionBuilder).updateDmaapInstance();
+        verify(servletResponse).setStatus(403);
+        assertEquals(errorMsgJson, sw.toString());
+    }
+
+    private void configureServletRequest(String permission, String user, boolean isUserInRole) {
+        when(servletRequest.getUserPrincipal()).thenReturn(new PrincipalImpl(user));
+        when(servletRequest.isUserInRole(permission)).thenReturn(isUserInRole);
+    }
+
+    private void configureAAFUsage(Boolean isUsed) {
+        doReturn(isUsed.toString()).when(dmaapConfig).getProperty(eq(AAFAuthorizationFilter.AAF_AUTHZ_FLAG), anyString());
+    }
+}
\ No newline at end of file
index 01ef6ae..856a789 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  */
 package org.onap.dmaap.dbcapi.resources;
 
-import org.onap.dmaap.dbcapi.model.*;
-import org.onap.dmaap.dbcapi.service.*;
-import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
-import java.util.*;
-import java.sql.*;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Node;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
 
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.server.ResourceConfig;
 import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.Path;
-import javax.ws.rs.GET;
-
-
-public class DR_NodeResourceTest extends JerseyTest {
-
-       static DmaapObjectFactory factory = new DmaapObjectFactory();
-       static String entry_path = "dr_nodes";
-
-       @Override
-       protected Application configure() {
-               return new ResourceConfig( DR_NodeResource.class );
-       }
-
-       private static final String  fmt = "%24s: %s%n";
-
-
-
-/*  may conflict with test framework! 
-       @Before
-       public void preTest() throws Exception {
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-*/
-
-
-       @Test
-       public void GetTest() {
-               Response resp = target( entry_path ).request().get( Response.class );
-               System.out.println( "GET " + entry_path + " resp=" + resp.getStatus() );
-
-               assertTrue( resp.getStatus() == 200 );
-       }
-       @Test
-       public void PostTest() {
-               DR_Node node = factory.genDR_Node( "central" );
-               Entity<DR_Node> reqEntity = Entity.entity( node, MediaType.APPLICATION_JSON );
-               Response resp = target( entry_path ).request().post( reqEntity, Response.class );
-               System.out.println( "POST " + entry_path + " resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
-               assertTrue( resp.getStatus() == 200 );
-       }
-
-       @Test
-       public void PutTest() {
-
-/*
-               try {
-                       DcaeLocation loc = factory.genDcaeLocation( "central" );
-                       Entity<DcaeLocation> reqEntity = Entity.entity( loc, MediaType.APPLICATION_JSON );
-                       Response resp = target( "dcaeLocations").request().post( reqEntity, Response.class );
-                       System.out.println( "POST dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ));
-                       assertTrue( resp.getStatus() == 201 );
-               } catch (Exception e ) {
-               }
-*/
-
-               DR_Node node = factory.genDR_Node( "central" );
-               Entity<DR_Node> reqEntity = Entity.entity( node, MediaType.APPLICATION_JSON );
-               Response resp = target( entry_path ).request().post( reqEntity, Response.class );
-
-               // first, add it 
-               System.out.println( "POST " + entry_path + " resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
-               assertTrue( resp.getStatus() == 200 );
-
-               // now change a field
-               node.setVersion( "1.0.2" );
-               reqEntity = Entity.entity( node, MediaType.APPLICATION_JSON );
-
-               // update  currently fails...
-               resp = target( entry_path )
-                                       .path( node.getFqdn())
-                                       .request()
-                                       .put( reqEntity, Response.class );
-               System.out.println( "PUT " + entry_path + "/" + node.getFqdn() + " resp=" + resp.getStatus() + " " + resp.readEntity(String.class));
-               assertTrue( resp.getStatus() == 404 );
-
-       }
-
-
 
+import static javax.ws.rs.client.Entity.entity;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+
+public class DR_NodeResourceTest {
+
+    private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+    private static FastJerseyTestContainer testContainer;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+        testContainer = new FastJerseyTestContainer(new ResourceConfig()
+                .register(DR_NodeResource.class));
+        testContainer.init();
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        testContainer.destroy();
+        /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+        DatabaseClass.clearDatabase();
+        DatabaseClass.getDmaap().remove();*/
+    }
+
+    @Test
+    public void getDr_Nodes_test() {
+        Response response = testContainer.target("dr_nodes").request().get(Response.class);
+        System.out.println("GET dr_subs response=" + response.getStatus());
+
+        assertEquals(200, response.getStatus());
+        assertTrue(response.hasEntity());
+    }
+
+    @Test
+    public void addDr_Node_shouldReturnError_whenNoLocationAndFqdnProvided() {
+        DR_Node node = new DR_Node(null, null, "hostName", "1.0");
+        Entity<DR_Node> requestedEntity = entity(node, APPLICATION_JSON);
+
+        Response response = testContainer.target("dr_nodes")
+                .request()
+                .post(requestedEntity, Response.class);
+
+        assertEquals(400, response.getStatus());
+        ApiError responseError = response.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("dcaeLocation, fqdn", responseError.getFields());
+    }
+
+    @Test
+    public void addDr_Node_shouldReturnError_whenDrNodeWithGiveFqdnAlreadyExists() {
+        DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+
+        addDrNode(node);
+        Response response = addDrNode(node);
+
+        assertEquals(409, response.getStatus());
+        ApiError responseError = response.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("fqdn", responseError.getFields());
+        assertEquals("Node fqdn already exists", responseError.getMessage());
+    }
+
+    @Test
+    public void addDr_Node_shouldExecuteSuccessfully() {
+        DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+
+        Response response = addDrNode(node);
+
+        assertEquals(200, response.getStatus());
+        assertTrue(response.hasEntity());
+        assertDrNodeExistInDB(response.readEntity(DR_Node.class));
+    }
+
+    @Test
+    public void updateDr_Node_shouldReturnError_whenNoLocationAndFqdnProvided() {
+        DR_Node node = new DR_Node(null, null, "hostName", "1.0");
+        Entity<DR_Node> requestedEntity = entity(node, APPLICATION_JSON);
+
+        Response response = testContainer.target("dr_nodes")
+                .path("fqdn")
+                .request()
+                .put(requestedEntity, Response.class);
+
+        assertEquals(400, response.getStatus());
+        ApiError responseError = response.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("dcaeLocation, fqdn", responseError.getFields());
+    }
+
+    @Test
+    public void updateDr_Node_shouldReturnError_whenNoExistingFqdnProvided() {
+        DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+        Entity<DR_Node> requestedEntity = entity(node, APPLICATION_JSON);
+
+        Response response = testContainer.target("dr_nodes")
+                .path("")
+                .request()
+                .put(requestedEntity, Response.class);
+
+        assertEquals(405, response.getStatus());
+    }
+
+    @Test
+    public void updateDr_Node_shouldReturnError_whenDrNodeForUpdateDoesNotExistInDb() {
+        DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+        Entity<DR_Node> requestedEntity = entity(node, APPLICATION_JSON);
+
+        Response response = testContainer.target("dr_nodes")
+                .path(node.getFqdn())
+                .request()
+                .put(requestedEntity, Response.class);
+
+        assertEquals(404, response.getStatus());
+        ApiError responseError = response.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("fqdn", responseError.getFields());
+        assertEquals("Node " + node.getFqdn() + " does not exist", responseError.getMessage());
+    }
+
+    @Test
+    public void updateDr_Node_ShouldExecuteSuccessfully() {
+        DR_Node toUpdate = new DR_Node("fqdn", "location", "hostName", "1.0");
+        Entity<DR_Node> requestedEntity = entity(toUpdate, APPLICATION_JSON);
+
+        addDrNode(new DR_Node("fqdn", "old_location", "old_hostName", "old_1.0"));
+        Response response = testContainer.target("dr_nodes")
+                .path(toUpdate.getFqdn())
+                .request()
+                .put(requestedEntity, Response.class);
+
+        assertEquals(200, response.getStatus());
+        assertTrue(response.hasEntity());
+        assertEquals(toUpdate, response.readEntity(DR_Node.class));
+    }
+
+    @Test
+    public void deleteDr_Node_shouldReturnError_whenDrNodeForDeleteDoesNotExistInDb() {
+        Response response = testContainer.target("dr_nodes")
+                .path("fqdn")
+                .request()
+                .delete();
+
+        assertEquals(404, response.getStatus());
+        ApiError responseError = response.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("fqdn", responseError.getFields());
+        assertEquals("Node fqdn does not exist", responseError.getMessage());
+    }
+
+    @Test
+    public void deleteDr_Node_shouldReturnError_whenNoExistingFqdnProvided() {
+        Response response = testContainer.target("dr_nodes")
+                .path("")
+                .request()
+                .delete();
+
+        assertEquals(405, response.getStatus());
+    }
+
+    @Test
+    public void deleteDr_Node_shouldExecuteSuccessfully() {
+        DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+
+        addDrNode(node);
+        Response response = testContainer.target("dr_nodes")
+                .path("fqdn")
+                .request()
+                .delete();
+
+        assertEquals(204, response.getStatus());
+    }
+
+    @Test
+    public void getDr_Node_shouldReturnError_whenDrNodeForDeleteDoesNotExistInDb() {
+        Response response = testContainer.target("dr_nodes")
+                .path("fqdn")
+                .request()
+                .get();
+
+        assertEquals(404, response.getStatus());
+        ApiError responseError = response.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("fqdn", responseError.getFields());
+        assertEquals("Node fqdn does not exist", responseError.getMessage());
+    }
+
+    private Response addDrNode(DR_Node node) {
+        return testContainer.target("dr_nodes")
+                .request()
+                .post(entity(node, APPLICATION_JSON), Response.class);
+    }
+
+    private void assertDrNodeExistInDB(DR_Node created) {
+        Response response = testContainer.target("dr_nodes")
+                .path(created.getFqdn())
+                .request()
+                .get();
+        assertEquals(200, response.getStatus());
+        assertTrue(response.hasEntity());
+        assertEquals(created, response.readEntity(DR_Node.class));
+    }
+
+    @Before
+    public void cleanupDatabase() {
+        DatabaseClass.clearDatabase();
+    }
 
 }
 
index d4f71bb..bf03088 100644 (file)
@@ -8,9 +8,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * ============LICENSE_END=========================================================
  */
 package org.onap.dmaap.dbcapi.resources;
-import org.onap.dmaap.dbcapi.model.*;
-import org.onap.dmaap.dbcapi.service.*;
-import static org.junit.Assert.*;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import java.util.*;
-import java.sql.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.server.ResourceConfig;
 import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Response;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.Path;
-import javax.ws.rs.GET;
-
-public class DR_PubResourceTest extends JerseyTest{
-
-       @Override
-       protected Application configure() {
-               return new ResourceConfig()
-                               .register( DR_PubResource.class )
-                               .register( FeedResource.class );
-       }
-
-       private static final String  fmt = "%24s: %s%n";
-       String d, un, up, f, p;
-/*
-       @Before
-       public void setUp() throws Exception {
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-               f = "234";
-               p = "678";
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-*/
-
-
-
-/*  may conflict with test framework! 
-       @Before
-       public void setUp() throws Exception {
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-*/
-
-       private Feed addFeed( String name, String desc ) {
-               Feed feed = new Feed( name, "1.0", desc, "dgl", "unrestricted" );
-               Entity<Feed> reqEntity = Entity.entity( feed, MediaType.APPLICATION_JSON );
-               Response resp = target( "feeds").request().post( reqEntity, Response.class );
-               int rc = resp.getStatus();
-               System.out.println( "POST feed resp=" + rc );
-               assertTrue( rc == 200 || rc == 409 );
-               feed = resp.readEntity( Feed.class );
-               return feed;
-       }
-       
-       private DR_Pub addPub( String d, String un, String up, String feedId ) {
-               DR_Pub dr_pub = new DR_Pub( d, un, up, feedId, "" );
-               Entity<DR_Pub> reqEntity2 = Entity.entity( dr_pub, MediaType.APPLICATION_JSON);
-               Response resp = target( "dr_pubs").request().post( reqEntity2, Response.class);
-               System.out.println( "POST dr_pubs resp=" + resp.getStatus() );
-               assertTrue( resp.getStatus() == 201 );
-               dr_pub = resp.readEntity( DR_Pub.class );
-               
-               return dr_pub;
-       }
-       
-       private DR_Pub addPubByName( String d, String un, String up, String feedName) {
-               DR_Pub dr_pub = new DR_Pub( d, un, up, null, "" );
-               dr_pub.setFeedName(feedName);
-               Entity<DR_Pub> reqEntity2 = Entity.entity( dr_pub, MediaType.APPLICATION_JSON);
-               Response resp = target( "dr_pubs").request().post( reqEntity2, Response.class);
-               System.out.println( "POST dr_pubs resp=" + resp.getStatus() );
-               assertTrue( resp.getStatus() == 201 );
-               dr_pub = resp.readEntity( DR_Pub.class );
-               
-               return dr_pub;
-       }
-       
-       @Test
-       public void GetTest() {
-               Response resp = target( "dr_pubs").request().get( Response.class );
-               System.out.println( "GET dr_pubs resp=" + resp.getStatus() );
-
-               assertTrue( resp.getStatus() == 200 );
-       }
-       
-       @Test
-       public void PostTest() {
-
-               Feed feed = addFeed( "pubPostTest", "post unit test" );
-               System.out.println( "fpubPostTest: feedId=" + feed.getFeedId());
-               
-               String d, un, up;
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-
-               DR_Pub dr_pub = addPub( d, un, up, feed.getFeedId() );
-       }
-       
-       @Test
-       public void PostTestByName() {
-
-               Feed feed = addFeed( "pubPostTest2", "post unit test" );
-               System.out.println( "fpubPostTest: feedId=" + feed.getFeedId());
-               
-               String d, un, up;
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-
-               DR_Pub dr_pub = addPubByName( d, un, up, "pubPostTest2" );      
-       }
-
-       @Test
-       public void PutTest() {
-
-               Feed feed = addFeed( "pubPutTest", "put unit test");
-               String d, un, up;
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-
-               DR_Pub dr_pub = addPub( d, un, up, feed.getFeedId() );
-               
-               dr_pub.setUserpwd("newSecret");
-               Entity<DR_Pub> reqEntity2 = Entity.entity( dr_pub, MediaType.APPLICATION_JSON);
-               Response resp = target( "dr_pubs")
-                               .path( dr_pub.getPubId() )
-                               .request()
-                               .put( reqEntity2, Response.class);
-               System.out.println( "PUT dr_pubs resp=" + resp.getStatus() );
-               assertTrue( resp.getStatus() == 200 );
-       }
-               
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Pub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+public class DR_PubResourceTest {
+
+    private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+
+    private static final String DCAE_LOCATION_NAME = "central-onap";
+    private static final String USERNAME = "user1";
+    private static final String USRPWD = "secretW0rd";
+    private static final String FEED_ID = "someFakeFeedId";
+    private static final String PUB_ID = "0";
+    private static FastJerseyTestContainer testContainer;
+    private static TestFeedCreator testFeedCreator;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        //TODO: init is still needed here to assure that dmaap is not null
+        DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+        testContainer = new FastJerseyTestContainer(new ResourceConfig()
+            .register(DR_PubResource.class)
+            .register(FeedResource.class));
+
+        testContainer.init();
+        testFeedCreator = new TestFeedCreator(testContainer);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        testContainer.destroy();
+        /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+        DatabaseClass.clearDatabase();
+        DatabaseClass.getDmaap().remove();*/
+    }
+
+    @Before
+    public void cleanupDatabase() {
+        DatabaseClass.clearDatabase();
+    }
+
+    @Test
+    public void getDr_Pub_test() {
+        Response resp = testContainer.target("dr_pubs").request().get(Response.class);
+        assertTrue(resp.getStatus() == 200);
+        assertTrue(resp.hasEntity());
+    }
+
+    @Test
+    public void addDr_Pub_shallReturnError_whenNoFeedIdAndFeedNameInPubProvided() {
+        //given
+        DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, PUB_ID);
+        Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(400, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("feedName", responseError.getFields());
+    }
+
+    @Test
+    public void addDr_Pub_shallReturnError_whenFeedNameProvided_butFeedNotExist() {
+        //given
+        DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, PUB_ID);
+        Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+        drPub.setFeedName("feed_name");
+
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(404, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("feedName", responseError.getFields());
+
+    }
+
+    @Test
+    public void addDr_Pub_shallReturnError_whenFeedIdProvided_butFeedNotExist() {
+        //given
+        DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, FEED_ID, PUB_ID);
+        Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(404, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("feedId=" + FEED_ID, responseError.getFields());
+    }
+
+    @Test
+    public void addDr_Pub_shallExecuteSuccessfully_whenValidFeedIdProvided() {
+        //given
+        String feedId = assureFeedIsInDB();
+        DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+        Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(201, resp.getStatus());
+    }
+
+    @Test
+    public void addDr_Pub_shallExecuteSuccessfully_whenValidFeedNameProvided() {
+        //given
+        String feedName = "testFeed";
+        testFeedCreator.addFeed(feedName, "test feed");
+        DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, PUB_ID);
+        drPub.setFeedName(feedName);
+        Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(201, resp.getStatus());
+    }
+
+    @Test
+    public void updateDr_Pub_shallExecuteSuccessfully_whenAddingNewPublisher() {
+        //given
+        String pubId = "5";
+        DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, "feedId", PUB_ID);
+        Entity<DR_Pub> reqEntity2 = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .path(pubId)
+            .request()
+            .put(reqEntity2, Response.class);
+
+        //then
+        assertEquals(200, resp.getStatus());
+
+    }
+
+    @Test
+    public void updateDr_Pub_shallReturnError_whenPathIsWrong() {
+        //given
+        DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, FEED_ID, PUB_ID);
+        Entity<DR_Pub> reqEntity2 = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .path("")
+            .request()
+            .put(reqEntity2, Response.class);
+
+        //then
+        assertEquals(405, resp.getStatus());
+    }
+
+    @Test
+    public void deleteDr_Pub_shouldDeleteObjectWithSuccess() {
+        //given
+        String feedId = assureFeedIsInDB();
+        DR_Pub dr_pub = addPub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .path(dr_pub.getPubId())
+            .request()
+            .delete();
+
+        //then
+        assertEquals("Shall delete subscription with success", 204, resp.getStatus());
+        assertFalse("No entity object shall be returned", resp.hasEntity());
+    }
+
+    @Test
+    public void deleteDr_Pub_shouldReturnErrorResponse_whenGivenPubIdNotFound() {
+        //given
+        String notExistingPubId = "6789";
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+            .path(notExistingPubId)
+            .request()
+            .delete();
+
+        //then
+        assertEquals("Shall return error, when trying to delete not existing subscription", 404, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("pubId", responseError.getFields());
+    }
+
+    @Test
+    public void get_shallReturnExistingObject() {
+        //given
+        String feedId = assureFeedIsInDB();
+        DR_Pub dr_Pub = addPub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+        //when
+        Response resp = testContainer.target("dr_pubs")
+                .path(dr_Pub.getPubId())
+                .request()
+                .get();
+
+        //then
+        assertEquals("Subscription shall be found", 200, resp.getStatus());
+        assertEquals("Retrieved object shall be equal to eh one put into DB", dr_Pub, resp.readEntity(DR_Pub.class));
+    }
 
+    private DR_Pub addPub(String d, String un, String up, String feedId) {
+        DR_Pub dr_pub = new DR_Pub(d, un, up, feedId, "");
+        Entity<DR_Pub> reqEntity2 = Entity.entity(dr_pub, MediaType.APPLICATION_JSON);
+        Response resp = testContainer.target("dr_pubs").request().post(reqEntity2, Response.class);
+        System.out.println("POST dr_pubs resp=" + resp.getStatus());
+        assertTrue(resp.getStatus() == 201);
+        dr_pub = resp.readEntity(DR_Pub.class);
+        return dr_pub;
+    }
 
+    private String assureFeedIsInDB() {
+        Feed feed = testFeedCreator.addFeed("SubscriberTestFeed", "feed for DR_Sub testing");
+        assertNotNull("Feed shall be added into DB properly", feed);
+        return feed.getFeedId();
+    }
 }
 
 
index 2227870..13b89ea 100644 (file)
@@ -1,9 +1,8 @@
-
 /*-
  * ============LICENSE_START=======================================================
  * org.onap.dmaap
  * ================================================================================
- * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * ============LICENSE_END=========================================================
  */
 package org.onap.dmaap.dbcapi.resources;
-import org.onap.dmaap.dbcapi.model.*;
-import org.onap.dmaap.dbcapi.service.*;
-import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
-
-import static org.junit.Assert.*;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import java.util.*;
-import java.sql.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.server.ResourceConfig;
 import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Response;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.Path;
-import javax.ws.rs.GET;
-
-public class DR_SubResourceTest extends JerseyTest{
-       
-       static DmaapObjectFactory factory = new DmaapObjectFactory();
-
-       @Override
-       protected Application configure() {
-               return new ResourceConfig()
-                               .register( DR_SubResource.class )
-                               .register( FeedResource.class )
-                               .register( DcaeLocationResource.class )
-                               .register( DmaapResource.class );
-       }
-
-       String d, un, up, f, p;
-       
-       @Before
-       public void preTest() throws Exception {
-               try {
-
-                       Dmaap dmaap = factory.genDmaap();
-                       Entity<Dmaap> reqEntity = Entity.entity( dmaap, MediaType.APPLICATION_JSON );
-                       Response resp = target( "dmaap").request().post( reqEntity, Response.class );
-                       System.out.println( resp.getStatus() );
-                       assertTrue( resp.getStatus() == 200 );
-               }catch (Exception e ) {
-               }
-               try {
-                       DcaeLocation loc = factory.genDcaeLocation( "central" );
-                       Entity<DcaeLocation> reqEntity = Entity.entity( loc, MediaType.APPLICATION_JSON );
-                       Response resp = target( "dcaeLocations").request().post( reqEntity, Response.class );
-                       System.out.println( "POST dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ));
-                       if ( resp.getStatus() != 409 ) {
-                               assertTrue( resp.getStatus() == 201 );
-                       }
-               } catch (Exception e ) {
-               }
-       
-
-       }
-/*
-       @Before
-       public void setUp() throws Exception {
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-               f = "234";
-               p = "678";
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-*/
-
-
-
-/*  may conflict with test framework! 
-       @Before
-       public void setUp() throws Exception {
-       }
-
-       @After
-       public void tearDown() throws Exception {
-       }
-*/
-
-       private Feed addFeed( String name, String desc ) {
-               Feed feed = new Feed( name, "1.0", desc, "dgl", "unrestricted" );
-               Entity<Feed> reqEntity = Entity.entity( feed, MediaType.APPLICATION_JSON );
-               Response resp = target( "feeds").request().post( reqEntity, Response.class );
-               int rc = resp.getStatus();
-               System.out.println( "POST feed resp=" + rc );
-               assertTrue( rc == 200 || rc == 409 );
-               feed = resp.readEntity( Feed.class );
-               return feed;
-       }
-       
-       private DR_Sub addSub( String d, String un, String up, String feedId ) {
-               DR_Sub dr_sub = new DR_Sub( d, un, up, feedId, 
-                               "https://subscriber.onap.org/foo", "https://dr-prov/sublog", true );
-
-               Entity<DR_Sub> reqEntity2 = Entity.entity( dr_sub, MediaType.APPLICATION_JSON);
-               Response resp = target( "dr_subs").request().post( reqEntity2, Response.class);
-               System.out.println( "POST dr_subs resp=" + resp.getStatus() );
-               assertTrue( resp.getStatus() == 201 );
-               dr_sub = resp.readEntity( DR_Sub.class );
-               
-               return dr_sub;
-       }
-       private DR_Sub addSubByName( String d, String un, String up, String feedName ) {
-               DR_Sub dr_sub = new DR_Sub( d, un, up, null, 
-                               "https://subscriber.onap.org/foo", "https://dr-prov/sublog", true );
-               
-               dr_sub.setFeedName(feedName);
-
-               Entity<DR_Sub> reqEntity2 = Entity.entity( dr_sub, MediaType.APPLICATION_JSON);
-               Response resp = target( "dr_subs").request().post( reqEntity2, Response.class);
-               System.out.println( "POST dr_subs resp=" + resp.getStatus() );
-               assertTrue( resp.getStatus() == 201 );
-               dr_sub = resp.readEntity( DR_Sub.class );
-               
-               return dr_sub;
-       }
-
-       @Test
-       public void GetTest() {
-               Response resp = target( "dr_subs").request().get( Response.class );
-               System.out.println( "GET dr_subs resp=" + resp.getStatus() );
-
-               assertTrue( resp.getStatus() == 200 );
-       }
-       
-       @Test
-       public void PostTest() {
-
-               Feed feed = addFeed( "subPostTest", "post unit test" );
-               System.out.println( "subPostTest: feedId=" + feed.getFeedId());
-               
-               String d, un, up;
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-
-               DR_Sub dr_pub = addSub( d, un, up, feed.getFeedId() );
-       }
-
-       @Test
-       public void PostTestByName() {
-
-               Feed feed = addFeed( "subPostTest2", "post unit test" );
-               System.out.println( "subPostTest2: feedId=" + feed.getFeedId());
-               
-               String d, un, up;
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-
-               DR_Sub dr_pub = addSubByName( d, un, up, feed.getFeedName() );
-       }
-
-       @Test
-       public void PutTest() {
-
-               Feed feed = addFeed( "subPutTest", "put unit test");
-               String d, un, up;
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-
-               DR_Sub dr_sub = addSub( d, un, up, feed.getFeedId() );
-               
-               dr_sub.setUserpwd("newSecret");
-               Entity<DR_Sub> reqEntity2 = Entity.entity( dr_sub, MediaType.APPLICATION_JSON);
-               Response resp = target( "dr_subs")
-                               .path( dr_sub.getSubId() )
-                               .request()
-                               .put( reqEntity2, Response.class);
-               System.out.println( "PUT dr_subs resp=" + resp.getStatus() );
-               assertTrue( resp.getStatus() == 200 );
-       }
-
-/*
- * TODO: figure out how to check delete() response
-       @Test
-       public void DelTest() {
-
-               Feed feed = addFeed( "subDelTest", "del unit test");
-               String d, un, up;
-               d = "central-onap";
-               un = "user1";
-               up = "secretW0rd";
-
-               DR_Sub dr_sub = addSub( d, un, up, feed.getFeedId() );
-               
-               Entity<DR_Sub> reqEntity2 = Entity.entity( dr_sub, MediaType.APPLICATION_JSON);
-               Response resp = target( "dr_subs")
-                               .path( dr_sub.getSubId() )
-                               .request()
-                               .delete();
-               System.out.println( "DEL dr_subs resp=" + resp.getStatus() );
-               assertTrue( resp.getStatus() == 200 );
-       }
-*/
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Sub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
 
+public class DR_SubResourceTest {
+
+    private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+
+    private static final String DCAE_LOCATION_NAME = "central-onap";
+    private static final String USERNAME = "user1";
+    private static final String USRPWD = "secretW0rd";
+    private static final String DELIVERY_URL = "https://subscriber.onap.org/delivery/id";
+    private static final String LOG_URL = "https://dr-prov/sublog/id";
+    private static final String DELIVERY_URL_TEMPLATE = "https://subscriber.onap.org/delivery/";
+    private static final String LOG_URL_TEMPLATE = "https://dr-prov/sublog/";
+    private static FastJerseyTestContainer testContainer;
+    private static TestFeedCreator testFeedCreator;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        //TODO: init is still needed here to assure that dmaap is not null
+        DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+        testContainer = new FastJerseyTestContainer(new ResourceConfig()
+            .register(DR_SubResource.class)
+            .register(FeedResource.class));
+        testContainer.init();
+        testFeedCreator = new TestFeedCreator(testContainer);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        testContainer.destroy();
+        /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+        DatabaseClass.clearDatabase();
+        DatabaseClass.getDmaap().remove();*/
+    }
+
+    @Before
+    public void cleanupDatabase() {
+        DatabaseClass.clearDatabase();
+    }
+
+    //TODO: figure out generic entity list unmarshall to check the entity list
+    @Test
+    public void getDr_Subs_test() {
+        Response resp = testContainer.target("dr_subs").request().get(Response.class);
+        System.out.println("GET dr_subs resp=" + resp.getStatus());
+
+        assertEquals(200, resp.getStatus());
+        assertTrue(resp.hasEntity());
+    }
+
+    @Test
+    public void addDr_Sub_shallReturnError_whenNoFeedIdAndFeedNameInSubProvided() {
+        //given
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(400, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("feedName", responseError.getFields());
+    }
+
+    @Test
+    public void addDr_Sub_shallReturnError_whenFeedNameProvided_butFeedNotExist() {
+        //given
+        String notExistingFeedName = "notRealFead";
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+        drSub.setFeedName(notExistingFeedName);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(404, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("feedName", responseError.getFields());
+    }
+
+    @Test
+    public void addDr_Sub_shallReturnError_whenFeedNameProvided_andManyFeedsWithTheSameNameInDB() {
+        //given
+        String notDistinctFeedName = "notDistinctFeedName";
+        Feed feed1 = new Feed(notDistinctFeedName, "1.0", "description", "dgl", "unrestricted");
+        Feed feed2 = new Feed(notDistinctFeedName, "2.0", "description", "dgl", "unrestricted");
+        DatabaseClass.getFeeds().put("1", feed1);
+        DatabaseClass.getFeeds().put("2", feed2);
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+        drSub.setFeedName(notDistinctFeedName);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(409, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("feedName", responseError.getFields());
+    }
+
+    @Test
+    public void addDr_Sub_shallReturnError_whenFeedIdProvided_butFeedNotExist() {
+        //given
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, "someFakeFeedId", DELIVERY_URL, LOG_URL, true);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(404, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertTrue(responseError.getFields().contains("feedId"));
+    }
+
+    @Test
+    public void addDr_Sub_shallExecuteSuccessfully_whenValidFeedIdProvided() {
+        //given
+        String feedId = assureFeedIsInDB();
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId, DELIVERY_URL, LOG_URL, true);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(201, resp.getStatus());
+        assertTrue(resp.hasEntity());
+        DR_Sub created = resp.readEntity(DR_Sub.class);
+        assertSubscriptionExistInDB(created);
+    }
+
+    @Test
+    public void addDr_Sub_shallExecuteSuccessfully_whenValidFeedNameProvided() {
+        //given
+        String feedName = "testFeed";
+        testFeedCreator.addFeed(feedName, "test feed");
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+        drSub.setFeedName(feedName);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .request()
+            .post(requestedEntity, Response.class);
+
+        //then
+        assertEquals(201, resp.getStatus());
+        assertTrue(resp.hasEntity());
+        DR_Sub created = resp.readEntity(DR_Sub.class);
+        assertSubscriptionExistInDB(created);
+    }
+
+
+    @Test
+    public void updateDr_Sub_shallReturnError_whenNoFeedIdInSubProvided() {
+        //given
+        String subId = "1234";
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(subId)
+            .request()
+            .put(requestedEntity, Response.class);
+
+        //then
+        assertEquals(400, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("feedId", responseError.getFields());
+    }
+
+    @Test
+    public void updateDr_Sub_shallReturnError_whenNoDCAELocationInSubProvided() {
+        //given
+        String subId = "1234";
+        DR_Sub drSub = new DR_Sub(null, USERNAME, USRPWD, "someFeedId", DELIVERY_URL, LOG_URL, true);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(subId)
+            .request()
+            .put(requestedEntity, Response.class);
+
+        //then
+        assertEquals(400, resp.getStatus());
+        ApiError responseError = resp.readEntity(ApiError.class);
+        assertNotNull(responseError);
+        assertEquals("dcaeLocationName", responseError.getFields());
+    }
+
+    @Test
+    public void updateDr_Sub_shallReturnError_whenFeedWithGivenIdInSubNotExists() {
+        //given
+        String subId = "1234";
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, "someFeedId", DELIVERY_URL, LOG_URL, true);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(subId)
+            .request()
+            .put(requestedEntity, Response.class);
+
+        //then
+        assertEquals(404, resp.getStatus());
+        assertNotNull(resp.readEntity(ApiError.class));
+    }
+
+    @Test
+    public void updateDr_Sub_shallReturnSuccess_whenAddingNewSubscription() {
+        //given
+        String subId = "31";
+        String feedId = assureFeedIsInDB();
+        DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId, null, null, true);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(subId)
+            .request()
+            .put(requestedEntity, Response.class);
+
+        //then
+        assertEquals(200, resp.getStatus());
+
+        DR_Sub createdDrSub = resp.readEntity(DR_Sub.class);
+        assertNotNull(createdDrSub.getLastMod());
+        assertEquals(subId, createdDrSub.getSubId());
+        assertEquals(DCAE_LOCATION_NAME, createdDrSub.getDcaeLocationName());
+        assertEquals(USERNAME, createdDrSub.getUsername());
+        assertEquals(USRPWD, createdDrSub.getUserpwd());
+        assertEquals(DELIVERY_URL_TEMPLATE + subId, createdDrSub.getDeliveryURL());
+        assertEquals(LOG_URL_TEMPLATE + subId, createdDrSub.getLogURL());
+
+        assertSubscriptionExistInDB(createdDrSub);
+    }
+
+    @Test
+    public void updateDr_Sub_shallReturnSuccess_whenUpdatingExistingSubscription() {
+        //given
+        String feedId = assureFeedIsInDB();
+        DR_Sub existingDrSub = addSub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+        DR_Sub drSubUpdate = new DR_Sub("newDcaeLocationName", "newUserName", "newUserPwd", feedId, null, null, false);
+        Entity<DR_Sub> requestedEntity = Entity.entity(drSubUpdate, MediaType.APPLICATION_JSON);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(existingDrSub.getSubId())
+            .request()
+            .put(requestedEntity, Response.class);
+
+        //then
+        assertEquals(200, resp.getStatus());
+
+        DR_Sub updatedDrSub = resp.readEntity(DR_Sub.class);
+        assertNotNull(updatedDrSub.getLastMod());
+        assertEquals(existingDrSub.getSubId(), updatedDrSub.getSubId());
+        assertEquals(drSubUpdate.getDcaeLocationName(), updatedDrSub.getDcaeLocationName());
+        assertEquals(drSubUpdate.getUsername(), updatedDrSub.getUsername());
+        assertEquals(drSubUpdate.getUserpwd(), updatedDrSub.getUserpwd());
+        assertEquals(DELIVERY_URL_TEMPLATE + existingDrSub.getSubId(), updatedDrSub.getDeliveryURL());
+        assertEquals(LOG_URL_TEMPLATE + existingDrSub.getSubId(), updatedDrSub.getLogURL());
+
+        assertSubscriptionExistInDB(updatedDrSub);
+    }
+
+    @Test
+    public void deleteDr_Sub_shouldDeleteSubscriptionWithSuccess() {
+        //given
+        String feedId = assureFeedIsInDB();
+        DR_Sub dr_sub = addSub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(dr_sub.getSubId())
+            .request()
+            .delete();
+
+        //then
+        assertEquals("Shall delete subscription with success", 204, resp.getStatus());
+        assertFalse("No entity object shall be returned",resp.hasEntity());
+        assertSubscriptionNotExistInDB(dr_sub.getSubId());
+    }
+
+    @Test
+    public void deleteDr_Sub_shouldReturnErrorResponse_whenGivenSubIdNotFound() {
+        //given
+        String notExistingSubId = "6789";
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(notExistingSubId)
+            .request()
+            .delete();
+
+        //then
+        assertEquals("Shall return error, when trying to delete not existing subscription", 404, resp.getStatus());
+        assertNotNull(resp.readEntity(ApiError.class));
+    }
+
+    @Test
+    public void get_shallReturnExistingObject() {
+        //given
+        String feedId = assureFeedIsInDB();
+        DR_Sub dr_sub = addSub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(dr_sub.getSubId())
+            .request()
+            .get();
+
+        //ten
+        assertEquals("Subscription shall be found",200, resp.getStatus());
+        assertEquals("Retrieved object shall be equal to eh one put into DB", dr_sub, resp.readEntity(DR_Sub.class));
+    }
+
+    @Test
+    public void get_shouldReturnError_whenSubWithIdNotFound() {
+        //given
+        String notExistingSubId = "1234";
+
+        //when
+        Response resp = testContainer.target("dr_subs")
+            .path(notExistingSubId)
+            .request()
+            .get();
+
+        //then
+        assertEquals("Subscription shall not be found", 404, resp.getStatus());
+        assertNotNull(resp.readEntity(ApiError.class));
+    }
+
+    private DR_Sub addSub(String d, String un, String up, String feedId) {
+        DR_Sub dr_sub = new DR_Sub(d, un, up, feedId,
+            "https://subscriber.onap.org/foo", "https://dr-prov/sublog", true);
+
+        Entity<DR_Sub> reqEntity2 = Entity.entity(dr_sub, MediaType.APPLICATION_JSON);
+        Response resp = testContainer.target("dr_subs").request().post(reqEntity2, Response.class);
+        System.out.println("POST dr_subs resp=" + resp.getStatus());
+        assertEquals(201, resp.getStatus());
+        dr_sub = resp.readEntity(DR_Sub.class);
+
+        return dr_sub;
+    }
+
+    private String assureFeedIsInDB() {
+        Feed feed = testFeedCreator.addFeed("SubscriberTestFeed", "feed for DR_Sub testing");
+        assertNotNull("Feed shall be added into DB properly", feed);
+        return feed.getFeedId();
+    }
+
+
+    private void assertSubscriptionNotExistInDB(String subId) {
+        assertEquals(404, testContainer.target("dr_subs")
+            .path(subId)
+            .request()
+            .get()
+            .getStatus());
+    }
+
+    private void assertSubscriptionExistInDB(DR_Sub sub) {
+        Response response = testContainer.target("dr_subs")
+            .path(sub.getSubId())
+            .request()
+            .get();
+        assertEquals(200, response.getStatus());
+        assertTrue(response.hasEntity());
+        assertEquals(sub, response.readEntity(DR_Sub.class));
+    }
 }
 
 
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/FastJerseyTestContainer.java b/src/test/java/org/onap/dmaap/dbcapi/resources/FastJerseyTestContainer.java
new file mode 100644 (file)
index 0000000..8d38a9f
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.resources;
+
+import org.glassfish.jersey.test.JerseyTest;
+
+import javax.ws.rs.core.Application;
+
+class FastJerseyTestContainer extends JerseyTest {
+
+    FastJerseyTestContainer(Application jaxrsApplication) {
+        super(jaxrsApplication);
+    }
+
+    void init() throws Exception {
+        this.setUp();
+    }
+
+    void destroy() throws Exception {
+        this.tearDown();
+    }
+}
\ No newline at end of file
index e4d1da0..7367471 100644 (file)
@@ -28,7 +28,9 @@ import javax.ws.rs.core.Response;
 
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Before;
 import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
 import org.onap.dmaap.dbcapi.model.DcaeLocation;
 import org.onap.dmaap.dbcapi.model.MR_Cluster;
 import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
@@ -50,11 +52,12 @@ public class MR_ClusterResourceTest extends JerseyTest {
 
 
 
-/*  may conflict with test framework! 
+
        @Before
-       public void preTest() throws Exception {
+       public void init() throws Exception {
+               DatabaseClass.clearDatabase();
        }
-
+/*
        @After
        public void tearDown() throws Exception {
        }
@@ -75,7 +78,7 @@ public class MR_ClusterResourceTest extends JerseyTest {
                Response resp = target( "mr_clusters").request().post( reqEntity, Response.class );
                System.out.println( "POST MR_Cluster resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
                if (resp.getStatus() != 409 ) {
-                       assertTrue( resp.getStatus() == 201);
+                       assertTrue( resp.getStatus() >= 200 && resp.getStatus() < 300);
                }
                resp = target( "mr_clusters").
                                path( cluster.getDcaeLocationName()).request().get( Response.class );
@@ -94,7 +97,7 @@ public class MR_ClusterResourceTest extends JerseyTest {
                        Response resp = target( "dcaeLocations").request().post( reqEntity, Response.class );
                        System.out.println( "POST dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ));
                        if ( resp.getStatus() != 409 ) {
-                               assertTrue( resp.getStatus() == 201 );
+                               assertTrue( resp.getStatus() >= 200 && resp.getStatus() < 300 );
                        }
                } catch (Exception e ) {
                }
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilterTest.java b/src/test/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilterTest.java
new file mode 100644 (file)
index 0000000..0c88c0c
--- /dev/null
@@ -0,0 +1,78 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * org.onap.dmaap\r
+ * ================================================================================\r
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+package org.onap.dmaap.dbcapi.resources;\r
+\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.mockito.Matchers.anyString;\r
+import static org.mockito.Matchers.eq;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import java.time.Clock;\r
+import java.time.Instant;\r
+import java.time.ZoneId;\r
+import javax.ws.rs.container.ContainerRequestContext;\r
+import javax.ws.rs.container.ContainerResponseContext;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.mockito.Mock;\r
+import org.mockito.runners.MockitoJUnitRunner;\r
+\r
+@RunWith(MockitoJUnitRunner.class)\r
+public class RequestTimeLogFilterTest {\r
+\r
+    private Clock clock ;\r
+    private RequestTimeLogFilter requestTimeLogFilter;\r
+    public static final long START = 1L;\r
+    @Mock\r
+    private ContainerRequestContext requestContext;\r
+    @Mock\r
+    private ContainerResponseContext responseContext;\r
+    @Mock\r
+    private EELFLogger logger;\r
+\r
+\r
+    @Before\r
+    public void setup() {\r
+        clock = Clock.fixed(Instant.parse("1970-01-01T00:00:10Z"), ZoneId.systemDefault());\r
+        requestTimeLogFilter = new RequestTimeLogFilter(logger, clock);\r
+    }\r
+\r
+    @Test\r
+    public void shouldHaveDefaultConstructor() {\r
+        assertNotNull(new RequestTimeLogFilter());\r
+    }\r
+\r
+    @Test\r
+    public void filterShouldSetStartTimestampProperty() {\r
+        requestTimeLogFilter.filter(requestContext);\r
+        verify(requestContext).setProperty("start",clock.millis());\r
+    }\r
+\r
+    @Test\r
+    public void filterShouldPrintElapsedTime() {\r
+        when(requestContext.getProperty("start")).thenReturn(START);\r
+\r
+        requestTimeLogFilter.filter(requestContext, responseContext);\r
+\r
+        verify(logger).info(anyString(),eq(clock.millis() - START));\r
+    }\r
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredCheckerTest.java b/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredCheckerTest.java
new file mode 100644 (file)
index 0000000..f07058b
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dmaap.dbcapi.resources;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static org.junit.Assert.fail;
+
+public class RequiredCheckerTest {
+
+    private static final String NAME = "field_name";
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+    private RequiredChecker requiredChecker = new RequiredChecker();
+
+
+    @Test
+    public void required_shouldThrowExceptionWhenObjectIsNull() throws RequiredFieldException {
+        thrown.expect(RequiredFieldException.class);
+        thrown.expect(new ApiErrorMatcher(new ApiError(BAD_REQUEST.getStatusCode(),
+                "missing required field", NAME)));
+
+        requiredChecker.required(NAME, null);
+    }
+
+    @Test
+    public void required_shouldThrowExceptionWhenRegexValidationFailed() throws RequiredFieldException {
+        thrown.expect(RequiredFieldException.class);
+        thrown.expect(new ApiErrorMatcher(new ApiError(BAD_REQUEST.getStatusCode(),
+                "value 'with white space' violates regexp check '^\\S+$'", NAME)));
+
+        requiredChecker.required(NAME, "with white space", "^\\S+$");
+    }
+
+    @Test
+    public void required_shouldPassValidation() {
+        try {
+            requiredChecker.required(NAME, "value", "^\\S+$");
+        } catch (RequiredFieldException e) {
+            fail("No exception should be thrown");
+        }
+    }
+
+    class ApiErrorMatcher extends BaseMatcher {
+
+        private final ApiError expectedApiEror;
+
+        ApiErrorMatcher(ApiError expectedApiEror) {
+            this.expectedApiEror = expectedApiEror;
+        }
+
+        @Override
+        public boolean matches(Object exception) {
+            return expectedApiEror.equals(((RequiredFieldException) exception).getApiError());
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Following ApiError is expected: ").appendValue(expectedApiEror);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredFieldExceptionTest.java b/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredFieldExceptionTest.java
new file mode 100644 (file)
index 0000000..d3dcc42
--- /dev/null
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dmaap.dbcapi.resources;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+public class RequiredFieldExceptionTest {
+    ApiError apiError;
+    RequiredFieldException requiredFieldException;
+    String expectedValue;
+
+    @Before
+    public void setUp() {
+        apiError = new ApiError(BAD_REQUEST.getStatusCode(), "value 'with white space' violates regexp check '^\\S+$'",
+                "field_name");
+
+        expectedValue = "RequiredFieldException{" + "apiError=" + apiError + '}';
+
+        requiredFieldException = new RequiredFieldException(apiError);
+    }
+
+    @Test
+    public void testRequiredFieldExceptionToString() {
+        assertEquals(expectedValue, requiredFieldException.toString());
+    }
+}
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/ResponseBuilderTest.java b/src/test/java/org/onap/dmaap/dbcapi/resources/ResponseBuilderTest.java
new file mode 100644 (file)
index 0000000..ff61d14
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dmaap.dbcapi.resources;
+
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+import javax.ws.rs.core.Response;
+
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE;
+import static javax.ws.rs.core.Response.Status.UNAUTHORIZED;
+import static org.junit.Assert.assertEquals;
+
+public class ResponseBuilderTest {
+
+    private static final String OBJECT = "Objcect";
+    private static final String MESSAGE = "msg";
+    private static final int CODE = 100;
+    private ResponseBuilder responseBuilder = new ResponseBuilder();
+
+    @Test
+    public void success_shouldCreateResponseWithOKStatusCode() {
+
+        Response response = responseBuilder.success(OBJECT);
+
+        assertEquals(OBJECT, response.getEntity());
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+    }
+
+    @Test
+    public void success_shouldCreateResponseWithDefinedStatusCode() {
+
+        Response response = responseBuilder.success(CODE, OBJECT);
+
+        assertEquals(OBJECT, response.getEntity());
+        assertEquals(CODE, response.getStatus());
+    }
+
+    @Test
+    public void unauthorized_shouldCreateCorrectResponse() {
+
+        ApiError error = new ApiError(UNAUTHORIZED.getStatusCode(), MESSAGE, "Authorization");
+        Response response = responseBuilder.unauthorized(MESSAGE);
+
+        assertEquals(error, response.getEntity());
+        assertEquals(error.getCode(), response.getStatus());
+    }
+
+    @Test
+    public void unavailable_shouldCreateCorrectResponse() {
+
+        ApiError error = new ApiError(SERVICE_UNAVAILABLE.getStatusCode(),
+                "Request is unavailable due to unexpected condition");
+        Response response = responseBuilder.unavailable();
+
+        assertEquals(error, response.getEntity());
+        assertEquals(error.getCode(), response.getStatus());
+    }
+
+    @Test
+    public void notFound_shouldCreateCorrectResponse() {
+        ApiError error = new ApiError(NOT_FOUND.getStatusCode(), "Requested object not found");
+        Response response = responseBuilder.notFound();
+
+        assertEquals(error, response.getEntity());
+        assertEquals(error.getCode(), response.getStatus());
+    }
+
+    @Test
+    public void error_shouldCreateCorrectResponse() {
+        ApiError error = new ApiError(CODE, "Some Error");
+        Response response = responseBuilder.error(error);
+
+        assertEquals(error, response.getEntity());
+        assertEquals(error.getCode(), response.getStatus());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onap/dmaap/dbcapi/resources/TestFeedCreator.java b/src/test/java/org/onap/dmaap/dbcapi/resources/TestFeedCreator.java
new file mode 100644 (file)
index 0000000..e4dedb1
--- /dev/null
@@ -0,0 +1,49 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * org.onap.dmaap\r
+ * ================================================================================\r
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+package org.onap.dmaap.dbcapi.resources;\r
+\r
+import static org.junit.Assert.assertTrue;\r
+\r
+import javax.ws.rs.client.Entity;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import org.onap.dmaap.dbcapi.model.Feed;\r
+\r
+\r
+public class TestFeedCreator {\r
+\r
+\r
+    private final FastJerseyTestContainer testContainer;\r
+\r
+    public TestFeedCreator(FastJerseyTestContainer testContainer) {\r
+        this.testContainer = testContainer;\r
+    }\r
+\r
+    Feed addFeed(String name, String desc) {\r
+        Feed feed = new Feed(name, "1.0", desc, "dgl", "unrestricted");\r
+        Entity<Feed> reqEntity = Entity.entity(feed, MediaType.APPLICATION_JSON);\r
+        Response resp = testContainer.target("feeds").request().post(reqEntity, Response.class);\r
+        int rc = resp.getStatus();\r
+        System.out.println("POST feed resp=" + rc);\r
+        assertTrue(rc == 200 || rc == 409);\r
+        feed = resp.readEntity(Feed.class);\r
+        return feed;\r
+    }\r
+}\r
index b494a59..88840fe 100644 (file)
@@ -30,6 +30,7 @@ import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.Before;
 import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
 import org.onap.dmaap.dbcapi.model.DcaeLocation;
 import org.onap.dmaap.dbcapi.model.Dmaap;
 import org.onap.dmaap.dbcapi.model.MR_Cluster;
@@ -54,15 +55,14 @@ public class TopicResourceTest extends JerseyTest {
        private static final String  fmt = "%24s: %s%n";
 
 
-
-
        @Before
        public void preTest() throws Exception {
+               DatabaseClass.clearDatabase();
                try {
 
                        Dmaap dmaap = factory.genDmaap();
                        Entity<Dmaap> reqEntity = Entity.entity( dmaap, MediaType.APPLICATION_JSON );
-                       Response resp = target( "dmaap").request().post( reqEntity, Response.class );
+                       Response resp = target( "dmaap").request().put( reqEntity, Response.class );
                        System.out.println( resp.getStatus() );
                        assertTrue( resp.getStatus() == 200 );
                }catch (Exception e ) {
@@ -83,7 +83,7 @@ public class TopicResourceTest extends JerseyTest {
                        Response resp = target( "mr_clusters").request().post( reqEntity, Response.class );
                        System.out.println( "POST MR_Cluster resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
                        if (resp.getStatus() != 409 ) {
-                               assertTrue( resp.getStatus() == 201);
+                               assertTrue( resp.getStatus() == 20);
                        }       
                } catch (Exception e ) {
                        
index 67489e1..dccfadf 100644 (file)
  */
 package org.onap.dmaap.dbcapi.service;
 
-import  org.onap.dmaap.dbcapi.model.*;
-import  org.onap.dmaap.dbcapi.aaf.*;
 import org.onap.dmaap.dbcapi.authentication.AuthenticationErrorException;
 import org.onap.dmaap.dbcapi.resources.*;
 import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
 
-import static org.junit.Assert.*;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import java.util.List;
-import javax.ws.rs.core.Response;
 
 public class ApiServiceTest {
 
@@ -55,8 +49,8 @@ public class ApiServiceTest {
        public void test1() {
 
 
-               //rh.reflect( "org.onap.dmaap.dbcapi.service.ApiService", "get", null );        
-       
+               //rh.reflect( "org.onap.dmaap.dbcapi.service.ApiService", "get", null );
+
        }
 
        @Test
@@ -65,28 +59,4 @@ public class ApiServiceTest {
                rh.reflect( "org.onap.dmaap.dbcapi.service.ApiService", "set", v );
 
        }
-
-       @Test
-       public void test3() {
-               ApiService nd = new ApiService();
-               nd.setAuth( "auth" );
-               try {
-                       nd.required( "aName", null, "anExpr" );
-               } catch ( RequiredFieldException rfe ) {
-               }
-               String out = nd.toString();     
-               Response r = nd.unauthorized( "aMessage" );
-               r = nd.unauthorized();
-               r = nd.unavailable();
-               r = nd.notFound();
-               r = nd.error();
-               try {
-                       nd.checkAuthorization( "authval", "/uri/Path", "GET" );
-                       nd.checkAuthorization();
-               } catch ( AuthenticationErrorException aee ) {
-               } catch ( Exception e ) {
-               }
-       }
-
-
 }
index 7029bd2..c1fa0fd 100644 (file)
  */
 package org.onap.dmaap.dbcapi.service;
 
-import  org.onap.dmaap.dbcapi.model.*;
-import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
-import  org.onap.dmaap.dbcapi.aaf.*;
-
-import static org.junit.Assert.*;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import java.util.List;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
 
 public class DmaapServiceTest {
 
index d601bc4..acbc738 100644 (file)
@@ -95,5 +95,14 @@ public class FeedServiceTest {
 
        }
 
+       
+       @Test 
+       public void syncTestHard() {
+               ApiError err = new ApiError();
+               ds.sync(  true, err );
+               
+               assert( 200 == err.getCode());
+       }
+
 
 }
index 8fd7b47..f571520 100644 (file)
@@ -20,6 +20,7 @@
 package org.onap.dmaap.dbcapi.service;
 
 import  org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
 import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
 
 import static org.junit.Assert.*;
@@ -33,17 +34,42 @@ import java.util.ArrayList;
 public class TopicServiceTest {
 
        private static final String  fmt = "%24s: %s%n";
-
+       private static DmaapObjectFactory factory = new DmaapObjectFactory();
        ReflectionHarness rh = new ReflectionHarness();
 
-       TopicService ts;
-       MR_ClusterService mcs;
-       String locname = "central-onap";
+       private TopicService ts;
+       private MR_ClusterService mcs;
+       private MR_ClientService cls;
+       private DcaeLocationService dls;
+
+       DmaapService ds;
+       String locname;
 
        @Before
        public void setUp() throws Exception {
+               ts = new TopicService();
+               assert( ts != null );
+               mcs = new MR_ClusterService();
+               assert( mcs != null );
+               Dmaap nd = factory.genDmaap();
+               ds = new DmaapService();
+               ds.addDmaap( nd );
                ts = new TopicService();
                mcs = new MR_ClusterService();
+               cls = new MR_ClientService();
+
+               dls = new DcaeLocationService();
+               DcaeLocation loc = factory.genDcaeLocation( "central" );
+               locname = loc.getDcaeLocationName();
+               dls.addDcaeLocation( loc );
+               loc = factory.genDcaeLocation( "edge");
+
+               ApiError err = new ApiError();
+               
+               MR_Cluster node = factory.genMR_Cluster( "central" );
+               mcs.addMr_Cluster( node, err);
+               node = factory.genMR_Cluster("edge" );
+               mcs.addMr_Cluster(node,  err);
        }
 
        @After
@@ -68,32 +94,31 @@ public class TopicServiceTest {
 
        @Test
        public void test3() {
-               Topic topic = new Topic();
+               String t = "test3";
+               Topic topic = factory.genSimpleTopic( t );
                ApiError err = new ApiError();
-               topic.setTopicName( "test3" );
-               topic.setFqtnStyle( FqtnType.Validator("none") );
-               topic.getFqtn();
+               
                Topic nTopic = ts.addTopic( topic, err, false );
                if ( nTopic != null ) {
-                       assertTrue( nTopic.getTopicName().equals( topic.getTopicName() ));
+                       assertTrue( nTopic.getTopicName().equals( t ));
                }
 
        }
 
        @Test
        public void test3a() {
-               Topic topic = new Topic();
+
+
                ApiError err = new ApiError();
-               topic.setTopicName( "test3" );
-               topic.setFqtnStyle( FqtnType.Validator("none") );
-               topic.getFqtn();
+
                String t = "org.onap.dmaap.interestingTopic";
+               Topic topic = factory.genSimpleTopic(t);
                String f = "mrc.onap.org:3904/events/org.onap.dmaap.interestingTopic";
                String c = "publisher";
                String[] a = { "sub", "view" };
-               MR_Client sub = new MR_Client( locname, f, c, a );
+               MR_Client sub = factory.genMR_Client("central",  f, c, a );
                String[] b = { "pub", "view" };
-               MR_Client pub = new MR_Client( "edge", f, c, b );
+               MR_Client pub = factory.genMR_Client( "edge", f, c, b );
                ArrayList<MR_Client> clients = new ArrayList<MR_Client>();
 
                clients.add( sub );
@@ -106,7 +131,7 @@ public class TopicServiceTest {
                
                Topic nTopic = ts.addTopic( topic, err, false );
                if ( nTopic != null ) {
-                       assertTrue( nTopic.getTopicName().equals( topic.getTopicName() ));
+                       assertTrue( nTopic.getTopicName().equals( t ));
                }
                
 
@@ -122,21 +147,60 @@ public class TopicServiceTest {
        @Test
        public void test5() {
                ApiError err = new ApiError();
-/*
-
-TODO: find a null pointer in here...
-               String[] hl = { "host1", "host2", "host3" };
-               String loc = "central-onap";
-               MR_Cluster cluster = new MR_Cluster( loc, "localhost", "", hl );
-               mcs.addMr_Cluster( cluster, err );
-               Topic topic = new Topic();
-               topic.setTopicName( "test5" );
-               topic.setFqtnStyle( FqtnType.Validator("none") );
-               topic.setReplicationCase( ReplicationType.Validator("none") );
-               String f = topic.getFqtn();
+
+               Topic topic = factory.genSimpleTopic("test5");
                Topic nTopic = ts.updateTopic( topic, err );
-*/
-               assertTrue( err.getCode() == 0 );
+
+               assertTrue( err.getCode() == 200 );
+       }
+       
+       @Test
+       public void bridgeTest6() {
+               ApiError err = new ApiError();
+
+               String t = "org.onap.dmaap.bridgingTopic";
+               Topic topic = factory.genSimpleTopic(t);
+               topic.setReplicationCase( ReplicationType.REPLICATION_EDGE_TO_CENTRAL );
+
+               String c = "publisher";
+               String[] a = { "sub", "view" };
+               MR_Client sub = factory.genMR_Client("central",  topic.getFqtn(), c, a );
+               String[] b = { "pub", "view" };
+               MR_Client pub = factory.genMR_Client( "edge", topic.getFqtn(), c, b );
+               ArrayList<MR_Client> clients = new ArrayList<MR_Client>();
+
+               clients.add( sub );
+               clients.add( pub );
+
+               topic.setClients( clients );
+
+               Topic nTopic = ts.updateTopic( topic, err );
+
+               assertTrue( err.getCode() == 200 );
+       }
+       @Test
+       public void bridgeTest7() {
+               ApiError err = new ApiError();
+
+               String t = "org.onap.dmaap.bridgingTopic7";
+               Topic topic = factory.genSimpleTopic(t);
+               topic.setReplicationCase( ReplicationType.REPLICATION_CENTRAL_TO_EDGE );
+
+               String c = "publisher";
+               String[] a = { "sub", "view" };
+               MR_Client sub = factory.genMR_Client("edge",  topic.getFqtn(), c, a );
+               String[] b = { "pub", "view" };
+               MR_Client pub = factory.genMR_Client( "central", topic.getFqtn(), c, b );
+               ArrayList<MR_Client> clients = new ArrayList<MR_Client>();
+
+               clients.add( sub );
+               clients.add( pub );
+
+               topic.setClients( clients );
+
+               Topic nTopic = ts.updateTopic( topic, err );
+
+               assertTrue( err.getCode() == 200 );
        }
 
 }
index 0bce106..901b4ea 100644 (file)
@@ -99,6 +99,7 @@ public class DmaapObjectFactory {
         t.setFqtnStyle( FqtnType.Validator("none") );
         t.setTopicDescription( "a simple Topic named " + tname );
         t.setOwner( "ut");
+        t.setFqtn(t.genFqtn());
                return t;
        }
 
diff --git a/src/test/java/org/onap/dmaap/dbcapi/util/PermissionBuilderTest.java b/src/test/java/org/onap/dmaap/dbcapi/util/PermissionBuilderTest.java
new file mode 100644 (file)
index 0000000..1858e47
--- /dev/null
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dmaap.dbcapi.util;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+
+@RunWith(MockitoJUnitRunner.class)
+public class PermissionBuilderTest {
+
+    private static final String DMAAP_NAME = "mr";
+    private PermissionBuilder permissionBuilder;
+    @Mock
+    private DmaapConfig dmaapConfig;
+    @Mock
+    private DmaapService dmaapService;
+    @Mock
+    private HttpServletRequest request;
+
+
+    @Test
+    public void updateDmaapInstance_shouldSetBootInstance_whenDmaapIsNotInitialized() {
+        //given
+        doReturn(null).when(dmaapService).getDmaap();
+        permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+        //when
+        permissionBuilder.updateDmaapInstance();
+
+        //then
+        assertEquals(PermissionBuilder.BOOT_INSTANCE, permissionBuilder.getInstance());
+    }
+
+    @Test
+    public void updateDmaapInstance_shouldSetBootInstance_whenDmaapIsInitializedWithDefaultInstance() {
+        //given
+        doReturn(provideDefaultInstance()).when(dmaapService).getDmaap();
+        permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+        //when
+        permissionBuilder.updateDmaapInstance();
+
+        //then
+        assertEquals(PermissionBuilder.BOOT_INSTANCE, permissionBuilder.getInstance());
+    }
+
+    @Test
+    public void updateDmaapInstance_shouldSetRealInstance_whenDmaapServiceProvidesOne() {
+        //given
+        when(dmaapService.getDmaap()).thenReturn(provideDefaultInstance(), provideRealInstance(DMAAP_NAME));
+        permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+        //when
+        permissionBuilder.updateDmaapInstance();
+
+        //then
+        assertEquals(DMAAP_NAME, permissionBuilder.getInstance());
+    }
+
+    @Test
+    public void updateDmaapInstance_shouldNotUpdateDmaapInstance_whenAlreadyInitializedWithRealInstance() {
+        //given
+        when(dmaapService.getDmaap()).thenReturn(provideRealInstance(DMAAP_NAME), provideRealInstance("newName"));
+        permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+        //when
+        permissionBuilder.updateDmaapInstance();
+
+        //then
+        assertEquals(DMAAP_NAME, permissionBuilder.getInstance());
+        verify(dmaapService, atMost(1)).getDmaap();
+    }
+
+    @Test
+    public void buildPermission_shouldBuildPermissionWithBootInstance() {
+        //given
+        String path = "/dmaap";
+        String method = "GET";
+        initPermissionBuilder(path, method, provideDefaultInstance());
+
+        //when
+        String permission = permissionBuilder.buildPermission(request);
+
+        //then
+        assertEquals("org.onap.dmaap-bc.api.dmaap|boot|GET", permission);
+    }
+
+    @Test
+    public void buildPermission_shouldBuildPermissionWithRealInstance() {
+        //given
+        String path = "/subpath/topics/";
+        String method = "GET";
+        initPermissionBuilder(path, method, provideRealInstance(DMAAP_NAME));
+
+        //when
+        String permission = permissionBuilder.buildPermission(request);
+
+        //then
+        assertEquals("org.onap.dmaap-bc.api.topics|mr|GET", permission);
+    }
+
+    private void initPermissionBuilder(String path, String method, Dmaap dmaapInstance) {
+        when(dmaapConfig.getProperty(PermissionBuilder.API_NS_PROP, PermissionBuilder.DEFAULT_API_NS))
+            .thenReturn(PermissionBuilder.DEFAULT_API_NS);
+        when(dmaapService.getDmaap()).thenReturn(dmaapInstance);
+        permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+        when(request.getPathInfo()).thenReturn(path);
+        when(request.getMethod()).thenReturn(method);
+    }
+
+    private Dmaap provideDefaultInstance() {
+        return new  Dmaap("0", "", "", "", "", "", "", "");
+    }
+
+    private Dmaap provideRealInstance(String dmaapName) {
+        Dmaap dmaap = new Dmaap("1", "org.onap.dmaap", dmaapName, "https://dmaap-dr-prov:8443", "", "DCAE_MM_AGENT", "", "");
+        dmaap.setStatus(DmaapObject_Status.VALID);
+        return dmaap;
+    }
+
+}
\ No newline at end of file
index c811740..8a9bf52 100644 (file)
@@ -27,7 +27,7 @@
 
 major=1
 minor=0
-patch=23
+patch=26
 base_version=${major}.${minor}.${patch}
 
 # Release must be completed with git revision # in Jenkins