From e8a1d9cbbefb2988092e96b13d0b13254c92d1b2 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Tue, 1 Dec 2015 16:49:03 +1100 Subject: Block startup until initial profile load completed It is possible for the CMS getStatus resource to indicate that CMS is ready when the initial loading of profiles (which is performed by another thread) is not complete. During startup, wait for the initial loading of profiles to complete before continuing. Fixes: https://fedorahosted.org/pki/ticket/1702 --- .../cmscore/profile/LDAPProfileSubsystem.java | 37 ++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'base/server') diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java index f48aea391..28b34cda8 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java +++ b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java @@ -19,10 +19,12 @@ package com.netscape.cmscore.profile; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.util.Arrays; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.TreeMap; import java.util.TreeSet; +import java.util.concurrent.CountDownLatch; import netscape.ldap.LDAPAttribute; import netscape.ldap.LDAPConnection; @@ -68,6 +70,11 @@ public class LDAPProfileSubsystem /* Set of nsUniqueIds of deleted entries */ private TreeSet deletedNsUniqueIds; + /* Variables to track initial loading of profiles */ + private Integer initialNumProfiles = null; + private int numProfilesLoaded = 0; + private CountDownLatch initialLoadDone = new CountDownLatch(1); + /** * Initializes this subsystem with the given configuration * store. @@ -109,6 +116,13 @@ public class LDAPProfileSubsystem monitor = new Thread(this, "profileChangeMonitor"); monitor.start(); + try { + initialLoadDone.await(); + } catch (InterruptedException e) { + CMS.debug("LDAPProfileSubsystem: caught InterruptedException " + + "while waiting for initial load of profiles."); + } + CMS.debug("LDAPProfileSubsystem: finished init"); } /** @@ -380,6 +394,12 @@ public class LDAPProfileSubsystem return "cn=" + id + "," + dn; } + private void checkInitialLoadDone() { + if (initialNumProfiles != null + && numProfilesLoaded >= initialNumProfiles) + initialLoadDone.countDown(); + } + public void run() { int op = LDAPPersistSearchControl.ADD | LDAPPersistSearchControl.MODIFY @@ -400,12 +420,23 @@ public class LDAPProfileSubsystem cons.setServerControls(persistCtrl); cons.setBatchSize(1); cons.setServerTimeLimit(0 /* seconds */); - String[] attrs = {"*", "entryUSN", "nsUniqueId"}; + String[] attrs = {"*", "entryUSN", "nsUniqueId", "numSubordinates"}; LDAPSearchResults results = conn.search( - dn, LDAPConnection.SCOPE_ONE, "(objectclass=*)", + dn, LDAPConnection.SCOPE_SUB, "(objectclass=*)", attrs, false, cons); while (!stopped && results.hasMoreElements()) { LDAPEntry entry = results.next(); + + String[] objectClasses = + entry.getAttribute("objectClass").getStringValueArray(); + if (Arrays.asList(objectClasses).contains("organizationalUnit")) { + initialNumProfiles = new Integer( + entry.getAttribute("numSubordinates") + .getStringValueArray()[0]); + checkInitialLoadDone(); + continue; + } + LDAPEntryChangeControl changeControl = (LDAPEntryChangeControl) LDAPUtil.getControl( LDAPEntryChangeControl.class, results.getResponseControls()); @@ -436,6 +467,8 @@ public class LDAPProfileSubsystem } else { CMS.debug("Profile change monitor: immediate result"); readProfile(entry); + numProfilesLoaded += 1; + checkInitialLoadDone(); } } } catch (ELdapException e) { -- cgit