Create Helm based Certificates for Clients
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / reports / Analyze.java
index 0d5ad47..60902f1 100644 (file)
@@ -106,8 +106,6 @@ public class Analyze extends Batch {
                 tt.done();
             }
             
-            // Load Cred.  We don't follow Visitor, because we have to gather up everything into Identity Anyway
-            Cred.load(trans, session);
 
             minOwners=1;
 
@@ -149,8 +147,6 @@ public class Analyze extends Batch {
             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 {
@@ -160,335 +156,356 @@ public class Analyze extends Batch {
 
     @Override
     protected void run(AuthzTrans trans) {
+       TimeTaken tt;
        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);
+               // Hold Good Tickets to keyed User/Role for UserRole Step
+               Map<String,Ticket> mur = new TreeMap<>();
+
        try {
-                       Future.load(noAvg, session, Future.withConstruct, fut -> {
-                               List<Approval> appls = Approval.byTicket.get(fut.id());
-                               if(!futureRange.inRange(fut.expires())) {
-                                       deleteCW.comment("Future %s expired", fut.id());
-                                       Future.row(deleteCW,fut);
-                                       if(appls!=null) {
-                                               for(Approval a : appls) {
-                                                       Approval.row(deleteCW, a);
+               Approval.load(trans, session, Approval.v2_0_17);
+       
+                       ////////////////////
+                       final Map<UUID,Ticket> goodTickets = new TreeMap<>();
+               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(!futureRange.inRange(fut.expires())) {
+                                               deleteCW.comment("Future %s expired", fut.id());
+                                               Future.row(deleteCW,fut);
+                                               if(appls!=null) {
+                                                       for(Approval a : appls) {
+                                                               Approval.row(deleteCW, a);
+                                                       }
                                                }
+                                       } else if(appls==null) { // Orphaned Future (no Approvals)
+                                               deleteCW.comment("Future is Orphaned");
+                                               Future.row(deleteCW,fut);
+                                       } else  {
+                                               goodTickets.put(fut.fdd.id, new Ticket(fut));
+                                       }
+                               });
+               } finally {
+                       tt.done();
+               }
+                       
+               Set<String> approvers = new TreeSet<>();
+               tt = trans.start("Connect Approvals with Futures",Trans.SUB);
+               try {
+                               for(Approval appr : Approval.list) {
+                                       Ticket ticket=null;
+                                       UUID ticketID = appr.getTicket();
+                                       if(ticketID!=null) {
+                                               ticket = goodTickets.get(appr.getTicket());
+                                       }
+                                       if(ticket == null) { // Orphaned Approvals, no Futures
+                                               deleteCW.comment("Approval is Orphaned");
+                                               Approval.row(deleteCW, appr);
+                                       } else {
+                                               ticket.approvals.add(appr); // add to found Ticket
+                                               approvers.add(appr.getApprover());
                                        }
-                               } else if(appls==null) { // Orphaned Future (no Approvals)
-                                       deleteCW.comment("Future is Orphaned");
-                                       Future.row(deleteCW,fut);
-                               } else  {
-                                       goodTickets.put(fut.fdd.id, new Ticket(fut));
-                               }
-                       });
-       } finally {
-               tt.done();
-       }
-               
-       Set<String> approvers = new TreeSet<>();
-       tt = trans.start("Connect Approvals with Futures",Trans.SUB);
-       try {
-                       for(Approval appr : Approval.list) {
-                               Ticket ticket=null;
-                               UUID ticketID = appr.getTicket();
-                               if(ticketID!=null) {
-                                       ticket = goodTickets.get(appr.getTicket());
-                               }
-                               if(ticket == null) { // Orphaned Approvals, no Futures
-                                       deleteCW.comment("Approval is Orphaned");
-                                       Approval.row(deleteCW, appr);
-                               } else {
-                                       ticket.approvals.add(appr); // add to found Ticket
-                                       approvers.add(appr.getApprover());
                                }
-                       }
-       } finally {
-               tt.done();
-       }
-
-               /* Run through all Futures, and see if 
-                * 1) they have been executed (no longer valid)
-                * 2) The current Approvals indicate they can proceed 
-                */
-               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()) {
-                               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;
+               } finally {
+                       tt.done();
+               }
+       
+                       /* Run through all Futures, and see if 
+                        * 1) they have been executed (no longer valid)
+                        * 2) The current Approvals indicate they can proceed 
+                        */
+                       Map<String,Pending> pendingApprs = new HashMap<>();
+                       Map<String,Pending> pendingTemp = new HashMap<>();
+       
+                       String approver;
+                       
+                       tt = trans.start("Analyze Good Tickets",Trans.SUB);
+                       try {
+                               for(Ticket ticket : goodTickets.values()) {
+                                       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];
-                                                                               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();
+                                                               
+                                                               // 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 {
-                                       if("user_role".equals(ticket.f.fdd.target)) {
-                                               String key = ticket.f.fdd.target_key; 
-                                               if(key!=null) {
-                                                       mur.put(key, ticket);
                                                }
                                        }
                                }
+                       } finally {
+                               tt.done();
                        }
-               } finally {
-                       tt.done();
-               }
-
-               // Good Tickets no longer needed
-               goodTickets.clear();
-
-               /**
-                * Decide to Notify about Approvals, based on activity/last Notified
-                */
-               tt = trans.start("Analyze Approval Reminders", Trans.SUB);
-               try {
-                       GregorianCalendar gc = new GregorianCalendar();
-                       gc.add(GregorianCalendar.DAY_OF_WEEK, 5);
-                       Date remind = gc.getTime();
-                       
-                       for(Entry<String, Pending> es : pendingApprs.entrySet()) {
-                               Pending p = es.getValue();
-                               if(p.newApprovals() 
-                                               || p.earliest() == null 
-                                               || p.earliest().after(remind)) {
-                                       p.row(needApproveCW,es.getKey());
+                       // Good Tickets no longer needed
+                       goodTickets.clear();
+       
+                       /**
+                        * Decide to Notify about Approvals, based on activity/last Notified
+                        */
+                       tt = trans.start("Analyze Approval Reminders", Trans.SUB);
+                       try {
+                               GregorianCalendar gc = new GregorianCalendar();
+                               gc.add(GregorianCalendar.DAY_OF_WEEK, 5);
+                               Date remind = gc.getTime();
+                               
+                               for(Entry<String, Pending> es : pendingApprs.entrySet()) {
+                                       Pending p = es.getValue();
+                                       if(p.newApprovals() 
+                                                       || p.earliest() == null 
+                                                       || p.earliest().after(remind)) {
+                                               p.row(needApproveCW,es.getKey());
+                                       }
                                }
+                       } finally {
+                               tt.done();
                        }
-               } finally {
-                       tt.done();
-               }
-               
-               // clear out Approval Intermediates
-               pendingTemp = null;
-               pendingApprs = null;
-               
+                       
+                       // clear out Approval Intermediates
+                       pendingTemp = null;
+                       pendingApprs = null;
+       } finally {
+               Approval.clear();
+       }
+                       
                /**
                   Run through User Roles.  
                   Owners are treated specially in next section.
                   Regular roles are checked against Date Ranges.  If match Date Range, write out to appropriate file.
-               */              
-               try {
-                       tt = trans.start("Analyze UserRoles, storing Owners",Trans.SUB);
-                       Set<String> specialCommented = new HashSet<>();
-                       Map<String, Set<UserRole>> owners = new TreeMap<>();
-                       try {
-                               UserRole.load(noAvg, session, UserRole.v2_0_11, ur -> {
-                                       Identity identity;
-                                       try {
-                                               identity = trans.org().getIdentity(noAvg,ur.user());
-                                               if(identity==null) {
-                                                       // Candidate for Delete, but not Users if Special
-                                                       String id = ur.user();
-                                                       for(String s : specialDomains) {
-                                                               if(id.endsWith(s)) {
+               */      
+       
+       try {
+               Role.load(trans, session);
+       
+                       try {
+                               tt = trans.start("Analyze UserRoles, storing Owners",Trans.SUB);
+                               Set<String> specialCommented = new HashSet<>();
+                               Map<String, Set<UserRole>> owners = new TreeMap<>();
+                               try {
+                                       UserRole.load(noAvg, session, UserRole.v2_0_11, ur -> {
+                                               Identity identity;
+                                               try {
+                                                       identity = trans.org().getIdentity(noAvg,ur.user());
+                                                       if(identity==null) {
+                                                               // Candidate for Delete, but not Users if Special
+                                                               String id = ur.user();
+                                                               for(String s : specialDomains) {
+                                                                       if(id.endsWith(s)) {
+                                                                               if(!specialCommented.contains(id)) {
+                                                                                       deleteCW.comment("ID %s is part of special Domain %s (UR Org Check)", id,s);
+                                                                                       specialCommented.add(id);
+                                                                               }
+                                                                               return;
+                                                                       }
+                                                               }
+                                                               if(specialNames.contains(id)) {
                                                                        if(!specialCommented.contains(id)) {
-                                                                               deleteCW.comment("ID %s is part of special Domain %s (UR Org Check)", id,s);
+                                                                               deleteCW.comment("ID %s is a special ID  (UR Org Check)", id);
                                                                                specialCommented.add(id);
                                                                        }
                                                                        return;
                                                                }
-                                                       }
-                                                       if(specialNames.contains(id)) {
-                                                               if(!specialCommented.contains(id)) {
-                                                                       deleteCW.comment("ID %s is a special ID  (UR Org Check)", id);
-                                                                       specialCommented.add(id);
-                                                               }
+                                                               ur.row(deleteCW, UserRole.UR,"Not in Organization");
+                                                               return;
+                                                       } else if(Role.byName.get(ur.role())==null) {
+                                                               ur.row(deleteCW, UserRole.UR,String.format("Role %s does not exist", ur.role()));
                                                                return;
                                                        }
-                                                       ur.row(deleteCW, UserRole.UR,"Not in Organization");
-                                                       return;
-                                               } else if(Role.byName.get(ur.role())==null) {
-                                                       ur.row(deleteCW, UserRole.UR,String.format("Role %s does not exist", ur.role()));
-                                                       return;
-                                               }
-                                               // 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);
+                                                       // 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);
+                                                                                       }
                                                                                }
                                                                        }
                                                                }
                                                        }
+                                               } catch (OrganizationException e) {
+                                                       noAvg.error().log(e);
                                                }
-                                       } catch (OrganizationException e) {
-                                               noAvg.error().log(e);
-                                       }
-                               });
-                       } finally {
-                               tt.done();
-                       }
-               
-                       /**
-                         Now Process Owners, one owner Role at a time, ensuring one is left,
-                         preferably a good one. If so, process the others as normal. 
-                         
-                         Otherwise, write to ExpiredOwners Report
-                       */
-                       tt = trans.start("Analyze Owners Separately",Trans.SUB);
-                       try {
-                               if (!owners.values().isEmpty()) {
-                                       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,sdate,2);
-
-                                       try {
-                                               for (Set<UserRole> sur : owners.values()) {
-                                                       int goodOwners = 0;
-                                                       for (UserRole ur : sur) {
-                                                               if (ur.expires().after(now)) {
-                                                                       ++goodOwners;
-                                                               }
-                                                       }
+                                       });
+                               } finally {
+                                       tt.done();
+                               }
+                               mur.clear();
+                               
+                               /**
+                                 Now Process Owners, one owner Role at a time, ensuring one is left,
+                                 preferably a good one. If so, process the others as normal. 
+                                 
+                                 Otherwise, write to ExpiredOwners Report
+                               */
+                               tt = trans.start("Analyze Owners Separately",Trans.SUB);
+                               try {
+                                       if (!owners.values().isEmpty()) {
+                                               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,sdate,2);
        
-                                                       for (UserRole ur : sur) {
-                                                               if (goodOwners >= minOwners) {
-                                                                       Range r = writeAnalysis(noAvg, ur);
-                                                                       if(r!=null) {
+                                               try {
+                                                       for (Set<UserRole> sur : owners.values()) {
+                                                               int goodOwners = 0;
+                                                               for (UserRole ur : sur) {
+                                                                       if (ur.expires().after(now)) {
+                                                                               ++goodOwners;
+                                                                       }
+                                                               }
+               
+                                                               for (UserRole ur : sur) {
+                                                                       if (goodOwners >= minOwners) {
+                                                                               Range r = writeAnalysis(noAvg, ur);
+                                                                               if(r!=null) {
+                                                                                       Approval existing = findApproval(ur);
+                                                                                       if(existing==null) {
+                                                                                               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(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(needApproveCW,UserRole.APPROVE_UR);
-                                                                       }
                                                                }
                                                        }
-                                               }
-                                       } finally {
-                                               if(expOwner!=null) {
-                                                       expOwner.close();
+                                               } finally {
+                                                       if(expOwner!=null) {
+                                                               expOwner.close();
+                                                       }
                                                }
                                        }
-                               }
-                       } finally {
-                               tt.done();
-                       }
+                               } finally {
+                                       tt.done();
+                               }
+                       } finally {
+                               Role.clear();
+                               UserRole.clear();
+                       }
                        
                        /**
                         * Check for Expired Credentials
-                        * 
-                        * 
                         */
-                       tt = trans.start("Analyze Expired Credentials",Trans.SUB);
                        try {
-                               for (Cred cred : Cred.data.values()) {
-                               List<Instance> linst = cred.instances;
-                               if(linst!=null) {
-                                       Instance lastBath = null;
-                                       for(Instance inst : linst) {
-       //                                      if(inst.attn>0) {
-       //                                              writeAnalysis(trans, cred, inst);
-       //                                              // Special Behavior: only eval the LAST Instance
-       //                                      } else 
-                                               // All Creds go through Life Cycle
-                                               if(deleteDate!=null && inst.expires.before(deleteDate)) {
-                                                       writeAnalysis(noAvg, cred, inst); // will go to Delete
-                                               // Basic Auth has Pre-EOL notifications IF there is no Newer Credential
-                                               } else if (inst.type == CredDAO.BASIC_AUTH || inst.type == CredDAO.BASIC_AUTH_SHA256) {
-                                                       if(lastBath==null || lastBath.expires.before(inst.expires)) {
-                                                               lastBath = inst;
-                                                       }
-                                               }
-                                       }
-                                       if(lastBath!=null) {
-                                               writeAnalysis(noAvg, cred, lastBath);
+                       // Load Cred.  We don't follow Visitor, because we have to gather up everything into Identity Anyway
+                       Cred.load(trans, session);
+       
+                               tt = trans.start("Analyze Expired Credentials",Trans.SUB);
+                               try {
+                                       for (Cred cred : Cred.data.values()) {
+                                       List<Instance> linst = cred.instances;
+                                       if(linst!=null) {
+                                               Instance lastBath = null;
+                                               for(Instance inst : linst) {
+               //                                      if(inst.attn>0) {
+               //                                              writeAnalysis(trans, cred, inst);
+               //                                              // Special Behavior: only eval the LAST Instance
+               //                                      } else 
+                                                       // All Creds go through Life Cycle
+                                                       if(deleteDate!=null && inst.expires.before(deleteDate)) {
+                                                               writeAnalysis(noAvg, cred, inst); // will go to Delete
+                                                       // Basic Auth has Pre-EOL notifications IF there is no Newer Credential
+                                                       } else if (inst.type == CredDAO.BASIC_AUTH || inst.type == CredDAO.BASIC_AUTH_SHA256) {
+                                                               if(lastBath==null || lastBath.expires.before(inst.expires)) {
+                                                                       lastBath = inst;
+                                                               }
+                                                       }
+                                               }
+                                               if(lastBath!=null) {
+                                                       writeAnalysis(noAvg, cred, lastBath);
+                                               }
                                        }
-                               }
+                                       }
+                               } finally {
+                                       tt.done();
                                }
                        } finally {
-                               tt.done();
+                               Cred.clear();
                        }
-
+       
                        ////////////////////
                        tt = trans.start("Analyze Expired X509s",Trans.SUB);
                        try {