Batch, Remove unneeded Classes, refine, etc
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / reports / Analyze.java
index 3502083..0d5ad47 100644 (file)
@@ -38,6 +38,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.TreeSet;
 import java.util.UUID;
 
 import org.onap.aaf.auth.batch.Batch;
@@ -49,6 +50,7 @@ import org.onap.aaf.auth.batch.helpers.Cred.Instance;
 import org.onap.aaf.auth.batch.helpers.ExpireRange;
 import org.onap.aaf.auth.batch.helpers.ExpireRange.Range;
 import org.onap.aaf.auth.batch.helpers.Future;
+import org.onap.aaf.auth.batch.helpers.LastNotified;
 import org.onap.aaf.auth.batch.helpers.Role;
 import org.onap.aaf.auth.batch.helpers.UserRole;
 import org.onap.aaf.auth.batch.helpers.X509;
@@ -75,7 +77,7 @@ public class Analyze extends Batch {
     private static final int approved=2;
     
     
-       private static final String APPROVALS = "Approvals";
+       public static final String NEED_APPROVALS = "NeedApprovals";
        private static final String EXTEND = "Extend";
        private static final String EXPIRED_OWNERS = "ExpiredOwners";
        private static final String CSV = ".csv";
@@ -85,8 +87,11 @@ public class Analyze extends Batch {
        private ExpireRange expireRange;
        private Date deleteDate;
        private CSV.Writer deleteCW;
-       private CSV.Writer approveCW;
+       private CSV.Writer needApproveCW;
        private CSV.Writer extendCW;
+       private Range futureRange;
+       private final String sdate;
+       private LastNotified ln;
        
        public Analyze(AuthzTrans trans) throws APIException, IOException, OrganizationException {
         super(trans.env());
@@ -110,14 +115,14 @@ public class Analyze extends Batch {
             writerList = new HashMap<>();
             
             expireRange = new ExpireRange(trans.env().access());
-            String sdate = Chrono.dateOnlyStamp(expireRange.now);
+            sdate = Chrono.dateOnlyStamp(now);
             for( List<Range> lr : expireRange.ranges.values()) {
                for(Range r : lr ) {
                        if(writerList.get(r.name())==null) {
                        File file = new File(logDir(),r.name() + sdate +CSV);
                        CSV csv = new CSV(env.access(),file);
                        CSV.Writer cw = csv.writer(false);
-                       cw.row(INFO,r.name(),Chrono.dateOnlyStamp(expireRange.now),r.reportingLevel());
+                       cw.row(INFO,r.name(),sdate,r.reportingLevel());
                        writerList.put(r.name(),cw);
                        if("Delete".equals(r.name())) {
                                deleteDate = r.getEnd();
@@ -129,22 +134,25 @@ public class Analyze extends Batch {
             }
             
             // Setup New Approvals file
-            File file = new File(logDir(),APPROVALS + sdate +CSV);
+            futureRange = expireRange.newFutureRange();
+            File file = new File(logDir(),NEED_APPROVALS + sdate +CSV);
             CSV approveCSV = new CSV(env.access(),file);
-            approveCW = approveCSV.writer();
-            approveCW.row(INFO,APPROVALS,Chrono.dateOnlyStamp(expireRange.now),1);
-            writerList.put(APPROVALS,approveCW);
+            needApproveCW = approveCSV.writer();
+            needApproveCW.row(INFO,NEED_APPROVALS,sdate,1);
+            writerList.put(NEED_APPROVALS,needApproveCW);
             
             // Setup Extend Approvals file
             file = new File(logDir(),EXTEND + sdate +CSV);
             CSV extendCSV = new CSV(env.access(),file);
             extendCW = extendCSV.writer();
-            extendCW.row(INFO,EXTEND,Chrono.dateOnlyStamp(expireRange.now),1);
+            extendCW.row(INFO,EXTEND,sdate,1);
             writerList.put(EXTEND,extendCW);
             
             // Load full data of the following
             Approval.load(trans, session, Approval.v2_0_17);
             Role.load(trans, session);
+            ln = new LastNotified(session);
+
         } finally {
             tt0.done();
         }
@@ -154,13 +162,17 @@ public class Analyze extends Batch {
     protected void run(AuthzTrans trans) {
        AuthzTrans noAvg = trans.env().newTransNoAvg();
        
+       ////////////////////
+       // Load all Notifieds, and either add to local Data, or mark for Deletion.
+       ln.loadAll(noAvg,expireRange.approveDelete,deleteCW);
+       
                ////////////////////
                final Map<UUID,Ticket> goodTickets = new TreeMap<>();
        TimeTaken tt = trans.start("Analyze Expired Futures",Trans.SUB);
        try {
                        Future.load(noAvg, session, Future.withConstruct, fut -> {
                                List<Approval> appls = Approval.byTicket.get(fut.id());
-                               if(fut.expires().before(expireRange.now)) {
+                               if(!futureRange.inRange(fut.expires())) {
                                        deleteCW.comment("Future %s expired", fut.id());
                                        Future.row(deleteCW,fut);
                                        if(appls!=null) {
@@ -179,6 +191,7 @@ public class Analyze extends Batch {
                tt.done();
        }
                
+       Set<String> approvers = new TreeSet<>();
        tt = trans.start("Connect Approvals with Futures",Trans.SUB);
        try {
                        for(Approval appr : Approval.list) {
@@ -192,6 +205,7 @@ public class Analyze extends Batch {
                                        Approval.row(deleteCW, appr);
                                } else {
                                        ticket.approvals.add(appr); // add to found Ticket
+                                       approvers.add(appr.getApprover());
                                }
                        }
        } finally {
@@ -205,78 +219,96 @@ public class Analyze extends Batch {
                Map<String,Pending> pendingApprs = new HashMap<>();
                Map<String,Pending> pendingTemp = new HashMap<>();
 
+               // Convert Good Tickets to keyed User/Role for UserRole Step
+               Map<String,Ticket> mur = new TreeMap<>();
+               String approver;
+               
                tt = trans.start("Analyze Good Tickets",Trans.SUB);
                try {
                        for(Ticket ticket : goodTickets.values()) {
-                               pendingTemp.clear();
-                               switch(ticket.f.target()) {
-                                       case "user_role":
-                                               int state[][] = new int[3][3];
-                                               int type;
-                                                               
-                                               for(Approval appr : ticket.approvals) {
-                                                       switch(appr.getType()) {
-                                                               case "owner":
-                                                                       type=owner;
-                                                                       break;
-                                                               case "supervisor":
-                                                                       type=supervisor;
-                                                                       break;
-                                                               default:
-                                                                       type=0;
+                               try {
+                                       pendingTemp.clear();
+                                       switch(ticket.f.target()) {
+                                               case "user_role":
+                                                       int state[][] = new int[3][3];
+                                                       int type;
+                                                                       
+                                                       for(Approval appr : ticket.approvals) {
+                                                               switch(appr.getType()) {
+                                                                       case "owner":
+                                                                               type=owner;
+                                                                               break;
+                                                                       case "supervisor":
+                                                                               type=supervisor;
+                                                                               break;
+                                                                       default:
+                                                                               type=0;
+                                                               }
+                                                               ++state[type][total]; // count per type
+                                                               switch(appr.getStatus()) {
+                                                                       case "pending":
+                                                                               ++state[type][pending];
+                                                                               approver = appr.getApprover();
+                                                                               Pending n = pendingTemp.get(approver);
+                                                                               if(n==null) {
+                                                                                       Date lastNotified = ln.lastNotified(approver,"ur",ticket.f.fdd.target_key);
+                                                                                       pendingTemp.put(approver,new Pending(lastNotified));
+                                                                               } else {
+                                                                                       n.inc();
+                                                                               }
+                                                                               break;
+                                                                       case "approved":
+                                                                               ++state[type][approved];
+                                                                               break;
+                                                                       default:
+                                                                               ++state[type][unknown];
+                                                               }
                                                        }
-                                                       ++state[type][total]; // count per type
-                                                       switch(appr.getStatus()) {
-                                                               case "pending":
-                                                                       ++state[type][pending];
-                                                                       Pending n = pendingTemp.get(appr.getApprover());
-                                                                       if(n==null) {
-                                                                               pendingTemp.put(appr.getApprover(),new Pending(appr.getLast_notified()));
-                                                                       } else {
-                                                                               n.inc();
+                                                       
+                                                       // To Approve:
+                                                       // Always must have at least 1 owner
+                                                       if((state[owner][total]>0 && state[owner][approved]>0) &&
+                                                               // If there are no Supervisors, that's ok
+                                                           (state[supervisor][total]==0 || 
+                                                           // But if there is a Supervisor, they must have approved 
+                                                           (state[supervisor][approved]>0))) {
+                                                                       UserRoleDAO.Data urdd = new UserRoleDAO.Data();
+                                                                       try {
+                                                                               urdd.reconstitute(ticket.f.fdd.construct);
+                                                                               if(urdd.expires.before(ticket.f.expires())) {
+                                                                                       extendCW.row("extend_ur",urdd.user,urdd.role,ticket.f.expires());
+                                                                               }
+                                                                       } catch (IOException e) {
+                                                                               trans.error().log("Could not reconstitute UserRole");
                                                                        }
-                                                                       break;
-                                                               case "approved":
-                                                                       ++state[type][approved];
-                                                                       break;
-                                                               default:
-                                                                       ++state[type][unknown];
-                                                       }
-                                               }
-                                               
-                                               // To Approve:
-                                               // Always must have at least 1 owner
-                                               if((state[owner][total]>0 && state[owner][approved]>0) &&
-                                                       // If there are no Supervisors, that's ok
-                                                   (state[supervisor][total]==0 || 
-                                                   // But if there is a Supervisor, they must have approved 
-                                                   (state[supervisor][approved]>0))) {
-                                                               UserRoleDAO.Data urdd = new UserRoleDAO.Data();
-                                                               try {
-                                                                       urdd.reconstitute(ticket.f.fdd.construct);
-                                                                       if(urdd.expires.before(ticket.f.expires())) {
-                                                                               extendCW.row("extend_ur",urdd.user,urdd.role,ticket.f.expires());
+                                                       } else { // Load all the Pending.
+                                                               for(Entry<String, Pending> es : pendingTemp.entrySet()) {
+                                                                       Pending p = pendingApprs.get(es.getKey());
+                                                                       if(p==null) {
+                                                                               pendingApprs.put(es.getKey(), es.getValue());
+                                                                       } else {
+                                                                               p.inc(es.getValue());
                                                                        }
-                                                               } catch (IOException e) {
-                                                                       trans.error().log("Could not reconstitute UserRole");
-                                                               }
-                                               } else { // Load all the Pending.
-                                                       for(Entry<String, Pending> es : pendingTemp.entrySet()) {
-                                                               Pending p = pendingApprs.get(es.getKey());
-                                                               if(p==null) {
-                                                                       pendingApprs.put(es.getKey(), es.getValue());
-                                                               } else {
-                                                                       p.inc(es.getValue());
                                                                }
                                                        }
+                                                       break;
+                                       }
+                               } finally {
+                                       if("user_role".equals(ticket.f.fdd.target)) {
+                                               String key = ticket.f.fdd.target_key; 
+                                               if(key!=null) {
+                                                       mur.put(key, ticket);
                                                }
-                                               break;
+                                       }
                                }
                        }
                } finally {
                        tt.done();
                }
-               
+
+               // Good Tickets no longer needed
+               goodTickets.clear();
+
                /**
                 * Decide to Notify about Approvals, based on activity/last Notified
                 */
@@ -288,8 +320,10 @@ public class Analyze extends Batch {
                        
                        for(Entry<String, Pending> es : pendingApprs.entrySet()) {
                                Pending p = es.getValue();
-                               if(p.earliest() == null || p.earliest().after(remind)) {
-                                       p.row(approveCW,es.getKey());
+                               if(p.newApprovals() 
+                                               || p.earliest() == null 
+                                               || p.earliest().after(remind)) {
+                                       p.row(needApproveCW,es.getKey());
                                }
                        }
                } finally {
@@ -297,7 +331,6 @@ public class Analyze extends Batch {
                }
                
                // clear out Approval Intermediates
-               goodTickets.clear();
                pendingTemp = null;
                pendingApprs = null;
                
@@ -309,7 +342,7 @@ public class Analyze extends Batch {
                try {
                        tt = trans.start("Analyze UserRoles, storing Owners",Trans.SUB);
                        Set<String> specialCommented = new HashSet<>();
-                       Map<String, Set<UserRole>> owners = new TreeMap<String, Set<UserRole>>();
+                       Map<String, Set<UserRole>> owners = new TreeMap<>();
                        try {
                                UserRole.load(noAvg, session, UserRole.v2_0_11, ur -> {
                                        Identity identity;
@@ -340,20 +373,25 @@ public class Analyze extends Batch {
                                                        ur.row(deleteCW, UserRole.UR,String.format("Role %s does not exist", ur.role()));
                                                        return;
                                                }
-                                               // Cannot just delete owners, unless there is at least one left. Process later
-                                               if ("owner".equals(ur.rname())) {
-                                                       Set<UserRole> urs = owners.get(ur.role());
-                                                       if (urs == null) {
-                                                               urs = new HashSet<UserRole>();
-                                                               owners.put(ur.role(), urs);
-                                                       }
-                                                       urs.add(ur);
-                                               } else {
-                                                       Range r = writeAnalysis(noAvg,ur);
-                                                       if(r!=null) {
-                                                               Approval existing = findApproval(ur);
-                                                               if(existing==null) {
-                                                                       ur.row(approveCW,UserRole.APPROVE_UR);
+                                               // Just let expired UserRoles sit until deleted
+                                               if(futureRange.inRange(ur.expires())) {
+                                                       if(!mur.containsKey(ur.user() + '|' + ur.role())) {
+                                                               // Cannot just delete owners, unless there is at least one left. Process later
+                                                               if ("owner".equals(ur.rname())) {
+                                                                       Set<UserRole> urs = owners.get(ur.role());
+                                                                       if (urs == null) {
+                                                                               urs = new HashSet<UserRole>();
+                                                                               owners.put(ur.role(), urs);
+                                                                       }
+                                                                       urs.add(ur);
+                                                               } else {
+                                                                       Range r = writeAnalysis(noAvg,ur);
+                                                                       if(r!=null) {
+                                                                               Approval existing = findApproval(ur);
+                                                                               if(existing==null) {
+                                                                                       ur.row(needApproveCW,UserRole.APPROVE_UR);
+                                                                               }
+                                                                       }
                                                                }
                                                        }
                                                }
@@ -374,16 +412,16 @@ public class Analyze extends Batch {
                        tt = trans.start("Analyze Owners Separately",Trans.SUB);
                        try {
                                if (!owners.values().isEmpty()) {
-                                       File file = new File(logDir(), EXPIRED_OWNERS + Chrono.dateOnlyStamp(expireRange.now) + CSV);
+                                       File file = new File(logDir(), EXPIRED_OWNERS + sdate + CSV);
                                        final CSV ownerCSV = new CSV(env.access(),file);
                                        CSV.Writer expOwner = ownerCSV.writer();
-                                       expOwner.row(INFO,EXPIRED_OWNERS,Chrono.dateOnlyStamp(expireRange.now),2);
+                                       expOwner.row(INFO,EXPIRED_OWNERS,sdate,2);
 
                                        try {
                                                for (Set<UserRole> sur : owners.values()) {
                                                        int goodOwners = 0;
                                                        for (UserRole ur : sur) {
-                                                               if (ur.expires().after(expireRange.now)) {
+                                                               if (ur.expires().after(now)) {
                                                                        ++goodOwners;
                                                                }
                                                        }
@@ -394,14 +432,14 @@ public class Analyze extends Batch {
                                                                        if(r!=null) {
                                                                                Approval existing = findApproval(ur);
                                                                                if(existing==null) {
-                                                                                       ur.row(approveCW,UserRole.APPROVE_UR);
+                                                                                       ur.row(needApproveCW,UserRole.APPROVE_UR);
                                                                                }
                                                                        }
                                                                } else {
                                                                        expOwner.row("owner",ur.role(), ur.user(), Chrono.dateOnlyStamp(ur.expires()));
                                                                        Approval existing = findApproval(ur);
                                                                        if(existing==null) {
-                                                                               ur.row(approveCW,UserRole.APPROVE_UR);
+                                                                               ur.row(needApproveCW,UserRole.APPROVE_UR);
                                                                        }
                                                                }
                                                        }
@@ -462,7 +500,6 @@ public class Analyze extends Batch {
                                        } catch (CertificateException | IOException e) {
                                                noAvg.error().log(e, "Error Decrypting X509");
                                        }
-       
                                });
                        } finally {
                                tt.done();
@@ -489,9 +526,19 @@ public class Analyze extends Batch {
        private Range writeAnalysis(AuthzTrans trans, UserRole ur) {
                Range r = expireRange.getRange("ur", ur.expires());
                if(r!=null) {
-                       CSV.Writer cw = writerList.get(r.name());
-                       if(cw!=null) {
-                               ur.row(cw,UserRole.UR);
+                       Date lnd = ln.lastNotified(LastNotified.newKey(ur));
+                       // Note: lnd is NEVER null
+                       Identity i;
+                       try {
+                               i = org.getIdentity(trans, ur.user());
+                       } catch (OrganizationException e) {
+                               i=null;
+                       }
+                       if(r.needsContact(lnd,i)) {                             
+                               CSV.Writer cw = writerList.get(r.name());
+                               if(cw!=null) {
+                                       ur.row(cw,UserRole.UR);
+                               }
                        }
                }
                return r;
@@ -501,9 +548,19 @@ public class Analyze extends Batch {
        if(cred!=null && inst!=null) {
                        Range r = expireRange.getRange("cred", inst.expires);
                        if(r!=null) {
-                               CSV.Writer cw = writerList.get(r.name());
-                               if(cw!=null) {
-                                       cred.row(cw,inst);
+                               Date lnd = ln.lastNotified(LastNotified.newKey(cred,inst));
+                               // Note: lnd is NEVER null
+                               Identity i;
+                               try {
+                                       i = org.getIdentity(trans, cred.id);
+                               } catch (OrganizationException e) {
+                                       i=null;
+                               }
+                               if(r.needsContact(lnd,i)) {                             
+                                       CSV.Writer cw = writerList.get(r.name());
+                                       if(cw!=null) {
+                                               cred.row(cw,inst);
+                                       }
                                }
                        }
        }
@@ -512,9 +569,19 @@ public class Analyze extends Batch {
     private void writeAnalysis(AuthzTrans trans, X509 x509, X509Certificate x509Cert) throws IOException {
                Range r = expireRange.getRange("x509", x509Cert.getNotAfter());
                if(r!=null) {
-                       CSV.Writer cw = writerList.get(r.name());
-                       if(cw!=null) {
-                               x509.row(cw,x509Cert);
+                       Date lnd = ln.lastNotified(LastNotified.newKey(x509,x509Cert));
+                       // Note: lnd is NEVER null
+                       Identity i;
+                       try {
+                               i = org.getIdentity(trans, x509.id);
+                       } catch (OrganizationException e) {
+                               i=null;
+                       }
+                       if(r.needsContact(lnd,i)) {
+                               CSV.Writer cw = writerList.get(r.name());
+                               if(cw!=null) {
+                                       x509.row(cw,x509Cert);
+                               }
                        }
                }
        }