Updates for more code coverage
[dmaap/dbcapi.git] / src / main / java / org / onap / dmaap / dbcapi / service / TopicService.java
index a26205c..cb81619 100644 (file)
@@ -3,6 +3,8 @@
  * 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.
@@ -61,23 +63,28 @@ public class TopicService extends BaseLoggingClass {
        private Map<String, Topic> mr_topics = DatabaseClass.getTopics();
        
        private static DmaapService dmaapSvc = new DmaapService();
-       private static Dmaap dmaap = new DmaapService().getDmaap();
        private MR_ClientService clientService = new MR_ClientService();
        private MR_ClusterService clusters = new MR_ClusterService();
        private DcaeLocationService locations = new DcaeLocationService();
        private MirrorMakerService      bridge = new MirrorMakerService();
        
        private static String centralCname;
+       private static boolean createTopicRoles;
+       private boolean strictGraph = true;
 
 
        public TopicService(){
                DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
                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;
+               }
                logger.info( "TopicService properties: CentralCname=" + centralCname + 
-                               "   defaultGlobarlMrHost=" + defaultGlobalMrHost  );
+                               "   defaultGlobarlMrHost=" + defaultGlobalMrHost +
+                               " createTopicRoles=" + createTopicRoles );
        }
        
        public Map<String, Topic> getTopics() {                 
@@ -92,7 +99,7 @@ public class TopicService extends BaseLoggingClass {
        }
        
        private List<Topic> getAllTopics( Boolean withClients ) {
-               ArrayList<Topic> topics = new ArrayList<Topic>(mr_topics.values());
+               ArrayList<Topic> topics = new ArrayList<>(mr_topics.values());
                if ( withClients ) {
                        for( Topic topic: topics ) {
                                topic.setClients( clientService.getAllMrClients(topic.getFqtn()));
@@ -117,9 +124,9 @@ public class TopicService extends BaseLoggingClass {
        }
        
        private void aafTopicSetup(Topic topic, ApiError err ) {
-
-               String t = dmaapSvc.getTopicPerm();
-               if ( t == null ) {
+               
+               String nsr = dmaapSvc.getDmaap().getTopicNsRoot();
+               if ( nsr == null ) {
                        err.setCode(500);
                        err.setMessage("Unable to establish AAF namespace root: (check /dmaap object)"  );
                        err.setFields("topicNsRoot");
@@ -129,76 +136,85 @@ public class TopicService extends BaseLoggingClass {
                // establish AAF Connection using TopicMgr identity
                AafService aaf = new AafService(ServiceType.AAF_TopicMgr);
                
-
+               AafRole pubRole = null;
+               AafRole subRole = null;
                
-               // create AAF namespace for this topic
-               AafNamespace ns = new AafNamespace( topic.getFqtn(), aaf.getIdentity());
-               {
-                       int rc = aaf.addNamespace( ns );
+               // creating Topic Roles was not an original feature.
+               // For backwards compatibility, only do this if the feature is enabled.
+               // Also, if the namespace of the topic is a foreign namespace, (i.e. not the same as our root ns)
+               // then we likely don't have permission to create sub-ns and Roles so don't try.
+               if ( createTopicRoles && topic.getFqtn().startsWith(nsr)) {
+                       // create AAF namespace for this topic
+                       AafNamespace ns = new AafNamespace( topic.getFqtn(), aaf.getIdentity());
+                       {
+                               int rc = aaf.addNamespace( ns );
+                               if ( rc != 201 && rc != 409 ) {
+                                       err.setCode(500);
+                                       err.setMessage("Unexpected response from AAF:" + rc );
+                                       err.setFields("namespace:" + topic.getFqtn() + " identity="+ aaf.getIdentity());
+                                       return;
+                               }
+                       }
+                       
+                       // create AAF Roles for MR clients of this topic
+                       String rn = "publisher";
+                       pubRole = new AafRole( topic.getFqtn(), rn );
+                       int rc = aaf.addRole( pubRole );
                        if ( rc != 201 && rc != 409 ) {
                                err.setCode(500);
                                err.setMessage("Unexpected response from AAF:" + rc );
-                               err.setFields("namespace:" + topic.getFqtn() + " identity="+ aaf.getIdentity());
+                               err.setFields("topic:" + topic.getFqtn() + " role="+ rn);
                                return;
                        }
+                       topic.setPublisherRole( pubRole.getFullyQualifiedRole() );
+                       
+                       rn = "subscriber";
+                       subRole = new AafRole( topic.getFqtn(), rn );
+                       rc = aaf.addRole( subRole );
+                       if ( rc != 201 && rc != 409 ) {
+                               err.setCode(500);
+                               err.setMessage("Unexpected response from AAF:" + rc );
+                               err.setFields("topic:" + topic.getFqtn() + " role="+ rn);
+                               return;
+                       }
+                       topic.setSubscriberRole( subRole.getFullyQualifiedRole() );
                }
-               
-               // create AAF Roles for MR clients of this topic
-               String rn = "publisher";
-               AafRole pubRole = new AafRole( topic.getFqtn(), rn );
-               int rc = aaf.addRole( pubRole );
-               if ( rc != 201 && rc != 409 ) {
-                       err.setCode(500);
-                       err.setMessage("Unexpected response from AAF:" + rc );
-                       err.setFields("topic:" + topic.getFqtn() + " role="+ rn);
-                       return;
-               }
-               topic.setPublisherRole( pubRole.getFullyQualifiedRole() );
-               
-               rn = "subscriber";
-               AafRole subRole = new AafRole( topic.getFqtn(), rn );
-               rc = aaf.addRole( subRole );
-               if ( rc != 201 && rc != 409 ) {
-                       err.setCode(500);
-                       err.setMessage("Unexpected response from AAF:" + rc );
-                       err.setFields("topic:" + topic.getFqtn() + " role="+ rn);
-                       return;
-               }
-               topic.setSubscriberRole( subRole.getFullyQualifiedRole() );
        
-               
                // create AAF perms checked by MR
                String instance = ":topic." + topic.getFqtn();
                String[] actions = { "pub", "sub", "view" };
+               String t = dmaapSvc.getTopicPerm();
                for ( String action : actions ){
                        DmaapPerm perm = new DmaapPerm( t, instance, action );
-                       rc = aaf.addPerm( perm );
+                       int rc = aaf.addPerm( perm );
                        if ( rc != 201 && rc != 409 ) {
                                err.setCode(500);
                                err.setMessage("Unexpected response from AAF:" + rc );
                                err.setFields("t="+t + " instance="+ instance + " action="+ action);
                                return;
                        }
-                       // Grant perms to our default Roles
-                       if ( action.equals( "pub") || action.equals( "view") ) {
-                               DmaapGrant g = new DmaapGrant( perm, pubRole.getFullyQualifiedRole() );
-                               rc = aaf.addGrant( g );
-                               if ( rc != 201 && rc != 409 ) {
-                                       err.setCode(rc);
-                                       err.setMessage( "Grant of " + perm.toString() + " failed for " + pubRole.getFullyQualifiedRole() );
-                                       logger.warn( err.getMessage());
-                                       return;
-                               } 
-                       }
-                       if ( action.equals( "sub") || action.equals( "view") ) {
-                               DmaapGrant g = new DmaapGrant( perm, subRole.getFullyQualifiedRole() );
-                               rc = aaf.addGrant( g );
-                               if ( rc != 201 && rc != 409 ) {
-                                       err.setCode(rc);
-                                       err.setMessage( "Grant of " + perm.toString() + " failed for " + subRole.getFullyQualifiedRole() );
-                                       logger.warn( err.getMessage());
-                                       return;
-                               } 
+                       if ( createTopicRoles ) {
+                               // Grant perms to our default Roles
+                               if ( action.equals( "pub") || action.equals( "view") ) {
+                                       DmaapGrant g = new DmaapGrant( perm, pubRole.getFullyQualifiedRole() );
+                                       rc = aaf.addGrant( g );
+                                       if ( rc != 201 && rc != 409 ) {
+                                               err.setCode(rc);
+                                               err.setMessage( "Grant of " + perm.toString() + " failed for " + pubRole.getFullyQualifiedRole() );
+                                               logger.warn( err.getMessage());
+                                               return;
+                                       } 
+                               }
+                               if ( action.equals( "sub") || action.equals( "view") ) {
+                                       DmaapGrant g = new DmaapGrant( perm, subRole.getFullyQualifiedRole() );
+                                       rc = aaf.addGrant( g );
+                                       if ( rc != 201 && rc != 409 ) {
+                                               err.setCode(rc);
+                                               err.setMessage( "Grant of " + perm.toString() + " failed for " + subRole.getFullyQualifiedRole() );
+                                               logger.warn( err.getMessage());
+                                               return;
+                                       } 
+                               }
                        }
 
                }
@@ -258,6 +274,7 @@ public class TopicService extends BaseLoggingClass {
                                logger.info( "c fqtn=" + c.getFqtn() + " ID=" + c.getMrClientId() + " url=" + c.getTopicURL());
                                MR_Client nc = new MR_Client( c.getDcaeLocationName(), topic.getFqtn(), c.getClientRole(), c.getAction());
                                nc.setFqtn(topic.getFqtn());
+                               nc.setClientIdentity( c.getClientIdentity());
                                logger.info( "nc fqtn=" + nc.getFqtn() + " ID=" + nc.getMrClientId() + " url=" + nc.getTopicURL());
                                clients2.add( clientService.addMr_Client(nc, topic, err));
                                if ( ! err.is2xx()) {
@@ -285,10 +302,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);
@@ -297,6 +317,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());
@@ -360,7 +381,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;   
@@ -370,6 +392,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 ) {
@@ -384,19 +407,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");